Sauvegarder une fois par séance plutôt qu'à chaque modification

L'interface enregistre après une seconde d'inactivité, et le serveur copiait
le planning avant chaque écriture : une après-midi d'édition produisait des
dizaines de fichiers quasi identiques.

Le problème n'est pas la place occupée mais ce que la rotation en faisait —
les cinquante emplacements se remplissaient en quelques heures et chassaient
les états anciens, les seuls qu'on cherche à retrouver. Un filet qui ne
remonte pas au-delà de la dernière demi-heure ne protège pas de la bêtise
qu'on découvre le lendemain.

La copie est désormais prise à l'ouverture, quand le planning est encore dans
l'état d'avant la séance. Deux garde-fous : au plus une par jour si le serveur
reste allumé longtemps, et rien du tout si le contenu n'a pas bougé depuis la
dernière copie. Les cinquante conservées couvrent maintenant des mois.

La copie et le remplacement partagent un état — la date de la dernière
sauvegarde — donc un verrou les sérialise, ce qui protège au passage du cas
où deux onglets enregistrent simultanément.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 17:08:26 +02:00
parent 558d42f4cb
commit faac28172e
4 changed files with 201 additions and 14 deletions

View File

@@ -64,8 +64,9 @@ serveur de la bibliothèque standard, `GET` et `PUT` sur `/api/data`, tient en u
— soit **moins** de code que l'API navigateur plus son repli plus son miroir. Et il fonctionne
partout, sans sélecteur à réautoriser.
Bénéfice supplémentaire : le serveur peut écrire une sauvegarde horodatée à chaque écriture, ce que
la File System Access API ne permettait pas simplement.
Bénéfice supplémentaire : le serveur peut écrire une sauvegarde horodatée, ce que la File System
Access API ne permettait pas simplement. Elle l'était alors à chaque écriture ; son rythme a depuis
changé, voir décision 23.
## 4. DOM et CSS plutôt que SVG
@@ -500,3 +501,33 @@ sans recompiler.
`serve.py` a été supprimé une fois le binaire validé en usage réel. Il n'y avait rien à migrer : le
format du fichier et les routes sont identiques, et son historique reste dans git si le besoin de
le relire se présentait.
## 23. Une sauvegarde par séance, pas une par modification
Le serveur copiait le planning dans `backups/` avant **chaque** écriture. Comme l'interface
enregistre après une seconde d'inactivité, une séance d'édition un peu soutenue produisait des
dizaines de fichiers quasi identiques.
Le défaut n'est pas l'espace occupé — cinquante copies d'un planning macro pèsent 250 Ko — mais ce
que la rotation en fait : les cinquante emplacements se remplissaient en une après-midi, et
chassaient précisément les états anciens qu'on cherche à retrouver. Un filet de sécurité qui ne
remonte pas plus loin que la dernière demi-heure protège de la faute de frappe, pas de la bêtise
qu'on découvre le lendemain.
La copie est donc prise **à l'ouverture**, et une seule fois. C'est le bon moment : l'état d'avant
la séance est exactement celui vers lequel on veut revenir, et il est figé avant qu'on y touche.
Deux garde-fous complètent la règle :
- si le serveur reste allumé longtemps — un serveur local qu'on ne ferme jamais est un cas
réel —, une copie est reprise au plus une fois par jour, faute de quoi une session de trois
semaines ne laisserait qu'un seul point de reprise ;
- si le planning est identique à la dernière sauvegarde, rien n'est écrit. Rouvrir l'outil sans
avoir rien modifié n'a pas à consommer un emplacement.
À raison d'une copie par séance, les cinquante conservées couvrent des mois. Pour un historique
plus long ou plus fin, la vraie réponse n'est pas d'en garder davantage mais de versionner le
planning dans git, ce que son format texte indenté rend parfaitement lisible (voir décision 5).
Ce changement a rendu concurrentes deux étapes qui ne l'étaient pas — la copie et le remplacement
dépendent maintenant d'un état partagé, la date de la dernière sauvegarde. Un verrou les sérialise,
ce qui protège au passage du cas où deux onglets enregistrent en même temps.