Aller au contenu

Vue filtrée pour Administrateur Planificateur Gestionnaire de patrimoine Enseignant Étudiant Tout afficher

J5 — Les contrats

Vérifié contre le produit le .

L’objectif du jour : ajouter un champ et le voir arriver jusqu’à l’écran, en sachant à chaque étape ce qui est écrit à la main et ce qui est engendré.

Durée réaliste une demi-journée, exercice compris
Prérequis J3 — la carte, et le réflexe du ^build

Le dépôt en porte deux, et on les confond volontiers :

  • packages/schemas — des schémas Zod écrits à la main, partagés par l’API, le web et le solveur. C’est le contrat de validation : mêmes règles des deux côtés du réseau, et des fonctions pures partagées plutôt que dupliquées.
  • packages/api-client — un client TypeScript entièrement engendré depuis l’OpenAPI que l’API émet. C’est le contrat de transport : les chemins, les paramètres, les formes de réponse.

Le premier se modifie. Le second se régénère. Rien ne s’écrit à la main sous packages/api-client/src/generated/.

Elle est déclarée dans turbo.json, et c’est la seule partie du dépôt qui a besoin d’être lue avant d’être comprise :

api#openapi:emit → @beemyschool/api-client#generate → @beemyschool/api-client#build

En clair :

  1. api#openapi:emit démarre l’application NestJS sans écouter de port, construit le document OpenAPI et l’écrit dans apps/api/openapi.json. Il tourne en NODE_ENV=test, ce qui saute les migrations au démarrage : aucune base n’est nécessaire pour engendrer la spécification.
  2. generate passe ce fichier à openapi-typescript, qui écrit packages/api-client/src/generated/schema.ts.
  3. build compile le paquet, que apps/web consomme.

Le typecheck du client dépend lui aussi de generate — sinon il vérifierait un fichier absent ou périmé.

Ce qu’il faut relancer après un changement de contrat : la chaîne entière, ce que fait bun run build à la racine. Turbo en respecte l’ordre et ne rejoue que ce qui a bougé.

Prenez un champ optionnel sur une ressource existante — c’est le meilleur exercice du dépôt, parce qu’il traverse tout sans rien risquer.

  1. packages/db/src/schema.ts — ajoutez la colonne, puis bun run --filter @beemyschool/db db:generate et relisez le SQL produit.
  2. packages/schemas — ajoutez le champ au schéma Zod de la ressource. Optionnel, pour ne rien casser chez les appelants existants.
  3. apps/api — le module concerné : le champ traverse le contrôleur, le service et la réponse.
  4. La chaînebun run build à la racine. Vérifiez que le champ apparaît bien dans apps/api/openapi.json, puis dans packages/api-client/src/generated/schema.ts.
  5. apps/web — affichez-le. Le client typé vous guide : si le champ n’existe pas dans les types, c’est que l’étape 4 n’a pas été rejouée.
  6. Les tests — un cas côté API, et bun run typecheck à la racine pour la traversée complète.

Si les six étapes passent, vous savez livrer une fonctionnalité de bout en bout. C’est aussi la première contribution que propose J7.

  • Vous savez distinguer le contrat de validation (schemas) du contrat de transport (api-client)
  • Vous savez réciter la chaîne openapi:emit → generate → build et dire ce que produit chaque étape
  • Vous savez que la génération de l’OpenAPI ne demande aucune base
  • Votre champ d’exercice remonte jusqu’à l’écran
  • Vous savez où regarder — openapi.json, puis generated/schema.ts — quand un type manque

J6 — Le solveur : le seul module du dépôt qui ne soit pas en TypeScript, et le seul dont le contrat est tenu par deux implémentations à la fois.

Documentation technique source (2)