DOCS/plan-import-ia-stats-subsides.md
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

206 lines
18 KiB
Markdown

# Plan — Import IA de contenu, Export PDF stats, Canal subsides
*Créé : juillet 2026. Mis à jour avec l'arbitrage des chantiers v2 (RAG, TTS, Ray-Ban).*
---
## Ordre recommandé
1. **Export PDF stats** (~1-2 semaines) — quick win, faible risque, argument commercial immédiat
2. **Import IA de contenu + pgvector** (~4-6 semaines) — chantier fusionné : le pipeline d'ingestion (save CMS → job Hangfire) est commun, le construire deux fois serait du gaspillage
3. **TTS pré-généré** — l'argument "audioguide multilingue automatique" (voir `v2/tts-pregenerated-plan.md`)
4. **Génération de visites à la demande** — RAG déjà en place à ce stade, coût marginal faible ; vendable aux villes/offices comme "balade sonore IA" sur smartphone
5. **Ray-Ban Meta** — uniquement comme pilote subventionné avec un client vitrine (Visit Namur), quand le SDK sort de preview. Projet phare / presse, pas une ligne produit
6. **Talking head** — polish, bouche-trou entre deux chantiers
En parallèle (pas de dev) : **canal subsides** — actions administratives et réseau.
La chaîne stratégique : **contenu importé par IA → indexé (RAG) → audio multilingue (TTS) → parcours générés**. Pitch cible : *"Envoyez vos brochures. Une heure plus tard : votre app, avec audioguide multilingue et guide IA."* Le rapport PDF ferme la boucle côté financeurs des lieux subventionnés.
---
## 1. Export PDF des stats (mensuel / annuel)
> **Mise à jour du 2026-08-07 — le périmètre a été coupé en deux.**
>
> **✅ Fait : le rapport à la demande.** Bouton « Télécharger le PDF » dans le bloc rapport de l'écran Statistiques, **généré côté client** avec le paquet `pdf` Dart (`manager-app/lib/Screens/Statistics/statistics_report.dart`). Aucun changement backend : l'écran a déjà tous les agrégats, `statsGetSummary` suffit. Couvert par `test/statistics_report_test.dart`.
>
> **⏳ Reste : l'envoi mensuel automatique**, seule partie qui exige vraiment le backend — personne n'a son navigateur ouvert le 1ᵉʳ à 6 h. C'est le périmètre des points 1, 2, 4, 5 ci-dessous, plus une méthode d'envoi avec pièce jointe. Le point 6 est fait.
>
> Détail des décisions : `v2/stats-screen-plan.md` § État d'implémentation.
### Existant réutilisable
- Données : `VisitEvent` (tous les événements trackés : sessions, sections, POI, QR, quiz, jeux, langues, mobile/kiosk)
- Agrégation : `StatsController.GetSummary` produit déjà tout le contenu du rapport (`StatsSummaryDTO` : sessions, durée moyenne, visites/jour, tops, distribution langues…)
- Hangfire opérationnel avec jobs récurrents (`agenda-sync-daily`, `weather-sync-*` dans `Startup.cs`) — pattern direct pour `stats-report-monthly`
- Gating abonnement : `Instance.HasStats` / `HasAdvancedStats` / `StatsHistoryDays`
### À créer
1. **Extraire l'agrégation** de `StatsController.GetSummary` vers un `StatsService` injectable (appelable hors HTTP par le job Hangfire) — *nécessaire seulement pour l'envoi automatique*
2. **Génération PDF côté serveur** : QuestPDF (licence Community gratuite sous 1M$ CA), en reprenant la maquette déjà rendue par la version client. ⚠️ **Piège Docker** : QuestPDF passe par SkiaSharp, qui sur Linux exige `libfontconfig1` **et une police installée**. Le Dockerfile actuel installe `libgdiplus libc6-dev` et rien d'autre — ça marchera en local sous Windows et lèvera une exception dans le conteneur
3. ~~**Service email** : `IEmailService` avec MailKit + SMTP (aucune infra email n'existe)~~**obsolète (2026-08-07)** : l'infra email **existe désormais**`IEmailService` + **Resend**, 9 templates transactionnels, domaine vérifié, envoi réel validé (livré avec l'onboarding self-service). ⚠️ mais **aucune de ses dix méthodes n'accepte de pièce jointe** : ce sont des templates figés `SendAsync(to, subject, html)`. Resend supporte les attachements (base64 dans le payload) — il faut ajouter la méthode et un template
4. **Config reporting** : champs sur `Instance` (ou table `ReportSetting`) — emails destinataires, fréquence (None / Monthly / Annual), activation. C'est la plus grosse pièce d'UI du chantier restant
5. **Jobs Hangfire** : `stats-report-monthly` (cron `0 6 1 * *`) + `stats-report-annual` (début janvier), pattern `IServiceScopeFactory` comme `NotificationService`
6.**À la demande****fait autrement** : pas d'endpoint, le PDF est construit dans le navigateur à partir des agrégats déjà chargés par l'écran. Bouton actif dans le bloc rapport
### Positionnement commercial
- Pro : rapport mensuel basique. Premium : rapport complet + annuel + envoi automatique multi-destinataires
- Pitch : *"Chaque mois, recevez le rapport PDF prêt à transmettre à votre commune, votre CA ou vos subsidiants."* — feature de rétention autant que de vente
> ✅ **Pricing tranché le 2026-08-09 — l'axe « durée » disparaît, 13 mois pour tous.**
>
> Le rapport a une vocation de dossier de subside, donc annuelle : plafonné à 30 jours il n'était envoyable à personne. Trois constats ont tranché : la landing **ne promettait aucune durée** (`statsBasic: "30 jours"` existe dans `translations.ts` mais n'est affiché nulle part — les cartes vendent la *profondeur*) ; les `VisitEvent` **n'étaient jamais purgés**, donc on stockait déjà l'historique tout en refusant de le lire ; et `HasAdvancedStats` était déjà le vrai différenciateur.
>
> - `StatsHistoryDays = 395` (13 mois) sur tous les plans — rapport annuel possible, et comparaison avec le même mois de l'an dernier
> - `HasAdvancedStats` reste le seul différenciateur stats
> - **L'export PDF est inclus dès qu'il y a les stats** : aucun champ, aucune migration. Le contenu se différencie tout seul — les tableaux POI/quiz/jeux/QR n'apparaissent que si `HasAdvancedStats`
> - Migration `UnifyStatsRetentionTo13Months` : met à jour les plans **et reprend les instances existantes en SQL** (c'est `Instance.StatsHistoryDays` que lit le contrôleur, pas celui du plan)
> - Purge `visit-events-purge` codée mais **inactive** tant que `Stats:RetentionDays` n'est pas défini — à n'activer qu'une fois le `pg_dump` quotidien en place
>
> **Reste technique** : `GetSummary` matérialise tous les événements en mémoire (`eventsQuery.ToList()`, `StatsController.cs:116`) avant d'agréger. Tenable au volume actuel, plus du tout sur 13 mois d'une grosse instance — l'agrégation doit passer en SQL avant de vendre le rapport annuel à un gros site.
>
> **Relevé au passage — le seed des plans ne correspond plus à la landing** : `MyInfoMateDbContext` sème `plan-starter`, `plan-standard`, `plan-premium` et `plan-essentiel`. **Il n'y a pas de `plan-pro`**, alors que Pro à 99 € est le plan mis en avant (« recommandé ») sur la landing. Seul Essentiel est câblé à l'onboarding et à Stripe (`OnboardingController.EssentielPlanId`, `StripeSettings.EssentielPriceId`) — Pro et Premium sont vendus « contactez-nous », donc provisionnés à la main, aujourd'hui forcément sur une ligne au mauvais nom. À nettoyer avec la migration v3, pas au moment de facturer le premier client Pro.
---
## 2. Import IA de contenu + pgvector (chantier fusionné)
> Fusion de l'import IA avec le delta #1 de `v2/rag-pgvector-integration-plan.md` : les deux ont besoin du même pipeline d'ingestion de contenu. À construire ensemble.
### Existant réutilisable
- `IChatClient` Gemini (`gemini-2.5-flash-lite`, endpoint OpenAI-compat) avec function calling, configuré dans `Startup.cs`
- Pattern service + endpoint + quota : `AssistantService` / `AiController` / `Instance.AiTokensPerMonth` (le quota est passé des **requêtes aux tokens**, migration `AiQuotaTokensInsteadOfRequests`)
- **`SectionFactory.Create`** : point d'entrée unique JSON → entités `Section` typées — le cœur du "brouillon → entité"
- Modèles cibles complets : tous les `Section*`, `GeoPoint` (POI), `QuizQuestion`, `GuidedPath`
- Front : les `*_config.dart` par type de section servent d'écrans d'édition des brouillons
### À créer
1. **Ingestion source** :
- PDF texte : extraction via PdfPig (ou UglyToad) côté backend
- URL : fetch + nettoyage HTML (extraction du contenu principal)
- V2 : PDF scannés/images via l'API Gemini native multimodale (l'endpoint OpenAI-compat actuel est texte seulement)
2. **État brouillon** : `Section.Status` (Draft / Published) + flag `GeneratedByAi``IsActive` seul ne suffit pas. Filtrer les endpoints consommés par les apps visiteurs
3. **`IContentImportService`** : prompt structuré → JSON contraint (liste de sections + POIs + quiz proposés) → `SectionFactory.Create` en Draft. Exécution en job Hangfire (`BackgroundJob.Enqueue`) avec table `ImportJob` pour le suivi (statut, erreurs, entités créées)
4. **`POST /api/Ai/import`** : multipart PDF ou URL + `configurationId` + langues cibles. Gate abonnement + décompte quota IA (mécanisme `AiRequestsThisMonth` existant, éventuellement quota séparé pour l'import)
5. **UI manager-app** : écran "Import IA" — upload/URL, progression du job, liste des brouillons générés avec badge "généré par IA", édition via les écrans existants, action Publier / Supprimer
### Volet pgvector (même chantier)
Suivre `v2/rag-pgvector-integration-plan.md`, en l'intégrant au pipeline ci-dessus :
> ⚠️ **Mis à jour le 2026-08-07** — `v2/rag-pgvector-integration-plan.md` fait autorité sur ce volet et a évolué : modèle **1 contenu = N chunks** (`ChunkIndex`/`PageNumber`/`Language`), stratégie delete-then-insert, piège du post-filtrage HNSW, et **le schéma part avec la migration Postgres v3** (voir `STATUS.md §1ter`). Le modèle d'embedding exact reste à confirmer avant de figer la dimension.
- Migration EF Core : extension `vector`, entité `ContentEmbedding` (768 dims), index HNSW — grouper avec la colonne persona/config prévue au delta #2
- `IEmbeddingService` (embedding Google, même clé API que Gemini) + `IVectorStoreService` (EF Core + `CosineDistance`)
- **Un seul point d'orchestration** : `IContentPipelineService.OnContentSavedAsync` déclenché après chaque `SaveChanges()` de section/POI — enqueue embedding (et plus tard TTS). Les sections créées par l'import IA passent par le même chemin : le contenu importé est indexé dès sa création
- `GetEmbeddableText()` par type de section (titre + description + champs pertinents)
- Endpoint `/ask` RAG : peut venir juste après, il upgrade l'assistant existant (`AssistantService`) en remplaçant/complétant le function calling par du retrieval
### Phasage
| Version | Contenu |
|---|---|
| V1 | PDF texte + URL → SectionArticle (multilingue), SectionMenu, propositions de Quiz + ingestion pgvector systématique |
| V2 | POIs carte (adresses détectées → géocodage), parcours guidés, PDF scannés (multimodal), endpoint `/ask` RAG |
| V3 | Extraction des images du PDF → upload auto en `Resource` |
### Positionnement commercial
- Pitch : *"Envoyez vos brochures, l'IA construit votre app. Vous relisez, vous publiez."*
- Démo de vente : importer en live la brochure du prospect pendant le rendez-vous — l'app remplie avec SON contenu en 5 minutes
- Aucun concurrent (Smartify, STQRY, SmartGuide…) ne propose ça
---
## 3. Suite v2 — arbitrage (juillet 2026)
Analyse des chantiers `v2/` : le levier réel est la chaîne **RAG → TTS → parcours générés**, pas le hardware.
### TTS pré-généré — priorité haute après l'import IA
- Se vend comme **"audioguide multilingue automatique"** — le produit que les musées achètent depuis toujours (cœur de métier de SmartGuide, izi.TRAVEL), à coût marginal quasi nul. Aucun concurrent de cette gamme de prix ne le fait
- Plan technique déjà écrit : `v2/tts-pregenerated-plan.md` (Google Cloud TTS + Firebase Storage, trigger via le même `IContentPipelineService` que l'embedding)
- Inclut le refactor "uploads Firebase centralisés backend" — à faire à ce moment-là
### Génération de visites à la demande — priorité haute, aucun hardware requis
- "Parcours 45 min pour familles", "uniquement le 17e siècle" : prompt structuré + RAG sur le contenu du venue
- Fonctionne sur le smartphone du visiteur avec ses écouteurs, **aujourd'hui** — zones GPS + parcours + TTS existants
- Produit dérivé vendable aux villes et offices de tourisme : **"balade sonore IA"**
### Ray-Ban Meta — pilote subventionné uniquement, pas une ligne produit
- Contre (à date) : SDK en developer preview (distribution publique limitée), parc installé marginal chez les visiteurs wallons, modèle "kit de prêt" opérationnellement trop lourd pour des clients à 99 €/mois
- 90% de l'expérience "visite de ville IA" est livrable en audio-only smartphone — la caméra n'ajoute que le "qu'est-ce que je regarde ?"
- Pour : valeur presse/démo réelle ("première visite guidée par lunettes IA en Wallonie") et profil parfait pour un **appel à projets innovation** (Digital Wallonia, FWB, Interreg) — donc financé par un subside, avec Visit Namur comme client vitrine, quand le SDK sortira de preview
### Talking head & personas vocaux — polish, pas un levier
- Talking head (`v2/talking-head-plan.md`) : quelques jours d'effort, effet démo borne/enfants — bouche-trou entre deux chantiers
- Personas vocaux avec wakewords (Viva/Marco) : pertinents uniquement sur lunettes — suivent le calendrier Ray-Ban
---
## 4. Canal subsides & réseaux — actions concrètes
### Constat clé (recherche juillet 2026)
**Les ASBL sont exclues des chèques-entreprises** (sauf exceptions marginales). Or la majorité des musées/lieux culturels sont des ASBL ou des structures publiques. Le levier principal n'est donc PAS les chèques-entreprises mais les subsides CGT et FWB.
### 4a. CGT — subventions attractions touristiques (levier principal)
- Attractions **certifiées ou en cours de certification** : subvention **40%** (majorable +10% accessibilité/bilinguisme), et **60% pour ASBL et pouvoirs subordonnés** (si 2 ans d'activité au-delà du territoire communal)
- Subvention minimum 1 500 € (mobilier/équipement), plafond de minimis 300 000 € / 3 ans, une demande max tous les 3 ans
- Demandes via « Mon espace » de Tourisme Wallonie
- **Action 1 : appeler le CGT pour confirmer que le numérique (app, kiosk, abonnement SaaS, tablettes) est éligible au titre de l'article R.IV.56 du Code wallon du Tourisme.** Si oui → argumentaire "votre solution digitale subsidiée à 60%" + accompagnement du client dans sa demande (facturable en service à 55 €/h)
- **Action 2 : cibler les attractions déjà certifiées** (liste publique CGT) — elles peuvent introduire une demande immédiatement
- Timing offices de tourisme : le nouveau Code wallon du Tourisme impose une **demande de certification avant le 1er juillet 2026** pour pouvoir demander des subsides — les organismes en cours de re-certification revoient leurs outils : moment idéal pour prospecter
### 4b. Chèques-entreprises (levier secondaire — clients privés uniquement)
- Pertinent pour : hôtels, parcs privés, attractions commerciales (SRL/SA), organisateurs d'événements privés
- Chèque "maturité numérique" : 50% des honoraires HTVA, jusqu'à 50 000 € / 3 ans par bénéficiaire ; réforme 2026 en cours (plateforme unifiée, labellisation renforcée)
- **Action 3 : demander la labellisation prestataire** (gratuite, dossier expertise + viabilité économique via cheques-entreprises.be) — crédibilité + accès au segment privé. Attention : couvre le conseil/l'accompagnement, pas les licences logicielles — packager l'onboarding/formation/création de contenu comme prestation subsidiable
### 4c. MSW — Musées et Société en Wallonie
- Fédération des musées wallons : formations, journées d'étude, journée inter-réseaux
- **Ils invitent explicitement les prestataires à se faire connaître** (formulaire sur msw.be/formations)
- **Action 4 : se signaler à MSW comme prestataire** (démo MyInfoMate, proposition d'atelier "digitaliser son musée sans budget ni compétences techniques")
- **Action 5 : formation MSW "législation IA dans les musées" le 24/09/2026** — y assister (réseau) et proposer une intervention/démo sur l'IA appliquée (assistant visiteur + import de contenu = cas concrets parfaits)
### 4d. FWB — patrimoine culturel
- Appels à projets réguliers : patrimoineculturel.cfwb.be/nos-appels-a-projets + culture.be (appels à projet/candidature)
- **Action 6 : mettre en place une veille mensuelle** sur ces deux pages — quand un appel "numérique/médiation" sort, prévenir ses clients et prospects avec une offre packagée prête à déposer
### Récap actions (par priorité)
| # | Action | Quand |
|---|---|---|
| 1 | Appel CGT : éligibilité du numérique aux subventions attractions | Immédiat |
| 4 | Se signaler à MSW comme prestataire | Immédiat |
| 5 | S'inscrire à la formation MSW IA du 24/09/2026 | Immédiat |
| 3 | Dossier labellisation chèques-entreprises | Ce trimestre |
| 2 | Prospection ciblée attractions certifiées CGT | Dès confirmation action 1 |
| 6 | Veille appels à projets FWB | Récurrent |
### Sources
- [Chèque maturité numérique — Wallonie.be](https://www.wallonie.be/en/demarches/receive-help-expert-digitalise-my-companys-internal-processes-digital-maturity-voucher)
- [Chèques-entreprises 2026 et projets IA — ia-pme.be](https://ia-pme.be/articles/cheques-entreprises-financer-projet-ia-2026)
- [Maturité numérique — cheques-entreprises.be](https://www.cheques-entreprises.be/cheques/maturite-numerique/)
- [Devenir prestataire labellisé — SPW Économie](https://economie.wallonie.be/en/home/gerer-mon-entreprise/me-developper/obtenir-un-agrement-ou-une-labellisation/devenir-prestataire-labellise-cheques-entreprises.html)
- [S'informer sur les chèques-entreprises — Wallonie.be](https://www.wallonie.be/en/demarches/find-out-about-business-vouchers)
- [Subventions attractions touristiques — Tourisme Wallonie](https://www.tourismewallonie.be/attractions/)
- [Nouveau Code wallon du Tourisme — Tourisme Wallonie](https://www.tourismewallonie.be/nouveau-code-wallon-du-tourisme-premieres-informations/)
- [Subventions des organismes touristiques — Tourisme Wallonie](https://organismes.tourismewallonie.be/subventions-des-organismes-touristiques/)
- [MSW — formations](https://msw.be/formations/)
- [MSW — numérique](https://msw.be/category/numerique/)
- [Appels à projets patrimoine culturel — FWB](https://patrimoineculturel.cfwb.be/nos-appels-a-projets/)
- [Appels à projet/candidature — culture.be](https://www.culture.be/vous-cherchez/appels-a-projetcandidature/)