docs: ADR-003 mode street Mapillary (architecture), README 5 modes, deploiement token PUBLIC_MAPILLARY_TOKEN

This commit is contained in:
sucupira
2026-07-18 20:15:13 -04:00
parent e4a0bfd045
commit 79b2ef72a9
3 changed files with 32 additions and 5 deletions
+12
View File
@@ -110,3 +110,15 @@ Règles :
## 9. Correctif UX résultat (2026-07-17)
- **Carte résultat façon GeoGuessr** : à la révélation, le marqueur du joueur **reste à sa position** (corail) et la position réelle apparaît (vert), reliées par une ligne pointillée avec **étiquette de distance au milieu** (`distanceKm`) ; la carte cadre les deux points (`fitBounds`, instantané si `prefers-reduced-motion`). Remplace l'ancien « vol » du marqueur vers la position réelle, qui détruisait la comparaison visuelle. Prop `distanceKm` ajoutée à `GameMap` (alimentée par la réponse serveur, jamais calculée côté client).
## 10. ADR-003 — Mode street « An lari a » via Mapillary (2026-07-18)
5e mode de jeu : le joueur voit une **photo street-level navigable** (visionneuse Mapillary) au lieu d'une photo statique, et devine la commune. Mécanique carte + guess + score **inchangée**.
- **Pourquoi Mapillary** : seule source de street-level imagery couvrant correctement les 4 régions (bonne couverture Gwada/Martinique/Réunion, littoral guyanais) ; images **CC BY-SA 4.0**, lib `mapillary-js` **MIT**, API gratuite (token client requis, rate-limité par app). **Exception documentée** à « zéro service tiers » (Mapillary = plateforme Meta), limitée à ce mode ; alternative souveraine future = Panoramax (reco R4 audit passe 2), couverture DOM encore insuffisante à cette date.
- **Corpus curé, pas de tirage aléatoire dans l'API** : `app/src/lib/server/data/street.json` (20 lieux, 5/région), produit par `app/scripts/curate-street.mjs` (bbox < 0,01° ou grille de recherches par rayon autour de la **mairie** — le centroïde geo.api tombe souvent hors du centre-ville ; tri qualité/récence, préférence 360°), revérifié par `app/scripts/validate-street.mjs` (image existe, `computed_geometry` < 100 m, crédit auteur, sitelink frwiki). La vérité terrain (`coordonnees`) est **figée** dans le corpus (dérive possible de `computed_geometry` côté Mapillary).
- **Phase éducative par commune** : `wikidata_id` = QID de la **commune** (un coin de rue n'a pas vocation à avoir sa page) → `WikiFiche` réutilisé tel quel, aucune variante Cas B nouvelle. `aire_commune_km2` renseigné (équité Guyane, A1).
- **Anti-triche** : `/api/round?mode=street` + `sanitizeRoundStreet()` — seuls `id, nom, nom_creole, categorie, difficulte, mapillaryId, credit, indices` partent ; coords/commune/région/wikidata_id jamais avant le guess. **Limitation assumée** : l'`image_key` est publique (la visionneuse appelle Mapillary depuis le navigateur) → un joueur techniquement équipé peut retrouver la position via l'API Mapillary (même propriété que GeoGuessr/Street View ; acceptable en solo sans leaderboard). La visionneuse n'affiche **pas de carte** (mapillary-js n'en a pas par défaut), donc aucun spoiler visuel.
- **Visionneuse** : `StreetPanel.svelte`, lazy load façon MapLibre (`import('mapillary-js')` + CSS — chunk séparé ~1 MB, 0 occurrence dans le bundle initial), `component.cover: false`, `moveTo()` avec état d'erreur (image retirée → message + round suivant possible). Token `PUBLIC_MAPILLARY_TOKEN` via `$env/dynamic/public` (pattern `PUBLIC_TILES_URL`) : **token client**, conçu par Mapillary pour être exposé côté navigateur.
- **Réutilisation sans modification** : `GameMap`, `ResultPanel`, `WikiFiche`, scoring (`scoreGuess`/`skipResult` acceptent `Lieu | StreetLieu`), timer, indices, bouton « Passer ». `RoundPlace.photo` devient optionnel (`mapillaryId`/`credit` ajoutés) ; lookup unifié `getLieuById` (2 corpus) pour `/api/guess`, `getLieuPhotoById` conservé pour le défi et le proxy photo.
- **Hors scope v1** : street dans `/defi/[seed]` et `/explorer`, cache SW des tuiles Mapillary (les requêtes `graph.mapillary.com`/FBCDN passent en direct).