QR / nom d'app / proximité : STATUS, plan de test §23, kanban régénéré
Le §23 couvre les réglages du manager, les trois formats de QR (id brut du Fort, URL MDLF, nouvelle URL /download), la page de téléchargement et les notifications de proximité. §9 mis à jour : au premier plan c'est la popup, la notification n'arrive qu'écran verrouillé, et meterZoneGPS sert aux zones GPS, pas aux beacons. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
30c2f6c3e2
commit
2944fb5a05
@ -14,6 +14,7 @@ Résumé de la table de suivi de ce fichier :
|
||||
- **Fait** : SectionEvent, Escape/Puzzle games, GuidedPath + progression carte, push, stats tracking, sync agenda/météo, traduction IA, quotas (IA/stockage/stats) par plan, audit log backend fiabilisé, refacto SectionParcours/GuidedPath/SectionGame (backend, vérifié 2026-07-15).
|
||||
- **Partiel** : Beacons/geofencing (manager-app UI ⚠️), AI Assistant (manager-app ⚠️), ~~**mode offline**~~ ✅ **corrigé le 2026-08-11 (D1) puis complété le 13/08 (D5)** — le pipeline de collecte n'est plus commenté, une visite embarque désormais contenus, audios et icônes, et une visite incomplète ne s'annonce plus téléchargée. **Reste à confirmer sur device** (§21 / D0), c'est le seul point encore ouvert du volet offline. Repasse UI globale, refacto SectionParcours côté manager-app/visitapp-web/mymuseum-visitapp (UI présente mais sous-comportements non revérifiés en détail — voir section "Refactoring majeur" de todo-features.md).
|
||||
- **🧪 Implémenté mais jamais testé (2026-08-05)** : **onboarding self-service complet** — inscription sur myinfomate-landing (`/[lang]/signup`), création auto de l'instance + du premier user, essai 14j, Stripe (customer/Checkout/webhook/Tax), 9 emails Resend (domaine vérifié, envoi réel validé), job Hangfire du cycle d'essai, watermark « Aperçu » visitapp-web, écran Abonnement manager-app, mot de passe oublié + invitation user, plafond IA d'essai. Les 4 repos compilent, migrations appliquées en base locale, **aucun parcours exécuté** → checklist de test dans `todo-features.md` (section "🧪 Checklist de test end-to-end"). Reste à faire côté config : alias mail `onboarding@myinfomate.be`, et `whsec_` de la Stripe CLI pour tester le webhook en local.
|
||||
- **🧪 Codé et committé le 2026-09-10 (rien de poussé), pas encore testé** : scan d'id brut (QR du Fort) depuis l'accueil, drapeau « afficher le scan QR » et **nom de l'application** par app (Mobile/Web), liens stores (SuperAdmin), QR du manager vers la nouvelle page **`app.myinfomate.be/download/…`**, suggestions de proximité beacon + GPS avec **notification écran verrouillé** (mobile) et suggestion GPS dans la page (web). Tests : [test-plan.md §23](test-plan.md) ; restes hors code (redirection `web.mymuseum.be`, déclarations stores) : carte kanban « QR codes, nom d'application… ».
|
||||
- **À faire** : dashboard super-admin V2, facturation V2. ✅ **Le Stripe Customer Portal est complet le 2026-08-13** (backend + bouton manager-app).
|
||||
- ⚠️ **Cette ligne était périmée sur six points, revérifiés dans le code le 2026-08-13.** Sont **faits** : écran audit log manager-app (front livré le 12/08), **rate limiting API Keys** (livré, pas seulement décidé — politique `ai` dans `Startup.cs:279`, `UseRateLimiter()` en `:344`, les deux endpoints décorés), gestion des users par instance (plafond serveur + compteur UI, 12/08), nettoyage `SectionEvent.ParcoursIds` (11/08), et le **backend** du Customer Portal (13/08). L'**unification `QuestionType`** n'est pas « à faire » mais **écartée** : le trio TextLibre/Digicode/ExpectedAnswer n'a jamais existé dans le code, l'enum a trois valeurs et le digicode est un comportement dérivé, pas un type — reste une propreté front, elle aussi livrée (alias nommés, 11/08).
|
||||
- **📦 Reporté en V2 (décidé le 2026-08-07)** : **SectionForm**, **ressource 360°**, **AR image tracking (Mind AR)**. Les trois sont spécifiés en détail dans [todo-features.md](todo-features.md) mais sortent du périmètre V1 — aucun n'est un prérequis de la migration Postgres ni de la mise en prod. À reprendre tels quels quand la V1 sera stabilisée.
|
||||
|
||||
58
kanban.html
58
kanban.html
@ -461,10 +461,10 @@
|
||||
<div class="stat"><span class="n n-critical">2</span><span class="k">Urgent</span></div>
|
||||
<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">11</span><span class="k">À tester</span></div>
|
||||
<div class="stat"><span class="n">36</span><span class="k">Planifié</span></div>
|
||||
<div class="stat"><span class="n">12</span><span class="k">À tester</span></div>
|
||||
<div class="stat"><span class="n">38</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">62</span><span class="k">Fait récemment</span></div>
|
||||
<div class="stat"><span class="n n-good">63</span><span class="k">Fait récemment</span></div>
|
||||
</section>
|
||||
|
||||
<div class="filters" role="group" aria-label="Filtrer par domaine">
|
||||
@ -560,7 +560,7 @@
|
||||
|
||||
<!-- À TESTER -->
|
||||
<section class="col" style="--stripe: var(--brand)">
|
||||
<div class="col-head"><h2>À tester</h2><span class="count">11</span></div>
|
||||
<div class="col-head"><h2>À tester</h2><span class="count">12</span></div>
|
||||
<div class="stack">
|
||||
|
||||
<article class="card" data-area="visitapp">
|
||||
@ -660,12 +660,33 @@
|
||||
<span class="src">conversation du 2026-09-08 — captures du Fort de Saint-Héribert</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="visitapp" data-horizon="v1">
|
||||
<div class="card-meta"><span class="tag">§23</span><span class="tag">manager-service</span><span class="tag">manager-app</span><span class="tag">visitapp-web</span><span class="tag">mymuseum-visitapp</span><span class="flag f-warn">Codé 10/09 · device requis · redirection serveur à faire</span></div>
|
||||
<h3>QR codes, nom d'application, page <code>/download</code> et notifications de proximité</h3>
|
||||
<p><strong>Codé</strong> dans les quatre repos, rien n'est committé :</p>
|
||||
<ul>
|
||||
<li><strong>ApplicationInstance</strong> (par app, Mobile ≠ Web) : <code>IsQRCodeEnabled</code> (défaut <code>true</code>), <code>AppName</code> (traductions), <code>AppStoreUrl</code>/<code>PlayStoreUrl</code> (modifiables par un SuperAdmin seulement, contrôlé côté API). Migration <code>AddAppNameQrAndStoresToApplicationInstance</code>.</li>
|
||||
<li><strong>Scan mobile</strong> : id brut (QR du Fort) résolu via la section puis sa visite, y compris depuis l'accueil ; les URL <code>web.mymuseum.be</code> (MDLF) restent lues ; nouvelle URL <code>app.myinfomate.be/download/…</code>. QR d'une autre instance refusé.</li>
|
||||
<li><strong>QR du manager</strong> : <code>app.myinfomate.be/download/{instance}/{config}/{section}</code> — ou la section web directement pour une instance web seule.</li>
|
||||
<li><strong>visitapp-web</strong> : page <code>/download</code> (nom, image principale, liens stores), bouton de scan conditionné, nom de l'app sur l'accueil et dans l'onglet, suggestion de proximité GPS dans la page. Slugs <code>download</code>/<code>demo</code>/<code>api</code> réservés.</li>
|
||||
<li><strong>Proximité mobile</strong> : beacon + zones GPS (<code>meterZoneGPS</code>). App ouverte → popup ; écran verrouillé pendant une visite → notification, dont le tap ouvre la section. Android : service de premier plan <code>location</code> ; iOS : mode d'arrière-plan <code>location</code>. App tuée : rien, par choix.</li>
|
||||
</ul>
|
||||
<p>⚠️ <strong>Reste à faire hors code</strong> :</p>
|
||||
<ul>
|
||||
<li><strong>Redirection 301</strong> <code>web.mymuseum.be/{i}/{c}/{s}</code> → <code>app.myinfomate.be/download/{i}/{c}/{s}</code>, pour les QR MDLF scannés à l'appareil photo. Le domaine n'est routé dans aucun compose des repos : à poser là où il est servi.</li>
|
||||
<li><code>app.myinfomate.be</code> n'est pas encore déployé (carte 210) : les QR générés par le manager y mènent, les deux partent en prod ensemble.</li>
|
||||
<li>Stores : déclarer le service de premier plan de type <em>location</em> dans la Play Console ; justifier le mode <code>location</code> à la revue Apple.</li>
|
||||
</ul>
|
||||
<p>Bug corrigé au passage : la popup beacon (<code>BeaconArticleFound</code>) lisait les maps JSON brutes de <code>currentSections</code> comme des <code>SectionDTO</code> et plantait.</p>
|
||||
<span class="src">test-plan.md §23</span>
|
||||
</article>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- PLANIFIÉ -->
|
||||
<section class="col" style="--stripe: var(--ink-3)">
|
||||
<div class="col-head"><h2>Planifié</h2><span class="count">36</span></div>
|
||||
<div class="col-head"><h2>Planifié</h2><span class="count">38</span></div>
|
||||
<div class="stack">
|
||||
|
||||
<article class="card" data-area="visitapp" data-horizon="v1">
|
||||
@ -846,14 +867,25 @@
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="doc" data-horizon="v1">
|
||||
<div class="card-meta"><span class="tag">myinfomate-landing</span><span class="flag f-warn">Nouveau 28/08 · priorité 1</span></div>
|
||||
<div class="card-meta"><span class="tag">myinfomate-landing</span><span class="flag f-warn">10/09 : Thomas ne veut pas afficher de montant</span></div>
|
||||
<h3>Chiffrer les frais de mise en place sur la page tarifs</h3>
|
||||
<p><strong>Le défaut est de confiance, pas de design.</strong> La carte Pro annonce <code>€99/mois</code> et, juste dessous, <code>setupFeeNote</code> = « Frais de mise en place + engagement 12 mois (app mobile) » — <strong>sans aucun chiffre</strong> (<code>translations.ts:272</code>, repris tel quel en EN/NL/DE). L'acheteur budgète 1 200 €/an, puis découvre le setup en rendez-vous : c'est le pire moment pour l'apprendre. Remède : « <strong>à partir de X € selon le volume de contenu</strong> », dans les 4 langues. <strong>Priorité n°1 de la passe.</strong></p>
|
||||
<p><strong>⚖️ Arbitré le 10/09 : pas de montant affiché.</strong> Thomas ne veut pas publier de plancher. Mesure de repli appliquée le même jour, dans les 4 langues : <code>setupFeeNote</code> devient « <strong>Frais de mise en place uniques, chiffrés dans le devis</strong> + engagement 12 mois », et la FAQ de la nouvelle page <code>/tarifs</code> précise ce que couvrent ces frais (configuration et publication sur les stores) et qu'ils sont chiffrés <strong>avant signature</strong>. L'acheteur sait donc qu'une ligne s'ajoute, et quand il en connaîtra le montant. <strong>Ce qui reste ouvert</strong> : si un plancher est un jour décidé, c'est cette carte qui le porte.</p>
|
||||
<p><strong>Secondaire, même passe</strong> : badge « <strong>IA incluse</strong> » sur Premium — le badge « Recommandé » <em>reste</em> sur Pro (<code>HomeClient.tsx:525</code>), il ne se déplace pas ; regrouper assistant IA + traduction automatique + audio sous un intitulé unique type « <strong>Studio IA</strong> » plutôt que trois lignes de features indistinctes ; remplacer <strong>le stockage en GB</strong> (1 / 15 / 50 GB, en dur dans <code>HomeClient.tsx</code> et <code>SegmentPageClient.tsx</code>) par une métrique que l'acheteur sait évaluer : <strong>POI / parcours / langues / sites</strong>. Personne ne sait ce que pèsent ses contenus en gigaoctets.</p>
|
||||
<p>⚠️ <strong>Le « Bientôt disponible » sur Essentiel n'existe pas dans le code</strong> — vérifié le 28/08 : le seul badge « Bientôt » de la landing est sur le 4<sup>e</sup> mode de déploiement (XR, <code>HomeClient.tsx:154</code>), et la carte Essentiel pointe déjà vers <code>/signup</code>. Ce qui bloque réellement Essentiel est le <strong>déploiement de <code>app.myinfomate.be</code></strong> (carte dédiée dans ce tableau). L'arbitrage est donc : déployer, ou <em>ajouter</em> un badge honnête en attendant — pas retirer un badge absent.</p>
|
||||
<span class="src">myinfomate-landing/src/data/translations.ts · HomeClient.tsx §pricing · todo-features.md — Site vitrine</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="commercial" data-horizon="v1">
|
||||
<div class="card-meta"><span class="tag">myinfomate-landing</span><span class="tag">seo</span><span class="tag">linkedin</span><span class="flag f-good">Démarré 10/09 · actions 1-9 faites</span></div>
|
||||
<h3>Plan SEO/GEO de la landing et lancement LinkedIn</h3>
|
||||
<p><strong>Audit du 09/09 : 21 actions classées par rapport impact/effort.</strong> Faites le 10/09 et vérifiées dans le HTML servi : titres <code>h2</code>/<code>h3</code>, schema <code>Organization</code> ancré en Belgique avec la TVA, trois offres dans le schema, les 9 modules de la home enfin dans le HTML, liens morts, <code>llms.txt</code> en français, <strong>prérendu statique rétabli</strong> (58 pages, le layout racine est passé dans <code>[lang]</code>) et une page <strong><code>/tarifs</code></strong> avec FAQ tarifaire. <strong>Stagé, pas committé.</strong></p>
|
||||
<p><strong><code>/assistant-ia</code> est écrite le 10/09, en français seulement</strong> (~850 mots, 6 FAQ, schema <code>FAQPage</code>) : en attente de relecture, puis traduction NL/EN/DE. Les autres langues répondent 404, c'est volontaire.</p>
|
||||
<p><strong>Suite</strong> : vocabulaire acheteur dans les 6 segments, puis page marchés publics — <strong>preuve à mettre en avant, confirmée le 10/09 : Visit Namur a été gagné sur cahier des charges publié</strong>, mais ⚠️ aucun document d'appel d'offres n'existe encore, donc ne rien promettre. Les frais de mise en place restent <strong>sans montant, par décision de Thomas</strong> (carte 180).</p>
|
||||
<p><strong>LinkedIn</strong> : vitrine MyInfoMate créée sous Unov, fiche produit soumise. Huit posts rédigés en deux vagues : ⚠️ ceux qui poussent à l'inscription attendent la bascule prod.</p>
|
||||
<span class="src">myinfomate-landing/audit-seo-geo.md §0 · DOCS/linkedin-posts-lancement.md</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="backend visitapp" data-horizon="v2">
|
||||
<div class="card-meta"><span class="tag">priorité 4</span><span class="flag f-warn">V2</span></div>
|
||||
<h3>Génération de visites à la demande</h3>
|
||||
@ -861,6 +893,15 @@
|
||||
<span class="src">plan-import-ia-stats-subsides.md §3</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="doc" data-horizon="v1">
|
||||
<div class="card-meta"><span class="tag">juridique</span><span class="tag">myinfomate-landing</span><span class="flag f-warn">CGU publiées le 10/09 sans relecture juridique</span></div>
|
||||
<h3>Faire valider les CGU par un juriste belge</h3>
|
||||
<p><strong>Les CGU sont en ligne depuis le 10/09</strong> — publier valait mieux que faire cocher « j'accepte » sur un lien mort — mais elles n'ont <strong>jamais été relues par un juriste</strong>, ce que le document source dit lui-même depuis avril. Deux points appellent un œil professionnel : le <strong>§8 (RGPD)</strong>, réécrit le 11/08 quand le guide IA s'est mis à enregistrer les questions des visiteurs, et le <strong>§9 (SLA à 99 %)</strong>, qui est un engagement chiffré tenu par une infrastructure mono-serveur.</p>
|
||||
<p><strong>Deux sources à garder synchrones</strong> : <code>DOCS/cgu-myinfomate.md</code> fait foi, la page Next en est le rendu. Toute correction du juriste passe par les deux.</p>
|
||||
<p>⏱️ <strong>À faire avant d'ouvrir l'inscription self-service à de vrais clients payants</strong>, pas avant la mise en prod technique. Prévoir aussi le <strong>contrat de traitement des données (DPA)</strong> qu'un acheteur public demandera — il n'existe pas encore.</p>
|
||||
<span class="src">DOCS/cgu-myinfomate.md (note d'en-tête) · myinfomate-landing/src/app/(legal)/conditions-generales/page.tsx</span>
|
||||
</article>
|
||||
|
||||
<article class="card" data-area="manager backend" data-horizon="v2">
|
||||
<div class="card-meta"><span class="tag">guide IA</span><span class="flag f-warn">V2</span></div>
|
||||
<h3>Guides multiples & guide thématique</h3>
|
||||
@ -1456,6 +1497,11 @@
|
||||
<span>Les CGU décrivaient des plans abandonnés (Starter/Standard/Premium 69/99/199 €). Alignées sur la landing, avec un quota IA défini en tokens renvoyant au back-office plutôt qu'un chiffre figé dans un contrat. Landing : « req/mois » → « questions de visiteurs / mois » en 4 langues.</span>
|
||||
</div>
|
||||
|
||||
<div class="done-item">
|
||||
<strong>Le lien « conditions générales » de l'inscription ne mène nulle part</strong>
|
||||
<p>Relevé et corrigé le 10/09. Les CGU sont désormais publiées sur <code>myinfomate.be/conditions-generales</code> (groupe <code>(legal)</code>, page statique), la case de consentement de <code>/signup</code> pointe dessus, et le lien figure aussi dans les pieds de page des 4 langues et dans le sitemap. Deux contradictions du document source ont été corrigées au passage : le §6.1 citait les plans abandonnés (Starter 2 Go / Standard 10 Go) et le §7.1 réservait l'assistant IA aux « plans Standard et Premium ». ⚠️ La <strong>validation juridique</strong> reste due — carte dédiée.</p>
|
||||
</div>
|
||||
|
||||
<div class="done-item">
|
||||
<strong>Écran Guide IA — onglet Configuration livré</strong>
|
||||
<span>Migration additive (4 colonnes nullable), champs sur <code>Instance</code>, client généré étendu à la main, écran avec 35 clés i18n FR/EN/NL. <code>dotnet build</code> et <code>flutter build web</code> passent. Menu conditionné à <code>isAssistant</code>, le même drapeau que la garde d'<code>AiController</code>.</span>
|
||||
|
||||
65
test-plan.md
65
test-plan.md
@ -50,6 +50,7 @@ tests fonctionnels ci-dessous.
|
||||
19. [**Parité manager-app → apps visiteur (par type de section)**](#19-parité-manager-app--apps-visiteur-par-type-de-section)
|
||||
20. [Écarts de parité connus — à rejouer après correction](#20-écarts-de-parité-connus--à-rejouer-après-correction)
|
||||
21. [Visite hors ligne — diagnostic terrain](#21-visite-hors-ligne--diagnostic-terrain) ⚠️ **bugs suspectés, à jouer tôt**
|
||||
23. [QR codes, nom d'application, page de téléchargement, proximité](#23-qr-codes-nom-dapplication-page-de-téléchargement-proximité)
|
||||
|
||||
---
|
||||
|
||||
@ -274,14 +275,14 @@ Voir [v2/stats-screen-plan.md](v2/stats-screen-plan.md) § État d'implémentati
|
||||
|
||||
| # | Action | Résultat attendu | ✓ |
|
||||
|---|--------|-----------------|---|
|
||||
| 9.1 | Visitapp en range d'un iBeacon connu | Notification locale `beaconFound` affichée | |
|
||||
| 9.1 | Visitapp en range d'un iBeacon connu | App au premier plan : popup de suggestion, **sans** notification. App en arrière-plan / écran verrouillé : notification locale `beaconFound` (cf. §23) | |
|
||||
| 9.2 | Notification beacon | Titre/corps dans la langue active (clé `beaconFound` / `beaconFoundBody`) | |
|
||||
| 9.3 | Entrée dans une zone geo d'un `GuidedStep` | Notification locale `geoZone` affichée | |
|
||||
| 9.4 | Filtre par `minorId` + `accuracy` + cooldown | Pas de spam de notifications pour le même beacon | |
|
||||
| 9.5 | `beacon_scanner: ^0.0.4` | Scanner opérationnel sur Android et iOS | |
|
||||
| 9.6 | **iOS** — balise émettant un `proximityUUID` **autre** que `FDA50693-A4E2-4FB1-AFCF-C6EB07647825` | Le cas doit **échouer** : la région iOS est filtrée sur cet UUID en dur (`geo_beacon_trigger_service.dart:148-155`). Si ça déclenche quand même, le code ne fait pas ce qu'il dit — Android, lui, scanne sans filtre | |
|
||||
| 9.7 | Déclenchement **proactif de l'assistant** par balise (chemin distinct de 9.1) | Le prompt part depuis `geo_beacon_trigger_service._onBeaconResult`, uniquement si le mode proactif est actif | |
|
||||
| 9.8 | Distance réelle de déclenchement, mètre en main | ⚠️ `configuration_page.dart:43` = `meterToBeacon = 100` alors que le commentaire dit 15 m, et `Section.meterZoneGPS` est ignoré. Noter la distance **mesurée**, pas celle attendue | |
|
||||
| 9.8 | Distance réelle de déclenchement, mètre en main | ⚠️ `proximity_suggestion_service.dart` = `beaconMaxDistanceMeters = 100` (accuracy du ranging). `Section.meterZoneGPS` sert désormais aux zones **GPS**, pas aux beacons. Noter la distance **mesurée**, pas celle attendue | |
|
||||
| 9.9 | Stationner 2 min devant un POI | Une seule notification (cooldown), pas de répétition | |
|
||||
| 9.10 | Balise avec `major` porteur d'un niveau de batterie | Aucun effet sur l'identification du POI — l'app ne lit que le `minorId`. C'est ce qui rend le `major` utilisable pour la télémétrie | |
|
||||
|
||||
@ -918,6 +919,66 @@ Les comptages ne disent rien des traductions, des médias liés ni de l'ordre. *
|
||||
|
||||
---
|
||||
|
||||
## 23. QR codes, nom d'application, page de téléchargement, proximité
|
||||
|
||||
Prérequis : migration `AddAppNameQrAndStoresToApplicationInstance` appliquée ; visitapp buildée après `flutter clean` (empreinte de `libapp.so` vérifiée).
|
||||
|
||||
### 23.1 — Réglages dans manager-app (écrans Mobile et Web)
|
||||
|
||||
| # | Action | Résultat attendu | ✓ |
|
||||
|---|--------|-----------------|---|
|
||||
| 23.1.1 | Saisir le **nom de l'application** en FR/EN/NL, recharger | Valeurs conservées, par app (Mobile ≠ Web) | |
|
||||
| 23.1.2 | Décocher **Afficher le scan de QR code**, recharger | Case restée décochée | |
|
||||
| 23.1.3 | En **SuperAdmin**, saisir les liens App Store / Play Store (écran Mobile) | Enregistrés | |
|
||||
| 23.1.4 | En **InstanceAdmin** | Les champs de liens stores n'apparaissent pas ; un `PUT` forgé avec d'autres liens ne les modifie pas | |
|
||||
| 23.1.5 | QR d'une section (instance avec app mobile) | Encode `https://app.myinfomate.be/download/{instanceId}/{configId}/{sectionId}` | |
|
||||
| 23.1.6 | QR d'une section (instance **web seule**) | Encode `https://app.myinfomate.be/{slug}/{configId}/sections/{sectionId}` | |
|
||||
|
||||
### 23.2 — Scan dans l'app mobile
|
||||
|
||||
| # | QR scanné | Depuis | Résultat attendu | ✓ |
|
||||
|---|-----------|--------|-----------------|---|
|
||||
| 23.2.1 | Id brut d'une section (QR du **Fort**) | Accueil | La visite s'ouvre directement sur la section | |
|
||||
| 23.2.2 | Id brut d'une section de la visite ouverte | Visite | La section s'ouvre | |
|
||||
| 23.2.3 | Id brut d'une section d'une autre visite | Visite | Popup « autre visite » puis ouverture sur la section | |
|
||||
| 23.2.4 | URL `web.mymuseum.be/…` d'un vrai QR **MDLF** imprimé | Accueil et visite | Même comportement qu'avant | |
|
||||
| 23.2.5 | Nouvelle URL `app.myinfomate.be/download/…` | Accueil et visite | Ouvre la section | |
|
||||
| 23.2.6 | QR d'une **autre instance** | Accueil | « QR code invalide » | |
|
||||
| 23.2.7 | Visite hors ligne, mode avion, id brut | Accueil | Résolu depuis la base locale | |
|
||||
| 23.2.8 | Scan QR désactivé dans le manager | — | Bouton absent sur l'accueil, dans la visite et dans un menu | |
|
||||
| 23.2.9 | Nom de l'app renseigné | — | En-tête de l'accueil = nom de l'app (langue active) ; sans nom : titre de la 1re visite comme avant | |
|
||||
|
||||
### 23.3 — Web (visitapp-web)
|
||||
|
||||
| # | Action | Résultat attendu | ✓ |
|
||||
|---|--------|-----------------|---|
|
||||
| 23.3.1 | Ouvrir `/download/{instanceId}/{c}/{s}` (téléphone, appareil photo) | Image principale, nom de l'app, boutons stores renseignés, textes dans la langue du navigateur | |
|
||||
| 23.3.2 | Même URL sans liens stores | « Bientôt disponible sur les stores » | |
|
||||
| 23.3.3 | Instance sans app mobile | 404 | |
|
||||
| 23.3.4 | Scanner un QR `download` depuis l'app web | Ouvre la section web | |
|
||||
| 23.3.5 | Scan QR désactivé sur l'app **Web** | Bouton absent (accueil et visite) | |
|
||||
| 23.3.6 | Nom de l'app renseigné | Titre sur l'accueil et dans l'onglet | |
|
||||
| 23.3.7 | Visite avec sections géolocalisées, activer le bouton de proximité, forcer la position dans les DevTools | Carte « À proximité » une fois par section et par session, 20 s minimum entre deux | |
|
||||
| 23.3.8 | ⚠️ **Prendre l'`instanceId` d'un vrai QR MDLF imprimé** et ouvrir `/download/{cet id}/…` | La page **de MDLF** s'affiche (son nom, son image, ses liens). Si elle ne trouve rien, l'id a changé à la migration Mongo → Postgres : la redirection ne servirait à rien, à traiter avant de la poser | |
|
||||
| 23.3.9 | Instance sans **nom d'application** renseigné | Le titre retombe sur le nom de l'instance, jamais sur « Application mobile » | |
|
||||
| 23.3.10 | Ancien QR d'une instance **web seule** redirigé vers `/download/…` | Redirection vers la visite web à la bonne section | |
|
||||
|
||||
### 23.4 — Proximité et notifications (mobile, device réel)
|
||||
|
||||
| # | Action | Résultat attendu | ✓ |
|
||||
|---|--------|-----------------|---|
|
||||
| 23.4.1 | Visite avec zones GPS (sans beacon) | Le bouton de proximité apparaît une fois les sections chargées | |
|
||||
| 23.4.2 | Activer, entrer dans une zone (mock location Android), app ouverte | Popup de suggestion, **pas** de notification | |
|
||||
| 23.4.3 | Même chose écran verrouillé | Notification « Contenu à proximité » + titre de la section | |
|
||||
| 23.4.4 | Toucher la notification | L'app s'ouvre sur la section | |
|
||||
| 23.4.5 | Rester dans la zone écran verrouillé | Une seule notification par section et par visite | |
|
||||
| 23.4.6 | Android : pendant le scan | Notification persistante « Suggestions de contenu à proximité activées » ; disparaît en coupant le bouton ou en quittant la visite | |
|
||||
| 23.4.7 | iOS : écran verrouillé | Indicateur de localisation en arrière-plan ; notification reçue (beacon **et** GPS) | |
|
||||
| 23.4.8 | App tuée | Aucune notification (hors périmètre, par choix) | |
|
||||
| 23.4.9 | Mode vocal lunettes sans permission de localisation (Android 14+) | Pas de crash ; le service de premier plan ne démarre pas | |
|
||||
|
||||
---
|
||||
|
||||
## Hors scope (non implémenté)
|
||||
|
||||
| Feature | Statut |
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user