capitalisation: triage 95_a_capitaliser + création domaine infra

Triage des 27 propositions du buffer de capitalisation (skill
capitalisation-triage), avec vérification des doublons contre la base.

Intégré dans knowledge/ (23 entrées):
- backend: redis (compensation incrBy non-atomique), nestjs (injection
  cassée sous tsx watch; guard write mode dégradé), async (test rollback
  pipeline multi-fichiers), contracts (idempotence POST), auth (disclosure
  comptes soft-deleted), prisma (index partial soft-delete), llm-providers
  (nouveau: OAuth vs API key, prompt caching).
- frontend: tests (garde-fous parking Later), navigation (fichiers
  non-route sous src/app Expo Router), general (type client vs payload
  backend), state (fallback catch-all mapping DB→UI).
- workflow: story-tracking (statut BMAD vs narratif obsolète).
- product: general (nouveau: doc feature store sans UI).
- infra: NOUVEAU DOMAINE (traefik, tailscale, docker, docker-networking,
  reverse-proxy-paths, sidecar tailscale) + 00_INDEX.md.

Autres:
- 90_debug_et_postmortem.md: post-mortem réseau Docker partagé hors compose.
- Rejeté 3 doublons (types enum contracts, getter PrismaService, $transaction).
- Buffer 95_a_capitaliser.md purgé et restauré à son état initial.
- _projects.conf: MAJ statuts epics + ajout app-rl799.
This commit is contained in:
MaksTinyWorkshop
2026-06-25 10:31:22 +02:00
parent 1c876309f1
commit ef24d85d57
31 changed files with 1042 additions and 27 deletions
+53
View File
@@ -330,3 +330,56 @@ ALTER INDEX "tronc_entries_tenue_idx" RENAME TO "tronc_entries_tenue_id_idx";
- **Préventif** : `prisma migrate diff` régulièrement (CI/CD ou pré-commit) pour détecter la dérive AVANT qu'elle ne pollue une migration thématique
- **Curatif** : inspecter manuellement le SQL généré par `--create-only` avant de l'appliquer en migration thématique
---
## Réseau Docker partagé entre stacks supprimé par `compose down` malgré `external: true`
### Contexte
NUC sous Proxmox, le 22-04-2026. Plusieurs stacks Docker partagent un réseau commun : un Postgres mutualisé (`shared-postgres`) auquel se connectent plusieurs apps via leur IP Tailscale. Chaque stack déclare le réseau en `external: true` dans son `docker-compose.yml`. Après une coupure de courant et redémarrage de la stack, le conteneur Postgres tournait en `Up (healthy)` mais plus aucune app ne pouvait s'y connecter.
### Symptômes
- Conteneur `shared-postgres` en `Up (healthy)`, mais `docker port <container>` retourne vide et `docker inspect ... NetworkSettings.Ports` retourne `{}`.
- Les autres stacks connectées au réseau ont perdu toute connectivité.
### Cause
Double piège :
1. **`external: true` ne protège pas toujours contre la destruction.** Un `docker compose down` exécuté plus tôt a supprimé le réseau `shared-postgres-net` malgré son `external: true`, parce qu'aucun autre projet ne le "possédait" au moment de la commande. Le flag `external` protège contre la *création*, pas toujours contre la *destruction* — surtout quand le réseau a initialement été créé par un `compose up` (il porte alors les labels Compose et appartient au projet).
2. **Config figée à la création.** Le conteneur relancé par `restart: unless-stopped` garde sa config figée au moment de sa création : les modifications ultérieures du `docker-compose.yml` (ajout du bloc `ports:`, changement de réseau) ne sont pas prises en compte tant qu'on ne fait pas `up --force-recreate`. Le conteneur s'est donc recréé sans réseau ni mapping de ports.
### Correctif / règle à retenir
**Un réseau Docker partagé entre plusieurs stacks doit être créé explicitement hors compose, pas par une stack.**
```bash
docker network create shared-<nom>-net
```
Le réseau n'a alors aucun label Compose, donc aucun `compose down` ne peut le supprimer.
**Figer le nom de projet Compose.** Par défaut, le nom de projet Compose = nom du dossier. Si le `container_name` diffère du nom de dossier (ex. dossier `postgres/` mais `container_name: shared-postgres`), un `compose down` peut "ne rien voir à supprimer" car il cherche dans le mauvais projet. Solution : déclarer `name:` au top-level :
```yaml
name: shared-postgres
services:
postgres:
container_name: shared-postgres
...
```
**Règles opérationnelles pour les stacks partagées critiques :**
- Ne jamais faire `docker compose down` sur la stack qui "porte" le réseau partagé.
- Utiliser `stop` / `start` / `up -d --force-recreate` pour les maintenances.
- Documenter la procédure de recréation du réseau dans le README de la stack.
### Signal de détection
Conteneur `Up (healthy)` mais `docker port <container>` vide, ou `docker inspect ... NetworkSettings.Ports` à `{}` → le conteneur a été recréé sans sa config de ports à jour. Fix : `compose up -d --force-recreate` (après avoir vérifié que le réseau externe existe).
> Risque connexe côté DNS Docker : voir `knowledge/infra/risques/docker.md`.