7 Commits

Author SHA1 Message Date
Thomas Fransolet
851b062668 Update docs, kanban etc 2026-09-04 16:48:04 +02:00
Thomas Fransolet
396debb4ff C4 et K8 livrés, et le travail DOCS de la session manager-service
Ce commit porte deux sessions à la fois — voir la note de collision en
fin de message.

C4 — compression des images à l'upload, flutter build web vert. Un seul
helper appelé par les deux chemins d'upload de resources_screen, le
motif exact qui a fait diverger Create et Upload côté serveur en C1 puis
en C3. La compression se fait avant resourceCreate parce que le pré-vol
de quota de C3 porte sur sizeBytes à la création. Écart assumé à
l'énoncé « JPEG q82 » : un PNG à canal alpha reste un PNG, sinon la
transparence se remplit de noir. Défaut préexistant trouvé au passage :
le second chemin d'upload ne renseignait sizeBytes ni avant ni après,
donc tout ce qui est passé par là compte 0 octet au quota.

K8 — retour à l'accueil après 5 min, flutter build apk vert. Écrit une
seule fois dans section_page_detail, qui enveloppe les treize types.
Le retour passe par le même dispose, donc il émet un sectionLeave avec
sa durée réelle : K8 répare une statistique en plus d'un écran.

Checklist D0 ajoutée — DOCS/claude design/checklist-d0-offline.html.
Les 15 cas du §21, chaque groupe relié au bug qu'il décide : 21.2 tranche
D2 et D4, 21.1.4 tranche D3, 21.4.1 tranche D5. Les cas 21.1.2/3/5/6 sont
la première vérification RÉELLE de D1, corrigé le 11/08 mais validé par
l'analyse seule. Si tout passe, le lot D se ferme et le plan perd un à
deux jours — c'est le lien L11.

COLLISION SUR DOCS, à retenir. La session manager-service avait des
modifications stagées et non commitées sur STATUS.md, kanban.html et
v1-plan.md, alors que son prompt lui demandait de ne pas toucher à
DOCS/. Rien n'est perdu : ses changements et les miens coexistent, et
ils sont tous dans ce commit — deux cartes ferées de son côté (tests du
RAG, dettes serveur audit & plafond users) plus ses done-items.

Ce que ça a produit : mes compteurs de kanban étaient calculés par
arithmétique à partir d'un état déjà périmé, donc faux de trois cartes.
Ils sont désormais recalés sur la MESURE — on compte les <article> et on
écrit le résultat, on ne raisonne plus par delta. Planifié 19, six
colonnes cohérentes, 44 done-items, bandeau et libellé alignés.

Leçon pour la suite : un compteur dérivé d'un delta est faux dès qu'une
autre main touche le fichier. Mesurer, toujours.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 16:03:20 +02:00
Thomas Fransolet
3fe18e088b K3 et K7 livrés : la borne couvre 12 des 13 types
flutter build apk --debug vert, APK produit. SectionArticle et
SectionEvent sont branchés dans main_view.getContent ; seul
SectionParcours reste dehors, et définitivement.

Quatre choses que l'implémentation a corrigées ou apprises, toutes
reportées dans le plan, STATUS et la maquette :

- La barre de pied de la maquette n'appartient pas aux écrans.
  section_page_detail la dessine déjà pour les treize types, avec les
  clés back/menu selon isFromMenu. La dessiner aurait affiché deux
  boutons retour. La maquette est corrigée sur ce point.
- Un seul constructeur de marqueurs au lieu des quatre de mymuseum.
  MapAnnotationDTO et MapAnnotation ont des champs rigoureusement
  identiques mais sont deux types Dart distincts. Normalisé par une
  classe interne — L5 appliqué au front, et il porte d'autant plus que
  la convention [lng, lat] est l'endroit exact où une divergence ne
  lève aucune erreur.
- L'audio d'article se résout dans contents avant l'API, donc sans
  appel réseau quand il est embarqué, donc hors ligne aussi. Mymuseum
  appelle l'API systématiquement en ligne.
- Clé i18n event.live ajoutée aux 10 langues. Sans les 10,
  getFromLocale renvoie "" et la pastille rendrait une boîte vide.
  PL, CN, UK et AR sont de ma main et demandent une relecture humaine.

Ce qui n'est pas prouvé, et qui est écrit comme tel : le rendu. Aucun
des deux écrans n'a été vu à l'œil — un build vert ne dit rien d'une
mise en page, c'est la leçon du §1bis appliquée au design. Et aucun
SectionEvent n'existe en base, le type étant né avec Postgres v3 : le
§19.13 cas E en créera un.

