mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
795 lines
24 KiB
Markdown
795 lines
24 KiB
Markdown
# Décisions techniques & architecture
|
||
|
||
Ce fichier documente les choix importants (format type ADR mais léger).
|
||
|
||
Objectifs :
|
||
|
||
- garder une trace du raisonnement
|
||
- éviter de reposer les mêmes questions
|
||
- assumer les compromis
|
||
|
||
Dernière mise à jour : 2026-03-10
|
||
|
||
---
|
||
|
||
## Index
|
||
|
||
- [Story sizing — foundations vs qualité non bloquante](#decision-story-sizing-foundations)
|
||
- [Code review adversariale — contexte frais](#decision-code-review-adversariale)
|
||
- [Workflows n8n complexes = mini-systèmes](#decision-n8n-mini-systemes)
|
||
- [Le front-end est un logiciel en production](#decision-frontend-production)
|
||
- [Le back-end est un logiciel en production](#decision-backend-production)
|
||
- [Contrats d’API explicites et versionnés](#decision-contrats-api)
|
||
- [Single source of truth des contrats — schémas runtime partagés (Zod) + z.infer (No-DTO)](#decision-contrats-sso-zod)
|
||
- [User views — User public par défaut + MeUser explicite](#decision-user-views)
|
||
- [Gestion standard des erreurs et des statuts HTTP](#decision-erreurs-http)
|
||
- [Migrations et évolution de schéma maîtrisées](#decision-migrations)
|
||
- [Observabilité minimale obligatoire](#decision-observabilite)
|
||
- [Authentification et autorisation centrales](#decision-auth-central)
|
||
- [Idempotence et gestion des retries](#decision-idempotence-retries)
|
||
- [Structure Docker et données persistantes](#decision-structure-docker)
|
||
- [Accès réseau des VM de développement via Tailscale](#decision-reseau-tailscale-vm-dev)
|
||
|
||
---
|
||
|
||
<a id="decision-reseau-tailscale-vm-dev"></a>
|
||
|
||
## Accès réseau des VM de développement via Tailscale
|
||
|
||
- Date : 2026-03-12
|
||
- Statut : Accepted
|
||
- Périmètre : infra
|
||
|
||
### Contexte
|
||
|
||
Les machines de développement personnelles (NUC / homelab) hébergent plusieurs VM :
|
||
|
||
- Home Assistant
|
||
- Docker-dev
|
||
- OpenClaw
|
||
- autres services internes
|
||
|
||
Ces VM exposent parfois :
|
||
|
||
- SSH
|
||
- bases de données
|
||
- interfaces web d’administration
|
||
- services de développement
|
||
|
||
Exposer ces services sur le LAN local ou sur Internet augmente inutilement la surface d’attaque et complique la lecture de l’infrastructure.
|
||
|
||
Le réseau privé Tailscale est utilisé comme couche d’accès sécurisée entre les machines de confiance.
|
||
|
||
### Options envisagées
|
||
|
||
- Exposer certains services sur le LAN local et filtrer “au cas par cas”
|
||
- Utiliser Tailscale comme frontière réseau principale pour les accès d’administration et de développement
|
||
- Lier directement les services à une interface donnée sans politique firewall explicite
|
||
|
||
### Décision
|
||
|
||
Les VM internes n’acceptent les connexions entrantes que via l’interface Tailscale.
|
||
|
||
Le pare-feu local (`ufw`) applique cette politique avec la configuration minimale suivante :
|
||
|
||
```bash
|
||
ufw default deny incoming
|
||
ufw default allow outgoing
|
||
```
|
||
|
||
Les services explicitement nécessaires sont autorisés uniquement sur `tailscale0`.
|
||
|
||
Exemples :
|
||
|
||
```bash
|
||
ufw allow in on tailscale0 to any port 22
|
||
ufw allow in on tailscale0 to any port 8080
|
||
ufw allow in on tailscale0 to any port 5432
|
||
```
|
||
|
||
Tout accès depuis Internet, le LAN local ou une autre interface réseau est refusé par défaut.
|
||
|
||
### Justification
|
||
|
||
- Réduit fortement la surface d’attaque
|
||
- Évite les expositions accidentelles de services de dev ou d’administration
|
||
- Simplifie l’accès distant sans ouvrir de ports ni gérer du NAT
|
||
- Rend la topologie réseau plus lisible et plus cohérente entre les VM
|
||
|
||
### Conséquences
|
||
|
||
- Tailscale devient la frontière réseau de confiance pour les VM internes
|
||
- SSH est accessible via Tailscale uniquement
|
||
- Les interfaces web de dev/admin et services de données ne sont ouverts que si un besoin réel existe
|
||
- Les règles `ufw` font partie de la configuration standard d’une nouvelle VM
|
||
|
||
Quand c’est possible, les services doivent écouter directement sur l’interface Tailscale plutôt que sur toutes les interfaces.
|
||
|
||
Exemples :
|
||
|
||
- préférable : `100.x.x.x:5432`
|
||
- acceptable si le firewall est strict : `0.0.0.0:5432`
|
||
- à éviter : écoute large + politique réseau permissive
|
||
|
||
Certains services restent fermés par défaut tant qu’un besoin explicite n’existe pas, en particulier :
|
||
|
||
- Redis
|
||
- bases de données non nécessaires en accès distant
|
||
- interfaces d’administration
|
||
|
||
Modèle visé :
|
||
|
||
```txt
|
||
Internet → ❌
|
||
LAN local → ❌
|
||
Tailscale → ✅
|
||
```
|
||
|
||
Cette convention est recommandée pour toutes les nouvelles VM du NUC, notamment `docker-dev` et `openclaw`.
|
||
|
||
---
|
||
|
||
<a id="decision-story-sizing-foundations"></a>
|
||
|
||
## Story sizing — foundations bloquantes vs qualité non bloquante (CI mobile)
|
||
|
||
- Date : 2026-03-09
|
||
- Statut : Accepted
|
||
- Périmètre : global
|
||
|
||
### Contexte
|
||
|
||
Des items “infra” ont été mis dans des stories foundations d’epic alors qu’aucune story métier suivante n’en dépendait (ex : CI Maestro mobile iOS/Android).
|
||
Résultat observé : story foundations “never-done”, friction et coût de contexte, sans bénéfice sur le throughput métier.
|
||
|
||
### Options envisagées
|
||
|
||
- Mettre toutes les améliorations de qualité dans foundations “par principe”
|
||
- Séparer les prérequis réellement bloquants du reste (qualité non bloquante)
|
||
|
||
### Décision
|
||
|
||
On distingue explicitement :
|
||
|
||
- **Prérequis bloquants** : à inclure dans foundations (les stories suivantes en dépendent)
|
||
- **Qualité non bloquante** : story indépendante, en parallèle ou après, sans bloquer le métier
|
||
|
||
### Justification
|
||
|
||
- Un epic doit pouvoir avancer sur le métier dès que les dépendances techniques minimales sont là
|
||
- Les chantiers “qualité” (CI mobile, perf, audits…) ont souvent une inertie qui ne doit pas geler l’epic
|
||
|
||
### Conséquences
|
||
|
||
- Pour chaque AC “infra” en foundations : poser la question “la story X+1 est-elle bloquée si ce n’est pas fait ?”
|
||
- Si la réponse est non : sortir l’AC en story dédiée (tag qualité / infra), et la planifier à part
|
||
|
||
---
|
||
|
||
<a id="decision-code-review-adversariale"></a>
|
||
|
||
## Code review adversariale — passe dédiée en contexte frais
|
||
|
||
- Date : 2026-03-09
|
||
- Statut : Accepted
|
||
- Périmètre : global
|
||
|
||
### Contexte
|
||
|
||
Certaines issues CRITICAL sont invisibles dans le contexte d’implémentation (biais de confirmation : “je sais comment c’est censé marcher”).
|
||
Elles émergent uniquement en lecture froide : fondations manquantes, usages dépréciés, invariants non respectés (ex : sessions sans TTL).
|
||
|
||
### Options envisagées
|
||
|
||
- Review “au fil de l’eau” dans le même contexte que l’implémentation
|
||
- Review dédiée, séparée, en contexte frais (nouvelle session / nouveau modèle / reviewer différent)
|
||
|
||
### Décision
|
||
|
||
La code review doit être une passe **séparée** de l’implémentation, en **contexte frais**, avec un objectif explicite : chercher des CRITICAL sans concession.
|
||
|
||
### Justification
|
||
|
||
- Les incohérences systémiques (sécurité, idempotence, TTL, drift de contracts) se détectent mieux en lecture froide
|
||
- Réduit fortement le coût de debug tardif (prod/staging) et les refactors “de fondations”
|
||
|
||
### Conséquences
|
||
|
||
- Process recommandé :
|
||
1. Dev termine l’implémentation, marque la story `review`
|
||
2. Nouvelle session (contexte frais) : charger uniquement story + diff
|
||
3. Review adversariale : lister CRITICAL + mitigations
|
||
4. Corriger avant `done`
|
||
|
||
---
|
||
|
||
## Format standard d’une décision
|
||
|
||
## <Titre>
|
||
|
||
- Date : YYYY-MM-DD
|
||
- Statut : Proposed | Accepted | Deprecated
|
||
- Périmètre : n8n | backend | infra | global
|
||
|
||
### Contexte
|
||
|
||
### Options envisagées
|
||
|
||
### Décision
|
||
|
||
### Justification
|
||
|
||
### Conséquences
|
||
|
||
---
|
||
|
||
<a id="decision-n8n-mini-systemes"></a>
|
||
|
||
## Workflows n8n complexes = mini-systèmes
|
||
|
||
- Date : 2025-12-19
|
||
- Statut : Accepted
|
||
- Périmètre : n8n
|
||
|
||
### Contexte
|
||
|
||
Certains workflows n8n dépassent le simple enchaînement de nodes et deviennent
|
||
de véritables systèmes applicatifs (orchestration, état, branches, retries, intégrations multiples).
|
||
|
||
### Options envisagées
|
||
|
||
- Traiter ces workflows comme de simples automatisations “low-code”
|
||
- Les considérer comme du code à part entière (discipline, patterns, doc, prudence sur upgrades)
|
||
|
||
### Décision
|
||
|
||
Les considérer comme du code.
|
||
|
||
### Justification
|
||
|
||
- Complexité réelle (logique, état, orchestration)
|
||
- Sensibilité aux versions n8n (upgrade-risk)
|
||
- Besoin de maintenabilité et de capitalisation
|
||
|
||
### Conséquences
|
||
|
||
- Prudence accrue lors des upgrades
|
||
- Documentation minimale mais ciblée
|
||
- Patterns explicitement identifiés et partagés
|
||
- On accepte d’utiliser du Code (JS) quand nécessaire
|
||
|
||
---
|
||
|
||
<a id="decision-frontend-production"></a>
|
||
|
||
## Le front-end est un logiciel en production
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : global
|
||
|
||
### Contexte
|
||
|
||
Les applications front-end modernes (SPA, webapps) portent une part significative
|
||
de la logique applicative : state, validations, permissions, erreurs, performance,
|
||
sécurité côté client, expérience utilisateur.
|
||
|
||
Les traiter comme une simple “couche UI” conduit régulièrement à :
|
||
|
||
- une dette technique rapide,
|
||
- des bugs difficiles à diagnostiquer,
|
||
- une expérience utilisateur incohérente,
|
||
- une maintenance coûteuse dans le temps.
|
||
|
||
### Options envisagées
|
||
|
||
- Traiter le front-end comme une couche de rendu légère, peu structurée
|
||
- Traiter le front-end comme un logiciel à part entière, avec des exigences similaires au backend
|
||
|
||
### Décision
|
||
|
||
Le front-end est traité comme un **logiciel en production**.
|
||
|
||
Il est soumis aux mêmes principes que le backend :
|
||
|
||
- architecture explicite,
|
||
- gestion des erreurs,
|
||
- conventions de code,
|
||
- tests au bon niveau,
|
||
- attention portée à la maintenabilité et à l’évolution.
|
||
|
||
### Justification
|
||
|
||
- Le front concentre une logique métier et technique réelle
|
||
- Les bugs front ont un impact direct sur les utilisateurs
|
||
- La complexité augmente mécaniquement avec le produit
|
||
- Les choix initiaux conditionnent fortement la maintenabilité future
|
||
|
||
### Conséquences
|
||
|
||
- Mise en place de patterns front validés et documentés
|
||
- Gestion explicite des états UI, erreurs et formulaires
|
||
- Attention portée à la performance et à l’accessibilité
|
||
- Acceptation d’un léger surcoût initial pour réduire la dette long terme
|
||
|
||
---
|
||
|
||
<a id="decision-backend-production"></a>
|
||
|
||
## Le back-end est un logiciel en production (qualité, observabilité, sécurité)
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
Le back-end porte la logique métier, l’accès aux données, la sécurité et la fiabilité.
|
||
Les bugs et régressions y ont un impact direct (données, paiements, confidentialité, disponibilité).
|
||
|
||
Sans cadre explicite, on dérive vers :
|
||
|
||
- des erreurs non diagnostiquables,
|
||
- des endpoints incohérents,
|
||
- des migrations risquées,
|
||
- une sécurité “au feeling”.
|
||
|
||
### Options envisagées
|
||
|
||
- Traiter le back-end comme un simple “serveur d’API” avec peu de discipline
|
||
- Traiter le back-end comme un logiciel en production avec exigences explicites
|
||
|
||
### Décision
|
||
|
||
Le back-end est traité comme un **logiciel en production**.
|
||
|
||
Exigences minimales :
|
||
|
||
- conventions de code et structure de projet explicites,
|
||
- gestion standard des erreurs (codes, formats, logs),
|
||
- observabilité (logs structurés, corrélation, métriques de base),
|
||
- sécurité par défaut (authn/authz, validation, secrets),
|
||
- migrations et changements de schéma maîtrisés.
|
||
|
||
### Justification
|
||
|
||
- Réduction drastique du temps de debug
|
||
- Diminution du risque de régressions et d’incidents
|
||
- Base saine pour itérer vite sans casser
|
||
|
||
### Conséquences
|
||
|
||
- On documente les décisions structurantes (ce fichier)
|
||
- On capitalise les incidents dans Debug & post-mortems
|
||
- On privilégie des patterns éprouvés plutôt que “créatif”
|
||
|
||
---
|
||
|
||
<a id="decision-contrats-api"></a>
|
||
|
||
## Contrats d’API explicites et versionnés
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
Les front-ends, automatisations et intégrations dépendent du back-end via des contrats.
|
||
Quand les contrats sont implicites, les changements cassent silencieusement et coûtent cher à diagnostiquer.
|
||
|
||
### Options envisagées
|
||
|
||
- Contrats implicites (docs “à la main”, alignement informel)
|
||
- Contrats explicites (schémas, validations, compatibilité)
|
||
|
||
### Décision
|
||
|
||
Les contrats d’API sont **explicites** et **versionnés**.
|
||
|
||
Minimum attendu :
|
||
|
||
- formats de requêtes/réponses définis (ex. OpenAPI/JSON Schema),
|
||
- validations côté serveur (entrée) et formats de sortie cohérents,
|
||
- compatibilité gérée (breaking changes évitées ou versionnées).
|
||
|
||
### Justification
|
||
|
||
- Réduit les bugs d’intégration
|
||
- Permet des évolutions plus sereines
|
||
- Facilite tests, mocks et onboarding
|
||
|
||
### Conséquences
|
||
|
||
- Toute évolution de contrat est traitée comme un changement “important”
|
||
- Les breaking changes passent par une décision et/ou une version
|
||
- Les erreurs retournées suivent un format standard (voir décision dédiée)
|
||
|
||
---
|
||
|
||
<a id="decision-contrats-sso-zod"></a>
|
||
|
||
## Single source of truth des contrats — schémas runtime partagés (Zod) + z.infer (No-DTO)
|
||
|
||
- Date : 2026-03-10
|
||
- Statut : Proposed
|
||
- Périmètre : global
|
||
|
||
### Contexte
|
||
|
||
TypeScript ne valide pas les payloads HTTP au runtime (les types disparaissent à l’exécution).
|
||
Quand on maintient à la fois des DTO/back (ex. Nest + decorators) et des types/contracts côté clients, on obtient une double source de vérité → drift, régressions, temps de debug.
|
||
|
||
### Options envisagées
|
||
|
||
- DTO NestJS + `class-validator` (validation runtime OK côté API, mais non partageable tel quel côté clients → duplication ou génération)
|
||
- Schémas runtime partagés dans un package `contracts` + types dérivés (validation + types alignés)
|
||
- OpenAPI/JSON Schema “first” + codegen (artefact contractuel unique, mais pipeline/outillage à maintenir)
|
||
|
||
### Décision
|
||
|
||
La source de vérité des contrats API↔clients est un package `contracts` contenant des **schémas runtime** (Zod), et les types TypeScript sont **dérivés** via `z.infer` (No-DTO / pas de redéfinition locale).
|
||
|
||
Principe opérationnel :
|
||
|
||
- validation concentrée aux frontières (ex. pipe/guard de validation côté API),
|
||
- le reste du code consomme des **types** (et non des classes DTO redondantes),
|
||
- les contrats restent “wire-level” (pas de métier, pas de stores, pas de classes Nest).
|
||
|
||
### Justification
|
||
|
||
- Un seul artefact sert à la fois de validation runtime et de typage compile-time
|
||
- Propagation des changements plus fiable (compile + tests) → réduction du temps de debug
|
||
|
||
### Conséquences
|
||
|
||
- Dépendance assumée à Zod dans `contracts`
|
||
- Les clients consomment les types; la validation côté client reste optionnelle (utile surtout sur entrées non-API : storage, deeplinks, etc.)
|
||
- En contexte non-mobile (Nest/React), OpenAPI-first + codegen reste une alternative valide si multi-clients/externe ou besoin fort de contrat public/documenté
|
||
|
||
---
|
||
|
||
<a id="decision-user-views"></a>
|
||
|
||
## User views — User public par défaut + MeUser explicite
|
||
|
||
- Date : 2026-03-10
|
||
- Statut : Proposed
|
||
- Périmètre : global
|
||
|
||
### Contexte
|
||
|
||
Un “User” complet est rarement un bon contrat universel : il peut contenir des champs sensibles (email, adresse, téléphone, flags internes…).
|
||
Les dérivations TypeScript seules (`Omit<User, "password">`) ne protègent pas au runtime et favorisent les fuites accidentelles.
|
||
|
||
### Options envisagées
|
||
|
||
- Un type `User` “god object” + dérivations TS (Omit/Pick) au cas par cas
|
||
- Des “views” explicites par contexte (public, self, admin…), dérivées depuis les schémas runtime
|
||
- Un modèle unique côté DB + sérialisation implicite (risque élevé de fuite)
|
||
|
||
### Décision
|
||
|
||
`User` (dans les contracts) est **public par défaut** et minimal (safe-by-default).
|
||
La vue self/compte est un contrat séparé `MeUser`.
|
||
Toute vue plus riche est créée explicitement et nommée (ex. `AdminUser`, `UserDirectoryEntry`).
|
||
|
||
Règles associées :
|
||
|
||
- les vues sont dérivées depuis les schémas runtime (extend/pick/omit) + `z.infer`
|
||
- `password` (et assimilés) n’existe que dans des requêtes d’auth (login/register/reset/change), jamais dans un `User*`
|
||
|
||
### Justification
|
||
|
||
- Réduit le risque de fuite de données et clarifie les permissions/UX
|
||
- Évite les champs optionnels ambigus et les contrats “implicites”
|
||
|
||
### Conséquences
|
||
|
||
- Chaque endpoint choisit explicitement la vue renvoyée (et côté DB, un `select` explicite par vue)
|
||
- Les clients typent “public” vs “mon compte” distinctement
|
||
- Des tests “no secret keys” sur réponses user/auth deviennent simples et efficaces
|
||
|
||
---
|
||
|
||
<a id="decision-erreurs-http"></a>
|
||
|
||
## Gestion standard des erreurs et des statuts HTTP
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
Sans standard, chaque endpoint renvoie des erreurs différentes (formats, codes, messages),
|
||
ce qui complique le front, les automatisations et l’observabilité.
|
||
|
||
### Options envisagées
|
||
|
||
- Erreurs “au cas par cas”
|
||
- Format d’erreur et mapping HTTP standardisés
|
||
|
||
### Décision
|
||
|
||
Les erreurs HTTP sont standardisées :
|
||
|
||
- codes HTTP cohérents (4xx vs 5xx),
|
||
- format de réponse d’erreur stable,
|
||
- logs corrélés (requestId / traceId),
|
||
- messages utilisateur séparés des détails techniques.
|
||
|
||
### Justification
|
||
|
||
- Debug plus rapide
|
||
- UX meilleure (erreurs compréhensibles et gérables côté client)
|
||
- Observabilité fiable
|
||
|
||
### Conséquences
|
||
|
||
- Les handlers d’erreurs sont centralisés
|
||
- Les erreurs applicatives ont des codes internes stables
|
||
- Les détails sensibles ne fuitent pas vers le client
|
||
|
||
---
|
||
|
||
<a id="decision-migrations"></a>
|
||
|
||
## Migrations et évolution de schéma maîtrisées
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
Les changements de schéma/DB sont une source majeure d’incidents et de downtime,
|
||
surtout quand on déploie sans discipline (ordre des déploiements, rétrocompatibilité).
|
||
|
||
### Options envisagées
|
||
|
||
- Changements manuels / non traçables
|
||
- Migrations versionnées, reproductibles, avec stratégie de compatibilité
|
||
|
||
### Décision
|
||
|
||
Toute évolution de schéma passe par des **migrations versionnées** et reproductibles.
|
||
|
||
Principes :
|
||
|
||
- migrations idempotentes quand possible,
|
||
- stratégie de déploiement compatible (expand/contract si nécessaire),
|
||
- rollback envisagé ou plan de mitigation.
|
||
|
||
### Justification
|
||
|
||
- Réduit le risque prod
|
||
- Permet de rejouer l’historique en dev/staging
|
||
- Facilite l’audit et la reproductibilité
|
||
|
||
### Conséquences
|
||
|
||
- Les changements DB sont revus comme du code
|
||
- Les migrations sont testées (au moins sur staging)
|
||
- Les déploiements tiennent compte de l’ordre (code vs DB)
|
||
|
||
---
|
||
|
||
<a id="decision-observabilite"></a>
|
||
|
||
## Observabilité minimale obligatoire (logs, corrélation, signaux)
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
Sans signaux, on “devine” en production : pas de corrélation, pas de métriques,
|
||
pas de compréhension de l’impact utilisateur.
|
||
|
||
### Options envisagées
|
||
|
||
- Logs non structurés, pas de corrélation
|
||
- Observabilité minimale standard (logs structurés, IDs, métriques de base)
|
||
|
||
### Décision
|
||
|
||
Observabilité minimale obligatoire :
|
||
|
||
- logs structurés (niveau, événement, contexte),
|
||
- requestId/traceId propagé et présent dans chaque log,
|
||
- métriques de base (taux d’erreur, latence, throughput),
|
||
- alertes simples sur erreurs 5xx / latence.
|
||
|
||
### Justification
|
||
|
||
- Réduit drastiquement le MTTR
|
||
- Permet de prioriser les vrais problèmes
|
||
- Facilite les post-mortems
|
||
|
||
### Conséquences
|
||
|
||
- On standardise le middleware de logging/corrélation
|
||
- Les endpoints critiques ont des logs et métriques dédiés
|
||
- Les incidents sont capitalisés dans Debug & post-mortems
|
||
|
||
---
|
||
|
||
<a id="decision-auth-central"></a>
|
||
|
||
## Authentification et autorisation comme responsabilités centrales
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
L’authentification (qui est l’utilisateur) et l’autorisation (ce qu’il a le droit de faire)
|
||
sont au cœur de la sécurité applicative. Les traiter de manière dispersée ou implicite
|
||
conduit à des failles, des incohérences et des bugs difficiles à auditer.
|
||
|
||
### Options envisagées
|
||
|
||
- Gestion ad hoc de l’authentification et des permissions (logique dispersée)
|
||
- Centralisation claire des mécanismes d’authentification et d’autorisation
|
||
|
||
### Décision
|
||
|
||
L’authentification et l’autorisation sont des **responsabilités centrales du back-end**.
|
||
|
||
Principes :
|
||
|
||
- mécanisme d’authentification unique et explicite,
|
||
- règles d’autorisation centralisées et testables,
|
||
- séparation claire entre authentification (authn) et autorisation (authz),
|
||
- décisions d’accès traçables (logs/audit).
|
||
|
||
### Justification
|
||
|
||
- Réduction du risque de failles de sécurité
|
||
- Lisibilité et auditabilité accrues
|
||
- Évolutivité des règles de permissions
|
||
|
||
### Conséquences
|
||
|
||
- Les contrôles d’accès ne sont pas codés “au fil de l’eau”
|
||
- Les règles sensibles sont documentées
|
||
- Toute évolution des permissions est traitée comme un changement critique
|
||
|
||
---
|
||
|
||
<a id="decision-idempotence-retries"></a>
|
||
|
||
## Idempotence et gestion des retries pour les opérations sensibles
|
||
|
||
- Date : 2026-01-25
|
||
- Statut : Accepted
|
||
- Périmètre : backend
|
||
|
||
### Contexte
|
||
|
||
Les appels réseau peuvent échouer ou être rejoués (timeouts, retries automatiques,
|
||
webhooks, erreurs client). Sans idempotence, certaines opérations critiques
|
||
(paiement, création de ressources, envoi d’événements) peuvent être exécutées plusieurs fois.
|
||
|
||
### Options envisagées
|
||
|
||
- Gérer les erreurs au cas par cas sans garantie d’idempotence
|
||
- Concevoir explicitement les opérations sensibles comme idempotentes
|
||
|
||
### Décision
|
||
|
||
Les opérations sensibles sont conçues pour être **idempotentes**.
|
||
|
||
Principes :
|
||
|
||
- identification unique des requêtes (idempotency key),
|
||
- protection contre les doublons,
|
||
- comportements définis en cas de retry.
|
||
|
||
### Justification
|
||
|
||
- Prévention des doublons et incohérences de données
|
||
- Robustesse face aux pannes réseau
|
||
- Sécurité accrue pour les flux critiques
|
||
|
||
### Conséquences
|
||
|
||
- Les endpoints critiques documentent leur stratégie d’idempotence
|
||
- Les retries sont maîtrisés et prévisibles
|
||
- Les automatisations et intégrations peuvent être rejouées sans risque
|
||
|
||
---
|
||
|
||
<a id="decision-structure-docker"></a>
|
||
|
||
## Convention de structure pour les projets Docker et les données persistantes
|
||
|
||
- Date : 2026-03-06
|
||
- Statut : Accepted
|
||
- Périmètre : infra
|
||
|
||
### Contexte
|
||
|
||
Sur un serveur de développement (NUC / VM docker-dev), Docker mélange facilement
|
||
code applicatif, données persistantes, volumes et backups si aucune convention
|
||
n’est définie.
|
||
|
||
Avec le temps cela rend :
|
||
|
||
- les sauvegardes ambiguës
|
||
- le nettoyage risqué
|
||
- la compréhension de l’infrastructure difficile
|
||
- la reconstruction d’un environnement compliquée
|
||
|
||
Une structure simple et explicite permet d’éviter ces problèmes.
|
||
|
||
### Options envisagées
|
||
|
||
- Laisser Docker gérer implicitement les volumes (`/var/lib/docker/volumes`)
|
||
- Laisser chaque projet organiser librement ses dossiers
|
||
- Définir une convention globale claire séparant code, données et sauvegardes
|
||
|
||
### Décision
|
||
|
||
La structure standard suivante est adoptée sur les machines d’infrastructure
|
||
(NUC / serveurs de développement) :
|
||
|
||
```
|
||
/srv
|
||
├ projects
|
||
├ docker-data
|
||
└ backups
|
||
```
|
||
|
||
Principes :
|
||
|
||
- `/srv/projects`
|
||
contient les projets applicatifs (code, `docker-compose.yml`, `.env`, scripts).
|
||
|
||
- `/srv/docker-data`
|
||
contient les données persistantes des conteneurs (bases de données, uploads,
|
||
état applicatif).
|
||
|
||
- `/srv/backups`
|
||
contient les dumps, archives et exports destinés à la sauvegarde.
|
||
|
||
### Justification
|
||
|
||
- séparation claire **code / données / sauvegardes**
|
||
- sauvegardes plus simples et plus fiables
|
||
- nettoyage d’un projet possible sans risque pour les autres
|
||
- lisibilité immédiate de l’infrastructure
|
||
- reproductibilité de l’environnement
|
||
|
||
### Conséquences
|
||
|
||
Les conteneurs utilisent en priorité des **bind mounts explicites**, par exemple :
|
||
|
||
```txt
|
||
/srv/docker-data/monapp-postgres:/var/lib/postgresql/data
|
||
```
|
||
|
||
Les volumes Docker implicites (`/var/lib/docker/volumes`) sont évités quand la
|
||
lisibilité et la maintenabilité priment.
|
||
|
||
Les données critiques à sauvegarder se trouvent principalement dans :
|
||
|
||
```
|
||
/srv/projects
|
||
/srv/docker-data
|
||
```
|
||
|
||
Convention de nommage recommandée pour les dossiers de données :
|
||
|
||
```
|
||
ex :
|
||
rl799-postgres
|
||
monapp-redis
|
||
n8n-postgres
|
||
```
|
||
|
||
---
|