diff --git a/README.md b/README.md index fb9fa2a..2dea046 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # JWE

-JWE est un jeu de géolocalisation souverain, dans l'esprit de GeoGuessr, centré sur 4 régions : Guadeloupe, Martinique, Guyane, La Réunion. Le joueur voit une photo unique d'un lieu et place un marqueur sur une carte pour deviner la commune — puis découvre une fiche éducative Wikipédia/Wikidata… ou un appel à contribution quand le lieu n'y est pas documenté (Pwen blindé). +JWE est un jeu de géolocalisation souverain, dans l'esprit de GeoGuessr, centré sur 4 régions : Guadeloupe, Martinique, Guyane, La Réunion. Le joueur voit une photo unique d'un lieu — ou navigue dans une rue en visionneuse Mapillary (mode An lari a) — et place un marqueur sur une carte pour deviner la commune — puis découvre une fiche éducative Wikipédia/Wikidata… ou un appel à contribution quand le lieu n'y est pas documenté (Pwen blindé).

@@ -12,10 +12,11 @@ JWE est un jeu de géolocalisation souverain, dans l'esprit de GeoGuessr, centr

-- **Souverain** : zéro Google, zéro Mapbox. MapLibre + tiles libres, Wikipédia/Wikidata, auto-hébergeable sur un petit VPS. +- **Souverain** : zéro Google, zéro Mapbox. MapLibre + tiles libres, Wikipédia/Wikidata, auto-hébergeable sur un petit VPS. (Exception documentée : le mode street « An lari a » utilise la visionneuse Mapillary — images CC BY-SA 4.0, lib MIT, token client gratuit.) - **Éthique** : pas de comptes, pas de leaderboard, pas de mécanique dopaminergique. - **Bilingue** : français / créole. -- **Stack** : Svelte 5 + SvelteKit 2, MapLibre GL JS, Node ≥ 20, licence MIT. +- **5 modes** : Konnèt moniman, Kote mwen ye ?, Défi 5 rounds, Aprann (explorer), An lari a (street-level Mapillary). +- **Stack** : Svelte 5 + SvelteKit 2, MapLibre GL JS, mapillary-js, Node ≥ 20, licence MIT. ## Utilisation @@ -23,6 +24,7 @@ JWE est un jeu de géolocalisation souverain, dans l'esprit de GeoGuessr, centr git clone https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/JWE.git cd JWE/app npm ci +cp .env.example .env # puis renseignez PUBLIC_MAPILLARY_TOKEN (token client gratuit) npm run dev # développement npm run build && node build # production (adapter-node) ``` @@ -46,4 +48,4 @@ La version 1 (PHP, cartes des communes) a été remplacée par cette refonte en Copyright (C) 2024-2026 Cédric Famibelle-Pronzola & ORGANISATION KA INTERNATIONALE (OKI) -Code sous licence **MIT** (voir [LICENSE](LICENSE)). Les photographies restent la propriété de leurs auteurs sous leurs licences Wikimedia Commons (voir [`content/credits.md`](content/credits.md)) ; les extraits Wikipédia sont sous CC BY-SA 4.0. +Code sous licence **MIT** (voir [LICENSE](LICENSE)). Les photographies restent la propriété de leurs auteurs sous leurs licences Wikimedia Commons ; les images street-level Mapillary sont sous CC BY-SA 4.0 par leurs contributeurs (voir [`content/credits.md`](content/credits.md)) ; les extraits Wikipédia sont sous CC BY-SA 4.0. diff --git a/docs/architecture.md b/docs/architecture.md index b0816ed..19da057 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -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). diff --git a/docs/deploiement.md b/docs/deploiement.md index 1afe0d9..e32bbef 100644 --- a/docs/deploiement.md +++ b/docs/deploiement.md @@ -1,6 +1,8 @@ # JWE v2 — Guide de déploiement auto-hébergé -Cible : un petit VPS (1 vCPU / 1 Go RAM suffit) sous Debian/Ubuntu, derrière nginx ou Caddy. Aucun service propriétaire, aucune clé API. +Cible : un petit VPS (1 vCPU / 1 Go RAM suffit) sous Debian/Ubuntu, derrière nginx ou Caddy. Aucun service propriétaire, aucune clé API payante. + +> **Exception documentée (mode street)** : le 5e mode « An lari a » utilise la visionneuse Mapillary (images CC BY-SA 4.0, lib MIT) et requiert un **token client Mapillary gratuit** — voir §2.1. Sans ce token, les 4 autres modes fonctionnent normalement ; seul le mode street affiche un message d'indisponibilité. ## 1. Application SvelteKit @@ -32,6 +34,7 @@ WorkingDirectory=/srv/jwe/app Environment=PORT=3000 Environment=ORIGIN=https://jwe.o-k-i.net Environment=PUBLIC_TILES_URL=https://tiles.o-k-i.net/styles/oki/style.json +Environment=PUBLIC_MAPILLARY_TOKEN=MLY|xxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ExecStart=/usr/bin/node build Restart=on-failure @@ -39,6 +42,16 @@ Restart=on-failure WantedBy=multi-user.target ``` +## 2.1 Token Mapillary (mode street « An lari a ») + +1. Créez un compte sur [mapillary.com](https://www.mapillary.com) puis une application sur le [dashboard développeurs](https://www.mapillary.com/dashboard/developers) : récupérez le **client token** (format `MLY|…|…`). +2. Exposez-le via `PUBLIC_MAPILLARY_TOKEN` (service systemd ci-dessus, ou `app/.env` en développement — voir `app/.env.example`). C'est un **token client** : conçu pour être visible côté navigateur, rate-limité par application — ce n'est pas un secret. +3. Vérifiez périodiquement le corpus street (images parfois retirées par leurs auteurs) : + +```bash +cd app && node scripts/validate-street.mjs # lit le token depuis .env +``` + ## 2. Reverse proxy (exemple nginx) ```nginx