Sur un réseau faible, une proposition, un souvenir, une photo posée sur l'arbre ou un moment pouvait être
créé deux fois : la réponse se perdait (délai dépassé), la personne renvoyait, le serveur recréait tout.
- Navigateur (api/client.js) : un envoi qui n'a pas abouti garde sa clé, et le même envoi refait (même
adresse, même contenu) la réutilise. Une réussite libère la clé.
- Serveur (lib/idempotency.ts) : sur les quatre routes de création, une clé déjà vue par la même personne
renvoie la réponse du premier envoi ; deux essais simultanés n'en traitent qu'un ; un échec n'est pas gardé.
En mémoire, 24 h, 5 000 clés au plus.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Les ronds des personnes identifiées ne restent plus posés sur les visages. Ils apparaissent au survol de la photo
(ordinateur), quand on touche la photo (téléphone, un second toucher les cache), ou pour une seule personne quand
on survole ou focalise son prénom sous la photo. Toujours visibles pendant l'identification.
- Rond plus large (34 px) et plus fin (1,5 px) : il entoure le visage au lieu de le couvrir.
- Sur téléphone, les prénoms ne s'affichent plus en permanence par-dessus la photo.
Planche validée par Patch le 27/10 (option A) : _bmad-output/parenthese/motion/2026-10-27-visages/
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Un hook commun (hooks/useUndoable.js) porte les trois suppressions annulables : bandeau 6 s,
Ctrl+Z, requête envoyée à la fin du délai ou à la fermeture de la page.
- Souvenir (gestionnaire de souvenirs) : il n'y avait aucune confirmation, la suppression était immédiate.
- Moment (onglet Vie) : plus de « Supprimer / Garder ».
Corrige deux défauts de #169 :
- Les tableaux du graphe étaient mutés en place (splice, push), alors que les index par personne
(getPersonById, getPersonMedias) ne se reconstruisent qu'au remplacement du tableau. Nouveau
replaceGraph() dans mockData, utilisé pour la suppression et l'ajout d'une personne en démo.
- Le rechargement après l'envoi vidait la sélection : une fiche ouverte pendant le délai se fermait.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Une vignette de la fiche touchée est retenue un court instant (utils/openOrigin.js) ; la visionneuse part de là,
même largeur, et grandit jusqu'à sa place en 280 ms, transform seul, sans fondu. Le point de départ suit
l'ancrage de la fenêtre : centre sur ordinateur, bord bas sur téléphone (pz-overlay en place-items: end).
- Ouverte autrement (photo de l'arbre, liste), la visionneuse ne change pas. Fermeture inchangée, d'un coup.
- Mouvements réduits : la carte n'avait pas la classe .pz-modal et jouait sa montée quand même ; elle s'affiche
désormais d'un coup.
Planche validée par Patch le 27/10 : _bmad-output/parenthese/motion/2026-10-27-souvenir/
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Ordinateur : plus d'entrée animée (fondu et flou de 260 ms) ; on ouvre une fiche des dizaines de fois par visite.
- Téléphone : la feuille monte en 240 ms au lieu de 400 ; en mouvements réduits, fondu court seulement sur téléphone.
- Geste des feuilles (fiche et menu de la barre) : tirée vers le haut, la feuille cède de moins en moins (40 px au plus)
et revient au lâcher, au lieu de buter net. Logique pure sheetOffset, testée. Une ombre pleine comble le dessous.
- Coins continus (corner-shape: squircle) sur la fiche, le portrait et les vignettes, seulement là où le navigateur
les dessine ; ailleurs rien ne change.
Planche validée par Patch le 27/10 : _bmad-output/parenthese/motion/2026-10-27-fiche/
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
La personne disparaît tout de suite et un bandeau propose « Annuler » (ou Ctrl+Z) pendant 6 s.
La requête ne part qu'à la fin du délai, ou à la fermeture de la page (fetch keepalive).
Un rechargement de l'arbre pendant le délai ne fait pas revenir la personne.
Démo : même bandeau, retour à l'état d'avant.
Corrige au passage la recherche, qui gardait des résultats périmés après un ajout ou une
suppression (le tableau des personnes est modifié sur place).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Galaxy : l'onglet du lien s'ouvre dès que l'arbre et ses onglets sont connus, et de nouveau si la personne de départ arrive après (visiteur), tant qu'on n'a pas changé d'onglet soi-même ; onglets coupés dans ce navigateur, l'arbre entier s'ouvre sur la charnière
- App : l'adresse de la page porte l'onglet ouvert, le lien à envoyer aussi, avec le nom de la famille dans le titre
- Même mot de passe, même accès : le lien choisit l'onglet d'arrivée, il ne restreint rien (Patch, 26/10)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Tailwind 4 (app) : plugin Vite, remise à zéro de la v3 gardée (main sur les boutons, placeholder, bordure grise), thème et utilitaires inutilisés retirés
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Tailwind 4 (landing) : plugin Vite comme l'app, remise à zéro de la v3 gardée, thème inutilisé retiré ; marge gauche du graphe du hero retirée, écrasée par lg:mx-0 en v3 et devenue visible en v4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Prisma 7 : client généré dans src/generated, pilote pg, prisma.config.ts
- générateur prisma-client (ESM, extension .js), compilé dans dist : plus de node_modules/.prisma à copier dans les images
- @prisma/adapter-pg, délai de connexion de 5 s comme le moteur de Prisma 6
- prisma.config.ts : adresse de la base et .env pour le CLI, sans dépendre de prisma/config à l'exécution (CLI à part dans les images)
- CI : migrate diff --from-config-datasource --to-schema
- deploy.sh : arrêt avant installation si Node est trop vieux pour Prisma 7
- remplace les PR Dependabot #135 et #137
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Prisma 7 : import du client généré dans token-revocation (#163)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Comptes : une déconnexion reste valable après un redémarrage de l'API (sessions fermées gardées en base)
* Déconnexion durable : sans rechargement des sessions fermées, l'API ne démarre pas ; modèle remonté au-dessus du commentaire des photos
* OIDC : un compte à mot de passe relie lui-même son identité du fournisseur (ticket à usage unique), pour passer une instance en PASSWORD_LOGIN=false sans l'enfermer dehors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Compte : « Se connecter aussi avec … » relie le fournisseur à un compte à mot de passe
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* README : relier un compte à mot de passe avant PASSWORD_LOGIN=false
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Souvenirs : envoi en flux et par plages (Range, 206), pour Safari ; le fichier ne passe plus en entier en mémoire
* Range : fichier vide refusé en 416 ; test d'un souvenir en attente demandé par morceaux