Parties enregistrées, branches et export SGF (étape 1b) #37

Manually merged
pierre merged 8 commits from parties-enregistrees into main 2026-11-03 19:55:20 +00:00
Owner

Pourquoi

Jusqu'ici, l'application ne gardait qu'une partie : son journal d'événements, sous une seule clé localStorage. Commencer une nouvelle partie effaçait l'ancienne, et les branches créées par « Rejouer d'ici » n'étaient visibles nulle part.

L'étape 1 a besoin de bien plus :

  • l'historique des parties, pour le bilan, l'analyse et la progression (1e, 1h) ;
  • la reprise d'une partie précise, pour le « Reprendre l'ancienne » de la révision UX ;
  • un moyen d'analyser ses parties dans GNU Backgammon de bureau.

Le plan docs/plans/2026-11-03-parties-enregistrees.md (sous-étape 1b) fixait ces objectifs. Il est supprimé dans cette MR.

Quoi

  • Toutes les parties restent sur l'appareil, finies ou en cours, chacune avec toutes ses branches.
  • Au démarrage, la partie en cours est reprise.
  • Une ligne « Mes parties » dans le menu en feuille donne la liste des parties. On peut :
    • reprendre une partie, ou l'une de ses branches, sans rechargement ;
    • l'exporter en SGF ;
    • la supprimer, en deux touchers et sans boîte du navigateur.
  • L'export SGF contient toutes les branches, en variantes, avec la branche courante en premier.
  • « Reprendre l'ancienne » relit maintenant l'ancienne partie dans le stockage et supprime la nouvelle, restée vide.
  • La partie enregistrée par les versions précédentes est migrée sans intervention.
  • Sans IndexedDB, l'app se replie sur localStorage, puis sur la mémoire.

Comment

Le travail a été délégué à un sous-agent, en deux temps : d'abord le stockage et le domaine, puis le branchement sur la révision UX une fois celle-ci fusionnée.

  • Stockage : l'interface GameLibrary (list, load, save, remove, current, setCurrent) s'appuie sur deux stockages :

    • IndexedDB, utilisé directement : base « ustagammon » version 1, avec trois magasins (games, journals, settings). Le résumé et le journal d'une partie sont écrits dans la même transaction ;
    • localStorage en repli.

    Les opérations s'exécutent dans l'ordre des appels. GameSession tient la partie affichée et sait reprendre l'ancienne. Le stockage s'ouvre pendant le chargement du moteur : le plateau s'affiche toujours avant le moteur.

  • Domaine : branches(journal) lit les feuilles de l'arbre d'événements, déjà en place. summarizeGame résume une partie. exportSgf écrit le SGF avec les conventions de sgf.c de gnubg. Le moteur ne sert qu'à décoder une position de départ particulière.

  • Vérification de l'export : 6 parties jouées sur le vrai moteur, soit 9 fichiers SGF, sont relues par le gnubg de bureau de référence (Docker). Après chaque coup, la position de gnubg doit égaler celle du journal. Un coup altéré ou une position altérée font bien échouer la vérification.

  • Interface : games-view.ts n'appelle ni le stockage ni le moteur ; dependency-cruiser le vérifie.

  • ADR 0007 amendé : le schéma IndexedDB et les clés localStorage deviennent des formats durables, comme le journal. Toute modification passe par une migration testée.

Vérification par la session principale, après fusion de main :

  • make lint : aucun problème ;
  • make test : 10/10, dont 20 scénarios Gherkin et la relecture des SGF par gnubg.

L'agent a lancé make test-browser sur son dernier code, avant la fusion de main, qui n'apportait que de la documentation. Il passe dans Chromium et Firefox :

  • « nouvelle partie puis Reprendre l'ancienne : journal identique » ;
  • « mes parties : 3 parties listées, SGF exporté, première partie reprise sans rechargement » ;
  • aucune boîte native, aucune erreur.

