chore(capitalisation): integrate triage entries and anchor new knowledge

This commit is contained in:
MaksTinyWorkshop
2026-04-18 13:19:27 +02:00
parent 7767f1f947
commit 02ad0de258
14 changed files with 528 additions and 4 deletions

View File

@@ -29,10 +29,6 @@ Ce fichier ne doit donc **jamais devenir une documentation permanente**.
---
_Aucune entrée pour le moment_
---
# Format attendu
Chaque proposition doit suivre ce format :
@@ -83,6 +79,10 @@ Description courte, factuelle, orientée réutilisation.
---
_Aucune entrée pour le moment_
---
# Rôle dans l'architecture
```

View File

@@ -296,3 +296,49 @@ Le helper `requireRoleAccess` doit retourner :
- [ ] 401 pour tout problème de token (absent, expiré, malformé)
- [ ] 403 uniquement quand le token est valide mais le rôle insuffisant
- [ ] Frontend redirige vers `/login` sur 401, affiche "accès refusé" sur 403
---
<a id="pattern-auth-dernier-admin-actif"></a>
## Pattern : Dernier admin actif non supprimable + auto-action admin encadrée
- Objectif : préserver l'accès administratif global et éviter les auto-actions destructrices.
- Contexte : endpoints d'administration utilisateurs/rôles.
- Quand l'utiliser : toute action de suppression, désactivation, rétrogradation d'un compte admin.
- Quand l'éviter : jamais.
### Règle
- Interdire toute action qui laisserait le système sans admin actif.
- Encadrer les auto-actions admin (self-disable, self-demote, self-delete) avec règles explicites.
### Checklist
- Vérification atomique "reste au moins un admin actif".
- Codes d'erreur explicites (`LAST_ADMIN_LOCKOUT`, `SELF_ACTION_FORBIDDEN` ou équivalent).
- Test dédié pour chaque cas limite.
- Validé le : 17-04-2026
- Contexte technique : auth / RBAC admin — RL799_V2
---
<a id="pattern-auth-audit-best-effort-vs-regalien"></a>
## Pattern : Distinguer audit best-effort et audit régalien
- Objectif : expliciter quelles écritures d'audit sont non-bloquantes vs bloquantes.
- Contexte : endpoints sensibles avec journalisation.
- Quand l'utiliser : toute opération ayant une exigence de traçabilité.
- Quand l'éviter : jamais.
### Règle
- Audit best-effort : ne bloque pas l'opération métier principale.
- Audit régalien/traçabilité critique : fait partie de la transaction logique et bloque en cas d'échec.
### Checklist
- Classification explicite de chaque événement d'audit.
- Politique d'échec documentée par endpoint.
- Tests de comportement en cas de panne du canal d'audit.
- Validé le : 17-04-2026
- Contexte technique : auth / audit — RL799_V2
---

View File

@@ -330,3 +330,39 @@ it('retourne 403 si subscription inactive', async () => {
- **Signal review** : import de `verifyToken` dans un fichier service (hors `authHelpers.ts`)
- Contexte technique : auth / architecture — RL799_V2 08-04-2026
---
<a id="risque-auth-acl-unique-champ-sensible"></a>
## ACL unique pour ressource globale et sous-champ sensible
### Risques
- Champs sensibles exposés à des rôles qui ne devraient accéder qu'à la vue agrégée.
### Symptômes
- Endpoint fonctionnellement "autorisé" mais fuite de notes/valeurs sensibles en clair.
### Bonnes pratiques / mitigations
- Séparer explicitement les règles d'accès : liste globale vs détails sensibles.
- Appliquer des guards dédiés au niveau du champ ou du sous-endpoint.
- Contexte technique : auth / ACL granulaire — RL799_V2 13-04-2026
---
<a id="risque-auth-jwt-user-introuvable"></a>
## JWT valide mais utilisateur introuvable en base
### Risques
- Retour `403` trompeur (authz) au lieu d'un `401` (auth invalide côté sujet).
### Symptômes
- Frontend affiche "accès refusé" au lieu de forcer une ré-authentification.
### Bonnes pratiques / mitigations
- Si le sujet JWT ne résout plus un user actif : répondre `401`.
- Déclencher invalidation de session côté client.
- Contexte technique : auth / cycle de vie compte — RL799_V2 17-04-2026
---

View File

@@ -748,3 +748,123 @@ try {
- Les checks applicatifs seuls ne suffisent pas sous concurrence
- Contexte technique : Prisma / contraintes — RL799_V2 08-04-2026
---
<a id="risque-deploiement-migrations-apres-redemarrage"></a>
## Docker Compose — migrations exécutées après redémarrage applicatif
### Risques
- Fenêtre de non-compatibilité entre code déployé et schéma DB.
- Crash silencieux sur colonnes/contraintes nouvellement requises.
### Symptômes
- Redéploiement "vert" puis erreurs runtime immédiates sur accès DB.
### Bonnes pratiques / mitigations
- Appliquer les migrations avant le redémarrage applicatif.
- Séquence recommandée : `docker compose build` -> `docker compose run --rm api prisma migrate deploy` -> `docker compose up -d`.
- Contexte technique : Docker Compose / déploiement — RL799_V2 08-04-2026
---
<a id="risque-shell-sourcing-global-env"></a>
## Scripts shell — sourcing global de `.env`
### Risques
- `set -a; source .env` exporte tous les secrets à tous les sous-processus.
### Symptômes
- Secrets inutiles visibles dans l'environnement de commandes annexes (docker/curl/webhooks).
### Bonnes pratiques / mitigations
- Charger uniquement les variables nécessaires (`grep`/`cut` ou équivalent).
- Réserver `source .env` aux scripts qui ont réellement besoin de tout le contexte.
- Contexte technique : shell / secrets env — RL799_V2 08-04-2026
---
<a id="risque-compose-service-sans-healthcheck"></a>
## Docker Compose — services auxiliaires sans `healthcheck`
### Risques
- Faux positifs de disponibilité d'un service qui démarre mais n'est pas prêt.
### Symptômes
- Service "up" mais non exploitable (port bloqué, DB locale corrompue, etc.).
### Bonnes pratiques / mitigations
- Ajouter un `healthcheck` homogène sur tous les services critiques et auxiliaires.
- Aligner la politique de readiness/liveness sur l'ensemble du compose.
- Contexte technique : Docker Compose / observabilité service — RL799_V2 08-04-2026
---
<a id="risque-securite-bind-fail-open-production"></a>
## Configuration fail-open d'un bind réseau en production
### Risques
- Dashboard/service exposé publiquement si variable d'environnement manquante.
### Symptômes
- Service censé rester localement accessible exposé sur `0.0.0.0`.
### Bonnes pratiques / mitigations
- Forcer le bind sûr dans l'override de production (`127.0.0.1` ou réseau privé explicite).
- Ne pas dépendre d'un `.env` optionnel pour une contrainte de sécurité.
- Contexte technique : Docker Compose / sécurité réseau — RL799_V2 08-04-2026
---
<a id="risque-logs-preview-pii"></a>
## Logging de previews payload/HTML contenant des PII
### Risques
- Fuite de données personnelles via logs applicatifs agrégés.
### Symptômes
- Logs de debug contenant noms/emails/contenu message en clair.
### Bonnes pratiques / mitigations
- Ne jamais logger le body complet d'un message métier en prod.
- Journaliser uniquement des métadonnées minimales (id, statut, taille, hash tronqué).
- Contexte technique : logs / conformité — RL799_V2 15-04-2026
---
<a id="risque-base64-buffer-from-sans-exception"></a>
## Base64 invalide — `Buffer.from(..., 'base64')` ne lève pas d'exception
### Risques
- Configuration/signature invalide traitée comme erreur avaleuse (401 répétés sans cause claire).
### Symptômes
- Échec systématique de vérification HMAC sans signal de configuration corrompue.
### Bonnes pratiques / mitigations
- Valider explicitement le format/base64 attendu avant dérivation HMAC.
- Retourner un signal d'erreur opérationnelle explicite (config invalide) côté logs internes.
- Contexte technique : crypto / intégration webhook — RL799_V2 15-04-2026
---
<a id="risque-date-locale-sans-timezone"></a>
## Dates localisées sans `timeZone` explicite
### Risques
- Rendu de date divergent entre dev/CI/prod selon TZ machine.
### Symptômes
- Même ISO affiché sur des jours différents selon environnement.
### Bonnes pratiques / mitigations
- Toujours passer `timeZone` dans `toLocaleDateString`/`Intl.DateTimeFormat` pour les sorties métier.
- Définir une timezone métier unique pour les communications utilisateur.
- Contexte technique : dates / formatage serveur — RL799_V2 15-04-2026

View File

@@ -407,3 +407,37 @@ Checklist minimale après `prisma migrate resolve --applied` :
- **Signal review** : `catch {` ou `catch (e) {` sans vérification de `e.code` dans un repository Prisma
- Contexte technique : Prisma / error handling — RL799_V2 08-04-2026
---
<a id="risque-prisma-filtre-lecture-ecriture-desaligne"></a>
## Filtre de lecture appliqué mais filtre d'écriture oublié
### Risques
- Mutation (`updateMany`/`deleteMany`) affectant des lignes hors périmètre autorisé.
### Symptômes
- Le listing semble correct, mais les opérations d'écriture touchent des données invisibles pour l'utilisateur.
### Bonnes pratiques / mitigations
- Aligner strictement les prédicats lecture/écriture sur les mêmes dimensions métier (ex: grade, tenant, statut).
- Factoriser le filtre dans un helper partagé côté service/repository.
- Contexte technique : Prisma / filtres métier — RL799_V2 09-04-2026
---
<a id="risque-prisma-deletemany-sans-partition"></a>
## `deleteMany` partiel sans clé de partition métier
### Risques
- Suppression transversale de données d'autres partitions (ex: grade, segment, scope logique).
### Symptômes
- Comportement correct tant que le frontend envoie un payload complet, puis corruption lors d'un refactor/concurrence.
### Bonnes pratiques / mitigations
- Inclure toutes les dimensions de partition dans les clauses `deleteMany`/`updateMany`.
- Ajouter des tests ciblés sur payload partiel et concurrence logique.
- Contexte technique : Prisma / partition logique — RL799_V2 09-04-2026

View File

@@ -176,3 +176,25 @@ return (
</>
);
```
---
<a id="pattern-navigation-overlay-focus-trap"></a>
## Pattern : Overlay/drawer accessible avec focus trap
### Synthèse
Teleport + backdrop + Escape + scroll-lock n'est pas suffisant : le focus trap est obligatoire.
### Analyse
Sans focus trap, le clavier peut sortir de la sheet/panel et casser l'ordre de navigation.
### Validation
- Validé le : 09-04-2026
- Contexte technique : Vue 3 / accessibilité overlays — RL799_V2
- Applicable à tout drawer/sheet/modal custom en SPA (desktop et mobile clavier).
### Implémentation
- Capturer le focus à l'ouverture (premier élément interactif).
- Boucler Tab/Shift+Tab dans le conteneur.
- Restaurer le focus au trigger à la fermeture.
---

View File

@@ -187,3 +187,24 @@ Ne jamais :
- [ ] Garde-fou explicite contre les doubles actions
- [ ] Refresh explicite après mutation réussie
- [ ] Tests sur succès, erreur et action concurrente
---
<a id="pattern-state-hydratation-auth-async"></a>
## Pattern : Hydratation auth asynchrone avec états explicites
### Synthèse
Lors d'un passage sync -> async au boot, exposer un statut d'hydratation explicite (`idle`/`hydrating`/`ready`).
### Analyse
Sans état transitoire formel, les guards lisent des valeurs incomplètes et déclenchent des redirections erronées.
### Validation
- Validé le : 18-04-2026
- Contexte technique : Vue 3 / Pinia / boot async — RL799_V2
- Applicable à toute initialisation critique : session, feature flags, restore état persistant.
### Implémentation (exemple minimal)
- Store : `hydrateStatus` + promesse partagée en cours pour les appels concurrents.
- Guards : `await hydrate()` avant toute décision d'accès.
- UI : fallback de rendu tant que l'hydratation n'est pas `ready`.

View File

@@ -132,3 +132,24 @@ expect(aBeforeB).toBe(true);
### Risque associé
`boundingBox().y` vérifie la position visuelle rendue par CSS, pas l'ordre dans le DOM. De plus `boundingBox()` retourne `null` pour les éléments hors viewport → crash non déterministe.
---
<a id="pattern-tests-selecteurs-e2e-stables"></a>
## Pattern : Sélecteurs E2E stables orientés intention
### Synthèse
Les tests E2E doivent cibler des sélecteurs stables (`data-testid`, role/name) et non la structure CSS/XPath.
### Analyse
Les classes et la structure DOM changent fréquemment sans régression fonctionnelle.
### Validation
- Validé le : 14-04-2026
- Contexte technique : Playwright / sélecteurs robustes — RL799_V2
- Ce pattern s'applique à Playwright/Cypress sur toutes les UIs réactives.
### Implémentation
- Préférer `data-testid` paramétré par identifiant métier stable.
- Éviter `locator.first()` si l'ordre peut muter.
- Isoler les tests mutateurs avec stratégie de remise à l'état (snapshot/restore).

View File

@@ -135,3 +135,39 @@ if (user === null || user.role !== 'ADMIN') return <View />;
- **Signal review** : `Authorization: Bearer` dans les tests alors que le code production utilise `credentials: 'include'`
- Contexte technique : Vue 3 / auth migration — RL799_V2 08-04-2026
---
<a id="risque-auth-me-fallback-localstorage"></a>
## Migration vers `/auth/me` — fallback localStorage réintroduit une confiance client
### Risques
- Un blocage réseau ciblé peut forcer un fallback sur des données locales falsifiables.
### Symptômes
- Rôle/grade consommés depuis localStorage en cas d'erreur endpoint d'autorité.
### Bonnes pratiques / mitigations
- Si l'endpoint d'autorité échoue, conserver un état non authentifié/dégradé, pas un fallback de privilèges.
- Garder localStorage strictement pour métadonnées UX non sensibles.
- Contexte technique : auth frontend / source d'autorité — RL799_V2 18-04-2026
---
<a id="risque-auth-store-source-verite-bypass-service"></a>
## Source de vérité auth déplacée vers store, appels directs service laissés en place
### Risques
- Guards/router lisent un état store non synchronisé après login/logout.
### Symptômes
- Login réussi puis redirection immédiate vers `/login`.
### Bonnes pratiques / mitigations
- Interdire les appels directs au service auth depuis les pages une fois le store source de vérité.
- Centraliser login/logout/change-password via actions store.
- Contexte technique : auth frontend / Pinia store — RL799_V2 18-04-2026
---

View File

@@ -119,3 +119,39 @@ Erreurs courantes :
- Activer `@typescript-eslint/no-unused-vars` et `no-unused-imports` dans la config ESLint mobile
- Lors de toute migration de tokens, auditer les imports de chaque composant UI concerné
- Contexte technique : React Native / ESLint — app-alexandrie, 25-03-2026
---
<a id="risque-design-tokens-fallback-theme-incoherent"></a>
## Fallbacks de tokens incohérents avec le thème actif
### Risques
- Composants lisibles en dev mais illisibles quand une variable manque en production.
### Symptômes
- Fallback hardcodé light-theme dans un contexte dark-theme.
### Bonnes pratiques / mitigations
- Utiliser des fallbacks cohérents avec le thème de référence.
- Préférer un fallback vers alias sémantique existant plutôt qu'une couleur brute.
- Contexte technique : design tokens / thèmes CSS — RL799_V2 10-04-2026
---
<a id="risque-design-tokens-variables-non-definies"></a>
## Variables CSS utilisées mais non définies (fallback silencieux)
### Risques
- Dérive invisible du design system (les fallbacks masquent les oublis de token).
### Symptômes
- L'UI semble correcte mais contourne les tokens sur une part significative des règles.
### Bonnes pratiques / mitigations
- Auditer régulièrement : variables utilisées moins variables définies.
- Traiter chaque variable non définie comme dette explicite.
- Contexte technique : design tokens / audit CSS vars — RL799_V2 17-04-2026
---

View File

@@ -248,3 +248,74 @@ Poser `role="menu"` / `role="menuitem"` implique obligatoirement :
- **Signal review** : tout `.catch(() => {})` ou `catch { /* ignore */ }` mérite au minimum un log ou un feedback visuel
- Contexte technique : frontend / actions async — RL799_V2 07-04-2026
---
<a id="risque-monorepo-shim-js-desynchronise"></a>
## Monorepo ESM — shim runtime `.js` désynchronisé de l'index TypeScript
### Risques
- Le typecheck passe mais le runtime navigateur casse (`named export not found`).
### Symptômes
- Erreur Vite/browser sur export absent alors que `index.ts` est correct.
### Bonnes pratiques / mitigations
- Si un shim `.js` est maintenu, imposer une mise à jour miroir à chaque nouvel export.
- Ajouter un test/guard de cohérence exports TS vs JS shim.
- Contexte technique : monorepo / ESM shim runtime — RL799_V2 15-04-2026
---
<a id="risque-eslint-flat-tsconfigrootdir-manquant"></a>
## ESLint flat config TypeScript sans `tsconfigRootDir`
### Risques
- Erreurs de parsing massives en IDE/monorepo selon CWD d'exécution.
### Symptômes
- `No TsConfigRootDir` / `Cannot read tsconfig.json` alors que le build TS passe.
### Bonnes pratiques / mitigations
- Toujours définir `tsconfigRootDir: import.meta.dirname` quand `parserOptions.project` est utilisé.
- Redémarrer le serveur ESLint après correction.
- Contexte technique : tooling / ESLint flat config — RL799_V2 17-04-2026
---
<a id="risque-pwa-auth-cookie-cache"></a>
## PWA + auth cookie httpOnly — stratégie de cache non maîtrisée
### Risques
- Réponses sensibles servies depuis cache offline.
- Comportement d'auth incohérent entre réseau/cached.
### Symptômes
- Session/app state divergents après activation SW ou reprise réseau.
### Bonnes pratiques / mitigations
- Exclure explicitement les routes authentifiées sensibles du cache persistant.
- Définir une stratégie stricte par classe de route (auth, API privée, assets publics).
- Contexte technique : PWA / service worker / auth cookie — RL799_V2 18-04-2026
---
<a id="risque-pwa-beforeinstallprompt-tardif"></a>
## PWA install prompt — capture tardive de `beforeinstallprompt`
### Risques
- Événement perdu au cold boot, prompt jamais proposé.
### Symptômes
- Implémentation correcte en apparence mais aucun déclenchement sur Android.
### Bonnes pratiques / mitigations
- Installer l'écouteur le plus tôt possible dans le cycle d'initialisation.
- Ne pas baser la détection iOS uniquement sur l'UA (cas iPad en mode desktop).
- Contexte technique : PWA / install prompt — RL799_V2 18-04-2026
---

View File

@@ -277,3 +277,22 @@ const routes = [
- **Signal review** : guards de navigation couverts uniquement par des tests `includes()` sans test comportemental
- Contexte technique : Vue 3 / Vue Router 4 / node:test — RL799_V2 08-04-2026
---
<a id="risque-navigation-router-push-undefined"></a>
## `router.push` construit avec segment potentiellement `undefined`
### Risques
- Navigation vers `/.../undefined`, historique pollué et diagnostics trompeurs.
### Symptômes
- Warnings Vue Router en cascade au boot ou à la reprise d'événements globaux.
### Bonnes pratiques / mitigations
- Valider les segments dynamiques avant `push/replace`.
- Préférer la navigation nommée avec params validés plutôt que concaténation de string.
- Contexte technique : Vue Router / navigation dynamique — RL799_V2 15-04-2026
---

View File

@@ -70,3 +70,46 @@ Plutôt que d'ouvrir un domaine `achievements` ou `analytics` dès la V1 :
- [ ] Compteurs calculés depuis la source de vérité existante
- [ ] Catalogue d'objectifs en code (pas en DB)
- [ ] Interface de sortie stable même si les sources de données évoluent
---
<a id="pattern-product-cercle-restreint-canal-primaire"></a>
## Pattern : Produit à cercle restreint — canal primaire externe conservé
- Objectif : calibrer la stratégie produit pour des communautés fermées/invitation-only.
- Contexte : app interne/associative où email/SMS précède l'usage applicatif.
- Quand l'utiliser : produit B2B/intranet/communauté restreinte.
- Quand l'éviter : produits mass-market où l'app doit devenir canal primaire.
### Description
Pour une app invitation-only (B2B/interne/associatif), email/SMS reste le canal d'information principal et fiable ; l'app le complète sans le remplacer.
### Checklist
- KPI de succès alignés sur l'usage réel (consultation/confirmation), pas sur le remplacement du canal primaire.
- Roadmap UX alignée avec une adoption progressive et non exclusive.
- Validé le : 18-04-2026
- Contexte produit : PWA / adoption progressive — RL799_V2
---
<a id="pattern-product-trigger-ux-login-count"></a>
## Pattern : Trigger UX basé sur signal métier serveur (`loginCount`)
- Objectif : déclencher les prompts UX via un signal robuste et auditable.
- Contexte : prompts d'installation PWA, notifications, feedback.
- Quand l'utiliser : tout trigger UX nécessitant un critère de maturité utilisateur.
- Quand l'éviter : prompts one-shot purement contextuels de page.
### Description
Pour des prompts significatifs (install PWA, notifications, feedback), privilégier un déclencheur serveur métier (ex: `loginCount`) plutôt que des heuristiques client fragiles (timer/scroll/pages vues).
### Checklist
- Signal incrémenté côté serveur sur événement métier confirmé.
- Règle de déclenchement unique partagée entre plateformes.
- Possibilité de désactiver/ajuster sans dépendre du contexte runtime navigateur.
- Validé le : 18-04-2026
- Contexte produit : PWA / triggers engagement — RL799_V2
---

View File

@@ -251,3 +251,22 @@ source_projects: [app-alexandrie, app-template-resto, RL799_V2]
- **Règle** : toute métrique dans les Completion Notes doit être vérifiable par une commande simple
- Contexte technique : BMAD / workflow agent — RL799_V2 08-04-2026
---
<a id="risque-story-convention-absente-code-projet"></a>
## Story impose une convention absente du code projet
### Risques
- Divergence silencieuse entre specification story et implémentation réelle.
### Symptômes
- Le dev adapte une convention introuvable sans la tracer dans la story/notes de review.
### Bonnes pratiques / mitigations
- Si une convention prescrite n'existe pas dans le repo, documenter explicitement l'adaptation retenue.
- Mettre à jour la story (Change Log / Completion Notes) avec justification et impact.
- Contexte technique : BMAD / traçabilité adaptation story — RL799_V2 15-04-2026
---