docs: mission, decisions d'architecture, guides de deploiement et contribution
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# JWE v2 — Décisions d'architecture (Agent Architecte)
|
||||
|
||||
Date : 2026-07-16 · Mission : refonte GeoGuessr souverain (voir `projet_geoguessr_97x.md`)
|
||||
|
||||
## 1. Décision back-end : SvelteKit seul (pas de Strapi)
|
||||
|
||||
**Décision : SvelteKit seul, avec les lieux dans un fichier JSON versionné dans Git.**
|
||||
|
||||
Arguments :
|
||||
|
||||
- **Frugalité OKI** : un seul processus Node à héberger, pas de CMS + admin + DB à maintenir, pas de surface d'attaque supplémentaire. SQLite serait de toute façon peu utile pour un corpus de ~40 lieux statiques.
|
||||
- **Critère du prompt** (« qui ajoute les lieux ? ») : le corpus est éditorial, produit par l'Agent Contenu et relu. Le workflow Git (pull request = relecture + crédits photos vérifiés) est la modération. Le `docs/contribution.md` documente l'ajout d'un lieu par PR.
|
||||
- **Livrables finaux** : le guide de déploiement demandé est « SvelteKit + Tile Server » — Strapi n'y figure pas.
|
||||
- **Anti-triche** : le JSON reste côté serveur (`src/lib/server/`), jamais importé par le client ; les endpoints filtrent les champs. Impossible de faire plus simple.
|
||||
|
||||
Si un jour des contributeurs non-dev doivent saisir des lieux en masse, la porte vers Strapi reste ouverte (le schéma JSON est le content-type tout désigné), mais ce n'est pas le besoin actuel.
|
||||
|
||||
## 2. Architecture des tiles MapLibre
|
||||
|
||||
- **Rendu** : MapLibre GL JS (verrouillé), chargé en lazy (import dynamique uniquement sur les écrans de jeu / exploration).
|
||||
- **Dev / démo** : tiles vectorielles [OpenFreeMap](https://openfreemap.org) — libres, basées OpenStreetMap, sans clé API. Style **custom OKI** (JSON de style propre, dérivé du style Positron, re-teinté : mer bleu profond caraïbe, terre sable, végétation verte dense, labels sobres — pas le « bleu Google »).
|
||||
- **Prod auto-hébergée** : `tileserver-gl` + extraits `.mbtiles` OpenStreetMap des 4 régions (Guadeloupe, Martinique, Guyane, La Réunion — quelques dizaines de Mo au total). Procédure dans `docs/deploiement.md`. Le style OKI accepte l'URL des tiles par variable d'environnement (`PUBLIC_TILES_URL`), bascule sans changement de code.
|
||||
- **Contrainte géographique** : `maxBounds` = enveloppe union des 4 régions (≈ lon −63…57, lat −23…18) + `minZoom`, donc impossible de scroller en Europe/Amérique du Nord. 4 boutons « saut de région » (GUADELOUPE / MARTINIQUE / GUYANE / RÉUNION) replacent la vue sur la région. Limite connue : l'enveloppe rectangulaire inclut l'Atlantique tropical et le Brésil — inoffensif (aucun indice sur le lieu), documenté.
|
||||
- Attribution © OpenStreetMap contributors affichée.
|
||||
|
||||
## 3. Stratégie Wikipedia / Wikidata
|
||||
|
||||
Principe : **rien de stocké en base**, interroge l'API en temps réel avec cache court, côté serveur uniquement.
|
||||
|
||||
Endpoint serveur : `GET /api/wiki/[qid]` (ex. `Q3077840` = Fort Delgrès — l'exemple `Q2216838` du prompt initial était erroné, corrigé par l'Agent Contenu)
|
||||
|
||||
1. `wbgetentities` sur `www.wikidata.org` → récupère le `sitelink` frwiki (et le libellé fr en fallback).
|
||||
2. `GET https://fr.wikipedia.org/api/rest_v1/page/summary/{titre}` → `title`, `extract`, `content_urls`, `thumbnail`.
|
||||
3. Réponse normalisée : `{ qid, title, extract, url, thumbnail, description }`.
|
||||
4. Pas de sitelink fr ou erreur → `404` : le front bascule sur l'écran **Cas B « Pwen blindé »**.
|
||||
5. **Cache** : `Map` en mémoire, TTL 24 h (+ `Cache-Control: max-age=3600`). User-Agent explicite (`JWE-OKI/x.y (contact)`) comme demandé par la politique Wikimédia.
|
||||
|
||||
## 4. Arborescence du projet
|
||||
|
||||
```
|
||||
JWE/ (dépôt existant — l'ancien PHP est conservé tel quel)
|
||||
├── app/ ← nouvelle application SvelteKit 2 / Svelte 5
|
||||
│ ├── src/
|
||||
│ │ ├── lib/
|
||||
│ │ │ ├── server/
|
||||
│ │ │ │ ├── lieux.ts (accès données + sélection aléatoire + scoring)
|
||||
│ │ │ │ └── data/lieux.json (corpus 40 lieux — serveur uniquement)
|
||||
│ │ │ ├── components/ (GameMap, PhotoPanel, ResultPanel, ScoreCard…)
|
||||
│ │ │ ├── i18n/ (fr.ts, gcf.ts, store)
|
||||
│ │ │ ├── styles/oki.css (tokens couleurs OKI)
|
||||
│ │ │ └── utils/ (score.ts, geo.ts)
|
||||
│ │ ├── routes/
|
||||
│ │ │ ├── +layout.svelte (header, switch langue FR/CR)
|
||||
│ │ │ ├── +page.svelte (accueil : 4 régions, modes, Jouer)
|
||||
│ │ │ ├── jeu/[mode]/ (écran de jeu split photo/carte)
|
||||
│ │ │ ├── explorer/ (mode Aprann : carte pleine page)
|
||||
│ │ │ └── api/
|
||||
│ │ │ ├── round/+server.ts (GET : lieu aléatoire SANITISÉ)
|
||||
│ │ │ ├── guess/+server.ts (POST : {placeId, lat, lon, hints, timeMs} → score + vérité)
|
||||
│ │ │ ├── lieux/+server.ts (GET : catalogue sanitise pour Explorer)
|
||||
│ │ │ └── wiki/[qid]/+server.ts (GET : extrait Wikipedia, cache 24 h)
|
||||
│ │ ├── app.html / app.d.ts
|
||||
│ │ └── service-worker.ts (PWA)
|
||||
│ ├── static/ (manifest.webmanifest, icônes, photos éventuelles)
|
||||
│ └── package.json / svelte.config.js / vite.config.ts
|
||||
├── docs/ (architecture, déploiement, contribution, audit)
|
||||
├── content/ (sources de travail de l'Agent Contenu : crédits photos)
|
||||
└── projet_geoguessr_97x.md
|
||||
```
|
||||
|
||||
## 5. Spécifications API REST (anti-triche)
|
||||
|
||||
| Endpoint | Méthode | Payload | Réponse |
|
||||
|---|---|---|---|
|
||||
| `/api/round?region=&mode=&exclude=` | GET | — | `{ id, nom, nom_creole, categorie, difficulte, photo{url,credit,alt}, indices[] }` — **jamais** `coordonnees`, `commune`, `region`, `wikidata_id` |
|
||||
| `/api/guess` | POST | `{ id, lat, lon, hintsUsed, timeMs? }` | `{ distanceKm, score, coordonnees, commune, region, nom, wikidata_id }` |
|
||||
| `/api/lieux` | GET | — | Catalogue sanitise (sans coordonnées précises : coords arrondies à 0.05° pour l'affichage Explorer uniquement — mode sans score) |
|
||||
| `/api/wiki/[qid]` | GET | — | `{ title, extract, url, thumbnail }` ou `404` |
|
||||
|
||||
Règles :
|
||||
|
||||
- Le scoring est **recalculé côté serveur** : `score = round(5000 × e^(−d/r))`, `r` selon difficulté du lieu (50/15/5/1 km), pénalité −10 %/indice, bonus temps ≤ +20 % plafonné à 5000.
|
||||
- Distance : haversine.
|
||||
- Le client ne reçoit la vérité (coordonnées, commune, wikidata_id) **qu'après** la soumission du marqueur.
|
||||
- `exclude` : liste d'ids déjà joués (mode Défi 5 rounds, stateless — pas de session serveur nécessaire, pas de leaderboard).
|
||||
|
||||
## 6. Décisions annexes
|
||||
|
||||
- **Adapter** : `adapter-node` (auto-hébergement sobre derrière nginx/caddy).
|
||||
- **PWA** : manifest + service worker minimal (cache app shell, photos en stale-while-revalidate).
|
||||
- **i18n** : dictionnaires maison `fr` / `gcf` (créole), store Svelte, `lang` persistée en localStorage.
|
||||
- **Photos** : URLs Wikimedia Commons (Special:FilePath, `?width=1200`) vérifiées CC par l'Agent Contenu ; `<img loading="lazy">` + `srcset`.
|
||||
- **A11y / calm tech** : `prefers-reduced-motion` respecté (pas de vol de marqueur), timer informatif non anxiogène, navigation clavier (carte : flèches déplacent le marqueur, Entrée valide).
|
||||
- **Licence code** : MIT (le dépôt historique était AGPL — la refonte est un nouveau module `app/` sous MIT comme exigé par le prompt ; le `LICENSE` racine reste l'historique, un `app/LICENSE` MIT est ajouté).
|
||||
@@ -0,0 +1,87 @@
|
||||
# JWE — Guide de contribution : ajouter un lieu
|
||||
|
||||
Le corpus de lieux vit dans `app/src/lib/server/data/lieux.json`, versionné dans Git. Ajouter un lieu = une pull request. La revue de PR sert de modération éditoriale (exactitude, crédits photo, licence).
|
||||
|
||||
## 1. Règles d'or d'un bon lieu
|
||||
|
||||
- **Photographiable et identifiable** : le lieu doit avoir une photo libre de qualité (Wikimedia Commons de préférence).
|
||||
- **Localisé précisément** : coordonnées GPS au lieu près (le score Expert se joue à 1 km).
|
||||
- **Éditorialement pertinent** : monument, paysage, lieu culturel, rue ordinaire… Le jeu mélange volontairement lieux célèbres et lieux du quotidien.
|
||||
- **Lacunes assumées** : il est VOLONTAIRE d'inclure des lieux sans page Wikipédia (`wikidata_id: null`) — le jeu affiche alors un écran pédagogique « Pwen blindé » appelant à documenter le territoire. Mais c'est un choix, pas une négligence : vérifiez d'abord qu'aucune page/frwiki ni entité Wikidata n'existe.
|
||||
|
||||
## 2. Schéma du lieu
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "générez un uuid (uuidgen)",
|
||||
"nom": "Fort Delgrès",
|
||||
"nom_creole": "Fò Delgrès",
|
||||
"region": "GUADELOUPE | MARTINIQUE | GUYANE | REUNION",
|
||||
"commune": "Basse-Terre",
|
||||
"coordonnees": { "lat": 16.0036, "lon": -61.7319 },
|
||||
"categorie": "MONUMENT | LIEU",
|
||||
"difficulte": "FACILE | MOYEN | DIFFICILE | EXPERT",
|
||||
"wikidata_id": "Q3077840",
|
||||
"photo": {
|
||||
"url": "https://commons.wikimedia.org/wiki/Special:FilePath/FICHIER?width=1200",
|
||||
"credit": "© Auteur / Wikimedia Commons CC-BY-SA-4.0",
|
||||
"alt": "Description précise (sert d'alternative textuelle)"
|
||||
},
|
||||
"indices": [
|
||||
{ "niveau": 1, "texte": "Indice doux" },
|
||||
{ "niveau": 2, "texte": "Indice précis" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Trouver et lier l'identifiant Wikidata
|
||||
|
||||
1. Cherchez le lieu sur https://www.wikidata.org
|
||||
2. L'identifiant ressemble à `Q3077840`.
|
||||
3. Vérifiez que l'entité a un lien vers une page **fr.wikipedia** (sitelink) — c'est ce qui permet au jeu d'afficher l'extrait de l'article :
|
||||
|
||||
```bash
|
||||
curl -s "https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q3077840&props=sitelinks&format=json" | grep frwiki
|
||||
```
|
||||
|
||||
4. **Si le lieu n'a ni page Wikipédia ni entité Wikidata** : mettez `"wikidata_id": null`. C'est une contribution précieuse : le jeu transforme la lacune en appel à contribution. Mieux encore : créez l'entité Wikidata vous-même, puis revenez renseigner l'ID !
|
||||
|
||||
## 4. Choisir la photo (licence obligatoire)
|
||||
|
||||
1. Cherchez sur https://commons.wikimedia.org une photo nette, paysage de préférence.
|
||||
2. Licences acceptées : CC BY, CC BY-SA, CC0, domaine public. **Jamais** de « fair use ».
|
||||
3. Vérifiez la licence et l'auteur via l'API :
|
||||
|
||||
```bash
|
||||
curl -s "https://commons.wikimedia.org/w/api.php?action=query&titles=File:NOM_DU_FICHIER&prop=imageinfo&iiprop=url|extmetadata&format=json"
|
||||
```
|
||||
|
||||
4. L'URL dans le JSON utilise `Special:FilePath` avec `?width=1200` (redimensionnement à la volée côté Wikimedia — pas besoin d'héberger l'image). Testez qu'elle renvoie bien 200.
|
||||
5. Reportez le crédit exact (auteur + licence) dans `photo.credit` ET dans `content/credits.md`.
|
||||
|
||||
## 5. Valider avant la PR
|
||||
|
||||
```bash
|
||||
cd app
|
||||
node -e "const l=require('./src/lib/server/data/lieux.json');console.log(l.length,'lieux')"
|
||||
npm run check
|
||||
```
|
||||
|
||||
Checklist de revue :
|
||||
|
||||
- [ ] coordonnées cohérentes avec la commune déclarée
|
||||
- [ ] `wikidata_id` vérifié (ou `null` justifié)
|
||||
- [ ] licence photo CC vérifiée + crédit complet
|
||||
- [ ] `alt` descriptif (accessibilité)
|
||||
- [ ] 2 indices progressifs, sans donner la réponse
|
||||
- [ ] `nom_creole` renseigné quand la forme créole est attestée (sinon, reprendre le nom français — ne pas inventer)
|
||||
|
||||
## 6. Contribuer à Wikipédia / Wikidata (au-delà du jeu)
|
||||
|
||||
Si vous ajoutez un lieu « Pwen blindé », envisagez de documenter le lieu vous-même :
|
||||
|
||||
- Créer un compte et un brouillon d'article : https://fr.wikipedia.org/wiki/Aide:Brouillon
|
||||
- Créer une entité Wikidata : https://www.wikidata.org/wiki/Wikidata:Main_Page
|
||||
- Contacter les groupes Wikimédia locaux (Wikimédia France, groupes antillais/guyanais/réunionnais).
|
||||
|
||||
Chaque entité créée enrichit Wikipédia, les cartes libres… et les futurs jeux comme JWE.
|
||||
@@ -0,0 +1,111 @@
|
||||
# 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.
|
||||
|
||||
## 1. Application SvelteKit
|
||||
|
||||
```bash
|
||||
# Prérequis : Node.js >= 20 (via nodesource ou nvm)
|
||||
git clone https://codeberg.org/OKI/jwe.git
|
||||
cd jwe/app
|
||||
npm ci
|
||||
npm run build # produit app/build (adapter-node)
|
||||
```
|
||||
|
||||
Lancer en production (port 3000 par défaut) :
|
||||
|
||||
```bash
|
||||
PORT=3000 node build
|
||||
```
|
||||
|
||||
Service systemd `/etc/systemd/system/jwe.service` :
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=JWE — jeu de géolocalisation OKI
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=jwe
|
||||
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
|
||||
ExecStart=/usr/bin/node build
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
## 2. Reverse proxy (exemple nginx)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name jwe.o-k-i.net;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
# + TLS via certbot
|
||||
```
|
||||
|
||||
## 3. Tiles cartographiques auto-hébergées (tileserver-gl)
|
||||
|
||||
Par défaut l'application utilise OpenFreeMap (libre, sans clé). Pour une souveraineté complète, hébergez vos propres tiles OSM des 4 régions.
|
||||
|
||||
### 3.1 Récupérer les extraits OpenStreetMap
|
||||
|
||||
```bash
|
||||
mkdir -p /srv/tiles && cd /srv/tiles
|
||||
# Guadeloupe, Martinique, Guyane : extraits Geofabrik
|
||||
wget https://download.geofabrik.de/north-america/guadeloupe-latest.osm.pbf
|
||||
wget https://download.geofabrik.de/north-america/martinique-latest.osm.pbf
|
||||
wget https://download.geofabrik.de/south-america/french-guiana-latest.osm.pbf
|
||||
# La Réunion
|
||||
wget https://download.geofabrik.de/africa/reunion-latest.osm.pbf
|
||||
```
|
||||
|
||||
### 3.2 Générer les .mbtiles
|
||||
|
||||
Avec [openmaptiles](https://github.com/openmaptiles/openmaptiles) (Docker requis) : générez un `.mbtiles` par région puis fusionnez-les avec `tile-join` (paquet `tippecanoe`) :
|
||||
|
||||
```bash
|
||||
tile-join -o dom-tom.mbtiles guadeloupe.mbtiles martinique.mbtiles guyane.mbtiles reunion.mbtiles
|
||||
```
|
||||
|
||||
(Alternative plus légère : extraire les 4 régions d'un `.mbtiles` Monde basse-résolution `tile-join --bbox=…` par région, puisque la carte de devinette n'a pas besoin d'un zoom très fin partout.)
|
||||
|
||||
### 3.3 Servir avec tileserver-gl
|
||||
|
||||
```bash
|
||||
docker run --rm -d --name tiles -v /srv/tiles:/data -p 8080:8080 \
|
||||
maptiler/tileserver-gl dom-tom.mbtiles
|
||||
```
|
||||
|
||||
Copiez le style OKI de l'application (`app/src/lib/map/style-oki.json`) dans `/srv/tiles/styles/oki/`, adaptez son URL de source vers votre `dom-tom.mbtiles`, puis :
|
||||
|
||||
```bash
|
||||
Environment=PUBLIC_TILES_URL=https://tiles.o-k-i.net/styles/oki/style.json
|
||||
```
|
||||
|
||||
### 3.4 Fontes et sprites
|
||||
|
||||
tileserver-gl sert aussi les fontes (glyphs) et sprites référencés par le style. Les fontes open-source utilisées par le style OKI (ex. Noto Sans) se récupèrent via `openmaptiles/fonts` ou `klokantech/tileserver-gl-fonts`.
|
||||
|
||||
## 4. Cache Wikipedia
|
||||
|
||||
Le endpoint `/api/wiki/[qid]` met en cache les extraits 24 h en mémoire. Aucune configuration requise ; pour un cache partagé entre instances, placez nginx en cache proxy devant `/api/wiki/` (respecte déjà `Cache-Control`).
|
||||
|
||||
## 5. Mise à jour
|
||||
|
||||
```bash
|
||||
cd jwe && git pull && cd app && npm ci && npm run build
|
||||
systemctl restart jwe
|
||||
```
|
||||
|
||||
L'ajout de lieux (voir `docs/contribution.md`) ne demande qu'un rebuild + restart : le corpus est embarqué dans le build.
|
||||
@@ -0,0 +1,254 @@
|
||||
Voici le prompt mis à jour. Les hésitations sur les librairies et les panoramas sont supprimées, et la dimension éducative/Wikipedia est intégrée comme un mécanisme de jeu à part entière (et non plus comme un simple fallback).
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
# Mission : JWE — Jeu de géolocalisation souverain type GeoGuessr
|
||||
## Refonte complète · Svelte + Strapi/SvelteKit · MapLibre · Photos uniques · Éducation Wikipedia
|
||||
|
||||
---
|
||||
|
||||
## 1. Contexte et ambition
|
||||
|
||||
### 1.1 Projet source
|
||||
- **URL actuelle** : https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/JWE
|
||||
- **Objet** : refonte complète pour en faire un jeu de géolocalisation dans l'esprit de GeoGuessr, centré sur 4 régions : **Guadeloupe, Martinique, Guyane, La Réunion**.
|
||||
|
||||
### 1.2 Mécanique de jeu verrouillée
|
||||
- **Pas de Street View, pas de panoramas, pas de 3D.**
|
||||
- Le joueur voit une **photo unique** d'un lieu (monument, paysage, rue, lieu culturel).
|
||||
- Il doit placer un marqueur sur une carte pour deviner **la commune** (et par déduction la région).
|
||||
- Le score est calculé selon la distance entre le marqueur et les coordonnées réelles.
|
||||
- Après le score : phase éducative basée sur **Wikipedia/Wikidata** (voir §1.3).
|
||||
|
||||
### 1.3 Le pivot éducatif : Wikipedia/Wikidata comme cœur du jeu
|
||||
JWE n'est pas qu'un jeu de score, c'est un outil de **souveraineté documentaire**.
|
||||
- Si le lieu photographié possède une page Wikipedia : afficher un extrait de l'article, ses coordonnées Wikidata, et un lien "Lire plus sur Wikipédia".
|
||||
- **Si le lieu n'a PAS de page Wikipedia ou de données Wikidata** : c'est intentionnel et pédagogique. Le jeu doit afficher un écran spécifique expliquant :
|
||||
1. Pourquoi ce lieu n'est pas sur Wikipedia (lacune documentaire).
|
||||
2. Pourquoi il est vital que les populations locales documentent leurs propres territoires (représentation numérique, décolonisation du savoir, importance pour les modèles d'IA qui s'entraînent sur ces données, tourisme, transmission).
|
||||
3. Un appel à l'action : "Contribuer sur Wikipédia" avec un lien vers l'éditeur Wikipédia pré-rempli (ou des liens vers des tutos OKI/Wikimédiens locaux).
|
||||
- **L'Agent Contenu doit intentionnellement inclure des lieux sans page Wikipedia** pour tester et démontrer cette fonctionnalité.
|
||||
|
||||
### 1.4 Cible OKI
|
||||
- **Souverain** : zéro Google, zéro Mapbox. Carte MapLibre + tiles libres.
|
||||
- **Éthique** : pas de loot boxes, pas de leaderboard forcé, pas d'anxiété.
|
||||
- **Performant** : jouable sur téléphone en 4G caribéen.
|
||||
- **Bilingue** : français / créole pour l'interface.
|
||||
|
||||
---
|
||||
|
||||
## 2. Stack technique (Verrouillée)
|
||||
|
||||
### 2.1 Front-end : Svelte 5 + SvelteKit 2
|
||||
- Obligatoire. Compilateur léger, CSS scopé natif, SSR, MIT, PWA.
|
||||
|
||||
### 2.2 Cartographie : MapLibre GL JS (Verrouillé)
|
||||
- **Obligatoire.** Pas d'évaluation de Cesium, iTowns ou Three.js à faire.
|
||||
- MapLibre pour la carte de devinette (placement du marqueur) et la carte récapitulative.
|
||||
- Style cartographique custom OKI (couleurs, fonts, labels) basé sur des tiles OpenStreetMap auto-hébergées ou libres.
|
||||
- Zoom contraint aux 4 régions (le joueur ne peut pas scroller la carte en Europe ou aux US, ce qui donnerait un indice).
|
||||
|
||||
### 2.3 Back-end : Strapi ou SvelteKit seul (L'Architecte décide)
|
||||
- **Critère** : qui ajoute les lieux ? Si contributeurs non-devs → Strapi. Si devs uniquement → SvelteKit avec fichiers JSON locaux.
|
||||
- **Contrainte Wikipedia** : Ne **pas** stocker le texte Wikipedia en base. Le back-end (Strapi ou SvelteKit) doit interroger l'API Wikipedia/Wikidata en temps réel (ou avec un cache court) lors de l'affichage du résultat, à partir de l'ID Wikidata lié au lieu.
|
||||
|
||||
### 2.4 Base de données
|
||||
- SQLite (frugalité OKI).
|
||||
|
||||
---
|
||||
|
||||
## 3. Design du jeu
|
||||
|
||||
### 3.1 Types de parties (Modes)
|
||||
|
||||
#### Mode 1 : « Konnèt moniman » (Reconnaître le monument)
|
||||
- Photo d'un monument. Deviner la commune.
|
||||
- Pas de limite de temps par défaut. Option timer activable.
|
||||
- Indices progressifs optionnels (Région → Département → "C'est un fort colonial") avec pénalité de score.
|
||||
|
||||
#### Mode 2 : « Kote mwen ye ? » (Où suis-je ?)
|
||||
- Photo d'un lieu ordinaire (rue, carrefour, bord de mer, forêt guyanaise).
|
||||
- Deviner la commune. Timer optionnel.
|
||||
|
||||
#### Mode 3 : « Défi 5 rounds »
|
||||
- 5 tours consécutifs mélangeant monuments et lieux.
|
||||
- Résumé final avec la carte montrant les 5 marqueurs vs positions réelles.
|
||||
|
||||
#### Mode 4 : « Aprann » (Explorer)
|
||||
- Pas de score. Parcourir la carte, cliquer sur les marqueurs, voir les photos et lire les fiches Wikipedia / les appels à contribution.
|
||||
|
||||
### 3.2 Système de score
|
||||
|
||||
#### Formule (adaptée à la taille des communes)
|
||||
Les communes DOM sont petites. Un écart de 2 km peut signifier "à côté" ou "dans la commune d'à côté".
|
||||
```
|
||||
score = MAX_POINTS × e^(-distance / radius)
|
||||
```
|
||||
- `MAX_POINTS` = 5000.
|
||||
- `radius` par difficulté :
|
||||
- Facile : 50 km (tu peux te tromper de commune voisine)
|
||||
- Moyen : 15 km (tu dois être dans la bonne commune)
|
||||
- Difficile : 5 km (tu dois être dans le bon quartier)
|
||||
- Expert : 1 km (précision rue)
|
||||
|
||||
#### Bonus / Pénalités
|
||||
- Bonus temps (si activé) : max 20%.
|
||||
- Pénalité indice : -10% par indice utilisé.
|
||||
|
||||
### 3.3 Schéma de données d'un lieu
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"nom": "Fort Delgrès",
|
||||
"nom_creole": "Fò Delgrès",
|
||||
"region": "GUADELOUPE",
|
||||
"commune": "Basse-Terre",
|
||||
"coordonnees": { "lat": 16.0036, "lon": -61.7319 },
|
||||
"categorie": "MONUMENT",
|
||||
"difficulte": "MOYEN",
|
||||
"wikidata_id": "Q2216838",
|
||||
"photo": {
|
||||
"url": "/assets/fort-delgres.webp",
|
||||
"credit": "© Collectif OKI / Wikimedia Commons CC-BY-SA",
|
||||
"alt": "Vue de face du Fort Delgrès en pierre grise surplombant la mer"
|
||||
},
|
||||
"indices": [
|
||||
{ "niveau": 1, "texte": "Situé dans une capitale régionale" },
|
||||
{ "niveau": 2, "texte": "C'est un fort historique face à la mer" }
|
||||
]
|
||||
}
|
||||
```
|
||||
*Note : Le texte éducatif vient de l'API Wikipedia via `wikidata_id`. Si `wikidata_id` est null, le front déclenche le mode "Lacune documentaire".*
|
||||
|
||||
---
|
||||
|
||||
## 4. Répartition des tâches par agent
|
||||
|
||||
### Agent Architecte (exécute en premier)
|
||||
**Sorties attendues** :
|
||||
1. **Décision Strapi vs SvelteKit seul** (argumentée).
|
||||
2. **Architecture des tiles** : Source des tiles MapLibre (style OKI, auto-hébergé via tileserver-gl).
|
||||
3. **Stratégie Wikipedia/Wikidata** : Comment le front/back récupère l'extrait Wikipedia en français à partir du `wikidata_id`. Endpoints API MWAPI à utiliser, stratégie de cache.
|
||||
4. **Arborescence du projet** complète.
|
||||
5. **Spécifications API REST** (sécurité anti-triche : ne jamais envoyer les coordonnées au client avant la soumission du marqueur).
|
||||
|
||||
### Agent Back-end (si Strapi retenu)
|
||||
**Tâches** :
|
||||
1. Strapi sur SQLite, zéro telemetry.
|
||||
2. Content Type `Lieu` (schéma ci-dessus).
|
||||
3. Endpoints custom sécurisés (random sans coordonnées, soumission guess).
|
||||
4. Mise en place d'un proxy/cache léger pour les requêtes Wikipedia (pour ne pas se faire bloquer par l'API Wikimédia et accélérer l'affichage).
|
||||
|
||||
### Agent Front-end (SvelteKit) — Le cœur du projet
|
||||
**Tâches** :
|
||||
|
||||
#### 4.1 Carte MapLibre
|
||||
- Intégration de MapLibre GL JS.
|
||||
- Style custom OKI (couleurs, typographie).
|
||||
- Zoom contraint aux 4 régions (bounds géographiques stricts).
|
||||
- Marqueur draggable pour la devinette.
|
||||
- Boutons zoom +/- visibles (pas de geste obligatoire).
|
||||
- Performance : lazy load de MapLibre (ne charger le JS que sur les écrans de jeu).
|
||||
|
||||
#### 4.2 L'Écran de jeu (Layout split)
|
||||
- **Mobile** : Photo en haut (60%), Carte en bas (40%), Bouton "Valider" fixe en zone du pouce (tiers inférieur).
|
||||
- **Desktop** : Photo à gauche (50%), Carte à droite (50%).
|
||||
- Timer discret si activé (cercle qui se vide, couleurs douces).
|
||||
- Bouton "Valider ma position" (action primaire unique, effet Von Restorff).
|
||||
- Bouton "Passer" (secondaire).
|
||||
- Bouton "Indice" (tertiaire, affiche le texte et la pénalité).
|
||||
|
||||
#### 4.3 L'Écran de résultat (CRUCIAL : Phase éducative)
|
||||
Après validation, le marqueur vole vers la position réelle (sauf si `prefers-reduced-motion`).
|
||||
|
||||
**Cas A : Le lieu a un `wikidata_id` (Données existantes)**
|
||||
- Afficher le score et la distance.
|
||||
- Afficher un panneau éducatif contenant :
|
||||
- Titre du lieu (lien vers la page Wikipedia).
|
||||
- Extrait de l'article Wikipedia (récupéré via API).
|
||||
- Commune et Région.
|
||||
- Ton : "Tu as trouvé ! Apprends-en plus sur ce lieu."
|
||||
|
||||
**Cas B : Le lieu n'a PAS de `wikidata_id` (Lacune documentaire)**
|
||||
- Afficher le score et la distance.
|
||||
- Afficher un panneau **distinct visuellement** (couleur différente, iconographie spécifique) avec un message pédagogique fort :
|
||||
- *Titre* : "Pwen blindé — Sa pa dokimanté" (Point aveugle — Ce n'est pas documenté).
|
||||
- *Texte (FR)* : "Ce lieu existe, mais il n'a pas de page sur Wikipédia ni de fiche sur Wikidata. Pour nos régions, c'est un enjeu majeur : si nous ne documentons pas nos propres territoires, notre histoire et notre géographie disparaissent des cartes numériques et des bases de données mondiales (qui alimentent même l'intelligence artificielle)."
|
||||
- *Texte (CRÉOLE)* : (Équivalent en créole, à intégrer via le système i18n).
|
||||
- *Call to action* : Bouton "Kontribyé sou Wikipédia" (lien vers l'éditeur Wikipédia avec le titre du lieu pré-rempli dans la barre de recherche, ou lien vers un guide OKI "Comment contribuer à Wikipédia").
|
||||
- **Soigner particulièrement cet écran (Peak-End rule de la doctrine OKI)** : c'est ici que le jeu devient un outil politique et éducatif, pas juste un divertissement.
|
||||
|
||||
#### 4.4 Écrans annexes
|
||||
- **Accueil** : Titre "JWE", 4 cartes régions, choix du mode, bouton "Jouer" en zone pouce.
|
||||
- **Résultat final** : Carte récapitulative, score total, bouton "Partager" (génère une image canvas à télécharger, pas de share API propriétaire).
|
||||
- **Explorer** : Carte pleine page avec marqueurs, filtres par région, panneau latéral/bottom sheet avec la fiche Wikipedia ou le message de lacune.
|
||||
|
||||
#### 4.5 Technique
|
||||
- PWA installable.
|
||||
- Photos en WebP/AVIF, `srcset`, lazy loading.
|
||||
- Navigation clavier sur la carte.
|
||||
- i18n (FR / Créole) pour toute l'UI.
|
||||
|
||||
### Agent Contenu (exécute en parallèle)
|
||||
**Tâches** :
|
||||
1. Produire un **JSON de test de 40 lieux** (10/region).
|
||||
2. **PIÈGE INTENTIONNEL** : Pour chaque région, inclure **2 à 3 lieux réels qui n'ont PAS de page Wikipedia française** (ex: une petite ravine en Guyane, un morne spécifique en Martinique, un calvaire ou une boutique historique en Guadeloupe, un site naturel à La Réunion). Laisser leur `wikidata_id` à `null` dans le JSON.
|
||||
3. Pour les 7-8 autres lieux par région : fournir le vrai `wikidata_id` (ex: Q2216838 pour Fort Delgrès).
|
||||
4. Fournir les URLs de photos Wikimedia Commons réelles (vérifier la licence CC).
|
||||
|
||||
### Agent Intégration & QA
|
||||
**Tâches** :
|
||||
1. Vérifier l'intégration MapLibre + API Lieux + API Wikipedia.
|
||||
2. **Tester spécifiquement le Cas B (Lacune documentaire)** : vérifier que le message s'affiche correctement, que le ton est bon, que le lien de contribution fonctionne.
|
||||
3. Jouer une partie complète.
|
||||
4. **Checklist d'audit OKI** :
|
||||
- [ ] Une seule action primaire par écran
|
||||
- [ ] Mobile : bouton Valider en zone du pouce, carte utilisable au doigt
|
||||
- [ ] Performance : premier écran < 3s, MapLibre lazy-loadé
|
||||
- [ ] Éthique : pas de mécanique dopaminergique, score non punitif
|
||||
- [ ] Éducation : les deux cas (Wiki OK / Wiki Manquant) fonctionnent et sont distincts visuellement
|
||||
- [ ] Bilinguisme FR/créole présent (y compris dans le message de lacune)
|
||||
- [ ] PWA installable
|
||||
5. Mesures Core Web Vuts mobile 4G.
|
||||
|
||||
---
|
||||
|
||||
## 5. Doctrine UI/UX OKI (Extraits applicables)
|
||||
|
||||
- **Système 1** : L'écran de jeu est immédiatement lisible (Photo | Carte | Valider).
|
||||
- **Von Restorff** : Le bouton "Valider" est le seul élément fortement coloré.
|
||||
- **Peak-End** : L'écran de résultat (avec la fiche Wiki ou l'appel à contribution) doit laisser une impression forte et positive. C'est la fin du round, c'est ce dont le joueur se souviendra.
|
||||
- **Calm technology** : Le timer est informatif, pas anxiogène.
|
||||
- **Territoire** : Le créole est utilisé dans les micro-interactions ("Bravo !", "Kité sa ye ?", "Pwen blindé"). Les visuels de la carte ne sont pas le default bleu Google, mais un style OKI ancré dans le territoire.
|
||||
|
||||
---
|
||||
|
||||
## 6. Contraintes transversales
|
||||
|
||||
- **Licence** : MIT pour le code. Crédits obligatoires pour les photos Wikimedia.
|
||||
- **Zéro dépendance propriétaire** : MapLibre (BSD), Svelte (MIT). Aucune clé API payante.
|
||||
- **Sécurité** : Les coordonnées réelles ne sont jamais dans le payload initial envoyé au client.
|
||||
- **Git** : Commits atomiques.
|
||||
|
||||
---
|
||||
|
||||
## 7. Ordre d'exécution
|
||||
|
||||
1. **Agent Architecte** → Stack, Schema, Stratégie Wiki/MapLibre.
|
||||
2. **Agent Contenu** → JSON des 40 lieux (avec le piège Wiki manquant).
|
||||
3. **Agent Back-end** (si Strapi).
|
||||
4. **Agent Front-end** → SvelteKit, MapLibre, Mécanique de score, Écrans éducatifs (Cas A & B).
|
||||
5. **Agent QA** → Audit, test du message de lacune documentaire, rapport.
|
||||
|
||||
---
|
||||
|
||||
## 8. Livrables finaux
|
||||
|
||||
1. Dépôt Git complet.
|
||||
2. JSON de 40 lieux (avec la structure `wikidata_id: null` pour tester la lacune).
|
||||
3. Rapport d'audit OKI.
|
||||
4. Guide de déploiement auto-hébergé (SvelteKit + Tile Server).
|
||||
5. Guide de contribution ("Comment ajouter un lieu et lier sa page Wikidata").
|
||||
```
|
||||
Reference in New Issue
Block a user