mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
Integrate Next.js runtime-only backend pattern
This commit is contained in:
@@ -8,7 +8,7 @@ Ce fichier contient **uniquement** des patterns back-end :
|
|||||||
|
|
||||||
Objectif : éviter de réinventer la roue et réduire le temps de debug.
|
Objectif : éviter de réinventer la roue et réduire le temps de debug.
|
||||||
|
|
||||||
Dernière mise à jour : 16-03-2026
|
Dernière mise à jour : 19-03-2026
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -34,6 +34,7 @@ Dernière mise à jour : 16-03-2026
|
|||||||
- [Autorisation interne minimale sans RBAC complet](#pattern-autorisation-interne-minimale)
|
- [Autorisation interne minimale sans RBAC complet](#pattern-autorisation-interne-minimale)
|
||||||
- [Anti-énumération sur endpoints auth liés à un email](#pattern-anti-enumeration-auth-email)
|
- [Anti-énumération sur endpoints auth liés à un email](#pattern-anti-enumeration-auth-email)
|
||||||
- [Token à usage unique — génération, hash et invalidation atomique](#pattern-token-usage-unique)
|
- [Token à usage unique — génération, hash et invalidation atomique](#pattern-token-usage-unique)
|
||||||
|
- [Next.js runtime-only — orchestration en bord et logique pure testable](#pattern-nextjs-runtime-only-logique-pure-testable)
|
||||||
- [Guardrails multi-tenant — 403 vs 404 selon la sémantique](#pattern-guardrails-multi-tenant-403-404)
|
- [Guardrails multi-tenant — 403 vs 404 selon la sémantique](#pattern-guardrails-multi-tenant-403-404)
|
||||||
- [Repository tenant-aware — `tenantId` obligatoire dans la signature](#pattern-repository-tenant-aware)
|
- [Repository tenant-aware — `tenantId` obligatoire dans la signature](#pattern-repository-tenant-aware)
|
||||||
- [Défense en profondeur — inclure `tenantId` dans les updates](#pattern-tenantid-dans-updates)
|
- [Défense en profondeur — inclure `tenantId` dans les updates](#pattern-tenantid-dans-updates)
|
||||||
@@ -826,6 +827,45 @@ handlePackWebhookEvent(event): PackWebhookResult | null
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<a id="pattern-nextjs-runtime-only-logique-pure-testable"></a>
|
||||||
|
## Pattern : Next.js runtime-only — orchestration en bord et logique pure testable
|
||||||
|
|
||||||
|
- Objectif : préserver la testabilité unitaire et la lisibilité du code serveur Next.js en limitant les dépendances runtime-only aux couches d’orchestration.
|
||||||
|
- Contexte : applications Next.js avec Server Actions, route handlers, modules email/auth et logique métier testée côté Node.
|
||||||
|
- Quand l’utiliser : dès qu’un flux serveur mélange APIs Next.js runtime-only (`cookies()`, `headers()`, `redirect()`, `server-only`) et logique métier réutilisable.
|
||||||
|
- Quand l’éviter : petits modules purement runtime sans logique métier notable, ou fonctions triviales sans intérêt à être testées séparément.
|
||||||
|
- Avantage :
|
||||||
|
- garde la logique métier importable dans un runner Node standard
|
||||||
|
- évite que `server-only` contamine des modules purs
|
||||||
|
- facilite les tests unitaires sans mocks lourds du runtime Next.js
|
||||||
|
- clarifie la responsabilité des Server Actions et handlers serveur
|
||||||
|
- Limites / vigilance :
|
||||||
|
- demande une discipline de découpage
|
||||||
|
- peut introduire une indirection inutile si la logique extraite est réellement triviale
|
||||||
|
- les frontières d’injection doivent rester simples pour éviter un excès d’abstraction
|
||||||
|
- Validé le : 19-03-2026
|
||||||
|
- Contexte technique : Next.js / Server Actions / Node test runner / modules backend injectables
|
||||||
|
|
||||||
|
### Implémentation (exemple minimal)
|
||||||
|
|
||||||
|
```txt
|
||||||
|
- réserver `import "server-only"` aux fichiers qui utilisent réellement des APIs runtime Next.js
|
||||||
|
- garder la Server Action, route handler ou module email comme couche d’orchestration fine
|
||||||
|
- extraire la logique métier pure dans une fonction ou un service sans dépendance à `cookies()`, `headers()`, `redirect()` ou `server-only`
|
||||||
|
- injecter explicitement les dépendances utiles (client DB, token, callback de redirect, logger, etc.)
|
||||||
|
- tester unitairement le module pur dans le runner Node ; tester l’orchestrateur plus légèrement
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checklist
|
||||||
|
|
||||||
|
- `server-only` absent des modules de logique pure
|
||||||
|
- APIs Next.js runtime-only limitées aux couches d’entrée
|
||||||
|
- Logique métier principale testable sans runtime Next.js
|
||||||
|
- Dépendances injectées explicitement quand utile
|
||||||
|
- Server Action ou handler fin et lisible
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
<a id="pattern-guardrails-multi-tenant-403-404"></a>
|
<a id="pattern-guardrails-multi-tenant-403-404"></a>
|
||||||
## Pattern : Guardrails multi-tenant — 403 vs 404 selon la sémantique
|
## Pattern : Guardrails multi-tenant — 403 vs 404 selon la sémantique
|
||||||
|
|
||||||
|
|||||||
@@ -174,32 +174,6 @@ Lors d'une implémentation, valider que chaque champ mentionné dans les tâches
|
|||||||
FILE_UPDATE_PROPOSAL
|
FILE_UPDATE_PROPOSAL
|
||||||
Fichier cible : 10_backend_patterns_valides.md
|
Fichier cible : 10_backend_patterns_valides.md
|
||||||
|
|
||||||
Pourquoi :
|
|
||||||
Le module sendPasswordResetEmail utilise `server-only` ce qui le rend non-importable dans le runner de tests Node. Résolution : tester la logique pure (safeHttpUrl) dans un fichier séparé sans dépendances Next.js.
|
|
||||||
|
|
||||||
Proposition :
|
|
||||||
**Pattern : Isolation des guards purs des modules server-only**
|
|
||||||
Extraire la logique pure (validation URL, sanitisation) dans des fonctions utilitaires sans import `server-only` ou `nodemailer`. Le module email orchestre uniquement. Cela permet de tester les guards en isolation sans les contraintes du runtime Next.js.
|
|
||||||
|
|
||||||
---
|
|
||||||
2026-03-16 — app-template-resto
|
|
||||||
|
|
||||||
FILE_UPDATE_PROPOSAL
|
|
||||||
Fichier cible : 10_backend_patterns_valides.md
|
|
||||||
|
|
||||||
Pourquoi :
|
|
||||||
Pattern validé sur story 1.10 — la règle `server-only` vs testabilité est implicite dans le projet mais mérite d'être explicitée pour les agents futurs.
|
|
||||||
|
|
||||||
Proposition :
|
|
||||||
**Pattern : `server-only` réservé aux modules avec APIs Next.js exclusivement serveur**
|
|
||||||
Ne pas mettre `import "server-only"` sur les modules de logique pure injectés via dépendances (ex: `deleteSession({ prisma, sessionToken })`). Réserver `server-only` aux modules qui appellent des APIs Next.js runtime-only (`cookies()`, `headers()`, `redirect()`). Les modules purs sans ces imports peuvent être importés par le test runner Node et testés unitairement sans friction.
|
|
||||||
|
|
||||||
---
|
|
||||||
2026-03-16 — app-template-resto
|
|
||||||
|
|
||||||
FILE_UPDATE_PROPOSAL
|
|
||||||
Fichier cible : 10_backend_patterns_valides.md
|
|
||||||
|
|
||||||
Pourquoi :
|
Pourquoi :
|
||||||
Pattern validé sur story 1.10 — suppression de session avec gestion idempotente, réutilisable pour toute opération de révocation.
|
Pattern validé sur story 1.10 — suppression de session avec gestion idempotente, réutilisable pour toute opération de révocation.
|
||||||
|
|
||||||
@@ -208,31 +182,26 @@ Proposition :
|
|||||||
Lors d'une déconnexion ou révocation de session, entourer le `prisma.session.delete()` d'un try/catch qui absorbe silencieusement le code Prisma `P2025` (record not found). Une session peut déjà avoir été supprimée (expiration, logout concurrent) — ce n'est pas une erreur, ne pas la propager.
|
Lors d'une déconnexion ou révocation de session, entourer le `prisma.session.delete()` d'un try/catch qui absorbe silencieusement le code Prisma `P2025` (record not found). Une session peut déjà avoir été supprimée (expiration, logout concurrent) — ce n'est pas une erreur, ne pas la propager.
|
||||||
|
|
||||||
---
|
---
|
||||||
2026-03-16 — app-template-resto
|
2026-03-19 — app-template-restau
|
||||||
|
|
||||||
FILE_UPDATE_PROPOSAL
|
FILE_UPDATE_PROPOSAL
|
||||||
Fichier cible : 10_backend_patterns_valides.md
|
Fichier cible : 10_frontend_patterns_valides.md
|
||||||
|
|
||||||
Pourquoi :
|
Pourquoi :
|
||||||
Pattern validé sur story 1.10 — Server Action Next.js qui orchestre des dépendances Next.js runtime non-testables : isoler la logique pure dans un module injectable.
|
Sur les fonctionnalités publiques reposant sur un service tiers en mode link-out (ex: réservation), un parcours canonique unique évite les ambiguïtés UX et centralise mieux les garde-fous, le wording et les fallbacks.
|
||||||
|
|
||||||
Proposition :
|
Proposition :
|
||||||
**Pattern : Server Action Next.js — isoler la logique pure dans un module injectable**
|
### Intégration tierce en mode link-out : préférer une page locale canonique
|
||||||
Une Server Action qui appelle `cookies()`, `headers()` ou `redirect()` ne peut pas être testée unitairement (imports runtime-only). Pattern : extraire la logique pure (suppression DB, validation) dans une fonction avec injection de dépendances (`performSignOut({ prismaClient, sessionToken, redirectFn })`). La Server Action reste fine et orchestre uniquement les dépendances Next.js. Le module extrait est testable sans friction avec le runner Node natif.
|
|
||||||
|
|
||||||
---
|
Quand une fonctionnalité publique dépend d’un service tiers accessible via lien externe, préférer le parcours :
|
||||||
2026-03-16 — app-template-resto / code-review story 1.11
|
|
||||||
|
|
||||||
FILE_UPDATE_PROPOSAL
|
- CTA internes (home, navigation, landing) → page locale du site
|
||||||
Fichier cible : 10_backend_risques_et_vigilance.md
|
- page locale dédiée → service tiers externe
|
||||||
|
|
||||||
Pourquoi :
|
Éviter de mélanger plusieurs parcours concurrents (ex: home qui sort directement vers le tiers alors qu’une page `/reservation` dédiée existe déjà).
|
||||||
`import "server-only"` dans les repositories casse les tests Node.js hors Next.js — rencontré lors de cette review.
|
|
||||||
|
|
||||||
Proposition :
|
Bénéfices :
|
||||||
## Risque : `server-only` dans les repositories bloque les tests unitaires
|
- UX plus cohérente
|
||||||
|
- garde-fous centralisés au même endroit
|
||||||
`import "server-only"` empêche l'exécution des fichiers hors runtime Next.js.
|
- fallbacks plus simples à gérer
|
||||||
Solution : créer un stub `node_modules/server-only/index.js` (no-op) pour les tests.
|
- évolution facilitée vers une variante embed / click-to-load
|
||||||
Alternativement, ne mettre `server-only` que dans les fichiers qui utilisent des APIs
|
|
||||||
Next.js (`cookies()`, `headers()`), pas dans les repositories purs.
|
|
||||||
|
|||||||
171
96_review_capitalisation.md
Normal file
171
96_review_capitalisation.md
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
# Review de capitalisation — 2026-03-19
|
||||||
|
|
||||||
|
Source revue : `95_a_capitaliser.md`
|
||||||
|
Périmètre de comparaison : `10_*`, `40_decisions_et_archi.md`, `90_debug_et_postmortem.md`
|
||||||
|
|
||||||
|
## Méthode
|
||||||
|
|
||||||
|
- L’exemple de format présent en tête de `95_a_capitaliser.md` n’est pas traité comme une proposition.
|
||||||
|
- Les entrées ont été triées selon 5 statuts : `duplicate`, `near-duplicate`, `candidate`, `too-local`, `unclear`.
|
||||||
|
- Aucun contenu n’a été intégré dans les fichiers de connaissance validée.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## duplicate
|
||||||
|
|
||||||
|
Aucune entrée classée `duplicate`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## near-duplicate
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto
|
||||||
|
**Cible proposée :** `10_backend_patterns_valides.md`
|
||||||
|
**Titre :** Transaction obligatoire pour les opérations auth multi-étapes
|
||||||
|
|
||||||
|
**Verdict :** `near-duplicate`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Recouvre fortement des principes déjà validés dans :
|
||||||
|
- `10_backend_patterns_valides.md` → `Token à usage unique — génération, hash et invalidation atomique`
|
||||||
|
- `40_decisions_et_archi.md` → `Idempotence et gestion des retries pour les opérations sensibles`
|
||||||
|
- L’apport utile existe, mais la proposition actuelle est une spécialisation auth/password-reset d’un invariant plus large : opérations sensibles multi-écritures = transaction.
|
||||||
|
|
||||||
|
**Recommandation :**
|
||||||
|
- À fusionner si intégration future, sous une formulation plus générique : transaction pour opérations sensibles multi-étapes, avec exemple auth.
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto
|
||||||
|
**Cible proposée :** `10_backend_patterns_valides.md`
|
||||||
|
**Titre :** Isolation des guards purs des modules server-only
|
||||||
|
|
||||||
|
**Verdict :** `near-duplicate`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Quasi même famille d’idée que :
|
||||||
|
- `server-only` réservé aux modules avec APIs Next.js exclusivement serveur
|
||||||
|
- `Server Action Next.js — isoler la logique pure dans un module injectable`
|
||||||
|
- Le cœur du savoir est le même : isoler la logique pure, limiter `server-only` aux bords runtime-only.
|
||||||
|
|
||||||
|
**Recommandation :**
|
||||||
|
- Ne pas intégrer seul.
|
||||||
|
- À absorber dans une entrée fusionnée sur `server-only` / testabilité / extraction de logique pure.
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto / code-review story 1.11
|
||||||
|
**Cible proposée :** `10_backend_risques_et_vigilance.md`
|
||||||
|
**Titre :** `server-only` dans les repositories bloque les tests unitaires
|
||||||
|
|
||||||
|
**Verdict :** `near-duplicate`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Même problème racine que les propositions précédentes sur `server-only`.
|
||||||
|
- Le risque est réel, mais il double essentiellement un futur pattern plus général sur la frontière runtime-only.
|
||||||
|
- La mitigation par stub `server-only` en test ne doit pas être capitalisée comme pratique de référence.
|
||||||
|
|
||||||
|
**Recommandation :**
|
||||||
|
- Ne pas intégrer sous cette forme.
|
||||||
|
- Si capitalisation ultérieure : reformuler le risque autour de “mélanger logique pure et dépendances runtime-only nuit à la testabilité”.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## candidate
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto
|
||||||
|
**Cible proposée :** `10_backend_patterns_valides.md`
|
||||||
|
**Titre :** `server-only` réservé aux modules avec APIs Next.js exclusivement serveur
|
||||||
|
|
||||||
|
**Verdict :** `candidate`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Savoir réutilisable, concret, testable, avec périmètre clair.
|
||||||
|
- Pas trouvé tel quel dans les fichiers validés.
|
||||||
|
- Complète utilement les patterns backend existants sur testabilité et séparation des responsabilités.
|
||||||
|
|
||||||
|
**Réserve :**
|
||||||
|
- À intégrer seulement après fusion avec les autres entrées proches sur `server-only` et Server Actions, pour éviter trois patterns quasi redondants.
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto
|
||||||
|
**Cible proposée :** `10_backend_patterns_valides.md`
|
||||||
|
**Titre :** Suppression de session idempotente (P2025)
|
||||||
|
|
||||||
|
**Verdict :** `candidate`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Cas réutilisable au-delà du projet : révocation/logout/suppression concurrente.
|
||||||
|
- Complète les principes généraux d’idempotence déjà présents avec un exemple Prisma actionnable.
|
||||||
|
- Suffisamment concret pour mériter potentiellement un pattern dédié si d’autres cas analogues existent.
|
||||||
|
|
||||||
|
**Réserve :**
|
||||||
|
- Bien cadrer le contexte technique (`Prisma`, suppression de session/révocation) pour éviter d’en faire une règle trop générale.
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto
|
||||||
|
**Cible proposée :** `10_backend_patterns_valides.md`
|
||||||
|
**Titre :** Server Action Next.js — isoler la logique pure dans un module injectable
|
||||||
|
|
||||||
|
**Verdict :** `candidate`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Le pattern est clair, réutilisable, et dépasse le cas local.
|
||||||
|
- Il apporte une couture explicite entre runtime Next.js et logique testable.
|
||||||
|
- Aucun équivalent direct n’est déjà capitalisé dans les fichiers validés.
|
||||||
|
|
||||||
|
**Réserve :**
|
||||||
|
- À fusionner avec les deux autres entrées `server-only` pour produire une seule entrée robuste : frontière runtime-only fine, orchestration en bord, logique pure injectable/testable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## too-local
|
||||||
|
|
||||||
|
### 2026-03-10 — app-alexandrie
|
||||||
|
**Cible proposée :** `10_backend_patterns_valides.md`
|
||||||
|
**Titre :** Progression V1 calculée sans persistance dédiée
|
||||||
|
|
||||||
|
**Verdict :** `too-local`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Le raisonnement est intéressant, mais reste très lié à un arbitrage produit/modélisation métier V1.
|
||||||
|
- Réutilisabilité trop faible en l’état : dépend du type de progression, du domaine, et du niveau d’anticipation produit.
|
||||||
|
- Même conclusion que la revue déjà présente dans `95_a_capitaliser.md` : utile, mais pas encore assez universel pour mémoire durable.
|
||||||
|
|
||||||
|
### 2026-03-16 — app-template-resto
|
||||||
|
**Cible proposée :** `10_backend_risques_et_vigilance.md`
|
||||||
|
**Titre :** Divergence schéma / spec story
|
||||||
|
|
||||||
|
**Verdict :** `too-local`
|
||||||
|
|
||||||
|
**Pourquoi :**
|
||||||
|
- Le problème relève surtout d’un défaut de process de story/review, pas d’un risque backend durable au bon niveau d’abstraction.
|
||||||
|
- Trop attaché au contexte BMAD/story-writing et à Prisma sur ce cas précis.
|
||||||
|
- Mieux traité dans des conventions de review ou de rédaction projet que dans la base Lead Tech durable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## unclear
|
||||||
|
|
||||||
|
Aucune entrée classée `unclear`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Intégré
|
||||||
|
|
||||||
|
### 2026-03-19
|
||||||
|
|
||||||
|
- Intégré dans `10_backend_patterns_valides.md` :
|
||||||
|
- `Next.js runtime-only — orchestration en bord et logique pure testable`
|
||||||
|
- Cette intégration absorbe les propositions proches suivantes :
|
||||||
|
- `Isolation des guards purs des modules server-only`
|
||||||
|
- ``server-only` réservé aux modules avec APIs Next.js exclusivement serveur`
|
||||||
|
- `Server Action Next.js — isoler la logique pure dans un module injectable`
|
||||||
|
- La proposition `server-only dans les repositories bloque les tests unitaires` n’a pas été intégrée comme risque autonome ; son signal utile est couvert par le pattern fusionné ci-dessus.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Synthèse
|
||||||
|
|
||||||
|
- **Candidates solides après fusion :**
|
||||||
|
- famille `server-only` / Server Actions / logique pure testable
|
||||||
|
- suppression de session idempotente (`P2025`) si on assume un pattern Prisma ciblé
|
||||||
|
- **À ne pas intégrer en l’état :**
|
||||||
|
- progression V1 sans persistance dédiée
|
||||||
|
- divergence schéma / spec story
|
||||||
|
- **Point principal de déduplication :**
|
||||||
|
- trois entrées parlent en pratique du même sujet : frontière runtime Next.js (`server-only`) vs logique pure testable.
|
||||||
Reference in New Issue
Block a user