Skip to content

Architecture

A TanStack Start application (React 19 + TypeScript 6 + Vite 8), client-only: it consumes the GLOBAL SIM GROUP NestJS backend over HTTP + JWT. No application server code lives here (no serverMiddleware, no database) — SSR rendering is used by the framework for HTML structure only.

┌─────────────────────────────────────────────────────────┐
│ src/routes/ routing glue (guards, layouts) │
│ src/features/ 19 business modules (residence, ...)│
│ src/components/ ui/ (shadcn) + layout/ (shell) │
│ src/core/ technical foundation │
│ api/ auth/ permissions/ query/ config/ │
│ src/integrations/ TanStack adapters (query) │
└─────────────────────────────────────────────────────────┘
│ HTTP + JWT (fetch wrapper)
▼
NestJS backend → PostgreSQL
https://dev.sim.strife-cyber.org/api/v1
Layer Content Rule
core/ Generic technical foundation (auth, api, permissions, query, env) No business logic, no coupling to modules. Imported by all other layers.
features/ One folder per real business module (residence, pressing, restaurant, salle de fête, billing, finances, HR, clients, supermarket, subscriptions, admin, reports, incidents, resident portal, client space, landing…) Business logic lives here, never in routes.
routes/ TanStack Router route files Orchestration glue only: guards, layouts, page layout.
components/ui Generated shadcn/ui + custom primitives Do not modify for business needs; compose instead.
components/layout Application shell (header, logout, notifications) Generic, shared by authenticated screens.
integrations/ Adapters between the framework and libs (tanstack-query) Survives a library migration without touching the rest.
File Generated by Regeneration
src/routeTree.gen.ts npm run generate-routes After every add/remove of a file in src/routes/.
src/core/api/generated/schema.ts npm run api:gen On every backend evolution (docs-json).

These files are excluded from Biome and are committed. See Development for the exact commands.

  • core/api does not know core/auth: the HTTP client receives its dependencies (getAccessToken, refresh, onSessionExpired) by injection when the session is built (core/auth/session.ts → setApiClient).
  • Route guards read the session from the router context (auth), never from a global module.
  • ❌ Add a raw fetch() in a component or route (everything goes through core/api).
  • ❌ Edit schema.ts or routeTree.gen.ts by hand.
  • ❌ Import a feature from another feature without going through its public index.