DOCS/status/postgres-v3.md
2026-09-03 14:00:51 +02:00

87 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1ter. Chantier « migration Postgres v3 » — ordre de bataille (ajouté le 2026-08-07)
> ← Section **§1ter** du tableau de bord : [STATUS.md](../STATUS.md)
> Postgres n'est pas encore en prod. Trois chantiers ont été analysés le 2026-08-07 et découpés selon une règle unique :
>
> **Ce qui touche aux données déjà écrites part avec la migration. Ce qui est purement additif attend.**
>
> Chaque ligne est faite pour être attaquée dans une conversation dédiée : lire le doc, faire l'étape.
>
> ⚠️ Cette section dit **ce qui doit entrer dans le schéma**, pas comment on remplit la base. L'opération de bascule elle-même — et l'état de `MigrationController` — sont au **§1quinquies**.
### Doit partir avec la migration (schéma — quelques heures)
| # | Quoi | Doc | Pourquoi maintenant |
|---|---|---|---|
| 1 | ✅ **Fait 2026-08-09** — Image Docker `postgis` + `pgvector` (`Deployment/Dockerfile.postgres`, digest épinglé) | [v2/rag-pgvector-integration-plan.md](../v2/rag-pgvector-integration-plan.md) | Base vide = 4 lignes de Dockerfile. Plus tard = fenêtre de maintenance sur la prod |
| 2 | ✅ **Fait 2026-08-09** — Table `ContentEmbedding` + index HNSW | idem | Table vide, ne dérange personne. Additif mais gratuit maintenant |
| 3 | ✅ **Fait 2026-08-09**`IEmbeddingService` + `GoogleEmbeddingService`, **dimension 768 validée contre l'API réelle** | idem | **Gèle la dimension du vecteur** — décision de schéma, à valider avant la migration |
| 4 | ✅ **Fait 2026-08-09** — Colonnes `Resource` : `StoragePath`, `FileName`, `IncludeInAiKnowledge`, `AiIndexStatus`… (`SizeBytes` existait déjà) | [v2/media-storage-plan.md](../v2/media-storage-plan.md) | Les URL Firebase absolues sont dispersées jusque dans le JSONB des sections |
| 5 | Backfill `SizeBytes` + `StoragePath` + inventaire des blobs orphelins | idem | La migration touche déjà chaque ligne `Resource` |
| 6 | Flag watermark sur `Instance` (+ exposition dans la config) | idem | Remplace un `if` sur un id d'instance codé en dur |
### Avant la release, hors schéma
| # | Quoi | Doc |
|---|---|---|
| 7 | Compression images côté client — **2560 px / JPEG q82**, ~12× de gain | [v2/media-storage-plan.md](../v2/media-storage-plan.md) |
| 8 | Alerte de budget GCP (5 min) | idem |
| 9 | Quota : pré-vol + contrôle autoritaire à `Create` + `Delete` du blob | idem |
### Bugs découverts — indépendants de la migration
| # | Quoi | Doc |
|---|---|---|
| 10 | **Visite hors ligne quasi non fonctionnelle** — le `switch` de collecte des ressources est commenté côté backend *et* côté visitapp : ni images d'articles, ni audios | [v2/offline-visit-plan.md](../v2/offline-visit-plan.md) |
| 11 | Ressource modifiée jamais re-téléchargée (filtre sur la présence, pas la version) | idem |
| 12 | `audio/mpeg` absent de la table d'extensions → MP3 probablement en `.unknown` | idem |
| 13 | Purge des fichiers obsolètes désactivée sur le device | idem |
### V1 — après la migration (décidé le 2026-08-07)
Le RAG **est** dans la V1, dans son périmètre restreint : `IVectorStoreService`, jobs Hangfire sur le contenu CMS, endpoint `/ask`, et l'écran **[Guide IA](../v2/guide-ia-screen-plan.md)** dans manager-app. Pas d'ingestion documentaire, pas d'OCR, pas de TTS — c'est ce qui le rend tenable.
**Deux écrans manager-app sont spécifiés et maquettés** :
| Écran | Plan | Maquette |
|---|---|---|
| **Guide IA** — 🔨 **onglet Configuration livré le 2026-08-07** | [v2/guide-ia-screen-plan.md](../v2/guide-ia-screen-plan.md) | https://claude.ai/code/artifact/c43fe02d-3283-48c2-992f-d687e18acdfa |
| **Statistiques** — 🔨 **refonte livrée le 2026-08-07** | [v2/stats-screen-plan.md](../v2/stats-screen-plan.md) | https://claude.ai/code/artifact/052fe8f3-0288-4847-b63f-4c7de06068ec |
Tableau de chantiers global : https://claude.ai/code/artifact/4c317904-2e23-45d3-ac14-dcca678ae5d3
> 🔨 **Premier morceau livré le 2026-08-07** — migration `AddGuideIaConfigToInstance` (4 colonnes nullable, additive), champs sur `Instance`/`InstanceDTO`, client `manager_api_new` étendu à la main, écran `Screens/GuideIa/` avec 35 clés i18n FR/EN/NL. `dotnet build` et `flutter build web` passent.
>
> ✅ **`AssistantService` branché sur la configuration le 2026-08-07** — l'écran ne pilote plus dans le vide. C'est le lot 1 du **§1quater** ci-dessous, qui donne l'ordre d'exécution de tout le chantier Guide IA.
>
> 📄 **Repartir de zéro dans une conversation neuve** : ordre de lecture et amorce à copier dans [v2/guide-ia-screen-plan.md](../v2/guide-ia-screen-plan.md) § « Reprendre ce chantier dans une conversation neuve ».
>
> ~~Relevé en vérifiant : tout le system prompt est codé en dur, dans deux blocs…~~ **Corrigé le 2026-08-07.** Il y avait en fait **quatre** blocs de prompt et non deux ; les quatre lisent maintenant la configuration du client. Détail : [v2/guide-ia-screen-plan.md](../v2/guide-ia-screen-plan.md).
> 🔨 **Statistiques — refonte livrée le 2026-08-07, export PDF compris**, `Screens/Statistics/statistics_screen.dart` réécrit, **aucun changement backend**. Les 7 défauts sont corrigés : barres horizontales monochromes à la place des barres verticales tronquées et des deux anneaux, barre de filtres unique avec les volumes par canal, canaux filtrés sur ceux que l'instance possède réellement, règle mono-canal, 4 KPI portant chacun leur variation, bandeau « à retenir », courbe en aire avec bandes de week-end et survol, bloc rapport avec **bouton de téléchargement actif** (PDF généré côté client, paquet `pdf` Dart). ~55 clés i18n FR/EN/NL. `flutter analyze lib/Screens/Statistics` est propre ; `flutter test test/statistics_report_test.dart` 4/4.
>
> ⚠️ **Rien de tout ça n'a été ouvert dans un navigateur** — ni l'écran sur des données réelles, ni le PDF produit. **Cases de test : [test-plan.md §8bis](../test-plan.md) (écran, 9 cas) et [§8ter](../test-plan.md) (export PDF, 6 cas)**. Trois écarts assumés par rapport au plan (comparaison de période côté client, bandeau généré côté client, « visiteurs uniques » remplacé par « contenus consultés » car non calculable) : détail dans [v2/stats-screen-plan.md](../v2/stats-screen-plan.md) § État d'implémentation.
>
> **Précision sur `flutter analyze`** : le projet a **68 erreurs**, toutes dans les fichiers modèle orphelins de `manager_api_new` (+ `lib/api/openApiTest.dart`) — c'est la dette « client généré désynchronisé » déjà listée, pas une régression. `flutter build web` passe malgré elles : ces fichiers ne sont pas dans le graphe de compilation. Ne pas lire un `flutter analyze` global comme un feu vert, filtrer sur le dossier travaillé.
⚠️ Point de correction V1 : l'indexation doit respecter `IsActive`. Une section non publiée ne doit pas être indexée, et la désactiver doit purger ses embeddings — sinon le guide révèle du contenu que le client prépare.
### V2 — incréments
**Côté IA** : ingestion documentaire (PDF/Word/images + OCR Gemini), TTS pré-généré, talking head, génération de visites, guides multiples et guide thématique par section. Détail : [v2/rag-pgvector-integration-plan.md](../v2/rag-pgvector-integration-plan.md).
**Côté produit — reporté en V2 le 2026-08-07** (spécifié dans [todo-features.md](../todo-features.md), rien n'en dépend en V1) :
| Chantier | Pourquoi ça peut attendre |
|---|---|
| **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. ⚠️ **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.
---