Choix et compromis

  • Pas de bibliothèque IndexedDB (idb, Dexie), donc aucune nouvelle dépendance. En contrepartie, le stockage IndexedDB n'est testé que dans un vrai navigateur ; la logique commune est testée sous Node.
  • Branche courante en premier dans le SGF : gnubg 1.08 ne lit que la première variante (« FIXME restore other variations » dans sgf.c). Les autres branches sont dans le fichier, mais gnubg les ignore.
  • Sauvegardes non attendues : fermer la page dans les millisecondes qui suivent une action peut perdre cette action.
  • Pas de score de match avant 1c ; le résultat de la partie en tient lieu.
  • Identifiants : date plus hasard. crypto.randomUUID n'existe pas en http, que sert make deploy.

Risques et déploiement

  • Migration à sens unique : l'ancienne clé localStorage est effacée une fois la partie importée. Si l'on revient à la version précédente, elle commence une partie neuve ; les parties restent dans IndexedDB.
  • Changement de schéma : modifier le schéma demandera une montée de version avec migration (ADR 0007 amendé).
  • Configuration : aucune configuration serveur.
  • Retour arrière : annuler la fusion.

Comment vérifier

make lint && make test        # relecture des SGF par gnubg dans tests/test_web.sh
make test-browser             # ligne « mes parties : ... »
ls build/sgf-samples/

Sur le téléphone :

  1. Jouer quelques coups.
  2. Ouvrir Menu, puis « Nouvelle partie ».
  3. Ouvrir Menu, puis « Mes parties » : les deux parties y sont.
  4. Reprendre la première, puis exporter un SGF.
  5. Ouvrir le SGF dans GNU Backgammon de bureau : load game fichier.sgf.

Hors périmètre

  • L'adresse #/parties (0e.4).
  • L'écran d'analyse et « Rejouer d'ici » depuis l'analyse (1e).
  • Le score de match (1c).
  • L'historique de progression (1h).
  • L'import de SGF.

Generated with Claude Code https://claude.com/claude-code

