Commit Graph
4 Commits
Author SHA1 Message Date
williamandClaude Sonnet 5 e82eb7ce88 Retire l'export exécutable (.exe) et la partie publique en ligne (/jouer)
Build and deploy / test-python (push) Successful in 7m5s
Build and deploy / test-js (push) Successful in 58s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Décision produit : seul l'export Web/SCORM (LMS) est pertinent — l'export
exécutable Windows autonome (publish/build_package.py, bouton "Publier")
et la partie publique par joueur (/jouer/<slug>, routes/public_play/,
"Publier en ligne") sont jugés redondants et retirés.

Conserve le mécanisme d'état "par joueur" (db/global_vars,
db/rows, per_player) : infrastructure générique déjà utilisée par
Score/Progression et testée indépendamment de toute route publique
(voir tests/test_player_state.py), aucune raison de la retirer.

_STATIC_ITEMS/_copy_characters (copie sélective des sprites CraftPix
réellement utilisés) migrent de build_package.py vers
build_scorm_package.py, seul appelant restant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 10:59:28 +02:00
williamandClaude Sonnet 5 9776fbc057 Score/Progression (Phase 1.1 de la feuille de route produit)
Build and deploy / test-python (push) Successful in 7m27s
Build and deploy / test-js (push) Successful in 1m16s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Concept de premier ordre, distinct du système de variables globales —
préalable identifié aux futurs exports SCORM/xAPI (note de cadrage
.claude/Forge_Engine_Cadrage.pdf) : ces standards ont besoin d'un signal
"score"/"terminé" propre, pas d'une convention sur une variable choisie
par le créateur.

- db/scoring/ (même patron que db/global_vars/) : table _scoring, un
  score numérique + un statut (non_commence/en_cours/termine/reussi/
  echoue) par joueur (voir db.PLAYER_SHARED pour l'aperçu créateur).
- Deux nouvelles actions de flux, dans les deux éditeurs (document et
  scène) : "Modifier le score" (réutilise le vocabulaire d'opérations
  déjà là pour "Modifier une variable" — incrémenter/définir/etc., aucune
  nouvelle colonne de nœud) et "Définir le statut de la partie".
- Routes créateur (routes/flow/flow_node_run_score.py,
  flow_node_run_status.py) + miroirs publics par joueur
  (routes/public_play/) — même principe que flow_node_run_variable.py.
- GET /game/<slug>/scoring/<player_id> : lecture interne, pas exposée au
  joueur, préparée pour être consommée par le futur export Web/SCORM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 06:23:37 +02:00
williamandClaude Sonnet 5 3c39f1a249 Phase 1 (2/3) : route publique /jouer/<slug> + identité visiteur
Build and deploy / test (push) Failing after 8s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Ajoute la vraie route hébergée multi-joueurs qui manquait totalement
(voir le constat d'exploration : /game/<slug>/play est réservé au
créateur connecté, "Publier" ne génère qu'un exécutable mono-joueur) —
un visiteur anonyme peut maintenant jouer un jeu explicitement publié en
ligne, avec sa propre partie (variables/objets per_player posés dans le
commit précédent).

core/player_identity.py : identité visiteur via un cookie NON SIGNÉ
(forge_player_id, secrets.token_urlsafe(16), 1 an) — une simple clé de
partition, jamais un jeton d'autorisation.

routes/public_play/ : 4 routes, miroirs des routes existantes de l'aperçu
créateur mais threadées avec le vrai player_id du cookie au lieu du
sentinel PLAYER_SHARED :
- GET /jouer/<slug> (game_play_public.py)
- GET /jouer/<slug>/runtime-payload
- POST /jouer/<slug>/flow/nodes/<id>/run-data
- POST /jouer/<slug>/flow/nodes/<id>/run-variable
Chacune vérifie elle-même db.is_public_played(slug) (404 sinon) — un jeu
n'est exposé publiquement que si le créateur l'a explicitement basculé
"Publier en ligne" (nouveau db/games/is_public_played.py, réutilise la
table générique _meta, comme game_meta.py pour 'name').

core/auth_guard.py : les 4 endpoints publics ajoutés à _PUBLIC_ENDPOINTS
— la garde générique de connexion les laisse passer sans session, mais
chaque vue vérifie quand même is_public_played elle-même (défense en
profondeur, pas seulement une liste d'exceptions). CSRF (core/csrf_guard.py)
n'a besoin d'AUCUN changement : le jeton est déjà lié à la session Flask,
qui existe pour n'importe quel visiteur (connecté ou non).

templates/play.html : FORGE_PLAY_URLS (posé en Phase -1) ne construit
plus ses URLs via des noms de endpoint fixes (url_for('runtime_payload',
...)) mais reçoit des URLs déjà résolues par la route elle-même
(runtime_payload_url/flow_node_run_data_url/flow_node_run_variable_url)
— nécessaire puisque ce même template sert maintenant DEUX familles de
routes (aperçu créateur ET partie publique), chacune avec ses propres
noms de endpoint. routes/play/game_play.py (aperçu créateur, INCHANGÉ
comportement) et game_play_public.py passent chacun ses propres URLs.

templates/base.html : bascule "🌐 Publier en ligne" dans la barre de
navigation du jeu, à côté de "📦 Publier" (export .zip) — deux
fonctionnalités distinctes. db/games/game_meta.py expose maintenant
is_public_played, disponible partout où `game` est dans le contexte.

Vérifié : 237 tests passent (5 nouveaux dans test_public_play.py, dont un
bout-en-bout via HTTP avec deux VRAIS clients de test anonymes — deux
cookies forge_player_id différents — qui obtiennent des valeurs de
variable indépendantes, et un qui verrouille que l'aperçu créateur reste
inchangé). Syntaxe JS validée sur les deux variantes de play.html rendu
(aperçu créateur et partie publique).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:46:00 +02:00
williamandwilliam 3f4ebc4527 first commit
Build and deploy / build-and-push (push) Successful in 17s
Build and deploy / deploy (push) Successful in 10s
2026-08-21 16:23:49 +02:00