Kanban : la carte « Types de section manquants sur le kiosk » quitte
Urgent (2 -> 1) pour Fait récemment (40 -> 41), bandeau du haut et
libellé « Quarante et un » compris. Compteurs des six colonnes
revérifiés un à un.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 15:20:29 +02:00
Thomas Fransolet
4a4523e3a2 Correction : tablet-app a bien un i18n, et V2 gagne l'orientation
Correction d'une affirmation fausse écrite plus tôt dans la journée et
reprise dans la maquette, le plan et une décision validée : « tablet-app
n'a aucun i18n ». Il en a un — lib/Helpers/translations.dart, 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, alors que le CLAUDE.md du repo le décrit.

Ce que ça change : le motif donné pour « hors dates, aucune prose » — un
bandeau serait français pour un néerlandophone — était faux. Un libellé
traduit coûte une clé × 10 langues. La règle reste défendable (rien à
traduire vaut mieux que quelque chose à traduire) mais devient un choix,
pas une contrainte. À reconfirmer.

Corollaire d'implémentation : le bouton Retour des deux écrans passe par
la clé back existante, il ne s'écrit pas en dur.

Ajouté en V2 — portrait et paysage sur toute la borne. tablet-app n'a
aucune stratégie d'orientation : chaque écran est écrit pour la forme
qu'on lui a vue, et la maquette du 12/08 ne tranche que le paysage, pour
deux types. Une borne se monte pourtant aussi bien en totem qu'en
comptoir, et le choix appartient au lieu. Le chantier n'est pas
« ajouter le portrait » mais rendre les treize types indifférents à
l'orientation — repasse UI transversale, même famille que la repasse
globale de manager-app. La maquette est compatible (le rail qui tombe
sous le texte est le comportement portrait) mais ne le spécifie pas.

Kanban : carte V2 ajoutée, Planifié 21 -> 22 (colonne et bandeau). Le
motif « et tablet-app ne compile même plus » de la carte Kiosk web est
corrigé — il est tombé avec K1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:55:39 +02:00
Thomas Fransolet
c2bda75885 Maquette : Article et Événement en paysage sur la borne (K3, K7, K8)
Une seule passe de design pour les deux écrans. Les trancher séparément
donnerait deux grammaires différentes sur la même dalle, alors qu'ils
posent la même question : ces écrans sont dessinés pour un téléphone tenu
debout, une borne fait 1280 px de large et se lit à un mètre.

Six règles communes, chacune corrigeant un idiome de téléphone qui devient
faux sur une dalle large et fixe : deux colonnes (un ancrage fixe, un flux
qui défile), texte plafonné à ~65 caractères, héros à 26 % au lieu de 52 %,
plus de showModalBottomSheet (il y a la place à côté), carte affichée à sa
taille utile sans « Agrandir », et accents dérivés de
configuration.primaryColor — précédent K4, tablet-app n'a pas de flavor.

Quatre décisions prises le 12/08 :

- Fond clair, aux valeurs réelles de l'app (kBackgroundColor #FFFFFF,
  kBackgroundLight #F3F3F3), pour que la section ne dénote pas.
- Pas de sélecteur de langue : elle est choisie en amont.
- Hors dates, aucune prose : le programme reste, sans pastille EN COURS,
  et les dates du héros disent qu'on est avant ou après.
- Retour automatique après 5 min : adopté mais sorti du périmètre, K8.

Trois états incomplets, tous possibles en configuration. La règle qui les
couvre : le rail média n'existe que s'il a quelque chose à ancrer.

- Sans audio : le dock tombe, l'image reprend la hauteur.
- Sans photo : le rail tombe — une colonne de 38 % avec un seul lecteur
  serait un trou. L'audio passe en tête de la colonne de lecture.
- Texte seul : une colonne centrée, toujours plafonnée. Le vide latéral
  est voulu, c'est lui qui garde le texte lisible.

Quatre vérifications faites dans le code plutôt que supposées :

- Les statistiques sont déjà acquises. section_page_detail émet
  sectionView et sectionLeave avec durée et enveloppe les treize types :
  l'article sera compté dès que son case entre dans le switch.
- 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 » et impose d'exprimer l'état hors dates par des dates.
- audioIds est une List<TranslationDTO> : « sans audio » est un état de
  la langue courante, pas de l'article. Un article peut avoir sa version
  française et pas sa néerlandaise.
