Compare commits
2 Commits
b5883be088
...
4a4523e3a2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a4523e3a2 | ||
|
|
c2bda75885 |
@ -120,7 +120,8 @@ Tableau de chantiers global : https://claude.ai/code/artifact/4c317904-2e23-45d3
|
||||
| **SectionForm** — formulaires personnalisés (feedback, satisfaction, inscription atelier) | Nouveau type de section + table de réponses : purement additif, aucun impact sur le schéma existant |
|
||||
| **Ressource 360°** — images panoramiques (`ResourceType.Panorama360` + package `panorama`) | Une valeur d'enum et un branchement dans l'affichage des ressources ; se greffe sans toucher aux sections |
|
||||
| **AR image tracking (Mind AR)** — modèle `ArAnchor`, microservice Node de compilation `.mind`, WebView scanner unifiée QR + image | Le plus gros des trois : nouveau service Docker, nouveau modèle, refonte du scanner visiteur. Fort effet démo, zéro urgence |
|
||||
| **Kiosk web** — version Flutter Web de `tablet-app` | Aucun client ne le demande, et `tablet-app` ne compile pas aujourd'hui : il faudrait d'abord réparer le build natif pour en dériver une cible web. ⚠️ **Ne pas confondre avec le visiteur web** (`visitapp-web`), lui déjà écrit et attendu en V1 |
|
||||
| **Kiosk web** — version Flutter Web de `tablet-app` | Aucun client ne le demande. ⚠️ **Ne pas confondre avec le visiteur web** (`visitapp-web`), lui déjà écrit et attendu en V1. *Mise à jour du 2026-08-12 : l'argument « et tablet-app ne compile pas » est tombé, l'APK est produit depuis K1.* |
|
||||
| **Portrait et paysage sur toute la borne** — ajouté le 2026-08-12 | `tablet-app` n'a **aucune stratégie d'orientation** : les écrans sont écrits pour la forme qu'on leur a vue, et la maquette K3/K7 tranche le paysage pour deux types seulement. Or une borne se monte aussi bien en portrait (totem d'accueil) qu'en paysage (comptoir), et le choix appartient au lieu, pas à l'app. Le chantier n'est donc pas « ajouter le portrait » mais **rendre les treize types indifférents à l'orientation** — un jeu de points de rupture et une règle unique du type « la colonne de texte reste plafonnée, le rail passe dessous quand la largeur manque ». C'est une repasse UI transversale, pas un correctif : hors V1 pour la même raison que la repasse UI globale de `manager-app` (DB1). ⚠️ **La maquette du 12/08 est compatible** — le rail qui tombe sous le texte est exactement le comportement portrait — mais elle ne l'a pas spécifié |
|
||||
|
||||
**Prochaine chose à faire si tu as 1h** : le **§21 du plan de test** — vérifier sur un device l'état réel de la visite hors ligne. C'est peut-être déjà remonté comme « l'appli marche mal dans le fort » sans que la cause ait été identifiée, et ça conditionne l'urgence des points 10-13.
|
||||
|
||||
|
||||
@ -683,9 +683,9 @@
|
||||
</div>
|
||||
<h3>Sans audio</h3>
|
||||
<p>
|
||||
Le dock disparaît, l'image reprend la hauteur libérée. Aucune autre reprise —
|
||||
c'est le cas le plus simple des trois.
|
||||
<span class="cond">audioIds vide pour la langue courante</span>
|
||||
Le dock disparaît, l'image reprend la hauteur libérée. <strong>Pas de lecteur grisé, pas de
|
||||
repli sur une autre langue</strong> — le lecteur n'existe pas pour ce visiteur.
|
||||
<span class="cond">pas d'entrée audioIds pour la langue choisie</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -771,15 +771,19 @@
|
||||
<p>
|
||||
<strong><code>audioIds</code> est une <code>List<TranslationDTO></code>, pas un id.</strong>
|
||||
L'audio est donc <em>par langue</em> : un article peut avoir sa version française et pas sa
|
||||
néerlandaise. « Sans audio » n'est pas un état de l'article, c'est un état de
|
||||
<strong>l'article dans la langue courante</strong> — et la borne doit basculer sur la variante
|
||||
du milieu pour ce visiteur-là seulement.
|
||||
néerlandaise. La règle est donc stricte — <strong>pas d'entrée pour la langue choisie, pas de
|
||||
lecteur du tout.</strong> Ni lecteur grisé, ni repli sur une autre langue : un visiteur
|
||||
néerlandophone à qui la borne servirait l'audio français serait plus mal servi que par le
|
||||
silence. « Sans audio » est un état <strong>du visiteur</strong>, pas de l'article.
|
||||
</p>
|
||||
<p>
|
||||
<strong><code>isContentTop</code> existe déjà</strong> et dit si le texte passe avant le média.
|
||||
En portrait, « avant » veut dire au-dessus. En paysage, il n'y a plus de dessus : le drapeau
|
||||
devient l'ordre des deux colonnes — média à gauche, ou texte à gauche. À câbler, pas à ignorer,
|
||||
sinon un réglage déjà offert dans <code>manager-app</code> devient sans effet sur la borne.
|
||||
En portrait, « avant » veut dire au-dessus ; en paysage il n'y a plus de dessus, donc
|
||||
<strong>le drapeau devient le côté</strong> :
|
||||
<code>isContentTop == true</code> → <strong>texte à gauche, rail média à droite</strong> ;
|
||||
sinon la disposition par défaut des maquettes, média à gauche. Le rail garde sa composition
|
||||
dans les deux cas — image, vignettes, audio docké — il change de bord, pas de contenu. À
|
||||
câbler, sinon un réglage déjà offert dans <code>manager-app</code> reste sans effet sur la borne.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -947,15 +951,23 @@
|
||||
</div>
|
||||
|
||||
<div class="ruleitem">
|
||||
<h3>Et c'est l'i18n qui tranche</h3>
|
||||
<h3>L'i18n existe — corrigé le 12/08</h3>
|
||||
<p>
|
||||
Ton réflexe sur les traductions était le bon, et il est plus contraignant que prévu :
|
||||
<strong><code>tablet-app</code> n'a aucun système d'i18n</strong> — pas de <code>l10n/</code>,
|
||||
pas d'<code>AppLocalizations</code>, les libellés sont en français en dur
|
||||
(<code>"Ce type n'est pas supporté"</code>). Un bandeau « Édition passée » serait donc
|
||||
<strong>français pour un visiteur néerlandophone</strong>. Le vrai libellé viendrait soit
|
||||
d'un champ backend traduit — qui n'existe pas — soit d'un i18n à créer, ce qui n'est pas un
|
||||
chantier de K3. D'où la règle ci-dessus : on affiche des dates, pas des phrases.
|
||||
⛔ <strong>Une affirmation de cette page était fausse et a été retirée</strong> :
|
||||
« <code>tablet-app</code> n'a aucun i18n ». Il en a un —
|
||||
<code>lib/Helpers/translations.dart</code>, une table de <strong>10 langues</strong>
|
||||
(FR, EN, NL, DE, IT, ES, PL, CN, AR, UK) lue par
|
||||
<code>TranslationHelper.getFromLocale</code> à <strong>19 endroits</strong>, avec déjà une
|
||||
clé <code>back</code>. Ce n'est pas de l'ARB, c'est une table à la main — le même pattern que
|
||||
mymuseum. Chercher <code>l10n/</code> et <code>AppLocalizations</code> ne le trouve pas.
|
||||
</p>
|
||||
<p style="margin-top: var(--s2);">
|
||||
Ce que ça change : un libellé traduit coûte <strong>une clé × 10 langues</strong>, pas un
|
||||
chantier. La règle « aucune prose » ci-dessus reste défendable — les dates suffisent, et
|
||||
rien à traduire vaut mieux que quelque chose à traduire — mais elle devient un
|
||||
<strong>choix</strong> et non une contrainte. <strong>À confirmer.</strong> Et le bouton
|
||||
« Retour » des maquettes doit passer par la clé <code>back</code> existante, pas être écrit
|
||||
en dur.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
15
kanban.html
15
kanban.html
@ -458,7 +458,7 @@
|
||||
<div class="stat"><span class="n n-info">2</span><span class="k">Migration v3</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">21</span><span class="k">Planifié</span></div>
|
||||
<div class="stat"><span class="n">22</span><span class="k">Planifié</span></div>
|
||||
<div class="stat"><span class="n n-gate">8</span><span class="k">Bascule prod</span></div>
|
||||
<div class="stat"><span class="n n-good">40</span><span class="k">Fait récemment</span></div>
|
||||
</section>
|
||||
@ -626,7 +626,7 @@
|
||||
|
||||
<!-- PLANIFIÉ -->
|
||||
<section class="col" style="--stripe: var(--ink-3)">
|
||||
<div class="col-head"><h2>Planifié</h2><span class="count">21</span></div>
|
||||
<div class="col-head"><h2>Planifié</h2><span class="count">22</span></div>
|
||||
|
||||
<article class="card" data-area="manager" data-horizon="v1">
|
||||
<div class="card-meta"><span class="tag">tablet-app</span><span class="flag f-warn">Lot K · K8 — nouveau 12/08</span></div>
|
||||
@ -732,10 +732,19 @@
|
||||
<article class="card" data-area="visitapp manager" data-horizon="v2">
|
||||
<div class="card-meta"><span class="tag">tablet-app</span><span class="flag f-warn">V2</span></div>
|
||||
<h3>Kiosk web (Flutter Web)</h3>
|
||||
<p>Extension web de <code>tablet-app</code> pour les clients ne voulant pas d'installation native. <strong>Reporté en V2 le 07/08</strong> : aucun client demandeur, et la cible native ne compile même plus — il faudrait réparer ce build avant d'en dériver une version web.</p>
|
||||
<p>Extension web de <code>tablet-app</code> pour les clients ne voulant pas d'installation native. <strong>Reporté en V2 le 07/08</strong> : aucun client demandeur. ⚠️ <em>Le second motif est tombé le 12/08</em> — « la cible native ne compile même plus » n'est plus vrai, l'APK est produit depuis K1.</p>
|
||||
<span class="src">architecture-web-saas.md — Kiosk web</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="visitapp" data-horizon="v2">
|
||||
<div class="card-meta"><span class="tag">tablet-app</span><span class="flag f-warn">V2 — nouveau 12/08</span></div>
|
||||
<h3>Portrait et paysage sur toute la borne</h3>
|
||||
<p><code>tablet-app</code> n'a <strong>aucune stratégie d'orientation</strong> : chaque écran est écrit pour la forme qu'on lui a vue. Or une borne se monte aussi bien en <strong>portrait</strong> (totem d'accueil) qu'en <strong>paysage</strong> (comptoir), et le choix appartient au lieu, pas à l'app.</p>
|
||||
<p>Le chantier n'est donc pas « ajouter le portrait » mais <strong>rendre les treize types indifférents à l'orientation</strong> — des points de rupture et une règle unique du type « la colonne de texte reste plafonnée, le rail passe dessous quand la largeur manque ». Repasse UI transversale, hors V1 pour la même raison que la repasse globale de <code>manager-app</code> (DB1).</p>
|
||||
<p>⚠️ <strong>La maquette K3/K7 du 12/08 est compatible</strong> — le rail qui tombe sous le texte <em>est</em> le comportement portrait — mais elle ne l'a pas spécifié : elle tranche le paysage, pour deux types.</p>
|
||||
<span class="src">STATUS.md §1ter V2 · maquette kiosk-paysage</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="backend manager visitapp" data-horizon="v2">
|
||||
<div class="card-meta"><span class="tag">produit</span><span class="flag f-warn">V2</span></div>
|
||||
<h3>SectionForm — formulaires personnalisés</h3>
|
||||
|
||||
@ -284,7 +284,7 @@ Ordre du §2 de STATUS.md, corrigé par **L12**.
|
||||
| ~~**K4**~~ ✅ **2026-08-12** | **Écran Game repris de mymuseum.** Les 6 fichiers de `Screens/Sections/Game/` sont dans `tablet-app/lib/Screens/Game/`, contexte adapté ; `lib/Screens/Puzzle/` supprimé ; `main_view` bascule sur `SectionType.Game` / `GameDTO` / `GamePage`. **Gains** : le puzzle glissant (mélange par mouvements valides, donc toujours soluble), le bouton d'indice, et un dimensionnement qui respecte le ratio de l'image — 508 lignes contre 237 à l'ancien `puzzle_view`.<br>⚠️ **Une décision de rendu à valider à l'œil** : mymuseum code ses couleurs **en dur par flavor client** (`kMainColor0/1/2` — rouge MDLF, bleu Fort). `tablet-app` n'a pas de flavor : un seul APK sert tous les clients et la charte vient de la configuration choisie au pincode. Recopier ces constantes aurait affiché du bleu chez MDLF. Le dégradé et le bouton d'indice sont donc **dérivés de `configuration.primaryColor`** (même parsing que `audio_player`/`loading_common`, repli `kTestSecondColor`, 3 nuances par `Color.lerp`). Plus juste sur le fond, mais **le rendu diffère de la version mobile** : si le dégradé dessiné à la main est préféré, figer les trois couleurs |
|
||||
| ~~K4 — énoncé d'origine~~ | **`SectionPuzzle` → `SectionGame` + le type glissant.** Le serveur a renommé et porte `GameTypes { Puzzle, SlidingPuzzle }` ; `tablet-app` a encore un écran `Puzzle/` qui ne connaît que l'ancien. **Reprendre le code de `mymuseum-visitapp/lib/Screens/Sections/Game/`** — `game_page.dart` et `sliding_puzzle_piece.dart` existent déjà là-bas, et cette version est **moins buguée** que celle de tablet-app | Récupération, pas réécriture |
|
||||
| ~~**K5**~~ ✅ **2026-08-12** | **Les trois flavors de `mymuseum-visitapp` construisent** (`dev`, `mdlf`, `fortsaintheribert`), exit 0, APK à l'appui. **D0 est débloqué.**<br>⛔ **L'énoncé était faux : il n'y avait pas de « même rattrapage » à faire.** Sa config Android était **déjà à niveau** — Gradle 8.11.1, AGP 8.9.0, `-Xmx4096M`, `enableJetifier=false`, aucun forçage d'`androidx.lifecycle`. Les dix crans de K1 ont amené **`tablet-app` jusqu'à `mymuseum`** ; le lot supposait la symétrie du problème, elle n'existait pas. Le réflexe du diff annoncé en K1 a donné la réponse en deux `cat`.<br>**Ce qui restait, et qui est fait** : les deux avertissements du build. NDK **27.0.12077973 → 28.2.13676358** (`speech_to_text` le réclame nommément) et Kotlin **2.1.0 → 2.3.10** (seuil 2.2.20 annoncé comme rupture ; c'est la version de `tablet-app`, donc un alignement). Six builds — trois avant, trois après. APK de **382 à 349 Mo**.<br>⚠️ **Un cran de plus existe, délibérément non pris** : Kotlin réglé, Flutter réclame Gradle 8.14.0 et AGP 8.11.1. C'est du **terrain neuf pour les deux repos** (`tablet-app` est à 8.11.1/8.9.1, mêmes avertissements latents) — le faire ici seul **désaligne** les deux apps. À faire d'un bloc sur les deux, ou pas du tout : c'est la dette d'outillage déjà parquée en V2 | Son code était déjà porté sur le nouveau contrat — **c'est ce qui aurait dû mettre la puce à l'oreille** : le repo qui a servi de modèle au portage K2 n'avait pas de raison d'être en retard d'outillage sur celui qui le copiait |
|
||||
| **K7** | **`SectionArticle` sur le kiosk — ajouté le 2026-08-12**, en recomptant les types couverts. Son `case` est commenté « TODO » dans `main_view.getContent` et `Screens/Article/article_view.dart` fait 1 Ko : un article rend « Ce type n'est pas supporté ». **Contrairement à `SectionEvent` et `SectionParcours`, ce type existait dans Mongo** — c'est donc un vrai retard, pas un type né avec Postgres v3, et il sortira de la migration avec du contenu réel.<br>**Le code est une reprise de `mymuseum-visitapp/lib/Screens/Sections/Article/`**, pas une conception. **Le travail n'est pas là** : il est dans le **passage en paysage**. Les écrans de mymuseum sont pensés pour un téléphone tenu debout ; une borne est large, et un article rendu en colonne unique sur 1280 px de large est illisible. C'est le seul endroit du lot K où il y a une décision de mise en page à prendre, pas une copie à faire.<br>✅ **Maquette faite et validée le 2026-08-12** — `DOCS/claude design/kiosk-paysage-article-event.html`, une seule passe pour K3 et K7. Six règles communes (deux colonnes ancrage/flux, texte à 65 caractères, héros à 26 % au lieu de 52 %, plus de `showModalBottomSheet`, carte sans « Agrandir », accents dérivés de `configuration.primaryColor` selon le précédent K4) et quatre décisions tranchées : **fond clair** aux valeurs réelles de l'app (`kBackgroundColor` / `kBackgroundLight`), **pas de sélecteur de langue** (choisie en amont), **hors dates : aucune prose**, et le **retour automatique** sorti du périmètre (ligne suivante).<br>⚠️ **Deux vérifications faites dans le code plutôt que supposées.** Les **statistiques sont déjà acquises** : `section_page_detail.dart:60/72` émet `sectionView` et `sectionLeave` avec durée, et il enveloppe les treize types — l'article sera compté dès que son `case` entre dans le `switch`, sans une ligne à écrire. Et **`tablet-app` n'a aucun i18n** : pas de `l10n/`, pas d'`AppLocalizations`, libellés français en dur. C'est ce qui interdit un bandeau « Édition passée » — il serait français pour un visiteur néerlandophone — et c'est pourquoi l'état hors dates s'exprime par les **dates**, numériques donc sans traduction | **À traiter avec K3** : `SectionEvent` pose exactement la même question de paysage (héros, programme, carte), et la trancher deux fois donnerait deux mises en page différentes sur la même borne. Une seule passe de design pour les deux, même raisonnement d'économie que **L5** et **L15**.<br>**Trois états incomplets couverts par la maquette** : sans audio (le dock tombe, l'image reprend la hauteur), sans photo (le rail tombe, l'audio passe en tête de la colonne de lecture), texte seul (une colonne centrée, toujours plafonnée). ⚠️ **`audioIds` est une `List<TranslationDTO>`** : « sans audio » est un état **de la langue courante**, pas de l'article. Et **`isContentTop` existe déjà** — en paysage il ne veut plus dire « au-dessus » mais « à gauche », à câbler sous peine de rendre sans effet un réglage déjà offert dans `manager-app` |
|
||||
| **K7** | **`SectionArticle` sur le kiosk — ajouté le 2026-08-12**, en recomptant les types couverts. Son `case` est commenté « TODO » dans `main_view.getContent` et `Screens/Article/article_view.dart` fait 1 Ko : un article rend « Ce type n'est pas supporté ». **Contrairement à `SectionEvent` et `SectionParcours`, ce type existait dans Mongo** — c'est donc un vrai retard, pas un type né avec Postgres v3, et il sortira de la migration avec du contenu réel.<br>**Le code est une reprise de `mymuseum-visitapp/lib/Screens/Sections/Article/`**, pas une conception. **Le travail n'est pas là** : il est dans le **passage en paysage**. Les écrans de mymuseum sont pensés pour un téléphone tenu debout ; une borne est large, et un article rendu en colonne unique sur 1280 px de large est illisible. C'est le seul endroit du lot K où il y a une décision de mise en page à prendre, pas une copie à faire.<br>✅ **Maquette faite et validée le 2026-08-12** — `DOCS/claude design/kiosk-paysage-article-event.html`, une seule passe pour K3 et K7. Six règles communes (deux colonnes ancrage/flux, texte à 65 caractères, héros à 26 % au lieu de 52 %, plus de `showModalBottomSheet`, carte sans « Agrandir », accents dérivés de `configuration.primaryColor` selon le précédent K4) et quatre décisions tranchées : **fond clair** aux valeurs réelles de l'app (`kBackgroundColor` / `kBackgroundLight`), **pas de sélecteur de langue** (choisie en amont), **hors dates : aucune prose**, et le **retour automatique** sorti du périmètre (ligne suivante).<br>⚠️ **Deux vérifications faites dans le code plutôt que supposées.** Les **statistiques sont déjà acquises** : `section_page_detail.dart:60/72` émet `sectionView` et `sectionLeave` avec durée, et il enveloppe les treize types — l'article sera compté dès que son `case` entre dans le `switch`, sans une ligne à écrire. ⛔ **Et une erreur à ne pas rouvrir : j'avais écrit que `tablet-app` n'a aucun i18n. C'est faux.** `lib/Helpers/translations.dart` porte une table de **10 langues** (FR, EN, NL, DE, IT, ES, PL, CN, AR, UK), ~150 entrées, lue par `TranslationHelper.getFromLocale` à **19 endroits**, avec déjà une clé `back`. Ce n'est pas de l'ARB : chercher `l10n/` ou `AppLocalizations` ne le trouve pas — c'est une table à la main, le même pattern que mymuseum, décrit dans le `CLAUDE.md` du repo. **Conséquence** : un libellé traduit coûte une clé × 10 langues, pas un chantier. La règle « hors dates, aucune prose » reste défendable — rien à traduire vaut mieux que quelque chose à traduire — mais c'est désormais un **choix, pas une contrainte**, et le motif d'origine était faux. ⚠️ Corollaire pour l'implémentation : le bouton « Retour » passe par la clé `back`, il ne s'écrit pas en dur | **À traiter avec K3** : `SectionEvent` pose exactement la même question de paysage (héros, programme, carte), et la trancher deux fois donnerait deux mises en page différentes sur la même borne. Une seule passe de design pour les deux, même raisonnement d'économie que **L5** et **L15**.<br>**Trois états incomplets couverts par la maquette** : sans audio (le dock tombe, l'image reprend la hauteur), sans photo (le rail tombe, l'audio passe en tête de la colonne de lecture), texte seul (une colonne centrée, toujours plafonnée). ⚠️ **`audioIds` est une `List<TranslationDTO>`** : « sans audio » est un état **du visiteur**, pas de l'article. Règle actée le 2026-08-12 — **pas d'entrée pour la langue choisie, pas de lecteur du tout** : ni lecteur grisé, ni repli sur une autre langue. Et **`isContentTop` existe déjà** ; en paysage il n'y a plus de « dessus », donc **le drapeau devient le côté** : `isContentTop == true` → texte à gauche et rail média à droite, sinon média à gauche. Le rail change de bord, pas de contenu. À câbler sous peine de rendre sans effet un réglage déjà offert dans `manager-app` |
|
||||
| **K8** | **Retour automatique à l'accueil après inactivité — ajouté le 2026-08-12**, sorti de la maquette K3/K7. Un visiteur part sans fermer l'écran ; le suivant trouve l'article du précédent. Délai proposé : **5 minutes**.<br>**À écrire une seule fois pour les treize types**, dans `section_page_detail` — il enveloppe déjà toutes les sections et porte déjà les crochets `initState`/`dispose`. Bénéfice de bord : le retour passant par le même `dispose`, il émet un `sectionLeave` **avec sa durée réelle** au lieu de laisser une consultation ouverte jusqu'au prochain visiteur. **La statistique devient juste, en plus de l'écran** | Ce n'est ni K3 ni K7 : c'est un comportement de borne qui vaut pour tous les types. À ne pas glisser dans le port des deux écrans, sinon il sera écrit deux fois puis une troisième |
|
||||
| **K6** | **Publier les APK à jour**, puis vérifier le renouvellement du parc | **L19**. Les tablettes kiosk sont des appareils que tu gères — mise à jour maîtrisée. **Les téléphones des visiteurs, non** : aucune manœuvre technique ne force une mise à jour, d'où la stratégie de coexistence du lot I |
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user