## Pourquoi Jusqu'ici, l'application ne gardait qu'une partie : son journal d'événements, sous une seule clé `localStorage`. Commencer une nouvelle partie effaçait l'ancienne, et les branches créées par « Rejouer d'ici » n'étaient visibles nulle part. L'étape 1 a besoin de bien plus : - l'historique des parties, pour le bilan, l'analyse et la progression (1e, 1h) ; - la reprise d'une partie précise, pour le « Reprendre l'ancienne » de la révision UX ; - un moyen d'analyser ses parties dans GNU Backgammon de bureau. Le plan `docs/plans/2026-11-03-parties-enregistrees.md` (sous-étape 1b) fixait ces objectifs. Il est supprimé dans cette MR. ## Quoi - **Toutes les parties restent sur l'appareil**, finies ou en cours, chacune avec toutes ses branches. - **Au démarrage, la partie en cours est reprise.** - **Une ligne « Mes parties » dans le menu en feuille** donne la liste des parties. On peut : - reprendre une partie, ou l'une de ses branches, sans rechargement ; - l'exporter en SGF ; - la supprimer, en deux touchers et sans boîte du navigateur. - **L'export SGF contient toutes les branches**, en variantes, avec la branche courante en premier. - **« Reprendre l'ancienne »** relit maintenant l'ancienne partie dans le stockage et supprime la nouvelle, restée vide. - **La partie enregistrée par les versions précédentes est migrée** sans intervention. - **Sans IndexedDB**, l'app se replie sur `localStorage`, puis sur la mémoire. ## Comment Le travail a été délégué à un sous-agent, en deux temps : d'abord le stockage et le domaine, puis le branchement sur la révision UX une fois celle-ci fusionnée. - **Stockage** : l'interface `GameLibrary` (list, load, save, remove, current, setCurrent) s'appuie sur deux stockages : - IndexedDB, utilisé directement : base « ustagammon » version 1, avec trois magasins (`games`, `journals`, `settings`). Le résumé et le journal d'une partie sont écrits dans la même transaction ; - `localStorage` en repli. Les opérations s'exécutent dans l'ordre des appels. `GameSession` tient la partie affichée et sait reprendre l'ancienne. Le stockage s'ouvre pendant le chargement du moteur : le plateau s'affiche toujours avant le moteur. - **Domaine** : `branches(journal)` lit les feuilles de l'arbre d'événements, déjà en place. `summarizeGame` résume une partie. `exportSgf` écrit le SGF avec les conventions de `sgf.c` de gnubg. Le moteur ne sert qu'à décoder une position de départ particulière. - **Vérification de l'export** : 6 parties jouées sur le vrai moteur, soit 9 fichiers SGF, sont relues par le gnubg de bureau de référence (Docker). Après chaque coup, la position de gnubg doit égaler celle du journal. Un coup altéré ou une position altérée font bien échouer la vérification. - **Interface** : `games-view.ts` n'appelle ni le stockage ni le moteur ; dependency-cruiser le vérifie. - **ADR 0007 amendé** : le schéma IndexedDB et les clés `localStorage` deviennent des formats durables, comme le journal. Toute modification passe par une migration testée. Vérification par la session principale, après fusion de `main` : - `make lint` : aucun problème ; - `make test` : 10/10, dont 20 scénarios Gherkin et la relecture des SGF par gnubg. L'agent a lancé `make test-browser` sur son dernier code, avant la fusion de `main`, qui n'apportait que de la documentation. Il passe dans Chromium et Firefox : - « nouvelle partie puis Reprendre l'ancienne : journal identique » ; - « mes parties : 3 parties listées, SGF exporté, première partie reprise sans rechargement » ; - aucune boîte native, aucune erreur. ## Choix et compromis - **Pas de bibliothèque IndexedDB** (idb, Dexie), donc aucune nouvelle dépendance. En contrepartie, le stockage IndexedDB n'est testé que dans un vrai navigateur ; la logique commune est testée sous Node. - **Branche courante en premier dans le SGF** : gnubg 1.08 ne lit que la première variante (« FIXME restore other variations » dans sgf.c). Les autres branches sont dans le fichier, mais gnubg les ignore. - **Sauvegardes non attendues** : fermer la page dans les millisecondes qui suivent une action peut perdre cette action. - **Pas de score de match** avant 1c ; le résultat de la partie en tient lieu. - **Identifiants** : date plus hasard. `crypto.randomUUID` n'existe pas en http, que sert `make deploy`. ## Risques et déploiement - **Migration à sens unique** : l'ancienne clé `localStorage` est effacée une fois la partie importée. Si l'on revient à la version précédente, elle commence une partie neuve ; les parties restent dans IndexedDB. - **Changement de schéma** : modifier le schéma demandera une montée de version avec migration (ADR 0007 amendé). - **Configuration** : aucune configuration serveur. - **Retour arrière** : annuler la fusion. ## Comment vérifier ``` make lint && make test # relecture des SGF par gnubg dans tests/test_web.sh make test-browser # ligne « mes parties : ... » ls build/sgf-samples/ ``` Sur le téléphone : 1. Jouer quelques coups. 2. Ouvrir Menu, puis « Nouvelle partie ». 3. Ouvrir Menu, puis « Mes parties » : les deux parties y sont. 4. Reprendre la première, puis exporter un SGF. 5. Ouvrir le SGF dans GNU Backgammon de bureau : `load game fichier.sgf`. ## Hors périmètre - L'adresse `#/parties` (0e.4). - L'écran d'analyse et « Rejouer d'ici » depuis l'analyse (1e). - Le score de match (1c). - L'historique de progression (1h). - L'import de SGF. Generated with Claude Code https://claude.com/claude-code
pierre added 8 commits 2026-11-03 19:55:03 +00:00
pierre manually merged commit 3cdd017768 into main 2026-11-03 19:55:20 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: pierre/Ustagammon#37