113 lines
8.1 KiB
Markdown
113 lines
8.1 KiB
Markdown
|
|
# JWE — ADR-001 & ADR-002 (format audit OKI)
|
|||
|
|
|
|||
|
|
Deux décisions d'architecture rédigées selon le format du prompt d'audit post-exécution : critères bloquants, preuves exigées, rapport tabulaire, interdits. Elles **ne modifient pas** le build v1 en cours ; elles cadrent la phase 2 et une optimisation perf.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# ADR-001 — Mode Défi : seed-link en v1, PlaySocketJS en phase 2 conditionnée
|
|||
|
|
|
|||
|
|
- **Statut** : Accepté (v1) / À étudier (v2, gate explicite)
|
|||
|
|
- **Date** : 2026-07-17
|
|||
|
|
- **Décideurs** : Architecte OKI
|
|||
|
|
- **Références** : PlaySocketJS (MIT, rooms, CRDT, server-authoritative, battle-tested >1,3 M duels sur 1 instance Node) ; Geoguess/Geoguess (modèle de room sans compte, max 5 joueurs) ; prompt v2 §A5 (pas de comptes, pas de leaderboard serveur).
|
|||
|
|
|
|||
|
|
## Contexte
|
|||
|
|
|
|||
|
|
Le prompt v2 interdit comptes et leaderboard serveur. L'usage réel visé (OKI, AKILPA, salles de classe, événements) crée pourtant un besoin : **jouer les mêmes 5 lieux que d'autres et comparer les scores**. Deux horizons : maintenant (zéro serveur) et plus tard (temps réel, si le projet prouve sa traction).
|
|||
|
|
|
|||
|
|
## Décision
|
|||
|
|
|
|||
|
|
**v1 — Défi asynchrone par lien à seed partagée.**
|
|||
|
|
- L'URL de défi contient une seed opaque (ex. `/defi/<seed>`) ; le serveur (ou la fonction SvelteKit) dérive de la seed les mêmes 5 lieux pour tous les joueurs (PRNG seedé côté serveur, jamais côté client).
|
|||
|
|
- Aucune coordonnée dans l'URL ni dans le payload initial (anti-triche §6 du prompt v2 maintenu).
|
|||
|
|
- Fin de partie : l'image de partage canvas (déjà prévue prompt v2 §4.4) affiche le score ; la comparaison se fait humainement (screenshot dans le groupe WhatsApp/Signal). Zéro serveur d'état, zéro compte, cohérent doctrine.
|
|||
|
|
|
|||
|
|
**v2 — Duel temps réel via PlaySocketJS, UNIQUEMENT si le gate §"Conditions" est franchi.**
|
|||
|
|
- Modèle : rooms sans compte à la Geoguess (nom de room partagé, 2–5 joueurs), état synchronisé par PlaySocketJS en mode **server-authoritative** (le serveur valide les guesses et calcule les scores — jamais le client).
|
|||
|
|
- Hébergement : 1 instance Node sur le VPS OKI existant, dans l'enveloppe 40–50 €/mois. Aucune dépendance Google/Firebase (contraire à Geoguess — voir annexe).
|
|||
|
|
|
|||
|
|
## Options considérées
|
|||
|
|
|
|||
|
|
| Option | Souveraineté | Coût serveur | Effort | Anti-triche | Verdict |
|
|||
|
|
|---|---|---|---|---|---|
|
|||
|
|
| Seed-link asynchrone (v1) | Totale | Nul | S | Serveur dérive les lieux, scores non comparés en ligne | **Retenu v1** |
|
|||
|
|
| PlaySocketJS rooms (v2) | Bonne (MIT, self-host) | 1 instance Node | M | Server-authoritative natif | **Retenu v2 si gate** |
|
|||
|
|
| Socket.io maison | Bonne | 1 instance Node | M–L | À réimplémenter | Rejeté (réinvention) |
|
|||
|
|
| Supabase/Firebase Realtime | Mauvaise (cloud propriétaire) | Abonnement | M | Faible côté client | Rejeté (doctrine) |
|
|||
|
|
|
|||
|
|
## Conditions de déclenchement de la v2 (gate — bloquant)
|
|||
|
|
|
|||
|
|
La v2 n'est étudiée que si TOUTES les conditions suivantes sont remplies et documentées dans le rapport de gate :
|
|||
|
|
1. Traction mesurée : ≥ 30 parties/semaine pendant 4 semaines consécutives (mesure locale anonymisée, pas d'analytics tiers).
|
|||
|
|
2. Demande explicite : ≥ 5 retours d'utilisateurs ou partenaires (OKI, AKILPA, enseignants) demandant le défi en direct.
|
|||
|
|
3. Capacité d'hébergement confirmée sur le VPS OKI sans dépasser l'enveloppe 40–50 €/mois.
|
|||
|
|
|
|||
|
|
## Vérifications (obligatoires, preuves à l'appui)
|
|||
|
|
|
|||
|
|
- **V1 (bloquant, v1)** — Déterminisme : la même URL de défi produit les mêmes 5 lieux, dans le même ordre, sur deux machines différentes. Preuve : double exécution filmée ou logs serveur.
|
|||
|
|
- **V2 (bloquant, v1)** — Anti-fuite : l'URL et les payloads initiaux ne contiennent ni coordonnées, ni commune, ni `wikidata_id` décodable. Preuve : inspection réseau + revue de l'URL.
|
|||
|
|
- **V3 (bloquant, v1)** — L'image de partage n'affiche que score/pseudo libre, jamais les réponses des autres joueurs.
|
|||
|
|
- **V4 (bloquant, v2)** — POC PlaySocketJS : room à 3 clients, déconnexion/reconnexion d'un joueur sans perte d'état (CRDT), score validé côté serveur (tentative de triche client rejetée — preuve par requête forgée).
|
|||
|
|
- **V5 (v2)** — Licence : `npm view playsocketjs license` = MIT, consigné dans le rapport.
|
|||
|
|
- **V6 (v2)** — Charge : 10 rooms simultanées × 5 joueurs sur le VPS sans saturation (preuve : log ressources).
|
|||
|
|
|
|||
|
|
## Rapport (format obligatoire)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
| ID | Vérification | Méthode / Preuve | PASS/FAIL | Correctif appliqué |
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Interdits
|
|||
|
|
|
|||
|
|
- Aucun compte utilisateur, aucun leaderboard global, aucun stockage de pseudos au-delà de la room.
|
|||
|
|
- Aucune dépendance Google/Firebase/Supabase pour le temps réel.
|
|||
|
|
- Aucune copie de code Geoguess/Geoguess (Vue.js) : référence de design uniquement.
|
|||
|
|
- La v2 ne doit pas régresser le hors-scope du prompt v2 pour le solo.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# ADR-002 — Carte SVG/topojson légère pour les écrans hors-jeu (perf 4G)
|
|||
|
|
|
|||
|
|
- **Statut** : Accepté
|
|||
|
|
- **Date** : 2026-07-17
|
|||
|
|
- **Références** : composant carte SVG/topojson d'OpenGuessr Education (inspiration uniquement — licence MIT + Commons Clause = non-commercial, **aucune copie de code**) ; geo.api.gouv.fr (contours de communes GeoJSON, gratuit, sans clé — testé OK) ; prompt v2 §4.1 (lazy-load MapLibre) et §4.5 (perf).
|
|||
|
|
|
|||
|
|
## Contexte
|
|||
|
|
|
|||
|
|
MapLibre GL JS pèse ~800 kB de JS avant la première tile. L'accueil, le récapitulatif final et les fiches « Aprann » n'ont pas besoin d'une carte interactive complète. Sur 4G caribéen, charger MapLibre sur ces écrans détruit le budget < 3 s du prompt v2.
|
|||
|
|
|
|||
|
|
## Décision
|
|||
|
|
|
|||
|
|
- Les écrans **hors-jeu** (accueil 4 régions, mini-carte du récapitulatif, vignette de fiche lieu) utilisent une **carte SVG statique** générée au build depuis un topojson des communes des 4 régions, projection précalculée, aucune tile, aucun JS carte.
|
|||
|
|
- MapLibre reste réservé aux écrans **de jeu** (devinette, résultat, explorer interactif) et reste lazy-loadé.
|
|||
|
|
- Pipeline données : contours communes via `geo.api.gouv.fr/communes?codeRegion=01|02|03|04&fields=nom,code,contour&format=json&geometry=contour` → simplification (mapshaper, seuil à calibrer) → topojson versionné dans le repo → composant Svelte SVG from scratch (MIT).
|
|||
|
|
|
|||
|
|
## Vérifications
|
|||
|
|
|
|||
|
|
- **V1 (bloquant)** — Budget poids : topojson simplifié des 4 régions ≤ 150 kB gzippé ; preuve : taille du fichier + `gzip -9` consignés. Si dépassement : simplifier davantage ou découper par région avec import dynamique.
|
|||
|
|
- **V2 (bloquant)** — LCP accueil < 2,5 s en throttling 4G (Lighthouse mobile, 3 runs, médiane consignée).
|
|||
|
|
- **V3** — Rendu sans JS : la carte SVG s'affiche en SSG avec JS désactivé ; chaque région est un `<a>` ou `<button>` réel (accessibilité clavier, lecteur d'écran : nom de région en FR + créole).
|
|||
|
|
- **V4** — Attribution données : © contributeurs OpenStreetMap / réutilisation données publiques mentionnée dans le footer (licence ODbL pour les contours dérivés OSM le cas échéant).
|
|||
|
|
- **V5** — Zéro code copié d'OpenGuessr Education : revue de provenance, le composant est écrit from scratch (licence MIT du projet).
|
|||
|
|
|
|||
|
|
## Rapport (format obligatoire)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
| ID | Vérification | Méthode / Preuve | PASS/FAIL | Correctif appliqué |
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Interdits
|
|||
|
|
|
|||
|
|
- Ne pas charger MapLibre (ni son CSS) sur l'accueil ou le récapitulatif.
|
|||
|
|
- Ne pas embarquer de tuiles raster de substitution (le SVG est vectoriel pur).
|
|||
|
|
- Ne pas copier le code d'OpenGuessr Education (Commons Clause).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Annexe — Étude Geoguess/Geoguess (référence, 2026-07-17)
|
|||
|
|
|
|||
|
|
- **Projet** : clone GeoGuessr open source, solo + multijoueur par rooms (nom de room partagé, ≤ 5 joueurs), PWA, cartes custom GeoJSON, licence **MIT**.
|
|||
|
|
- **Stack** : Vue.js + Google Maps StreetView + Firebase → **non réutilisable** (doctrine zéro Google ; Vue ≠ Svelte).
|
|||
|
|
- **Signal fort** : leur README admet que la démo publique est limitée par le **prix de l'API Google** et renvoie vers l'auto-déploiement avec clé personnelle — justification directe du zéro propriétaire OKI, à citer dans l'ADR d'architecture initial.
|
|||
|
|
- **À retenir** : (1) le modèle de room sans compte (base UX de l'ADR-001 v2) ; (2) le repo **GeoGuess-Maps**, liste de cartes communautaires — modèle pour les futurs map-packs JWE contribués par la communauté OKI/AKILPA via PR, sans CMS.
|