13 KiB
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 : 2025-12-19
Format standard d’une décision
- Date : YYYY-MM-DD
- Statut : Proposed | Accepted | Deprecated
- Périmètre : n8n | backend | infra | global
Contexte
Options envisagées
Décision
Justification
Conséquences
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
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
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”
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)
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
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)
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
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
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
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/projectscontient les projets applicatifs (code,docker-compose.yml,.env, scripts). -
/srv/docker-datacontient les données persistantes des conteneurs (bases de données, uploads, état applicatif). -
/srv/backupscontient 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 :
/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