# Guide : SectionEvent, SectionMap & SectionGame — Configuration et affichage > Cas d'usage typiques : **carnaval**, **parc à thème**, **festival**, **musée en plein air**, **escape game** --- ## Vue d'ensemble La plateforme permet de proposer à un visiteur une **vue carte** ou une **vue liste** pour naviguer dans un événement géolocalisé, ou de lancer un **escape game** (géolocalisé ou non). Les types de section principaux : | Type | Usage | Contient | |---|---|---| | `SectionMap` | Carte interactive ou liste de POI | GeoPoints, catégories, parcours guidés | | `SectionEvent` | Événement avec dates + programme | Dates, carte de base, programme horaire, annotations carte, parcours guidés | | `SectionGame` | Jeu interactif | Puzzle, puzzle glissant, **escape game** (géolocalisé ou non) | --- ## Modèles de données (manager-service) ### Section (base commune) `ManagerService/Data/Section.cs` Tous les types héritent de cette classe : - `Id`, `Label`, `Title`, `Description`, `Order`, `Type` - `ConfigurationId`, `InstanceId`, `IsActive` - `IsSubSection`, `ParentId` — pour sections imbriquées - `Latitude`, `Longitude`, `BeaconId`, `MeterZoneGPS` — déclenchement géoloc ### SectionMap `ManagerService/Data/SubSection/SectionMap.cs` ``` SectionMap ├── MapMapProvider → Google ou MapBox ├── MapMapType → Normal / Satellite / Terrain / Hybrid (Google) ├── MapTypeMapbox → Standard / Streets / Outdoors / Light / Dark / Satellite ├── MapZoom → Niveau de zoom par défaut (défaut: 18) ├── MapCenterLatitude/Longitude ├── IsListViewEnabled → ⭐ toggle carte / liste dans la visitapp ├── MapCategories[] → Catégories de filtrage des points └── MapPoints[] → GeoPoints (POI sur la carte) ``` **GeoPoint** (POI) : - `Title`, `Description`, `Contents[]` - `Geometry` (Point / Polyline / Circle / Polygon) - `CategorieId` — pour le filtrage - `SectionMapId` **ou** `SectionEventId` (multi-parent) - `Schedules`, `Prices`, `Phone`, `Email`, `Site` ### SectionEvent `ManagerService/Data/SubSection/SectionEvent.cs` ``` SectionEvent ├── StartDate / EndDate ├── BaseSectionMapId → ⭐ lien vers une SectionMap (carte de fond) ├── BaseMap → navigation property vers la SectionMap ├── GlobalMapAnnotations[]→ annotations au niveau de l'événement entier ├── Programme[] → blocs horaires └── ParcoursIds[] → ⚠️ INUTILISÉ (voir GuidedPath.SectionEventId) ``` **ProgrammeBlock** (bloc horaire) : - `StartTime`, `EndTime` - `Title`, `Description` (traduits) - `MapAnnotations[]` — annotations spécifiques à ce créneau **MapAnnotation** : - `GeometryType` : Point / Polyline / Circle / Polygon - `Geometry` (PostGIS) - `Type` (traduit) : "first_aid", "parking", "scène", etc. - `PolyColor`, `Icon`, `IconResourceId` - `SectionEventId` (null = annotation de bloc) ### SectionGame `ManagerService/Data/SubSection/SectionGame.cs` ``` SectionGame ├── GameType → Puzzle | SlidingPuzzle | Escape ⭐ ├── GameMessageDebut[] → message d'intro (traduit + media) ├── GameMessageFin[] → message de fin (traduit + media) ├── GamePuzzleImageId → image source du puzzle ├── GamePuzzleRows → nombre de lignes (défaut: 3) └── GamePuzzleCols → nombre de colonnes (défaut: 3) ``` Pour le mode `Escape`, les parcours guidés sont portés par `GuidedPath.SectionGameId` (pas de champ direct sur SectionGame). ### GuidedPath (Parcours guidé) `ManagerService/Data/SubSection/GuidedPath.cs` Un parcours peut être attaché à une carte **ou** un événement **ou** un jeu : ``` GuidedPath ├── SectionMapId → lié à une SectionMap (nullable) ├── SectionEventId → lié à un SectionEvent (nullable) ├── SectionGameId → lié à un SectionGame (nullable) ⭐ escape game ├── IsLinear → ordre obligatoire ├── RequireSuccessToAdvance → résoudre une énigme pour avancer ├── HideNextStepsUntilComplete ├── Order └── Steps[] → GuidedStep ``` **GuidedStep** (étape du parcours) : - `Geometry`, `ZoneRadiusMeters` — zone de déclenchement géoloc - `TriggerGeoPointId` — peut référencer un GeoPoint - `IsHiddenInitially`, `IsStepLocked` - `IsStepTimer`, `TimerSeconds`, `TimerExpiredMessage` - `QuizQuestions[]` — énigmes/questions à résoudre pour valider l'étape --- ## Endpoints API (manager-service) ### SectionEvent → `/api/sectionevent/{id}/...` | Méthode | Route | Description | |---|---|---| | GET | `/{id}/programmes` | Tous les blocs horaires | | POST | `/{id}/programmes` | Créer un bloc | | PUT | `/programmes` | Modifier un bloc | | DELETE | `/programmes/{blockId}` | Supprimer un bloc | | GET | `/{id}/global-map-annotations` | Annotations globales | | POST | `/{id}/global-map-annotations` | Ajouter annotation globale | | DELETE | `/map-annotations/{annotationId}` | Supprimer annotation | ### SectionMap → `/api/sectionmap/{id}/...` | Méthode | Route | Description | |---|---|---| | GET | `/{id}/points` | Tous les GeoPoints | | POST | `/{id}/points` | Créer un GeoPoint | | PUT | `/points` | Modifier un GeoPoint | | DELETE | `/points/{pointId}` | Supprimer un GeoPoint | | GET | `/{id}/guided-path` | Tous les parcours | | POST | `/{id}/guided-path` | Créer un parcours | | PUT | `/guided-path` | Modifier un parcours | | DELETE | `/guided-path/{pathId}` | Supprimer un parcours | | GET | `/guided-path/{pathId}/guided-step` | Étapes d'un parcours | | POST | `/guided-path/{pathId}/guided-step` | Créer une étape | --- ## Configuration dans le manager-app ### EventConfig `manager-app/lib/Screens/Configurations/Section/SubSection/Event/event_config.dart` Interface de configuration d'un SectionEvent : 1. **Dates** (début / fin avec date+heure picker) 2. **Carte de base** — dropdown des SectionMap disponibles dans la configuration → sette `baseSectionMapId` 3. **Annotations globales** — marqueurs/zones visibles sur toute la durée de l'événement 4. **Programme** — blocs horaires avec titre, description, heures 5. **Parcours guidés** — via `ParcoursConfig(isEvent: true, parentId: eventDTO.id!)` ### MapConfig `manager-app/lib/Screens/Configurations/Section/SubSection/Map/map_config.dart` Deux onglets : - **"Points d'intérêt"** — CRUD sur les GeoPoints avec filtrage par catégorie - **"Parcours"** — via `ParcoursConfig(isEvent: false, parentId: mapId)` Paramètre clé : `isListViewEnabled` → détermine si la visitapp affiche la carte ou une liste. ### GameConfig `manager-app/lib/Screens/Configurations/Section/SubSection/Game/game_config.dart` Interface à **3 onglets** selon le `GameType` : 1. **Puzzle** — configuration lignes/colonnes + image source 2. **Puzzle Glissant** — idem 3. **Escape Game** — intègre `ParcoursConfig(isEscapeMode: true, parentId: gameId)` ### ParcoursConfig `manager-app/lib/Screens/Configurations/Section/SubSection/Parcours/parcours_config.dart` Composant réutilisé pour maps, events **et escape games** via 3 flags : | Appel | Contexte | FK créée sur GuidedPath | |---|---|---| | `isEscapeMode: true` | SectionGame | `sectionGameId` | | `isEvent: true` | SectionEvent | `sectionEventId` | | les deux à false | SectionMap | `sectionMapId` | - Liste réordrable (drag & drop) des parcours - Création/édition via `showNewOrUpdateGuidedPath` - Suppression avec confirmation `showNewOrUpdateGuidedPath` permet de configurer : - Titre / description (multilingue) - Options : linéaire, réussite requise, cacher les étapes suivantes - CRUD des étapes avec géolocalisation et quiz optionnel --- ## Affichage dans la visitapp ### Routing des sections `mymuseum-visitapp/lib/Screens/section_page.dart` ```dart switch(sectionDTO.type) { case SectionType.Map: → MapPage(mapDTO) case SectionType.Agenda: → AgendaPage(agendaDTO) case SectionType.Game: → GamePage(gameDTO) // SectionType.Event n'est pas encore géré nativement } ``` > ⚠️ **Limitation actuelle** : `SectionType.Event` n'a pas de page dédiée dans la visitapp. Les événements passent actuellement par `SectionType.Agenda`. ### MapPage `mymuseum-visitapp/lib/Screens/Sections/Map/map_page.dart` - `mapDTO.isListViewEnabled` → bascule carte / liste - Provider : Google (`GoogleMapView`) ou MapBox (`MapBoxView` / `FlutterMapView`) - Filtrage par catégorie via `GeoPointFilter` - Tap sur point → détail du GeoPoint ### AgendaPage (événements) `mymuseum-visitapp/lib/Screens/Sections/Agenda/agenda_page.dart` - Grille 2 colonnes d'`EventAgenda` items - Filtrage par mois - Tap → `EventPopup` avec détails ### GamePage (jeux) `mymuseum-visitapp/lib/Screens/Sections/Game/game_page.dart` - Reçoit `GameDTO` avec `gameType` - Affiche le message d'intro (`GameMessageDebut`) au lancement - **Modes Puzzle / SlidingPuzzle** : découpe l'image en pièces, gameplay drag & drop, message de fin à la complétion - **Mode Escape** : ⚠️ pas encore implémenté nativement dans la visitapp — `gameType` n'est pas encore dispatché vers une UI dédiée --- ## Exemple concret : Carnaval / Parc à thème ### Setup manager-app #### Étape 1 — Créer la SectionMap "Plan du site" - Provider : MapBox (Outdoors pour un parc) - `isListViewEnabled: false` (vue carte par défaut) - Ajouter les GeoPoints : - Manèges / attractions → catégorie "Attractions" - Restauration → catégorie "Nourriture" - Premiers secours → catégorie "Services" - Parkings → catégorie "Accès" #### Étape 2 — Créer la SectionEvent "Carnaval 2025" - Dates : 1–7 mars 2025 - **Carte de base** : sélectionner "Plan du site" (créé à l'étape 1) - **Annotations globales** : - Zones de parade (Polyline) - Scène principale (Polygon) - Points de premiers secours (Point + icône) - **Programme** : - "Parade d'ouverture" — 1 mars 14h-16h (annotation : tracé de la parade) - "Spectacle de feu" — chaque soir 21h-22h (annotation : scène) - "Feux d'artifice" — 7 mars 22h (annotation : point de lancement) - **Parcours guidés** : - "Circuit famille" (linéaire) — 5 étapes vers les attractions family-friendly - "Tour photo" (non-linéaire) — spots photos librement visitables - "Chasse au trésor" (linéaire, réussite requise) — énigmes géolocalisées ### Ce que voit le visiteur **Vue carte** (baseSectionMapId défini) : - Carte du site avec tous les GeoPoints - Filtrage par catégorie (attractions, food, services...) - Annotations globales superposées (zones, tracés) - Selon l'heure : annotations du bloc programme actif surlignées - Onglet / bouton "Parcours" pour lancer un itinéraire guidé **Vue liste** (`isListViewEnabled: true` sur la SectionMap) : - Liste des attractions avec détails - Horaires par catégorie --- ## Escape Game — fonctionnement détaillé ### Deux variantes #### Escape game non-géolocalisé - Le visiteur progresse en résolvant des énigmes/quiz à chaque étape, **sans se déplacer physiquement** - Les `GuidedStep` n'ont pas de `Geometry` ni de `ZoneRadiusMeters` - Typiquement utilisé en intérieur (salle d'exposition, tablette fixe, kiosque) - Navigation : l'app passe à l'étape suivante dès que la condition est remplie (`RequireSuccessToAdvance`) #### Escape game géolocalisé - Le visiteur doit **se rendre physiquement à un endroit** pour débloquer une étape - Les `GuidedStep` ont une `Geometry` (Point avec `ZoneRadiusMeters`, ou Polygon) - Le déclenchement peut aussi passer par un `TriggerGeoPointId` (un POI de la carte) - Typiquement utilisé en extérieur (parc, ville, musée multi-salles) - L'app détecte l'entrée dans la zone → débloque l'étape ### Configuration d'un escape game dans le manager-app 1. Créer une `SectionGame` avec `GameType: Escape` 2. Dans l'onglet **Escape Game** → ajouter un ou plusieurs **Parcours** via `ParcoursConfig(isEscapeMode: true)` 3. Pour chaque parcours, configurer : - **isLinear** : oui = ordre imposé, non = étapes libres - **requireSuccessToAdvance** : oui = résoudre l'énigme avant d'aller au suivant - **hideNextStepsUntilComplete** : oui = étapes masquées tant que non débloquées 4. Pour chaque **étape** du parcours : - Titre + description (multilingue) - (Optionnel) Géométrie + rayon → pour version géolocalisée - (Optionnel) `TriggerGeoPointId` → lier à un POI existant - `IsStepTimer` + `TimerSeconds` → compte à rebours - `QuizQuestions[]` → énigmes/questions à résoudre ### Structure de données ``` SectionGame (GameType: Escape) └── GuidedPath[] (via SectionGameId) ├── IsLinear, RequireSuccessToAdvance, HideNextStepsUntilComplete └── GuidedStep[] ├── Title, Description ├── Geometry + ZoneRadiusMeters ← géoloc (optionnel) ├── TriggerGeoPointId ← lien POI (optionnel) ├── IsStepTimer, TimerSeconds ← countdown (optionnel) └── QuizQuestions[] ← énigmes à résoudre ``` ### Exemple : Escape game géolocalisé dans un parc à thème **Scénario** : "La Quête du Trésor" — 5 énigmes réparties dans le parc, à résoudre dans l'ordre. **Config** : - `SectionGame` → `GameType: Escape` - 1 `GuidedPath` : `isLinear: true`, `requireSuccessToAdvance: true`, `hideNextStepsUntilComplete: true` - 5 `GuidedStep` : 1. Zone fontaine centrale (polygon 10m) → quiz "Que représente cette statue ?" 2. Zone entrée château (point, rayon 15m) → quiz + timer 60s 3. Zone jardin secret (polygon) → quiz "Comptez les rosiers rouges" 4. Zone boutique (point, rayon 5m) → quiz avec image indice 5. Zone scène finale (polygon) → quiz final → débloque le message de fin **Ce que voit le visiteur** *(à implémenter dans la visitapp)* : - Carte avec marqueur de la prochaine étape - En approchant → notification de déclenchement - Énigme s'affiche → réponse validée → étape suivante révélée - Toutes étapes complétées → `GameMessageFin` affiché --- ## Relation `ParcoursIds` — clarification `SectionEvent.ParcoursIds` (liste de strings en JSONB) est **inutilisé** : - La relation réelle est portée par `GuidedPath.SectionEventId` (FK) - L'app charge les parcours via `sectionMapGetAllGuidedPathFromSection(eventId)` - `ParcoursIds` est une relique de conception initiale, peut être supprimé --- ## Bugs / limitations connus | Problème | Détail | |---|---| | `SectionType.Event` non géré dans visitapp | Passe par `SectionType.Agenda`, pas de page dédiée | | Escape game non affiché dans visitapp | `GamePage` ne dispatche pas sur `gameType == Escape` | | `GuidedPath.SectionGameId` non mis à jour | `UpdateGuidedPath()` dans le controller ne copie pas `sectionGameId` depuis le DTO | | `SectionEvent.ParcoursIds` inutilisé | Relique, remplacé par `GuidedPath.SectionEventId` | --- ## Hiérarchie de types Section ``` Section (base) ├── SectionEvent ← événement avec carte + programme ├── SectionMap ← carte / liste de POI ├── SectionAgenda ← agenda d'événements externe (JSON) ├── SectionArticle ├── SectionGame ← puzzle | puzzle glissant | escape game (géoloc ou non) ├── SectionQuiz ├── SectionVideo ├── SectionWeb ├── SectionPdf ├── SectionMenu ├── SectionSlider └── SectionWeather ```