Structure

convex/              Backend Convex
  schema.ts          Tables et index
  http.ts            Le routeur HTTP : il assemble les routes que chaque fonctionnalité enregistre (`features/<nom>/routes.ts`)
  auth.ts, auth/     Better Auth et ses e-mails
  extensions.ts      Points d'accroche (voir Extensions)
  _lib/              Le socle : constructeurs de fonctions (auth, triggers) et validators du schéma
  features/<nom>/    Une fonctionnalité : queries, mutations, actions, internal
  lib/<domaine>/     Le code partagé d'un domaine (leads, email, security, extensions…), sans fonction Convex
  seed/, setup/      Premier employé, assistant de configuration initiale
src/
  design-system/     Composants d'interface
  widgets/           Auth, layouts, providers
  features/<nom>/    Une fonctionnalité : components/, hooks/, lib/, types.ts
  pages/             Une page par route : elle compose les composants de sa fonctionnalité, elle n'en définit pas
  lib/               backend.ts (ré-exports Convex), erreurs, navigation, pays
tests/               backend/ (convex-test), frontend/, setup.ts (voir Tests)
scripts/             Générateurs (OpenAPI, formats d'adresse)
docker/              Caddyfile + entrypoint de l'image de production
docs/                Contrats : API publique (openapi.yaml), extensions, connecteurs, secrets

Alias d'import : @crm/* → ./src/* (déclaré dans tsconfig.json et vite.config.mts).

Où va un nouveau fichier du backend : une fonction Convex (query, mutation, action) dans features/<fonctionnalité>/, ses routes HTTP dans son routes.ts ; ce que plusieurs fonctionnalités partagent dans lib/<domaine>/, importé par son module, sans fichier d'index ; un validator de table dans _lib/validators/. Les imports descendent : lib/ n'importe aucune fonctionnalité, et les validators et les constantes de _lib/ n'importent ni lib/ ni features/ (tests/backend/layering.test.ts).

Côté interface : un composant, un hook ou un helper va dans src/features/<fonctionnalité>/ (un composant par fichier) ; src/pages/ ne garde que le composant de la page. Le backend n'est importé que par src/lib/backend.ts.

Les règles que le code suit, chacune gardée par un test :