- isContentTop existe déjà et dit si le texte passe avant le média. En
  paysage il ne veut plus dire « au-dessus » mais « à gauche » : à
  câbler, sinon un réglage déjà offert dans manager-app reste sans effet.

Retiré de la maquette : un repère « 3 / 8 » en pied d'article, inventé
pour occuper la place libérée par le sélecteur de langue. SectionPageDetail
ne reçoit qu'une section et un booléen isFromMenu, jamais la liste de ses
voisines — le repère n'était adossé à aucune donnée.

K8 ajouté au plan et au kanban : le retour à l'accueil s'écrit une seule
fois dans section_page_detail. Bénéfice de bord, il passe par le même
dispose et émet donc un sectionLeave avec sa durée réelle au lieu de
laisser une consultation ouverte jusqu'au visiteur suivant.

Source de vérité dans le repo, artifact pour la diffusion (convention DB0).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:55:39 +02:00
Thomas Fransolet
b5883be088 Maquette : Article et Événement en paysage sur la borne (K3, K7, K8)
Une seule passe de design pour les deux écrans. Les trancher séparément
donnerait deux grammaires différentes sur la même dalle, alors qu'ils
posent la même question : ces écrans sont dessinés pour un téléphone tenu
debout, une borne fait 1280 px de large et se lit à un mètre.

Six règles communes, chacune corrigeant un idiome de téléphone qui devient
faux sur une dalle large et fixe : deux colonnes (un ancrage fixe, un flux
qui défile), texte plafonné à ~65 caractères, héros à 26 % au lieu de 52 %,
plus de showModalBottomSheet (il y a la place à côté), carte affichée à sa
taille utile sans « Agrandir », et accents dérivés de
configuration.primaryColor — précédent K4, tablet-app n'a pas de flavor.

Quatre décisions prises le 12/08 :

- Fond clair, aux valeurs réelles de l'app (kBackgroundColor #FFFFFF,
  kBackgroundLight #F3F3F3), pour que la section ne dénote pas.
- Pas de sélecteur de langue : elle est choisie en amont.
- Hors dates, aucune prose : le programme reste, sans pastille EN COURS,
  et les dates du héros disent qu'on est avant ou après.
- Retour automatique après 5 min : adopté mais sorti du périmètre, K8.

Trois états incomplets, tous possibles en configuration. La règle qui les
couvre : le rail média n'existe que s'il a quelque chose à ancrer.

- Sans audio : le dock tombe, l'image reprend la hauteur.
- Sans photo : le rail tombe — une colonne de 38 % avec un seul lecteur
  serait un trou. L'audio passe en tête de la colonne de lecture.
- Texte seul : une colonne centrée, toujours plafonnée. Le vide latéral
  est voulu, c'est lui qui garde le texte lisible.

Quatre vérifications faites dans le code plutôt que supposées :

- Les statistiques sont déjà acquises. section_page_detail émet
  sectionView et sectionLeave avec durée et enveloppe les treize types :
  l'article sera compté dès que son case entre dans le switch.
- 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 » et impose d'exprimer l'état hors dates par des dates.
- audioIds est une List<TranslationDTO> : « sans audio » est un état de
  la langue courante, pas de l'article. Un article peut avoir sa version
  française et pas sa néerlandaise.
- isContentTop existe déjà et dit si le texte passe avant le média. En
  paysage il ne veut plus dire « au-dessus » mais « à gauche » : à
  câbler, sinon un réglage déjà offert dans manager-app reste sans effet.

Retiré de la maquette : un repère « 3 / 8 » en pied d'article, inventé
pour occuper la place libérée par le sélecteur de langue. SectionPageDetail
ne reçoit qu'une section et un booléen isFromMenu, jamais la liste de ses
voisines — le repère n'était adossé à aucune donnée.

K8 ajouté au plan et au kanban : le retour à l'accueil s'écrit une seule
fois dans section_page_detail. Bénéfice de bord, il passe par le même
dispose et émet donc un sectionLeave avec sa durée réelle au lieu de
laisser une consultation ouverte jusqu'au visiteur suivant.

Source de vérité dans le repo, artifact pour la diffusion (convention DB0).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:39:06 +02:00
Thomas Fransolet
a5a8ecdb20 Documentation interne MyInfoMate / Unov
Import initial de la documentation : statut, roadmap, plans V1/V2,
specs verticales (creche, sport), audits securite, plan de test,
analyse concurrentielle et maquettes de design.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:17:01 +02:00