Aller au contenu principal

Conventions

Ces conventions sont appliquées en revue (parfois par hook), pas toutes par le lint. Le CLAUDE.md racine en est la source normative ; cette page la rend navigable.

Object-arg functions

Toute fonction à ≥ 2 entrées logiques prend un seul argument objet. Les call-sites se lisent comme des arguments nommés, jamais positionnels.

function fetchPage({ url, timeoutMs = 5_000 }: { url: string; timeoutMs?: number }) {}
fetchPage({ url, timeoutMs: 1_000 })

Exemptions (la convention ne s'applique pas) : fonctions à un seul argument ; helpers variadiques (cn(...), path.join(...)) ; callbacks à signature imposée par le framework (arr.map((x, i) => …), comparateurs (a, b) => …, handlers Hono (c) => …, useEffect(fn, deps)) ; helpers renvoyant un tuple (useState) ; constructeurs/méthodes de SDK vendeur (à envelopper dans un adapter).

Pourquoi : élimine la mémorisation de l'ordre des arguments, tue le piège du booléen positionnel (render(true, false, true)), et rend l'ajout d'un champ optionnel non-breaking.

Variables d'environnement

Chaque app expose son environnement via un seul accesseur typé ; le code applicatif ne lit jamais process.env.X directement.

  • apps/api/src/env.tsgetEnv() renvoie un Env validé par zod (charge .env via dotenv).
  • apps/web/lib/env.ts — même forme, avec import "server-only" en tête pour ne jamais finir dans un Client Component.

Règles : pas de process.env nu (le seul hit grep par app = env.ts) ; les champs requis utilisent z.string().min(1) et plantent au boot si absents ; getEnv() met en cache ; au boundary web→client, les Server Components passent des valeurs en props, jamais l'import d'env.ts. Les factories de packages/lib ne lisent pas l'env — l'app construit la config et l'injecte.

i18n

next-intl v4, source de vérité apps/web/messages/fr.json. Aucune chaîne en dur dans un composant utilisateur — toujours t("namespace.key"). Liens locale-aware via @/i18n/navigation. Détails et workflow d'édition : apps/web → i18n.

Divers (baked into config)

  • TS strict avec noUncheckedIndexedAccess et verbatimModuleSyntax (api).
  • ESM partout (type: module) ; imports style NodeNext.
  • eslint-plugin-only-warn → la plupart des échecs lint sont des warnings.

Le workflow Git & PR (branches, hooks, sentinelles) a sa propre page : Conventions → Git.