Capitalise nouveaux patterns backend/frontend/BMAD et externalise les templates du post-install BMAD

This commit is contained in:
MaksTinyWorkshop
2026-03-10 10:52:07 +01:00
parent 4a3df7cd01
commit f7a55b1113
23 changed files with 742 additions and 220 deletions

View File

@@ -8,7 +8,7 @@ Objectifs :
- éviter de reposer les mêmes questions
- assumer les compromis
Dernière mise à jour : 2026-03-09
Dernière mise à jour : 2026-03-10
---
@@ -20,6 +20,8 @@ Dernière mise à jour : 2026-03-09
- [Le front-end est un logiciel en production](#decision-frontend-production)
- [Le back-end est un logiciel en production](#decision-backend-production)
- [Contrats dAPI explicites et versionnés](#decision-contrats-api)
- [Single source of truth des contrats — schémas runtime partagés (Zod) + z.infer (No-DTO)](#decision-contrats-sso-zod)
- [User views — User public par défaut + MeUser explicite](#decision-user-views)
- [Gestion standard des erreurs et des statuts HTTP](#decision-erreurs-http)
- [Migrations et évolution de schéma maîtrisées](#decision-migrations)
- [Observabilité minimale obligatoire](#decision-observabilite)
@@ -301,6 +303,89 @@ Minimum attendu :
---
<a id="decision-contrats-sso-zod"></a>
## Single source of truth des contrats — schémas runtime partagés (Zod) + z.infer (No-DTO)
- Date : 2026-03-10
- Statut : Proposed
- Périmètre : global
### Contexte
TypeScript ne valide pas les payloads HTTP au runtime (les types disparaissent à lexécution).
Quand on maintient à la fois des DTO/back (ex. Nest + decorators) et des types/contracts côté clients, on obtient une double source de vérité → drift, régressions, temps de debug.
### Options envisagées
- DTO NestJS + `class-validator` (validation runtime OK côté API, mais non partageable tel quel côté clients → duplication ou génération)
- Schémas runtime partagés dans un package `contracts` + types dérivés (validation + types alignés)
- OpenAPI/JSON Schema “first” + codegen (artefact contractuel unique, mais pipeline/outillage à maintenir)
### Décision
La source de vérité des contrats API↔clients est un package `contracts` contenant des **schémas runtime** (Zod), et les types TypeScript sont **dérivés** via `z.infer` (No-DTO / pas de redéfinition locale).
Principe opérationnel :
- validation concentrée aux frontières (ex. pipe/guard de validation côté API),
- le reste du code consomme des **types** (et non des classes DTO redondantes),
- les contrats restent “wire-level” (pas de métier, pas de stores, pas de classes Nest).
### Justification
- Un seul artefact sert à la fois de validation runtime et de typage compile-time
- Propagation des changements plus fiable (compile + tests) → réduction du temps de debug
### Conséquences
- Dépendance assumée à Zod dans `contracts`
- Les clients consomment les types; la validation côté client reste optionnelle (utile surtout sur entrées non-API : storage, deeplinks, etc.)
- En contexte non-mobile (Nest/React), OpenAPI-first + codegen reste une alternative valide si multi-clients/externe ou besoin fort de contrat public/documenté
---
<a id="decision-user-views"></a>
## User views — User public par défaut + MeUser explicite
- Date : 2026-03-10
- Statut : Proposed
- Périmètre : global
### Contexte
Un “User” complet est rarement un bon contrat universel : il peut contenir des champs sensibles (email, adresse, téléphone, flags internes…).
Les dérivations TypeScript seules (`Omit<User, "password">`) ne protègent pas au runtime et favorisent les fuites accidentelles.
### Options envisagées
- Un type `User` “god object” + dérivations TS (Omit/Pick) au cas par cas
- Des “views” explicites par contexte (public, self, admin…), dérivées depuis les schémas runtime
- Un modèle unique côté DB + sérialisation implicite (risque élevé de fuite)
### Décision
`User` (dans les contracts) est **public par défaut** et minimal (safe-by-default).
La vue self/compte est un contrat séparé `MeUser`.
Toute vue plus riche est créée explicitement et nommée (ex. `AdminUser`, `UserDirectoryEntry`).
Règles associées :
- les vues sont dérivées depuis les schémas runtime (extend/pick/omit) + `z.infer`
- `password` (et assimilés) nexiste que dans des requêtes dauth (login/register/reset/change), jamais dans un `User*`
### Justification
- Réduit le risque de fuite de données et clarifie les permissions/UX
- Évite les champs optionnels ambigus et les contrats “implicites”
### Conséquences
- Chaque endpoint choisit explicitement la vue renvoyée (et côté DB, un `select` explicite par vue)
- Les clients typent “public” vs “mon compte” distinctement
- Des tests “no secret keys” sur réponses user/auth deviennent simples et efficaces
---
<a id="decision-erreurs-http"></a>
## Gestion standard des erreurs et des statuts HTTP