Kanban régénéré : 43 chantiers planifiés

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Thomas Fransolet 2026-09-16 15:29:16 +02:00
parent 125813c34e
commit ad73aefe38

View File

@ -462,7 +462,7 @@
<div class="stat"><span class="n n-info">1</span><span class="k">Migration v3</span></div>
<div class="stat"><span class="n n-warn">2</span><span class="k">Bugs ouverts</span></div>
<div class="stat"><span class="n">12</span><span class="k">À tester</span></div>
<div class="stat"><span class="n">41</span><span class="k">Planifié</span></div>
<div class="stat"><span class="n">43</span><span class="k">Planifié</span></div>
<div class="stat"><span class="n n-gate">9</span><span class="k">Bascule prod</span></div>
<div class="stat"><span class="n n-good">66</span><span class="k">Fait récemment</span></div>
</section>
@ -706,7 +706,7 @@
<!-- PLANIFIÉ -->
<section class="col" style="--stripe: var(--ink-3)">
<div class="col-head"><h2>Planifié</h2><span class="count">41</span></div>
<div class="col-head"><h2>Planifié</h2><span class="count">43</span></div>
<div class="stack">
<article class="card" data-area="visitapp" data-horizon="v1">
@ -975,6 +975,17 @@
<span class="src">todo-features.md — AR</span>
</article>
<article class="card" data-area="backend manager visitapp" data-horizon="v2">
<div class="card-meta"><span class="tag">visitapp</span><span class="tag">matériel</span><span class="flag f-warn">Nouveau 16/09 · le gros du coût est les Universal/App Links, partagés avec le QR</span></div>
<h3>Tags NFC comme déclencheurs de section</h3>
<p><strong>Troisième déclencheur physique, à côté du QR et du beacon.</strong> Analyse et faisabilité : <a href="../v2/nfc-triggers-plan.md">v2/nfc-triggers-plan.md</a>.</p>
<p>⚠️ <strong>Deux recadrages par rapport à la formulation initiale.</strong> (1) Le déclencheur n'est pas un « POI » : dans MyInfoMate le POI est un point posé sur un GLB (VR/3D, <code>immersif-frontiere-plan.md</code>). Le déclencheur physique est une <strong>Section</strong><code>Section.IsBeacon</code> / <code>BeaconId</code>, lu par <code>geo_beacon_trigger_service.dart:177</code>. Le tag NFC se branche au même endroit que le beacon. (2) L'URL <code>/t/{instanceId}/{code}</code> et sa table de mapping <strong>n'ont pas d'équivalent existant à réutiliser</strong> : les QR d'aujourd'hui portent l'id de section directement dans l'URL (trois formats coexistants, <code>ScannerDialog.dart:31-38</code>), il n'y a aucun endpoint de résolution <code>code → section</code>. <strong>v1 = le tag porte la même URL que le QR</strong>, donc zéro entité, zéro endpoint, zéro CRUD ; l'indirection ne se justifie que si un client demande un parc de tags réassignables — et elle vaut bien moins qu'en QR, puisque réécrire un NTAG prend deux secondes alors qu'un QR se réimprime.</p>
<p><strong>Le vrai coût est ailleurs : les Universal Links (iOS) et App Links (Android) n'existent pas.</strong> Aucun <code>assetlinks.json</code> ni <code>apple-app-site-association</code> sur nos domaines (le seul du workspace est dans <code>OpenGlasses</code>, qui n'est pas à nous), et <code>app_links</code> n'est branché que sur le retour de deep link Meta AI (<code>main.dart:69</code>). ✅ <strong>Ce lot bénéficie autant au QR</strong> : aujourd'hui un QR scanné par l'appareil photo natif n'ouvre pas l'app.</p>
<p><strong>Dépendance</strong> : le fallback web d'un tag scanné sans app installée, c'est <code>visitapp-web</code><strong>pas encore déployé</strong> (carte « Déployer le visiteur web »). Sans lui, un tag scanné par un visiteur sans l'app tombe dans le vide.</p>
<p><strong>Ce qui ne marchera pas, à dire au commercial</strong> : pas de lecture NFC depuis <code>visitapp-web</code> (WebNFC est Chrome/Android uniquement, jamais Safari), et l'écriture de tags depuis iOS est trop contrainte — <strong>l'écran admin de programmation sera Android-only</strong>. En contrepartie, iPhone XS+ lit un tag NDEF <strong>sans aucune app</strong>, ce qui est l'argument réel du canal.</p>
<span class="src">nfc-triggers-plan.md · ScannerDialog.dart:31-38 · Section.cs:57 · main.dart:69</span>
</article>
<article class="card" data-area="manager" data-horizon="v2">
<div class="card-meta"><span class="tag">produit</span><span class="flag f-warn">V2 · nouveau 12/08</span></div>
<h3>Écran SuperAdmin — add-on IA &amp; canaux d'une instance</h3>
@ -1000,6 +1011,17 @@
<span class="src">v2/studio-plan.md — §8 (exécutable lots 0-4), §9 (catalogue v0), décisions 22-23</span>
</article>
<article class="card" data-area="backend manager" data-horizon="v2">
<div class="card-meta"><span class="tag">studio</span><span class="tag">crédits</span><span class="flag f-warn">Nouveau 16/09 · le plafond dur a été retiré exprès (décision 22)</span></div>
<h3>Seuil d'alerte sur le solde de crédits Studio (pas un nouveau plafond)</h3>
<p><strong>La limite demandée existe déjà, deux fois.</strong> Avec des crédits prépayés (décision 17), <strong>le solde <em>est</em> le plafond</strong> — c'est exactement pour ça que la décision 22 a retiré le plafond dur organisation le 13/09. Et le garde-fou contre le stagiaire qui vide le budget en une après-midi, c'est <code>Instance.StudioPerUserDailyCap</code>, déjà appliqué dans <code>StudioCreditService.ReserveAsync</code> (<code>CreditError.DailyCapReached</code>). Rien à ajouter de ce côté : <strong>ne pas recréer un plafond organisation.</strong></p>
<p>⚠️ <strong>Le modèle n'est pas celui de Google AI Studio ni de fal.ai.</strong> Là-bas on est en <strong>postpayé</strong> : sans budget alert ni hard cap, on découvre la facture. Ici le client a payé avant ; il ne peut pas se faire surprendre par une dépense, seulement par une <strong>indisponibilité</strong> — et ça, ça ne se règle pas avec un plafond, mais avec un préavis.</p>
<p><strong>Ce qui manque vraiment : le préavis.</strong> Aujourd'hui aucune alerte n'existe. <code>studio_credits_section.dart</code> affiche disponible / solde / réservé / expiration, mais il faut aller ouvrir l'écran Facturation pour les voir ; une génération qui échoue en <code>InsufficientCredits</code> est le premier signal reçu par le conservateur. Et surtout, <strong>l'expiration à 12 mois (décision 17) est le vrai piège</strong> : un solde qui s'évapore sans prévenir, sur une institution publique, c'est un litige — pas une notification manquée.</p>
<p><strong>À faire</strong> : <code>Instance.StudioCreditsAlertThreshold</code> (en crédits, 0 = désactivé) + <code>StudioCreditsAlertSentAt</code> pour ne pas renvoyer le mail à chaque génération ; déclenchement dans <code>StudioCreditService.Record</code> quand le solde passe sous le seuil, et dans <code>ExpireDueAsync</code> (déjà un job quotidien) pour un rappel d'expiration <strong>à J-30</strong>. Envoi par <code>IEmailService</code> / <code>ResendEmailService</code>, déjà en place. Côté manager-app : un champ dans l'écran Facturation et un bandeau dans le popover de la jauge du pied de menu, i18n FR/EN/NL.</p>
<p><strong>Petit lot</strong> : 2 colonnes, un hook, un template de mail, un champ d'UI. À faire <em>après</em> la fixation des prix (décision 16, fin du lot 3) — un seuil en crédits n'a pas de valeur par défaut tant que l'unité de crédit n'est pas arrêtée.</p>
<span class="src">studio-plan.md décisions 17 et 22 · StudioCreditService.cs · studio_credits_section.dart</span>
</article>
<article class="card" data-area="manager" data-horizon="v2">
<div class="card-meta"><span class="tag">manager-app</span><span class="tag">visitapp</span><span class="tag">tablet</span><span class="tag">vr</span><span class="flag f-good">Décision arrêtée, à exécuter après la bascule</span></div>
<h3>Loader animé — presets paramétriques, pas de format de fichier</h3>