Refonte du Scenario en arbre de decision (modale dediee, plus de vrai/faux
Build and deploy / test-python (push) Failing after 1m15s
Build and deploy / test-js (push) Successful in 54s
Build and deploy / lint-python (push) Failing after 1m12s
Build and deploy / lint-js (push) Failing after 1m8s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m4s
Build and deploy / test-python (push) Failing after 1m15s
Build and deploy / test-js (push) Successful in 54s
Build and deploy / lint-python (push) Failing after 1m12s
Build and deploy / lint-js (push) Failing after 1m8s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m4s
Retour utilisateur : "une consequence peut mener a d'autres choix et
ainsi de suite, il n'y a pas de notion vrai/faux, il faut une modale
avec la possibilite de construire un veritable arbre de choix
consequence". Remplace le modele plat (situation + 2-4 choix + un seul
bon choix + une consequence terminale) par un vrai graphe de nœuds :
{"title", "nodes": [{"id", "text", "choices": [{"text", "target_id"}]}]}
- nodes[0] est la situation initiale, chaque choix peut pointer vers
n'importe quel autre nœud (branchement, convergence, fins multiples),
un nœud sans choix est une fin de branche valide. Aucune notion de
bonne/mauvaise reponse.
L'arbre se construit desormais dans une modale dediee (trop de
structure pour la colonne etroite du panneau Proprietes) : liste de
nœuds, chaque choix avec un menu deroulant "mene a" listant les autres
nœuds ou "fin de branche". La modale est un composant generique
(.docModal*) independant de tout framework externe.
sanitize_scenario_config degrade silencieusement tout target_id
orphelin (nœud supprime) vers None plutot que de faire echouer le
scenario entier. Le lecteur cote client navigue le graphe nœud par
nœud, le texte du nœud visite remplace le precedent (toujours pas un
Quiz), jusqu'a une fin de branche puis passage au scenario suivant.
Verifie via simulation DOM reelle (jsdom) : navigation ramifiee
(branchement, convergence, fin via nœud vide ET via choix sans cible),
plusieurs arbres a la suite, et l'editeur modal complet (ouverture,
ajout/suppression de nœud avec reparation des references pendantes,
changement de cible, fermeture bouton/fond/Echap).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
c04a81cfec
commit
a529857379
@@ -183,21 +183,41 @@ liste finale est tronquée à `MAX_WORDS`.
|
||||
## `scenario_config.py` — modèle de données du mini-jeu Scénario
|
||||
|
||||
Cinquième mini-jeu implémenté : l'apprenant lit une situation initiale,
|
||||
choisit une option parmi 2 à 4, puis découvre la conséquence de SON
|
||||
choix ainsi que s'il s'agissait du bon choix (voir
|
||||
`document_engine/rendering/render_document_element.py`::
|
||||
`_render_scenario_player`). Le créateur peut définir plusieurs scénarios,
|
||||
joués les uns après les autres dans l'ORDRE d'écriture (jamais mélangés,
|
||||
contrairement à Association/Memory/Mots mêlés). Même convention que
|
||||
`quiz_config.py`.
|
||||
choisit une option, puis découvre la conséquence de SON choix — cette
|
||||
conséquence peut elle-même mener à de nouveaux choix, et ainsi de suite
|
||||
(arbre de décision, voir `document_engine/rendering/
|
||||
render_document_element.py`::`_render_scenario_player`). Aucune notion
|
||||
de bonne/mauvaise réponse (retour utilisateur du 20/09/2026 : "il n'y a
|
||||
pas de notion vrai/faux, l'utilisateur observe les conséquences") —
|
||||
l'apprenant explore simplement les branches jusqu'à une fin. Le
|
||||
créateur peut définir plusieurs scénarios (plusieurs arbres
|
||||
indépendants), joués les uns après les autres dans l'ORDRE d'écriture
|
||||
(jamais mélangés, contrairement à Association/Memory/Mots mêlés). Même
|
||||
convention resolve_X/sanitize_X que `quiz_config.py`.
|
||||
|
||||
### `MIN_SCENARIO_CHOICES`, `MAX_SCENARIO_CHOICES: int`
|
||||
Bornes de validation (`2`/`4` choix par scénario). Nommées explicitement
|
||||
"SCENARIO" (pas juste `MIN_CHOICES`/`MAX_CHOICES`) pour éviter toute
|
||||
collision avec les constantes de même nom de `quiz_config.py`, qui
|
||||
bornent un concept différent (le nombre de réponses d'une question de
|
||||
**Structure d'un scénario** : `{"title": str, "nodes": [...]}`.
|
||||
`nodes[0]` est TOUJOURS la situation initiale (racine de l'arbre, jamais
|
||||
supprimable depuis le panneau Propriétés — voir
|
||||
`forgeDocRenderScenarioNodeHtml`, static/document/js/document-editor.js).
|
||||
Chaque nœud est `{"id": str, "text": str, "choices": [...]}` — `id` est
|
||||
une référence STABLE (générée côté client, jamais recalculée côté
|
||||
serveur) vers laquelle un choix d'un AUTRE nœud peut pointer via son
|
||||
`target_id` ; un nœud SANS choix est une fin de branche (état normal,
|
||||
pas une erreur — contrairement à l'ancien modèle qui exigeait 2 à 4
|
||||
choix par scénario). Un choix est `{"text": str, "target_id": str |
|
||||
None}` — `target_id` à `None` signifie "fin de branche à ce choix".
|
||||
|
||||
### `MAX_SCENARIO_CHOICES: int`
|
||||
Borne technique du nombre de choix par nœud (`4`) — évite une UI
|
||||
disproportionnée, aucun lien avec une notion de bonne/mauvaise réponse.
|
||||
Nommée explicitement "SCENARIO" (pas juste `MAX_CHOICES`) pour éviter
|
||||
toute collision avec la constante de même nom de `quiz_config.py`, qui
|
||||
borne un concept différent (le nombre de réponses d'une question de
|
||||
quiz) — `document_engine/__init__.py` ré-exporte l'intégralité de l'API
|
||||
publique du paquet à plat, un nom générique entrerait en collision.
|
||||
Contrairement à l'ancien modèle, il n'existe PAS de minimum : un nœud
|
||||
peut avoir 0 choix (fin de branche), c'est un état valide, pas une
|
||||
erreur à filtrer.
|
||||
|
||||
### `DEFAULT_SCENARIO_CONFIG: dict[str, Any]`
|
||||
`{"theme_color": "#ff5f2e", "scenarios": []}`.
|
||||
@@ -207,13 +227,16 @@ Valide/nettoie une config de scénario arbitraire (JSON venu du client) —
|
||||
jamais ne lève, renvoie toujours un dict COMPLET fusionné sur
|
||||
`DEFAULT_SCENARIO_CONFIG`. Chaque scénario de `raw_config["scenarios"]`
|
||||
est validé indépendamment (voir `_sanitize_scenario`/
|
||||
`_sanitize_scenario_choice`, privées) : la `situation` doit être non
|
||||
vide une fois `.strip()`-ée, et il doit rester au moins
|
||||
`MIN_SCENARIO_CHOICES` choix valides (texte non vide) une fois la liste
|
||||
tronquée à `MAX_SCENARIO_CHOICES` — sinon le scénario entier est
|
||||
silencieusement supprimé de la liste. La `consequence` d'un choix, elle,
|
||||
peut rester vide (un créateur peut vouloir la renseigner plus tard sans
|
||||
que ça invalide le choix). `correct_index` retombe sur `0` s'il est hors
|
||||
bornes ou absent.
|
||||
`_sanitize_scenario_node`/`_sanitize_scenario_choice`, privées) : le
|
||||
`title` doit être non vide, chaque nœud doit avoir un `id` (chaîne non
|
||||
vide) et un `text` non vide une fois `.strip()`-é (sinon le nœud entier
|
||||
est supprimé), et ses choix sont tronqués à `MAX_SCENARIO_CHOICES`. Le
|
||||
scénario entier est supprimé s'il ne reste plus aucun nœud valide après
|
||||
nettoyage (il faut au moins la situation initiale). Une fois l'ensemble
|
||||
des ids valides connu, tout `target_id` qui ne pointe plus vers un nœud
|
||||
existant (nœud invalide/supprimé) est silencieusement remis à `None`
|
||||
("fin de branche") plutôt que de faire échouer tout le scénario — même
|
||||
philosophie que le reste de ce module : ne jamais faire échouer une
|
||||
structure entière pour une seule référence cassée.
|
||||
- **Retour** : dict complet (mêmes clés que `DEFAULT_SCENARIO_CONFIG`).
|
||||
- **Exceptions** : aucune.
|
||||
|
||||
Reference in New Issue
Block a user