ADR-064 : forge db:config amorce les variables d'environnement du backend ; le contrat backend porte env_template¶
Statut¶
Acceptée, Forge 1.0.0-rc.x (ticket DB-CONFIG-ENV-SCAFFOLD-001).
Décision actée ; l'implémentation accompagne cet ADR.
Étend le contrat DatabaseBackend d'ADR-054 et complète ADR-060 (la configuration de connexion appartient au backend).
Date¶
2026-07-06
Contexte¶
Installer un backend BDD se fait par pip install forge-mvc-<sgbd>.
Mais pip ne peut pas configurer le projet : il installe dans le .venv, ne connaît ni la racine du projet ni ses fichiers env/, et un wheel n'exécute aucun code à l'installation (packaging moderne, PEP 517).
La configuration de connexion doit donc passer par une commande forge, qui, elle, s'exécute dans le projet.
Or aujourd'hui, aucune commande ne remplit ce rôle.
Le squelette est livré sans backend (ADR-060) : env/example ne contient qu'un commentaire renvoyant à la documentation du backend, sans aucune clé.
Le développeur doit donc lire la documentation du backend et saisir à la main les bonnes clés (DB_HOST, DB_PORT, DB_NAME, DB_APP_*, DB_ADMIN_*…), sans filet : forge doctor ne signale même pas ces clés comme manquantes (il n'exige que les clés transverses du cadre).
Ce retour terrain (installation du backend MariaDB dans une application réelle) révèle un trou d'UX : le backend est installé, mais rien n'aide à configurer son environnement.
Décision¶
1. Le contrat backend déclare ses variables d'environnement¶
Le contrat DatabaseBackend (core) porte un attribut env_template : la liste ordonnée des variables d'environnement que le backend lit, chacune avec une valeur d'exemple ou un placeholder vide.
Chaque backend la fournit selon ses besoins :
- SQLite :
DB_NAME(chemin du fichier) ; - MariaDB :
DB_HOST,DB_PORT,DB_NAME,DB_APP_LOGIN,DB_APP_PWD,DB_ADMIN_LOGIN,DB_ADMIN_PWD; - PostgreSQL :
DB_HOST,DB_PORT,DB_NAME,DB_APP_LOGIN,DB_APP_PWD; - SQL Server : les mêmes, plus
DB_ODBC_DRIVER.
2. forge db:config amorce les fichiers d'environnement¶
Une nouvelle commande forge db:config :
- résout le backend installé (par entry point, ADR-054 ; erreur explicite si aucun) ;
- écrit les clés manquantes de son
env_templatedans les trois fichiers d'environnement du projet,env/example,env/devetenv/prod, groupées sous un en-tête# Base de données (forge-mvc-<name>); - procède en write-if-missing par fichier et par clé : elle n'écrase jamais une valeur déjà renseignée, et n'ajoute que ce qui manque ;
- annonce précisément ce qu'elle a ajouté et liste les clés restant à renseigner ;
- est idempotente : relancée quand tout est présent, elle indique que la configuration est complète.
db:config n'écrit jamais de secret : elle ne pose que des placeholders (valeurs d'exemple pour l'hôte et le port, vides pour les noms, comptes et mots de passe).
C'est ce qui rend légitime l'écriture dans env/example, versionné : le gabarit documente les clés attendues sans exposer aucune valeur sensible.
Le développeur renseigne ensuite les valeurs réelles dans env/dev et env/prod (ignorés par Git).
2 bis. db:config --remove retire ces variables (désinstallation)¶
Symétriquement (charte n°10 : une API publique est un contrat de complétude), forge db:config --remove retire des trois fichiers les clés de l'env_template du backend.
- Elle ne touche qu'à ces clés, jamais d'autres
DB_*. - Elle annonce les clés retirées et prévient que les valeurs renseignées (secrets) sont perdues : le retrait est plus destructif que l'ajout, qui ne posait que des placeholders.
- Elle se lance avant
pip uninstall forge-mvc-<sgbd>, tant que le backend est encore résolvable par son entry point.
3. db:init reste focalisé sur le provisioning¶
db:init ne change pas : il provisionne la base et les comptes (DB_ADMIN_*).
La séparation des responsabilités est nette : db:config prépare la configuration, db:init provisionne, db:apply crée les tables.
Aucune commande ne s'exécute « à moitié ».
Le cycle d'ajout d'un backend :
pip install --pre forge-mvc-mariadb
forge db:config # écrit DB_* dans env/example, env/dev, env/prod (annoncé)
# … renseigner les valeurs dans env/dev et env/prod …
forge db:init # provisionne base et comptes
forge db:apply # crée les tables
4. Cohérence avec ADR-060¶
db:config peut écrire env/example parce que le backend est désormais choisi : ce n'est pas forge new qui pré-câble un backend, mais une action explicite du développeur après son choix.
ADR-060 reste vrai : le squelette produit par forge new demeure sans backend.
Conséquences¶
- Le développeur n'a plus à connaître ni saisir les noms de clés :
forge db:configles pose dans tous les environnements, en une commande explicite et annoncée. env/exampledocumente enfin les clés du backend choisi (sans secret), ce qui aide toute personne clonant le dépôt.- L'écriture est explicite et annoncée : elle respecte la charte n°9 (pas d'écriture invisible) et n'a rien de la « magie » d'un
pip installqui modifierait le projet. - Le contrat
DatabaseBackends'enrichit d'un attribut ; les quatre backends doivent le fournir (garde-fou de conformité). doctorpeut, à terme, s'appuyer surenv_templatepour signaler les clés manquantes (hors périmètre de ce ticket).
Alternatives écartées¶
pip installmodifie lesenv: techniquement impossible (pip ne connaît pas le projet, un wheel n'exécute pas de code) et ce serait précisément l'écriture invisible que la charte interdit.db:initen deux temps (amorcer puis, au second appel, provisionner) : une même commande « s'arrête à moitié », ce qui brouille sa responsabilité (charte n°2). Un verbe dédié est plus clair.env/devseulement : laisseraitenv/example(le gabarit versionné) etenv/proddésynchronisés des clés réelles du projet.- Afficher seulement (sans écrire) : plus conservateur, mais le développeur devrait encore recopier les clés à la main.
Charte appliquée¶
- Principe 2 (une responsabilité par ticket/commande) :
db:configconfigure,db:initprovisionne. - Principe 3 (refuser la magie cachée) : l'écriture est déclenchée explicitement et annoncée, jamais au détour d'un
pip install. - Principe 9 (pas d'écriture invisible dans le code utilisateur) :
db:configannonce chaque ajout ; elle n'écrase jamais une valeur existante et n'écrit aucun secret. - Principe 11 (une seule façon officielle) : une commande unique et documentée pour amorcer la configuration d'un backend.
Lié à ADR-054 (contrat de backend), ADR-060 (la config de connexion appartient au backend), ADR-033 (comptes DB_ADMIN_* / DB_APP_*).