Commit Graph
3 Commits
Author SHA1 Message Date
Claude 4767d10507 Dire ce qu'il faut faire quand la connexion à la base est refusée
L'application redémarrait en boucle sur « P1000 » sans rien indiquer. Le point
d'entrée distingue désormais les deux causes et donne le remède.

Les deux codes ne disent pas la même chose, et c'est la mesure qui a permis de
les séparer : **P1010** signifie que le rôle n'existe pas, **P1000** qu'il existe
mais que son mot de passe ne correspond pas à celui que porte la pile — le cas
d'un rôle posé lors d'un déploiement antérieur avec une autre valeur. Le remède
est le même : `db-init` crée le rôle ou réaligne son mot de passe.

Le script d'initialisation lui-même a été éprouvé une fois de plus, y compris
avec l'argument parasite que Docker ajoute quand `entrypoint` est surchargé sans
`command` : il aboutit et pose le rôle.

Ce que je ne peux pas voir d'ici, et qu'il faut regarder sur le serveur : si le
service `db-init` figure dans la pile déployée, et ce qu'il a journalisé. Un
rôle dont le mot de passe ne correspond pas est précisément ce qu'il corrige.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv
2026-08-09 17:20:04 +00:00
Claude 0a15275d1b Livrer la CLI de migration dans une disposition qui tient
Le conteneur démarrait puis s'arrêtait sur « Cannot find module
'@prisma/config' ». Le Dockerfile prélevait à la main quelques répertoires de
node_modules — `prisma`, `.bin/prisma`, `@prisma` — en supposant une disposition
plate. pnpm range les dépendances dans un magasin virtuel `.pnpm`, sous des
répertoires au nom haché : la CLI arrivait sans les siennes.

Elle est désormais installée par npm, qui produit une disposition plate,
copiable telle quelle. La version est lue dans package.json plutôt que figée,
pour qu'elle ne diverge pas au premier changement.

Tout ce qui sert aux migrations — modules, schéma, configuration — vit dans un
arbre séparé. Les superposer aux modules de l'application les ferait entrer en
collision : la sortie `standalone` porte `react` en lien symbolique vers le
magasin pnpm, là où l'installation npm l'apporte en répertoire réel. Deux arbres
n'ont rien à s'écraser.

`prisma.config.ts` n'importe plus `dotenv` de façon ferme : la sortie
`standalone` n'embarque que ce que le serveur utilise, et `dotenv` n'en fait pas
partie — l'import aurait fait échouer les migrations au démarrage.

Cette fois l'image a été reconstituée à l'identique et **démarrée** : clé
produite, migrations appliquées, serveur prêt, `/connexion` en 200 et
`/api/sante` rapportant `tenantIsolation: enforced`. C'est ce que j'aurais dû
faire aux trois tentatives précédentes, où je n'avais éprouvé que des morceaux.

La simulation a d'ailleurs trouvé un chemin `/migrator` en dur dans le point
d'entrée ; il est désormais surchargeable, comme l'emplacement de la clé.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv
2026-08-09 11:09:23 +00:00
Claude e5524c6299 Produire la clé de chiffrement au premier démarrage
Le déploiement restait bloqué sur ENCRYPTION_KEY. J'ai tenu trop longtemps la
position « pas de valeur par défaut », en confondant deux choses : refuser une
clé livrée avec l'image — ce qui reste juste, une clé publiée dans un dépôt ne
protège rien — et exiger qu'un humain en fabrique une avant tout démarrage.

Une variable d'environnement n'est d'ailleurs pas un bon coffre : elle s'affiche
dans `docker inspect` et dans l'interface de gestion. Un fichier produit au
démarrage, dans un volume distinct de la base et des documents, n'est pas moins
protégé — et une sauvegarde de l'un n'emporte plus la clé de l'autre.

Le point d'entrée la produit donc si elle manque, l'écrit en 0600, et l'affiche
une fois dans les journaux avec ce qu'il faut en faire. Une clé fournie
explicitement l'emporte toujours : un déploiement qui gère ses secrets ailleurs
ne doit pas être contrarié. La pile démarre désormais sans aucune variable.

Éprouvé sur le script lui-même : première exécution, clé de 32 octets produite
et annoncée ; deuxième, reprise en silence depuis le fichier ; avec une clé
fournie, le fichier reste intact.

Corrigé au passage, révélé par un échec transitoire du test : une écriture
disque impossible — volume plein, droits, montage absent — remontait en
exception non traitée. L'écran restait muet, la pièce n'était pas déposée et
rien ne le disait.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv
2026-08-09 09:41:24 +00:00