# 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/)