mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-05-18 08:18:15 +02:00
capitalisation: intégration ~60 entrées RL799_V2 (triage 2026-05-02)
Triage du 95_a_capitaliser.md (~75 propositions) : - 60 entrées intégrées dans knowledge/ (backend, frontend, workflow) - 4 nouveaux fichiers : backend/patterns/tests.md, backend/risques/tests.md, frontend/patterns/general.md, workflow/patterns/general.md - 6 doublons rejetés - Mise à jour des READMEs index pour refléter les nouvelles entrées - 95_a_capitaliser.md restauré à sa structure initiale - 40_decisions_et_archi.md : décision mono-tenant déployable vs SaaS multi-tenant - 90_debug_et_postmortem.md : sub-agents Write indisponible, effet iceberg CI, prisma migrate diffs cosmétiques Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -365,4 +365,97 @@ it('retourne 403 si subscription inactive', async () => {
|
||||
|
||||
- Contexte technique : auth / cycle de vie compte — RL799_V2 17-04-2026
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
<a id="risque-helpers-x-actif-derivants"></a>
|
||||
## Helpers "X actif" qui dérivent silencieusement
|
||||
|
||||
### Risques
|
||||
|
||||
- Plusieurs helpers répondent à la même question — *"l'entité X est-elle active / opérante ?"* — avec des filtres légèrement différents
|
||||
- Un user passe la guard A mais pas la guard B sur la même ressource (ou inversement). Bugs silencieux, pas d'erreur, juste une asymétrie de comportement
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Délégation `secretaireDeSeance` "active" filtrée sur `status: 'published', closedAt: null, cancelledAt: null` dans un helper, juste `cancelledAt: null` dans l'autre
|
||||
- Un ex-délégué d'une soirée clôturée garde l'autorité cross-soirée indéfiniment
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
1. **Un seul helper canonique** par notion d'activité (ex : `isDelegationActive`, `isSoireeOpenForRappel`). Les autres l'appellent
|
||||
2. Si la centralisation n'est pas faisable immédiatement (ex : helper appelé en N+1 query, perf), au moins un test qui compare leur output sur des fixtures partagées et casse à la moindre divergence
|
||||
3. Au minimum : un commentaire en tête du helper "secondaire" qui pointe vers le canonique et liste explicitement les filtres à maintenir synchronisés
|
||||
|
||||
- Contexte technique : auth / RBAC — RL799_V2 27-04-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-guard-charge-objets-riches"></a>
|
||||
## Guard d'autorisation qui charge des objets riches
|
||||
|
||||
### Risques
|
||||
|
||||
- Une guard d'autorisation s'exécute à CHAQUE requête sur une route protégée
|
||||
- Si la guard a besoin de "trouver une candidate" (ex : "cette tenue est-elle dans les 'dernières rappelables' du grade pour une de mes délégations ?"), le repo helper utilisé doit avoir un select **minimal**, PAS le select complet utilisé par les services métier
|
||||
- Pour un user avec N délégations actives, on charge N agrégats volumineux à chaque requête
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Même fonction repo appelée par (1) un service qui a besoin de toutes les relations (rendu UI) et (2) une guard qui n'a besoin que de l'id
|
||||
- La guard paie le coût du fetch riche inutilement
|
||||
- Latence guard qui croît avec le nombre de relations chargées
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
Exposer **deux variantes** du repo helper :
|
||||
|
||||
- `findX(...)` — select riche, utilisé par les services métier
|
||||
- `findXIdOnly(...)` — select `{ id: true }`, utilisé par les guards
|
||||
|
||||
```typescript
|
||||
// Guard
|
||||
export const requireXAccess = async (request, id, { roleSet }) => {
|
||||
// utilise findXIdOnly (select minimal) — pas findX
|
||||
const candidate = await repo.findXIdOnly({ ... });
|
||||
if (!candidate || candidate.id !== id) return forbidden();
|
||||
};
|
||||
|
||||
// Service métier
|
||||
export const getXFullDetails = async (id) => {
|
||||
return repo.findX({ ... }); // include riche
|
||||
};
|
||||
```
|
||||
|
||||
Coût : duplication de la clause `where` (acceptable, factorisable en constante). Bénéfice : la guard reste O(1) en payload même quand les relations grossissent.
|
||||
|
||||
- Contexte technique : auth / performance — RL799_V2 27-04-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-suppression-flag-auth-global"></a>
|
||||
## Suppression d'un flag auth global (DB + DTO + tests) — cleanup atomique obligatoire
|
||||
|
||||
### Risques
|
||||
|
||||
- Un flag profondément câblé dans Prisma (ex : `mustChangePassword`, `isVerified`) ne peut pas être supprimé incrémentalement : chaque cleanup partiel produit un état non-compilable
|
||||
- Les fixtures de tests qui posent `mustChangePassword: false` cassent à la compilation TS au moment du drop — bloque tout commit séparé
|
||||
- Les helpers `helpers/db.ts` et les DTO partagés (`packages/shared`) sont prioritaires, sinon les imports cross-package échouent en cascade
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `Property 'mustChangePassword' does not exist on type 'User'` après un drop partiel
|
||||
- Tentative de découpage en sous-lots qui échoue au typecheck
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
Quand on prévoit de supprimer un flag auth profondément câblé :
|
||||
|
||||
1. **Le cleanup ne peut pas être incrémental** — soit on supprime tout dans un chantier, soit on garde le flag avec un nullable de transition
|
||||
2. **Les fixtures de tests doivent être nettoyées dans le même PR** — grep systématique avant de démarrer (`grep -rn "mustChangePassword" apps/`) pour estimer l'ampleur
|
||||
3. **Les helpers `helpers/db.ts`** sont prioritaires — un seul fichier touché casse tous les tests qui l'importent
|
||||
4. **Les DTO partagés (`packages/shared`)** doivent être alignés en premier
|
||||
5. Considérer un sous-lot dédié au cleanup si le flag est transverse — éviter de l'inclure dans un sous-lot fonctionnel
|
||||
|
||||
**Anti-pattern** : déprécier en douceur en gardant le flag avec un commentaire `// @deprecated` sans supprimer les usages. Le code mort s'accumule, les futurs devs hésitent à le nettoyer ("pourquoi c'est encore là ?"), la dépréciation ne se finit jamais.
|
||||
|
||||
- Contexte technique : auth / refactor schema — RL799_V2 28-04-2026
|
||||
Reference in New Issue
Block a user