D1 corrigé : le bug offline nº1 était 283 lignes de code mort
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
92d86fa066
commit
c69cb15ba2
10
STATUS.md
10
STATUS.md
@ -308,6 +308,12 @@ Les lots 1 et 2 sont terminés. **Le lot 3 et le lot médias sont tous les deux
|
|||||||
|
|
||||||
**Chemin critique** : A (assainir) → B (geler le schéma) → G (`MigrationController`) → H (tests) → **J (RGPD)** → I (bascule). C, D, D-bis, E, F se parallélisent.
|
**Chemin critique** : A (assainir) → B (geler le schéma) → G (`MigrationController`) → H (tests) → **J (RGPD)** → I (bascule). C, D, D-bis, E, F se parallélisent.
|
||||||
|
|
||||||
|
**D1 — le bug offline nº1 est corrigé (2026-08-11).** Le `switch` de collecte des ressources était commenté **des deux côtés** : 157 lignes mortes dans `ConfigurationController.Export`, 126 dans `Import`, et le pendant dans `downloadConfiguration.dart`. Une visite téléchargée n'embarquait donc que l'image de la configuration, celle du loader et l'image de chaque section.
|
||||||
|
|
||||||
|
Remplacé par `GetReferencedResourceIds()`, déjà implémentée sur les 13 sous-types. Côté import et côté client, la charge est enregistrée en une passe au lieu d'être redécouverte section par section — ce qui répare au passage la purge des fichiers obsolètes, pilotée par `usedImageOrAudioIds`. **4 tests**, dont un qui vérifie par réflexion que les 13 sous-types implémentent la collecte : le trou venait d'un `switch` où un type oublié passait dans le `default` sans bruit. `dotnet test` **148/148**.
|
||||||
|
|
||||||
|
⚠️ Le volet visiteur ne tient que sur `flutter analyze` — l'APK de `mymuseum-visitapp` ne compile pas (Gradle/NDK, §1bis). **À confirmer sur device au §21.**
|
||||||
|
|
||||||
**Lot G — les 8 écarts sont clos et le dry run est joué (2026-08-11).** `dotnet build` vert, `dotnet test` **143/143**.
|
**Lot G — les 8 écarts sont clos et le dry run est joué (2026-08-11).** `dotnet build` vert, `dotnet test` **143/143**.
|
||||||
|
|
||||||
**Trois des huit n'existaient pas.** Le plan les décrivait en « perte de données » ; l'export Mongo dit qu'il n'y a rien à perdre :
|
**Trois des huit n'existaient pas.** Le plan les décrivait en « perte de données » ; l'export Mongo dit qu'il n'y a rien à perdre :
|
||||||
@ -375,9 +381,9 @@ Constat du 2026-08-11, plus ouvert que ce que ce fichier annonçait : l'écran G
|
|||||||
|---|---|
|
|---|---|
|
||||||
| DB0 — rapatrier les maquettes | ✅ 2026-08-11 |
|
| DB0 — rapatrier les maquettes | ✅ 2026-08-11 |
|
||||||
| DB1 — socle visuel `constants.dart` | ✅ 2026-08-11 — 11 rôles typographiques, 8 espacements, 5 rayons. **Échelle des maquettes, couleurs de l'app** : un écran neuf se fond dans manager-app, il n'y ouvre pas une seconde palette. Pas de thème sombre |
|
| DB1 — socle visuel `constants.dart` | ✅ 2026-08-11 — 11 rôles typographiques, 8 espacements, 5 rayons. **Échelle des maquettes, couleurs de l'app** : un écran neuf se fond dans manager-app, il n'y ouvre pas une seconde palette. Pas de thème sombre |
|
||||||
| DB2 — sauvegarde au fil de l'eau SectionParcours | 🔨 2026-08-11 — **la perte silencieuse est fermée**. Les trois dialogues (`showNewOrUpdateGuidedPath`, `…GuidedStep`, `…QuizQuestion`) faisaient `Navigator.pop` sur « Annuler » sans rien demander, chacun jetant tout ce qui était saisi sous lui — le plus coûteux étant une question de quiz avec ses réponses. Confirmation ajoutée aux trois (réutilise `showConfirmationDialog`, pas de nouveau composant) + `PopScope` contre le retour navigateur. Détection par instantané JSON pris **après la première frame**, parce que `ensureSimpleResponse` écrit dans la question pendant la construction et ferait passer un dialog intact pour modifié. 3 clés i18n FR/EN/NL, `flutter build web` ✅.<br>**Décidé le même jour : la persistance incrémentale passe à DB4**, les deux étant alternatives — voir v1-plan.md |
|
| DB2 — sauvegarde au fil de l'eau SectionParcours | ✅ 2026-08-11, **puis retiré le même jour par DB4**. Le garde-fou (confirmation d'abandon sur les trois dialogues + `PopScope`) a fermé la perte silencieuse le temps que la persistance arrive. Les trois dialogues n'existent plus et il n'y a plus de travail non enregistré à perdre : les 3 clés i18n sont supprimées. C'était l'issue prévue par l'arbitrage — les deux étaient alternatives, pas cumulables |
|
||||||
| DB3 — écran Guide IA 2 onglets | 🔨 2026-08-11 — coquille à onglets, aperçu de conversation sur le **vrai** `/api/AI/chat`, onglet « Ce que demandent vos visiteurs » **alimenté** par `GET /api/Ai/insights/{id}`, carte « Ce que connaît votre guide » sur `GET /api/Ai/knowledge/{id}`, journalisation `VisitorQuestion` branchée dans `AiController.Chat`. 34 clés i18n FR/EN/NL. **Reste** : le job de regroupement en thèmes, la purge 90 j, **le RGPD dans les CGU avant mise en service**, l'onglet « Vocal » des stats |
|
| DB3 — écran Guide IA 2 onglets | 🔨 2026-08-11 — coquille à onglets, aperçu de conversation sur le **vrai** `/api/AI/chat`, onglet « Ce que demandent vos visiteurs » **alimenté** par `GET /api/Ai/insights/{id}`, carte « Ce que connaît votre guide » sur `GET /api/Ai/knowledge/{id}`, journalisation `VisitorQuestion` branchée dans `AiController.Chat`. 34 clés i18n FR/EN/NL. **Reste** : le job de regroupement en thèmes, la purge 90 j, **le RGPD dans les CGU avant mise en service**, l'onglet « Vocal » des stats |
|
||||||
| DB4 — forme SectionParcours | ❌ — **option A recommandée**. Le seul gain de B était une colonne d'aperçu, déjà couverte par l'aperçu du Guide IA |
|
| DB4 — forme SectionParcours | 🔨 2026-08-11 — **option A livrée : une fenêtre, un rail d'étapes, profondeur 2**. Les trois `showNewOrUpdate…` sont supprimés au profit de `guided_path_editor.dart` (coquille : fil d'Ariane, rail réordonnable, panneau, pied « Enregistré ») et de trois widgets de champs autonomes — `ParcoursFields`, `EtapeFields`, `QuestionFields` dans `Parcours/Fields/`. Une question se **déplie dans le panneau de l'étape**, plus dans une 4ᵉ fenêtre.<br>**Sauvegarde à la saisie** : `guided_path_api.dart` masque le choix `sectionParcoursApi` / `sectionMapApi`, un débounce de 700 ms écrit le parcours (PUT), chaque étape (POST/PUT/DELETE) et ses questions avec elle. Le parcours est **créé à la première modification**, pas à l'ouverture — fermer une fenêtre neuve sans rien saisir ne laisse rien en base. **Deux pièges du backend** : `UpdateGuidedPath` **supprime les étapes absentes du DTO**, donc le payload n'emporte que celles qui ont déjà un id (les autres attendent leur `CreateGuidedStep` et feraient un doublon) ; et les questions n'ayant pas d'endpoint, leur id entier est récupéré après coup **par `order`**, seul repère stable entre les deux listes. Échec d'écriture : la fenêtre refuse de se fermer et le pied de page porte un « Réessayer ». 14 clés i18n FR/EN/NL, 3 retirées (DB2). `flutter analyze` propre sur le dossier, `flutter build web` ✅.<br>**Reste** : DB5, la vérification à l'œil contre la maquette |
|
||||||
|
|
||||||
**`AIApi` était dans le client généré mais exposé nulle part** dans `client.dart` — les 18 autres façades y sont. Câblé le 2026-08-11.
|
**`AIApi` était dans le client généré mais exposé nulle part** dans `client.dart` — les 18 autres façades y sont. Câblé le 2026-08-11.
|
||||||
|
|
||||||
|
|||||||
48
kanban.html
48
kanban.html
@ -456,11 +456,11 @@
|
|||||||
<section class="summary" aria-label="Chiffres clés">
|
<section class="summary" aria-label="Chiffres clés">
|
||||||
<div class="stat"><span class="n n-critical">3</span><span class="k">Urgent</span></div>
|
<div class="stat"><span class="n n-critical">3</span><span class="k">Urgent</span></div>
|
||||||
<div class="stat"><span class="n n-info">4</span><span class="k">Migration v3</span></div>
|
<div class="stat"><span class="n n-info">4</span><span class="k">Migration v3</span></div>
|
||||||
<div class="stat"><span class="n n-warn">6</span><span class="k">Bugs ouverts</span></div>
|
<div class="stat"><span class="n n-warn">5</span><span class="k">Bugs ouverts</span></div>
|
||||||
<div class="stat"><span class="n">6</span><span class="k">À tester</span></div>
|
<div class="stat"><span class="n">6</span><span class="k">À tester</span></div>
|
||||||
<div class="stat"><span class="n">20</span><span class="k">Planifié</span></div>
|
<div class="stat"><span class="n">19</span><span class="k">Planifié</span></div>
|
||||||
<div class="stat"><span class="n n-gate">7</span><span class="k">Bascule prod</span></div>
|
<div class="stat"><span class="n n-gate">7</span><span class="k">Bascule prod</span></div>
|
||||||
<div class="stat"><span class="n n-good">30</span><span class="k">Fait récemment</span></div>
|
<div class="stat"><span class="n n-good">31</span><span class="k">Fait récemment</span></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="filters" role="group" aria-label="Filtrer par domaine">
|
<div class="filters" role="group" aria-label="Filtrer par domaine">
|
||||||
@ -556,17 +556,10 @@
|
|||||||
|
|
||||||
<!-- BUGS -->
|
<!-- BUGS -->
|
||||||
<section class="col" style="--stripe: var(--warn)">
|
<section class="col" style="--stripe: var(--warn)">
|
||||||
<div class="col-head"><h2>Bugs ouverts</h2><span class="count">6</span></div>
|
<div class="col-head"><h2>Bugs ouverts</h2><span class="count">5</span></div>
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
|
|
||||||
<article class="card" data-area="backend visitapp">
|
<article class="card" data-area="visitapp">
|
||||||
<div class="card-meta"><span class="tag">back + visitapp</span><span class="flag f-critical">Bloquant produit</span></div>
|
|
||||||
<h3>Visite hors ligne quasi non fonctionnelle</h3>
|
|
||||||
<p>Le <code>switch</code> de collecte des ressources est commenté dans <code>Export</code> <em>et</em> côté visitapp. Une visite téléchargée n'embarque ni images d'articles ni audios.</p>
|
|
||||||
<span class="src">v2/offline-visit-plan.md</span>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card" data-area="visitapp">
|
|
||||||
<div class="card-meta"><span class="tag">visitapp</span><span class="flag f-warn">Fraîcheur</span></div>
|
<div class="card-meta"><span class="tag">visitapp</span><span class="flag f-warn">Fraîcheur</span></div>
|
||||||
<h3>Ressource modifiée jamais re-téléchargée</h3>
|
<h3>Ressource modifiée jamais re-téléchargée</h3>
|
||||||
<p>Le filtre incrémental teste la présence du fichier, pas sa version. Une image remplacée dans le CMS ne remonte jamais sur le device. Invisible pour le client.</p>
|
<p>Le filtre incrémental teste la présence du fichier, pas sa version. Une image remplacée dans le CMS ne remonte jamais sur le device. Invisible pour le client.</p>
|
||||||
@ -656,7 +649,7 @@
|
|||||||
|
|
||||||
<!-- PLANIFIÉ -->
|
<!-- PLANIFIÉ -->
|
||||||
<section class="col" style="--stripe: var(--ink-3)">
|
<section class="col" style="--stripe: var(--ink-3)">
|
||||||
<div class="col-head"><h2>Planifié</h2><span class="count">20</span></div>
|
<div class="col-head"><h2>Planifié</h2><span class="count">19</span></div>
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
|
|
||||||
<article class="card" data-area="commercial" data-horizon="v1">
|
<article class="card" data-area="commercial" data-horizon="v1">
|
||||||
@ -707,19 +700,11 @@
|
|||||||
<span class="src">v1-plan.md — lot J · cgu-myinfomate.md §8 · mention-information-visiteurs.md</span>
|
<span class="src">v1-plan.md — lot J · cgu-myinfomate.md §8 · mention-information-visiteurs.md</span>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="card" data-area="manager visitapp" data-horizon="v1">
|
|
||||||
<div class="card-meta"><span class="tag">manager-app</span><span class="flag f-warn">Arbitrage en attente</span></div>
|
|
||||||
<h3>Parcours — sortir de l'empilement de popups</h3>
|
|
||||||
<p>Cinq surfaces empilées pour poser une question sur une étape et l'écrire en NL. <strong>Option A recommandée</strong> (fenêtre unique, rail d'étapes toujours visible, profondeur max 2) : le seul gain réel de l'option B était une colonne d'aperçu visiteur, <em>déjà couverte</em> par l'aperçu de conversation du Guide IA. Maquette rapatriée dans <code>claude design/sectionparcours-refonte-flux.html</code>.</p>
|
|
||||||
<p>Extraire d'abord <code>ParcoursFields</code> / <code>EtapeFields</code> / <code>QuestionFields</code> en widgets autonomes : sert A et B à l'identique.</p>
|
|
||||||
<p><strong>Porte aussi la sauvegarde incrémentale</strong>, héritée de DB2 le 11/08 : les deux sont alternatives, et c'est le rail d'étapes de l'option A qui rend la persistance à la saisie naturelle. Le terrain est déballé — <code>CreateGuidedStep</code> / <code>UpdateGuidedStep</code> / <code>DeleteGuidedStep</code> existent déjà sur <code>sectionParcoursApi</code> et <code>sectionMapApi</code>, et le backend persiste bien les questions imbriquées. Il n'y a <em>pas</em> d'endpoint QuizQuestion : les questions partent avec leur étape, c'est voulu.</p>
|
|
||||||
<span class="src">todo-features.md — SectionParcours · v1-plan.md — DB4, lien L18</span>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card" data-area="manager" data-horizon="v1">
|
<article class="card" data-area="manager" data-horizon="v1">
|
||||||
<div class="card-meta"><span class="tag">manager-app</span><span class="flag f-warn">Jamais ouvert</span></div>
|
<div class="card-meta"><span class="tag">manager-app</span><span class="flag f-warn">Jamais ouvert</span></div>
|
||||||
<h3>Écran Guide IA — vérification à l'œil</h3>
|
<h3>Écrans du lot design — vérification à l'œil</h3>
|
||||||
<p>La coquille à onglets, l'aperçu de conversation et la carte de connaissance compilent (<code>flutter build web</code> ✅) mais <strong>n'ont jamais été affichés dans un navigateur</strong> — le défaut récurrent de ce tableau. Exige un <code>manager-service</code> qui tourne et une session ouverte : <code>flutter run -d chrome</code>, puis comparaison côte à côte avec <code>claude design/guide-ia-screen.html</code>.</p>
|
<p>Deux écrans neufs compilent (<code>flutter build web</code> ✅) mais <strong>n'ont jamais été affichés dans un navigateur</strong> — le défaut récurrent de ce tableau. Le <strong>Guide IA</strong> (coquille à onglets, aperçu de conversation, carte de connaissance) et l'<strong>éditeur de parcours</strong> refondu (rail d'étapes, panneau, questions dépliées, enregistrement à la saisie).</p>
|
||||||
|
<p>Exige un <code>manager-service</code> qui tourne et une session ouverte : <code>flutter run -d chrome</code>, puis comparaison côte à côte avec <code>claude design/guide-ia-screen.html</code> et <code>claude design/sectionparcours-refonte-flux.html</code>. Pour le parcours, rejouer aussi <code>test-plan.md §19.13 cas 0</code>.</p>
|
||||||
<span class="src">v1-plan.md — DB5</span>
|
<span class="src">v1-plan.md — DB5</span>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
@ -876,9 +861,14 @@
|
|||||||
|
|
||||||
<section class="done">
|
<section class="done">
|
||||||
<h2>Fait récemment</h2>
|
<h2>Fait récemment</h2>
|
||||||
<p>Trente chantiers clos entre le 5 et le 11 août 2026.</p>
|
<p>Trente et un chantiers clos entre le 5 et le 11 août 2026.</p>
|
||||||
<div class="done-grid">
|
<div class="done-grid">
|
||||||
|
|
||||||
|
<div class="done-item">
|
||||||
|
<strong>La visite hors ligne embarque enfin ses médias</strong>
|
||||||
|
<span>Le <code>switch</code> qui collecte les ressources d'une configuration était commenté <strong>des deux côtés</strong> : 157 lignes mortes dans <code>ConfigurationController.Export</code>, 126 dans <code>Import</code>, et le pendant dans <code>downloadConfiguration.dart</code>. Une visite téléchargée n'embarquait donc que l'image de la configuration, celle du loader et l'image de chaque section — <strong>ni contenus d'articles, ni audios, ni icônes de carte, ni images de quiz</strong>. Remplacé par <code>GetReferencedResourceIds()</code>, qui existait déjà sur les 13 sous-types et n'attendait que d'être appelée. Côté import et côté client, la charge est enregistrée <em>en une passe</em> au lieu d'être redécouverte section par section : le serveur sait maintenant ce qu'il envoie, le client n'a plus à le deviner — et ça répare au passage la purge des fichiers obsolètes, pilotée par la même liste d'ids utilisés. 4 tests, dont un qui vérifie <strong>par réflexion que les 13 sous-types implémentent la collecte</strong> : le trou venait d'un <code>switch</code> où un type oublié passait dans le <code>default</code> sans bruit, et c'est exactement ce qu'il ne faut plus pouvoir refaire. <code>dotnet test</code> 148/148. ⚠️ Le volet visiteur ne tient que sur l'analyse — l'APK ne compile pas — <strong>confirmation sur device au §21</strong>, carte « Visite hors ligne sur device » déjà en attente.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="done-item">
|
<div class="done-item">
|
||||||
<strong>MigrationController — trois des huit écarts n'existaient pas</strong>
|
<strong>MigrationController — trois des huit écarts n'existaient pas</strong>
|
||||||
<span>Le plan les décrivait en « perte de données ». L'export Mongo, lu plutôt que supposé, dit qu'il n'y a rien à perdre. <strong>(a) « 11 types de section sur 13 »</strong> : les 327 sections de l'export ne contiennent que les types 0 à 10 — <code>SectionEvent</code> et <code>SectionParcours</code> sont nés avec Postgres v3, le <code>default</code> est un filet et non un trou, et le « scénario carnaval » qu'on croyait menacé est du contenu <em>à créer</em>, pas à migrer. <strong>(f) les trois booléens forcés à false</strong> : ces colonnes n'existent pas dans Mongo, <code>false</code> est le bon défaut — et le contrôle inverse a été fait, les cinq réglages qui <em>existent</em> vraiment dans l'export (<code>IsDate</code>, <code>IsHour</code>, <code>IsSectionImageBackground</code>, <code>RoundedValue</code>, <code>ScreenPercentageSectionsMainPage</code>) sont bien mappés sur <code>AppConfigurationLink</code>. <strong>(g)</strong> était tombé avec le rename du lot B. Trois cartes de la colonne « Bascule prod » se ferment sans une ligne de code.</span>
|
<span>Le plan les décrivait en « perte de données ». L'export Mongo, lu plutôt que supposé, dit qu'il n'y a rien à perdre. <strong>(a) « 11 types de section sur 13 »</strong> : les 327 sections de l'export ne contiennent que les types 0 à 10 — <code>SectionEvent</code> et <code>SectionParcours</code> sont nés avec Postgres v3, le <code>default</code> est un filet et non un trou, et le « scénario carnaval » qu'on croyait menacé est du contenu <em>à créer</em>, pas à migrer. <strong>(f) les trois booléens forcés à false</strong> : ces colonnes n'existent pas dans Mongo, <code>false</code> est le bon défaut — et le contrôle inverse a été fait, les cinq réglages qui <em>existent</em> vraiment dans l'export (<code>IsDate</code>, <code>IsHour</code>, <code>IsSectionImageBackground</code>, <code>RoundedValue</code>, <code>ScreenPercentageSectionsMainPage</code>) sont bien mappés sur <code>AppConfigurationLink</code>. <strong>(g)</strong> était tombé avec le rename du lot B. Trois cartes de la colonne « Bascule prod » se ferment sans une ligne de code.</span>
|
||||||
@ -926,7 +916,13 @@
|
|||||||
|
|
||||||
<div class="done-item">
|
<div class="done-item">
|
||||||
<strong>Parcours — on ne perd plus son travail sans être averti</strong>
|
<strong>Parcours — on ne perd plus son travail sans être averti</strong>
|
||||||
<span>Le défaut était pire que décrit : <strong>trois</strong> dialogues faisaient <code>Navigator.pop</code> sur « Annuler » sans rien demander, pas un — Parcours, Étape et Question, chacun jetant tout ce qui était saisi <em>sous</em> lui. Le plus coûteux est le plus profond : une question de quiz avec ses réponses. Ce n'était pas « la croix » comme le disait cette carte, c'était le bouton Annuler, et le clic hors fenêtre était déjà neutralisé — le vrai chemin de perte restant est le <strong>retour arrière du navigateur</strong>, couvert par <code>PopScope</code>. Détection des modifications par instantané JSON, pris <strong>après la première frame</strong> : le dialog Question normalise ses réponses pendant sa construction, un instantané pris avant aurait déclaré « modifié » une fenêtre intacte. Réutilise <code>showConfirmationDialog</code> plutôt que d'ouvrir un second composant de confirmation. 3 clés i18n FR/EN/NL, <code>flutter build web</code> ✅.</span>
|
<span>Le défaut était pire que décrit : <strong>trois</strong> dialogues faisaient <code>Navigator.pop</code> sur « Annuler » sans rien demander, pas un — Parcours, Étape et Question, chacun jetant tout ce qui était saisi <em>sous</em> lui. Le plus coûteux est le plus profond : une question de quiz avec ses réponses. Ce n'était pas « la croix » comme le disait cette carte, c'était le bouton Annuler, et le clic hors fenêtre était déjà neutralisé — le vrai chemin de perte restant est le <strong>retour arrière du navigateur</strong>, couvert par <code>PopScope</code>. Détection des modifications par instantané JSON, pris <strong>après la première frame</strong> : le dialog Question normalise ses réponses pendant sa construction, un instantané pris avant aurait déclaré « modifié » une fenêtre intacte. Réutilise <code>showConfirmationDialog</code> plutôt que d'ouvrir un second composant de confirmation. 3 clés i18n FR/EN/NL, <code>flutter build web</code> ✅. <strong>Retiré le jour même par la carte suivante</strong> — c'était l'issue prévue : un garde-fou n'a plus d'objet quand il n'y a plus rien à perdre.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="done-item">
|
||||||
|
<strong>Parcours — les quatre fenêtres empilées deviennent une seule</strong>
|
||||||
|
<span>Option A livrée, l'arbitrage tombe avec. Les trois <code>showNewOrUpdate…</code> sont supprimés au profit d'un <strong>rail d'étapes toujours visible</strong> à gauche, d'un panneau de détail à droite, et d'une question qui <strong>se déplie sur place</strong> au lieu d'ouvrir une quatrième fenêtre : la profondeur maximale retombe à <strong>2</strong> — l'éditeur, puis la traduction. Les champs sont d'abord sortis en trois widgets autonomes (<code>ParcoursFields</code>, <code>EtapeFields</code>, <code>QuestionFields</code>) — c'est ce qui a rendu la refonte possible sans tout réécrire, et ce qui resterait transposable si l'écran plein cadre revenait un jour.</span>
|
||||||
|
<span><strong>Plus de bouton « Sauvegarder » : tout part à la saisie</strong> (débounce 700 ms ; les ajouts, suppressions et réordonnancements partent sans attendre). Deux pièges du backend, trouvés en lisant le contrôleur plutôt qu'en le supposant : <code>UpdateGuidedPath</code> <strong>supprime les étapes absentes du DTO</strong>, donc le payload n'emporte que celles qui ont déjà un id — les autres attendent leur <code>CreateGuidedStep</code> et seraient dupliquées ; et comme les questions n'ont <em>pas</em> d'endpoint propre (c'est voulu, elles partent avec leur étape), leur id entier est récupéré après coup <strong>par <code>order</code></strong>, seul repère stable entre la liste locale et celle du serveur. Le parcours est créé <strong>à la première modification</strong>, pas à l'ouverture : une fenêtre neuve refermée intacte ne laisse rien en base. Si une écriture échoue, la fenêtre refuse de se fermer et le pied de page porte un « Réessayer ». 14 clés i18n FR/EN/NL, 3 retirées, <code>flutter build web</code> ✅. <strong>Reste la vérification à l'œil</strong> (DB5).</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="done-item">
|
<div class="done-item">
|
||||||
|
|||||||
@ -187,13 +187,15 @@ Composant réutilisé pour maps, events **et escape games** via 3 flags :
|
|||||||
| les deux à false | SectionMap | `sectionMapId` |
|
| les deux à false | SectionMap | `sectionMapId` |
|
||||||
|
|
||||||
- Liste réordrable (drag & drop) des parcours
|
- Liste réordrable (drag & drop) des parcours
|
||||||
- Création/édition via `showNewOrUpdateGuidedPath`
|
- Création/édition via `showGuidedPathEditor` (`Parcours/guided_path_editor.dart`, refonte DB4 du 2026-08-11 — remplace les trois popups empilées `showNewOrUpdate…`)
|
||||||
- Suppression avec confirmation
|
- Suppression avec confirmation
|
||||||
|
|
||||||
`showNewOrUpdateGuidedPath` permet de configurer :
|
`showGuidedPathEditor` ouvre une **fenêtre unique** avec un rail d'étapes à gauche et le panneau de détail à droite. On y configure :
|
||||||
- Titre / description (multilingue)
|
- Titre / description (multilingue)
|
||||||
- Options : linéaire, réussite requise, cacher les étapes suivantes
|
- Options : linéaire, réussite requise, cacher les étapes suivantes
|
||||||
- CRUD des étapes avec géolocalisation et quiz optionnel
|
- Les étapes, avec géolocalisation et quiz optionnel — la question se déplie dans le panneau de l'étape
|
||||||
|
|
||||||
|
Tout est **enregistré à la saisie** (débounce ~700 ms) : pas de bouton « Sauvegarder ». Le parcours est créé en base à la première modification, et les questions partent avec leur étape (elles n'ont pas d'endpoint propre).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -228,15 +228,15 @@
|
|||||||
|
|
||||||
#### 8. Manager-app — nouvelle section SectionParcours
|
#### 8. Manager-app — nouvelle section SectionParcours
|
||||||
|
|
||||||
> ✅ **Statut réel vérifié le 2026-08-05** : deux dossiers coexistent — `SubSection/SectionParcours/section_parcours_config.dart` (la section elle-même) et `SubSection/Parcours/` (`parcours_config.dart`, `showNewOrUpdateGuidedPath.dart`, `showNewOrUpdateGuidedStep.dart`, `showNewOrUpdateQuizQuestion.dart`). Tout est branché sauf les tooltips.
|
> ✅ **Statut réel vérifié le 2026-08-05, structure mise à jour le 2026-08-11 (DB4)** : deux dossiers coexistent — `SubSection/SectionParcours/section_parcours_config.dart` (la section elle-même) et `SubSection/Parcours/` (`parcours_config.dart`, `guided_path_editor.dart`, `guided_path_api.dart`, `progression_mode.dart` et `Fields/` : `parcours_fields.dart`, `etape_fields.dart`, `question_fields.dart`). Les trois `showNewOrUpdate…` empilés ont été supprimés. Tout est branché sauf les tooltips.
|
||||||
|
|
||||||
- [x] ✅ **Ajouter "Parcours" dans la liste des types de section** (vérifié 2026-08-05)
|
- [x] ✅ **Ajouter "Parcours" dans la liste des types de section** (vérifié 2026-08-05)
|
||||||
- `SectionParcours/section_parcours_config.dart` :
|
- `SectionParcours/section_parcours_config.dart` :
|
||||||
- Toggle **"Afficher la carte"** (`ShowMap`) — `l.63`, défaut `true`
|
- Toggle **"Afficher la carte"** (`ShowMap`) — `l.63`, défaut `true`
|
||||||
- Picker **"Carte de référence"** (`BaseSectionMapId`) — `l.70-90`, affiché si `showMap == true` et qu'au moins une SectionMap existe
|
- Picker **"Carte de référence"** (`BaseSectionMapId`) — `l.70-90`, affiché si `showMap == true` et qu'au moins une SectionMap existe
|
||||||
- Toggle **"Mode jeu"** (`IsGameMode`) + `GameMessageDebut`/`GameMessageFin` : sur le **GuidedPath**, pas sur la section (`showNewOrUpdateGuidedPath.dart:176-180`) — écart assumé documenté au point 1
|
- Toggle **"Mode jeu"** (`IsGameMode`) + `GameMessageDebut`/`GameMessageFin` : sur le **GuidedPath**, pas sur la section (`Fields/parcours_fields.dart`) — écart assumé documenté au point 1
|
||||||
- Gestion des GuidedPaths : `parcours_config.dart`
|
- Gestion des GuidedPaths : `parcours_config.dart` → `guided_path_editor.dart`
|
||||||
- ❌ Reste : les **tooltips ℹ️** (1 seul `Tooltip` dans tout le dossier Parcours, dans `showNewOrUpdateQuizQuestion.dart:237`) — voir section dédiée ci-dessous
|
- ❌ Reste : les **tooltips ℹ️** (1 seul `Tooltip` dans tout le dossier Parcours, sur la case « bonne réponse » de `Fields/question_fields.dart`) — voir section dédiée ci-dessous
|
||||||
|
|
||||||
- [ ] ❌ **Tooltips ℹ️ dans le manager-app**
|
- [ ] ❌ **Tooltips ℹ️ dans le manager-app**
|
||||||
- Sur le choix du type de section (SectionMap vs SectionParcours vs SectionGame vs SectionEvent) : exemples concrets
|
- Sur le choix du type de section (SectionMap vs SectionParcours vs SectionGame vs SectionEvent) : exemples concrets
|
||||||
|
|||||||
14
v1-plan.md
14
v1-plan.md
@ -127,7 +127,7 @@ L'étape A du §1quater est faite (`StoragePath`/`SizeBytes` écrits à `Create`
|
|||||||
| Ordre | Quoi |
|
| Ordre | Quoi |
|
||||||
|---|---|
|
|---|---|
|
||||||
| D0 | **Jouer le test-plan §21 sur un device** — 15 cas. Sortie : lesquels des 4 bugs restants se manifestent réellement |
|
| D0 | **Jouer le test-plan §21 sur un device** — 15 cas. Sortie : lesquels des 4 bugs restants se manifestent réellement |
|
||||||
| D1 | Remplacer le bloc commenté de `ConfigurationController.Export` (`:~400-577`) par des appels à `GetReferencedResourceIds()` — la méthode existe déjà sur les 13 sous-types. Même geste côté `mymuseum-visitapp`, où le switch est aussi commenté |
|
| ~~D1~~ ✅ **2026-08-11** | **Fait des deux côtés, et le bloc mort était plus gros qu'annoncé : 157 lignes dans `Export`, plus 126 dans `Import`.** Avant : une visite téléchargée n'embarquait que l'image de la configuration, celle du loader et l'image de chaque section — ni contenus d'articles, ni audios, ni icônes de carte, ni images de quiz. **Serveur** : `Export` matérialise les entités (pas seulement leurs DTO) et appelle `GetReferencedResourceIds(language)` ; `Import` cesse de redécouvrir les ressources section par section et crée toute la charge en une passe (`createResource` est idempotente). **Client** : `downloadConfiguration.dart` enregistre la charge au lieu de parser `section.data` type par type — ce qui répare aussi la purge, `usedImageOrAudioIds` pilotant la suppression des fichiers obsolètes.<br>**4 tests** ajoutés, dont un qui vérifie par réflexion que **les 13 sous-types implémentent la collecte** : le trou d'origine venait d'un `switch` où un type oublié passait dans le `default` sans bruit. `dotnet test` **148/148**, `flutter analyze` sans erreur.<br>⚠️ Le volet visiteur n'est vérifié que par l'analyse — l'APK de `mymuseum-visitapp` ne compile pas (Gradle/NDK). **Confirmation sur device au §21**, qui reste ouvert |
|
||||||
| D2 | Filtre incrémental sur la **version** de la ressource, pas sa présence |
|
| D2 | Filtre incrémental sur la **version** de la ressource, pas sa présence |
|
||||||
| D3 | `audio/mpeg` ajouté à la table d'extensions (`audio/mp3` n'est pas un MIME standard) |
|
| D3 | `audio/mpeg` ajouté à la table d'extensions (`audio/mp3` n'est pas un MIME standard) |
|
||||||
| D4 | Réactiver la purge des fichiers obsolètes (`deleteSync()` commenté) |
|
| D4 | Réactiver la purge des fichiers obsolètes (`deleteSync()` commenté) |
|
||||||
@ -141,7 +141,7 @@ L'étape A du §1quater est faite (`StoragePath`/`SizeBytes` écrits à `Create`
|
|||||||
> |---|---|---|
|
> |---|---|---|
|
||||||
> | Guide IA | « onglet Configuration livré le 07/08 » | `guide_ia_screen.dart` : 545 l., **5 cards en colonne unique, aucun `TabBar`**. Manquent le §4 (Sources de connaissance + recherche vectorielle) et le §5 (Aperçu de conversation) |
|
> | Guide IA | « onglet Configuration livré le 07/08 » | `guide_ia_screen.dart` : 545 l., **5 cards en colonne unique, aucun `TabBar`**. Manquent le §4 (Sources de connaissance + recherche vectorielle) et le §5 (Aperçu de conversation) |
|
||||||
> | Stats assistant IA | « onglet Vocal (V1) » spécifié | `statistics_screen.dart` : 1481 l., « vocal » n'apparaît **que dans un commentaire**. Stats assistant à zéro |
|
> | Stats assistant IA | « onglet Vocal (V1) » spécifié | `statistics_screen.dart` : 1481 l., « vocal » n'apparaît **que dans un commentaire**. Stats assistant à zéro |
|
||||||
> | SectionParcours | 2 options maquettées | Les 3 popups intactes. Rien n'a commencé |
|
> | SectionParcours | 2 options maquettées | Les 3 popups intactes. Rien n'a commencé — **résolu par DB4 le 2026-08-11 : les 3 popups sont supprimées** |
|
||||||
|
|
||||||
**Le problème de méthode avant le contenu.** Les trois maquettes sont des artifacts hébergés sur un **autre compte Claude** : illisibles depuis la machine de dev (constaté le 2026-08-10, cf. le §« Comment mettre à jour ce fichier » de STATUS.md). Toute session qui reprend un de ces écrans redessine — c'est la cause directe du Guide IA livré à la moitié de sa spec.
|
**Le problème de méthode avant le contenu.** Les trois maquettes sont des artifacts hébergés sur un **autre compte Claude** : illisibles depuis la machine de dev (constaté le 2026-08-10, cf. le §« Comment mettre à jour ce fichier » de STATUS.md). Toute session qui reprend un de ces écrans redessine — c'est la cause directe du Guide IA livré à la moitié de sa spec.
|
||||||
|
|
||||||
@ -151,9 +151,9 @@ Même découpage que le kanban : **contenu versionné dans le repo, diffusion pa
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| ~~**DB0**~~ ✅ 2026-08-11 | **HTML des maquettes rapatrié** dans `DOCS/claude design/` — `guide-ia-screen.html` (31,8 Ko), `statistics-screen.html` (27,4 Ko), `sectionparcours-refonte-flux.html` (45,6 Ko), JS interactif compris. Méthode : bascule temporaire sur le compte propriétaire, lecture de la source, copie. L'assistant `visitapp-web` n'a jamais été publié ; le kanban vit déjà dans `DOCS/kanban.html` | La source de vérité du design vit désormais dans le repo, l'artifact ne sert plus qu'à la diffusion. **Constat** : Guide IA et Statistiques déclarent des tokens **rigoureusement identiques** — c'était déjà un design system, jamais porté en Dart. Et `--brand #264863` **est** `kPrimaryColor` |
|
| ~~**DB0**~~ ✅ 2026-08-11 | **HTML des maquettes rapatrié** dans `DOCS/claude design/` — `guide-ia-screen.html` (31,8 Ko), `statistics-screen.html` (27,4 Ko), `sectionparcours-refonte-flux.html` (45,6 Ko), JS interactif compris. Méthode : bascule temporaire sur le compte propriétaire, lecture de la source, copie. L'assistant `visitapp-web` n'a jamais été publié ; le kanban vit déjà dans `DOCS/kanban.html` | La source de vérité du design vit désormais dans le repo, l'artifact ne sert plus qu'à la diffusion. **Constat** : Guide IA et Statistiques déclarent des tokens **rigoureusement identiques** — c'était déjà un design system, jamais porté en Dart. Et `--brand #264863` **est** `kPrimaryColor` |
|
||||||
| ~~**DB1**~~ ✅ 2026-08-11 | **Socle visuel dans `constants.dart`** : 11 rôles typographiques, 8 pas d'espacement, 5 rayons, paddings de carte et de page. `flutter analyze` propre. **Décision du 2026-08-11 : l'échelle vient des maquettes, les couleurs restent celles de l'app** — un écran neuf se fond dans manager-app, il n'y ouvre pas une seconde palette. Seules les valeurs sans équivalent existant sont reprises (`kSurface2/3`, `kLine`, `kLineSoft`, `kInk3`, `kWarning`). Pas de thème sombre. Reste : `size.width * 0.2` de `NumberInputContainer` | **L17** — sert aussi les 12 autres types de section. La reprise des écrans existants vers ces tokens est un chantier distinct (« repasse UI globale »), pas un effet de bord de celui-ci |
|
| ~~**DB1**~~ ✅ 2026-08-11 | **Socle visuel dans `constants.dart`** : 11 rôles typographiques, 8 pas d'espacement, 5 rayons, paddings de carte et de page. `flutter analyze` propre. **Décision du 2026-08-11 : l'échelle vient des maquettes, les couleurs restent celles de l'app** — un écran neuf se fond dans manager-app, il n'y ouvre pas une seconde palette. Seules les valeurs sans équivalent existant sont reprises (`kSurface2/3`, `kLine`, `kLineSoft`, `kInk3`, `kWarning`). Pas de thème sombre. Reste : `size.width * 0.2` de `NumberInputContainer` | **L17** — sert aussi les 12 autres types de section. La reprise des écrans existants vers ces tokens est un chantier distinct (« repasse UI globale »), pas un effet de bord de celui-ci |
|
||||||
| ~~**DB2**~~ 🔨 2026-08-11 | **SectionParcours — plus de perte silencieuse.** Confirmation avant d'abandonner du travail non enregistré, sur les **trois** niveaux de dialogue (Parcours, Étape, Question — chacun perdait tout ce qui était saisi sous lui), plus interception du retour navigateur par `PopScope`. 3 clés i18n FR/EN/NL. `flutter build web` ✅ | **Arbitrage du 2026-08-11 : DB2 se limite au garde-fou, la persistance incrémentale part avec DB4.** Motif : les deux sont **alternatives, pas cumulables** — si chaque étape est persistée à la saisie, le garde-fou n'a plus d'objet. Et la persistance impose de créer le parcours dès la 1ʳᵉ étape (donc des parcours à moitié remplis en base si l'utilisateur renonce, et un « Annuler » qui n'annule plus rien) : c'est précisément la sémantique qu'apporte le rail d'étapes de l'option A. L'écrire maintenant, c'est la câbler dans les callbacks `onSave` que DB4 supprime |
|
| ~~**DB2**~~ ✅ 2026-08-11 — **puis retiré par DB4 le même jour**, comme prévu | **SectionParcours — plus de perte silencieuse.** Confirmation avant d'abandonner du travail non enregistré, sur les **trois** niveaux de dialogue (Parcours, Étape, Question — chacun perdait tout ce qui était saisi sous lui), plus interception du retour navigateur par `PopScope`. 3 clés i18n FR/EN/NL. `flutter build web` ✅ | **Arbitrage du 2026-08-11 : DB2 se limite au garde-fou, la persistance incrémentale part avec DB4.** Motif : les deux sont **alternatives, pas cumulables** — si chaque étape est persistée à la saisie, le garde-fou n'a plus d'objet. Et la persistance impose de créer le parcours dès la 1ʳᵉ étape (donc des parcours à moitié remplis en base si l'utilisateur renonce, et un « Annuler » qui n'annule plus rien) : c'est précisément la sémantique qu'apporte le rail d'étapes de l'option A. L'écrire maintenant, c'est la câbler dans les callbacks `onSave` que DB4 supprime |
|
||||||
| DB3 | **Écran Guide IA complet, 2 onglets, stats assistant comprises**. 🔨 **Front livré le 2026-08-11** : coquille à onglets, §5 Aperçu de conversation branché sur le **vrai** `POST /api/AI/chat` (`AIApi` était dans le client généré mais jamais exposé dans `client.dart` — câblé), onglet « Ce que demandent vos visiteurs » avec ses tuiles, son bloc ambre des questions sans réponse et ses trois cartes de barres, 24 clés i18n FR/EN/NL. `flutter analyze` propre, `flutter build web` ✅.<br>**Complété le 2026-08-11** : carte §4 « Ce que connaît votre guide » sur `GET /api/Ai/knowledge/{id}` (agrégats `ContentEmbedding`), journalisation `VisitorQuestion` dans `AiController.Chat`, et `GET /api/Ai/insights/{id}` qui remplit l'onglet. `dotnet test` 130/130, `flutter build web` ✅.<br>**Reste dans ce lot** : l'onglet « Vocal » des stats et la vérification à l'œil (DB5). Le job de thèmes et tout le volet RGPD sont **déplacés au lot J**, en fin de backlog. La purge à 90 jours est livrée (`VisitorQuestionPurgeService`) | **L15**, **L16** — le contrat de données est fixé par `GuideIaInsights` dans `visitor_questions_tab.dart`, et `GuideInsightsDTO` en est le miroir exact : c'est lui que le job de thèmes doit remplir, pas l'inverse. **L9** : le §5 converge avec le Mode preview |
|
| DB3 | **Écran Guide IA complet, 2 onglets, stats assistant comprises**. 🔨 **Front livré le 2026-08-11** : coquille à onglets, §5 Aperçu de conversation branché sur le **vrai** `POST /api/AI/chat` (`AIApi` était dans le client généré mais jamais exposé dans `client.dart` — câblé), onglet « Ce que demandent vos visiteurs » avec ses tuiles, son bloc ambre des questions sans réponse et ses trois cartes de barres, 24 clés i18n FR/EN/NL. `flutter analyze` propre, `flutter build web` ✅.<br>**Complété le 2026-08-11** : carte §4 « Ce que connaît votre guide » sur `GET /api/Ai/knowledge/{id}` (agrégats `ContentEmbedding`), journalisation `VisitorQuestion` dans `AiController.Chat`, et `GET /api/Ai/insights/{id}` qui remplit l'onglet. `dotnet test` 130/130, `flutter build web` ✅.<br>**Reste dans ce lot** : l'onglet « Vocal » des stats et la vérification à l'œil (DB5). Le job de thèmes et tout le volet RGPD sont **déplacés au lot J**, en fin de backlog. La purge à 90 jours est livrée (`VisitorQuestionPurgeService`) | **L15**, **L16** — le contrat de données est fixé par `GuideIaInsights` dans `visitor_questions_tab.dart`, et `GuideInsightsDTO` en est le miroir exact : c'est lui que le job de thèmes doit remplir, pas l'inverse. **L9** : le §5 converge avec le Mode preview |
|
||||||
| DB4 | **SectionParcours — la forme**, après arbitrage. Extraire d'abord `ParcoursFields` / `EtapeFields` / `QuestionFields` en widgets autonomes : sert A et B à l'identique. **Porte aussi la sauvegarde incrémentale**, héritée de DB2 le 2026-08-11 | **L18** — recommandation : **A**. Point de départ concret côté persistance : les endpoints `CreateGuidedStep` / `UpdateGuidedStep` / `DeleteGuidedStep` existent déjà sur `sectionParcoursApi` **et** `sectionMapApi`, et le backend persiste correctement les questions imbriquées (`GuidedStep.FromDTO` appelle `SyncQuizQuestions`) — vérifié le 2026-08-11. Il n'y a **pas** d'endpoint QuizQuestion : les questions partent avec leur étape, c'est voulu. Le garde-fou de DB2 devient inutile dès que cette persistance est en place, le retirer alors |
|
| ~~**DB4**~~ ✅ 2026-08-11 | **SectionParcours — la forme, option A livrée.** Les trois `showNewOrUpdate…` sont supprimés. `Parcours/Fields/` porte les trois widgets autonomes (`ParcoursFields`, `EtapeFields`, `QuestionFields`) ; `guided_path_editor.dart` est la coquille : fil d'Ariane, rail d'étapes réordonnable toujours visible, panneau de détail, pied de page « Enregistré ». Une question se **déplie dans le panneau de son étape** — profondeur maximale **2**, la fenêtre puis la traduction. **Sauvegarde à la saisie** : `guided_path_api.dart` unifie `sectionParcoursApi` / `sectionMapApi`, un débounce de 700 ms écrit le parcours (PUT), les étapes (POST/PUT/DELETE) et leurs questions ; les changements de structure (ajout, suppression, réordonnancement) partent sans attendre. **Le garde-fou de DB2 est retiré** — 3 clés i18n supprimées, 14 ajoutées FR/EN/NL. `flutter build web` ✅ | **L18** — **A** retenue. Deux pièges du backend, tranchés à la lecture du contrôleur : `UpdateGuidedPath` **supprime les étapes absentes du DTO**, donc le payload n'emporte que celles qui ont déjà un id — les autres attendent leur `CreateGuidedStep` et seraient dupliquées. Et il n'y a **pas** d'endpoint QuizQuestion (voulu) : l'id entier attribué par `SyncQuizQuestions` est récupéré après coup **par `order`**, seul repère stable entre la liste locale et celle du serveur. Le parcours est **créé à la première modification**, pas à l'ouverture : fermer une fenêtre neuve intacte ne laisse rien en base. Si une écriture échoue, la fenêtre refuse de se fermer et le pied de page porte un « Réessayer » |
|
||||||
| DB5 | **Boucle de vérification, à chaque écran** : `flutter run -d chrome`, capture, comparaison côte à côte avec la maquette | `flutter analyze` ne prouve rien sur du design — et reste inexploitable tant que le lot A n'a pas nettoyé `manager_api_new` (**L8**) |
|
| DB5 | **Boucle de vérification, à chaque écran** : `flutter run -d chrome`, capture, comparaison côte à côte avec la maquette | `flutter analyze` ne prouve rien sur du design — et reste inexploitable tant que le lot A n'a pas nettoyé `manager_api_new` (**L8**) |
|
||||||
|
|
||||||
Ne change pas : la popup de traduction (un niveau justifié, langues verticales, pas d'onglets), et la conception des composants de `Components/` — leur problème est le dimensionnement, pas la structure.
|
Ne change pas : la popup de traduction (un niveau justifié, langues verticales, pas d'onglets), et la conception des composants de `Components/` — leur problème est le dimensionnement, pas la structure.
|
||||||
@ -325,7 +325,7 @@ A (½-1j) ──► B (2-3j) ──► G (3-4j) ──► H (1 sem.) ──► I
|
|||||||
├──► D0 (test device) ──► D1..D5
|
├──► D0 (test device) ──► D1..D5
|
||||||
├──► D-bis : DB0 ──► DB1 ──┬──► DB2
|
├──► D-bis : DB0 ──► DB1 ──┬──► DB2
|
||||||
│ ├──► DB3 ──► F (job de thèmes)
|
│ ├──► DB3 ──► F (job de thèmes)
|
||||||
│ └──► DB4 (après arbitrage A/B)
|
│ └──► DB4 ✅ (A tranchée et livrée)
|
||||||
├──► E
|
├──► E
|
||||||
└──► F
|
└──► F
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ A (½-1j) ──► B (2-3j) ──► G (3-4j) ──► H (1 sem.) ──► I
|
|||||||
- **DB3 doit précéder le job de thèmes du lot F** (L16) : c'est le seul endroit du plan où le design commande le backend.
|
- **DB3 doit précéder le job de thèmes du lot F** (L16) : c'est le seul endroit du plan où le design commande le backend.
|
||||||
- **La boucle du graphe a disparu le 2026-08-11.** Elle venait de : I3 dépend de la rotation des secrets (dans le lot A), et H4 dépend de I3 (L12). En déplaçant la rotation en **I0**, la contrainte devient linéaire — `I0 → I3 → H4` — et il n'y a plus de cycle à contourner. **Contrepartie à ne pas rater** : H4 (test d'onboarding) exige `app.myinfomate.be` déployé, donc I3, donc I0. Concrètement, **la rotation des secrets doit être faite avant la fin du lot H**, pas au tout dernier moment. C'est le seul endroit où le report du 11/08 crée une échéance interne.
|
- **La boucle du graphe a disparu le 2026-08-11.** Elle venait de : I3 dépend de la rotation des secrets (dans le lot A), et H4 dépend de I3 (L12). En déplaçant la rotation en **I0**, la contrainte devient linéaire — `I0 → I3 → H4` — et il n'y a plus de cycle à contourner. **Contrepartie à ne pas rater** : H4 (test d'onboarding) exige `app.myinfomate.be` déployé, donc I3, donc I0. Concrètement, **la rotation des secrets doit être faite avant la fin du lot H**, pas au tout dernier moment. C'est le seul endroit où le report du 11/08 crée une échéance interne.
|
||||||
|
|
||||||
**Ordre de grandeur : 5 à 6 semaines**, dont ~1 semaine de tests, 3-4 jours sur `MigrationController` seul, 1,5 à 2 semaines sur le lot design et 2-3 jours sur le lot J (RGPD). Les deux arbitrages du lot B (`ParcoursIds`, `QuestionType`) et celui du lot D-bis (flux SectionParcours) sont les seuls points où le plan attend une décision plutôt qu'un développement.
|
**Ordre de grandeur : 5 à 6 semaines**, dont ~1 semaine de tests, 3-4 jours sur `MigrationController` seul, 1,5 à 2 semaines sur le lot design et 2-3 jours sur le lot J (RGPD). **Les trois arbitrages structurants sont tranchés depuis le 2026-08-11** — `ParcoursIds` et `QuestionType` au lot B, le flux SectionParcours au lot D-bis : le plan n'attend plus de décision, seulement du développement.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -348,7 +348,7 @@ A (½-1j) ──► B (2-3j) ──► G (3-4j) ──► H (1 sem.) ──► I
|
|||||||
| ~~`SectionEvent.ParcoursIds`~~ | ✅ **2026-08-11 — supprimer.** Champ mort, et structurellement incapable du cas jour/bloc | — |
|
| ~~`SectionEvent.ParcoursIds`~~ | ✅ **2026-08-11 — supprimer.** Champ mort, et structurellement incapable du cas jour/bloc | — |
|
||||||
| ~~`QuestionType`~~ | ✅ **2026-08-11 — ne pas toucher au schéma.** Sort du lot B ; reste une propreté front au lot E | — |
|
| ~~`QuestionType`~~ | ✅ **2026-08-11 — ne pas toucher au schéma.** Sort du lot B ; reste une propreté front au lot E | — |
|
||||||
| ~~**Fournisseur de carte en web (W1)**~~ | ✅ **2026-08-11 — option a : le web reste sur Leaflet, quoi que le client configure.** Ni MapBox ni Google Maps JS : pas de coût récurrent ni de seconde librairie carto avant la prod. **Correction apportée à l'option** : le champ ne peut pas être retiré pour le web, il est porté par la section et partagé entre plateformes — il est donc conservé et **documenté dans l'interface** comme réglage mobile/tablette. Voir le lot E | — |
|
| ~~**Fournisseur de carte en web (W1)**~~ | ✅ **2026-08-11 — option a : le web reste sur Leaflet, quoi que le client configure.** Ni MapBox ni Google Maps JS : pas de coût récurrent ni de seconde librairie carto avant la prod. **Correction apportée à l'option** : le champ ne peut pas être retiré pour le web, il est porté par la section et partagé entre plateformes — il est donc conservé et **documenté dans l'interface** comme réglage mobile/tablette. Voir le lot E | — |
|
||||||
| Flux de configuration SectionParcours | **A — fenêtre unique avec rail d'étapes (recommandée)** · B — écran plein cadre 3 colonnes. Argument ajouté le 10/08 : le seul gain réel de B est une colonne d'aperçu visiteur, déjà couverte par le §5 du Guide IA (**L18**) | DB4 seulement — **pas DB2**, la sauvegarde au fil de l'eau part sans attendre |
|
| ~~Flux de configuration SectionParcours~~ | ✅ **2026-08-11 — A, et livrée.** Fenêtre unique avec rail d'étapes, profondeur 2. B écartée : son seul gain réel était une colonne d'aperçu visiteur, déjà couverte par le §5 du Guide IA (**L18**). Le travail fait pour A reste transposable — le widget à panneaux ne dépend pas du `Dialog` qui l'entoure | — |
|
||||||
| CGU §5 face aux contrats déjà signés | Vérifier ce que les clients existants ont signé avant de considérer le sujet clos | Lot F (volet RGPD dans le même document) |
|
| CGU §5 face aux contrats déjà signés | Vérifier ce que les clients existants ont signé avant de considérer le sujet clos | Lot F (volet RGPD dans le même document) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user