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>
112 lines
3.4 KiB
Python
112 lines
3.4 KiB
Python
"""
|
|
document_engine — support de formation : entité racine séparée du jeu 2D
|
|
(voir docs/plan/PLAN.md). Un support = un seul document, structuré en deux
|
|
couches sur le même canevas :
|
|
- le flux de contenu (titre/paragraphe/image/bouton/mini-jeux), organisé
|
|
en rangées ("row") par le moteur d'inférence de layout (voir
|
|
document_engine/rendering/render_document_element.py) ;
|
|
- la couche de formes libres (rectangle/cercle/triangle/trait), position-
|
|
nées en absolu (x/y/width/height/rotation/z_index).
|
|
|
|
Tout est stocké dans support.db (voir db/supports/) : une seule table,
|
|
_document_elements, portant les deux couches via parent_id (NULL = top-
|
|
niveau ou forme libre, sinon = enfant d'une rangée).
|
|
|
|
Aucun import croisé avec game_engine ou tout module lié au jeu 2D — voir
|
|
le contrat import-linter dans pyproject.toml (game_engine | document_engine
|
|
sont un même palier, mutuellement isolés).
|
|
|
|
Ce module se contente de ré-exporter l'intégralité de l'API publique du
|
|
paquet (pattern "un fichier = une fonction, un dossier = une responsabi-
|
|
lité", voir game_engine/__init__.py).
|
|
"""
|
|
|
|
from .elements.add_document_element import add_document_element
|
|
from .elements.delete_document_element import delete_document_element
|
|
from .elements.get_document_element import get_document_element
|
|
from .elements.list_document_elements import list_document_elements
|
|
from .elements.move_document_element import move_document_element
|
|
from .elements.update_document_element_attributes import update_document_element_attributes
|
|
from .labels.association_config import (
|
|
DEFAULT_ASSOCIATION_CONFIG,
|
|
MAX_PAIRS,
|
|
MIN_PAIRS,
|
|
sanitize_association_config,
|
|
)
|
|
from .labels.element_kind_labels import (
|
|
CONTENT_KINDS,
|
|
ELEMENT_KIND_LABELS,
|
|
ELEMENT_LIBRARY,
|
|
MINIGAME_KINDS,
|
|
SHAPE_KINDS,
|
|
element_default_attributes,
|
|
)
|
|
from .labels.memory_config import (
|
|
CARD_MODES,
|
|
DEFAULT_MEMORY_CONFIG,
|
|
MAX_CARDS,
|
|
MIN_CARDS,
|
|
sanitize_memory_config,
|
|
)
|
|
from .labels.mots_config import (
|
|
DEFAULT_MOTS_CONFIG,
|
|
MAX_WORDS,
|
|
MIN_WORDS,
|
|
sanitize_mots_config,
|
|
)
|
|
from .labels.quiz_config import (
|
|
DEFAULT_QUIZ_CONFIG,
|
|
MAX_CHOICES,
|
|
MAX_TIMER_SECONDS,
|
|
MIN_CHOICES,
|
|
MIN_TIMER_SECONDS,
|
|
quiz_total_points,
|
|
sanitize_quiz_config,
|
|
)
|
|
from .labels.scenario_config import (
|
|
DEFAULT_SCENARIO_CONFIG,
|
|
MAX_SCENARIO_CHOICES,
|
|
sanitize_scenario_config,
|
|
)
|
|
from .rendering.render_document_element import render_document, render_document_element
|
|
|
|
__all__ = [
|
|
"CARD_MODES",
|
|
"CONTENT_KINDS",
|
|
"DEFAULT_ASSOCIATION_CONFIG",
|
|
"DEFAULT_MEMORY_CONFIG",
|
|
"DEFAULT_MOTS_CONFIG",
|
|
"DEFAULT_QUIZ_CONFIG",
|
|
"DEFAULT_SCENARIO_CONFIG",
|
|
"ELEMENT_KIND_LABELS",
|
|
"ELEMENT_LIBRARY",
|
|
"MAX_CARDS",
|
|
"MAX_CHOICES",
|
|
"MAX_PAIRS",
|
|
"MAX_SCENARIO_CHOICES",
|
|
"MAX_TIMER_SECONDS",
|
|
"MAX_WORDS",
|
|
"MIN_CARDS",
|
|
"MIN_CHOICES",
|
|
"MIN_PAIRS",
|
|
"MIN_TIMER_SECONDS",
|
|
"MIN_WORDS",
|
|
"MINIGAME_KINDS",
|
|
"SHAPE_KINDS",
|
|
"add_document_element",
|
|
"delete_document_element",
|
|
"element_default_attributes",
|
|
"get_document_element",
|
|
"list_document_elements",
|
|
"move_document_element",
|
|
"quiz_total_points",
|
|
"render_document",
|
|
"render_document_element",
|
|
"sanitize_association_config",
|
|
"sanitize_memory_config",
|
|
"sanitize_mots_config",
|
|
"sanitize_quiz_config",
|
|
"sanitize_scenario_config",
|
|
"update_document_element_attributes",
|
|
]
|