mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
- backend/risques/nestjs : guard multi-statut READ_METHODS avant statut - backend/patterns/nestjs : fusionner lastSeenAt dans la réconciliation - backend/risques/contracts : pas de process.env dans services/helpers - backend/risques/nextjs : self-request Server Action + EXDEV atomic write - backend/risques/prisma : champ enum-like stocké en String - frontend/risques/general : Alert.prompt iOS-only - frontend/risques/tests : 3 anti-patterns (helpers copiés, test indirect, test façade) - workflow/risques/story-tracking : 2 entrées (hors périmètre, File List approximative) - skill capitalisation-triage : nouveau format de rapport (tableaux par domaine) - 95_a_capitaliser.md : purgé
123 lines
4.8 KiB
Markdown
123 lines
4.8 KiB
Markdown
# Backend — Risques & vigilance : Next.js
|
|
|
|
> Extrait de la base de connaissance Lead_tech. Voir `knowledge/backend/risques/README.md` pour l'index complet.
|
|
|
|
---
|
|
|
|
<a id="risque-prisma-init-module-build"></a>
|
|
## Prisma initialisé au chargement de module — casse le build Next.js
|
|
|
|
### Risques
|
|
|
|
- Un import global qui initialise Prisma immédiatement peut faire échouer la collecte de pages/routes au build si `DATABASE_URL` n'est pas disponible dans l'environnement de build
|
|
|
|
### Symptômes
|
|
|
|
- `PrismaClientInitializationError` ou `Error: Environment variable not found: DATABASE_URL` au `next build`
|
|
- L'app tourne en dev mais le build CI échoue
|
|
|
|
### Bonnes pratiques / mitigations
|
|
|
|
- Préférer une initialisation lazy-safe : retarder l'accès DB au moment de l'appel métier
|
|
- Retourner un proxy qui lève une erreur claire uniquement lors du premier accès réel à la DB
|
|
- Ne jamais instancier `new PrismaClient()` au top-level d'un module importé par Next.js
|
|
|
|
- Contexte technique : Next.js App Router / Prisma — app-template-resto 16-03-2026
|
|
|
|
---
|
|
|
|
<a id="risque-server-only-repositories-tests"></a>
|
|
## `server-only` dans les repositories — bloque les tests unitaires
|
|
|
|
### Risques
|
|
|
|
- `import "server-only"` empêche l'exécution des fichiers hors runtime Next.js
|
|
- Les tests Node.js échouent avec `Error: This module cannot be imported from a Client Component module`
|
|
|
|
### Symptômes
|
|
|
|
- Tests qui passent via le dev server mais échouent via `jest` en mode node
|
|
- Erreur au `require()` d'un repository depuis un test unitaire
|
|
|
|
### Bonnes pratiques / mitigations
|
|
|
|
- Ne mettre `server-only` que dans les fichiers qui utilisent des APIs Next.js runtime (`cookies()`, `headers()`, `redirect()`)
|
|
- **Ne pas** mettre `server-only` dans les repositories purs (qui n'appellent que Prisma)
|
|
- Alternative de secours : créer un stub `node_modules/server-only/index.js` no-op pour les tests
|
|
|
|
- Contexte technique : Next.js App Router / Jest — app-template-resto 16-03-2026
|
|
|
|
---
|
|
|
|
<a id="risque-redirect-boucle-infinie"></a>
|
|
## Redirect vers la page désactivée elle-même (boucle infinie feature flags)
|
|
|
|
### Risques
|
|
|
|
- Une page désactivée redirige vers elle-même via le fallback — boucle infinie silencieuse absorbée par Next.js mais UX cassée
|
|
|
|
### Symptômes
|
|
|
|
- Page `/` désactivée → redirect vers `buildLocalizedPath("home")` = `/` → boucle
|
|
- Next.js absorbe la boucle mais l'utilisateur voit un écran bloqué ou vide
|
|
|
|
### Bonnes pratiques / mitigations
|
|
|
|
```typescript
|
|
// Si la page est sa propre destination de fallback, ne pas rediriger
|
|
if (pageKey === "home") return null; // évite redirect home → home
|
|
return buildLocalizedPath(locale, "home");
|
|
```
|
|
|
|
- Règle : dans tout mécanisme de redirection sur page désactivée, toujours vérifier que `pageKey !== fallbackKey`
|
|
- Retourner `null` (accès non bloqué) plutôt que de boucler
|
|
|
|
- Contexte technique : Next.js App Router / feature flags tenant — app-template-resto 17-03-2026
|
|
|
|
---
|
|
|
|
<a id="risque-server-action-self-request"></a>
|
|
## Server Action : self-request / loopback HTTP vers sa propre API
|
|
|
|
### Risques
|
|
|
|
- Latence réseau inutile (aller-retour HTTP interne)
|
|
- Fragilité sur `APP_URL` en environnement Docker (loopback non résolu)
|
|
- Double authentification (cookies reconstitués manuellement)
|
|
- Surface d'attaque SSRF
|
|
|
|
### Symptômes
|
|
|
|
- `fetch(process.env.APP_URL + '/api/...')` dans une Server Action
|
|
- Reconstitution manuelle de cookies de session dans l'appel
|
|
|
|
### Bonnes pratiques / mitigations
|
|
|
|
- Une Server Action peut importer et appeler directement des modules marqués `server-only` sans `fetch` interne — les deux s'exécutent côté serveur.
|
|
- **Règle** : si tu te retrouves à reconstituer des cookies de session pour faire un `fetch` vers ta propre API depuis une Server Action, c'est le signal que l'appel doit être direct.
|
|
|
|
- Contexte technique : Next.js App Router / Server Actions — app-template-resto 31-03-2026
|
|
|
|
---
|
|
|
|
<a id="risque-exdev-atomic-write"></a>
|
|
## Écriture atomique (tmp + rename) : EXDEV si tmp sur device différent
|
|
|
|
### Risques
|
|
|
|
- `rename()` lève `EXDEV` si le fichier temporaire et la destination sont sur deux devices différents (cas courant Docker bind-mount).
|
|
- L'erreur survient uniquement en production (Docker) — invisible en dev local.
|
|
|
|
### Symptômes
|
|
|
|
- `Error: EXDEV: cross-device link not permitted, rename '/tmp/...' → '/data/...'`
|
|
- Upload de fichier fonctionnel en dev, cassé en production Docker
|
|
|
|
### Bonnes pratiques / mitigations
|
|
|
|
- Créer le fichier temporaire dans **le même répertoire** que la destination finale, pas dans `os.tmpdir()`.
|
|
- S'assurer que le répertoire cible existe avant l'écriture du fichier temporaire.
|
|
- **Règle** : `os.tmpdir()` est interdit pour les fichiers qui seront renommés vers un volume Docker bind-mounté.
|
|
|
|
- Contexte technique : Node.js / Docker / fichiers media — app-template-resto 31-03-2026
|