Build and deploy / test-python (push) Failing after 59s
Build and deploy / test-js (push) Successful in 50s
Build and deploy / lint-python (push) Failing after 59s
Build and deploy / lint-js (push) Failing after 1m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 59s
Cinquieme mini-jeu du support de formation : le createur ecrit une situation initiale, definit 2 a 4 choix, indique lequel est le bon, et redige la consequence de chaque choix. Plusieurs scenarios peuvent etre crees, joues dans l'ordre d'ecriture (jamais melanges, contrairement a Association/Memory/Mots meles : ce sont des mises en situation sequentielles). En Apercu, l'apprenant lit la situation, choisit une option, decouvre la consequence de SON choix et si c'etait le bon, puis passe au scenario suivant. Comme Association/Memory/Mots meles, le dernier scenario reste affiche une fois repondu : seul le bouton Recommencer apparait, jamais un ecran de resultat separe (reserve au Quiz). Reutilise les classes visuelles du Quiz (docQuizOptions/ docQuizFeedback/docQuizNextBar) plutot que de dupliquer ces regles. Verifie via simulation DOM reelle (jsdom) : progression entre plusieurs scenarios, choix correct/incorrect avec revelation de la bonne reponse, comportement de fin de partie, panneau Proprietes (ajout/suppression de scenario, changement du nombre de choix, selection du bon choix). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
220 lines
11 KiB
Markdown
220 lines
11 KiB
Markdown
# document_engine/labels/
|
|
|
|
Catalogue statique des types d'éléments du support de formation : bibliothèque
|
|
groupée par catégorie (panneau gauche de l'éditeur), libellés d'affichage, et
|
|
attributs par défaut posés à la création de chaque type.
|
|
|
|
## `SHAPE_KINDS: tuple[str, ...]`
|
|
`("rectangle", "cercle", "triangle", "trait")` — couche de formes libres,
|
|
toujours en position absolue (`parent_id = NULL`).
|
|
|
|
## `CONTENT_KINDS: tuple[str, ...]`
|
|
`("titre", "paragraphe", "image", "bouton")` — éléments du flux, peuvent
|
|
être top-niveau ou enfants d'une rangée.
|
|
|
|
## `MINIGAME_KINDS: tuple[str, ...]`
|
|
`("quiz", "association", "memory", "mots", "scenario", "zones")` —
|
|
`"quiz"`, `"association"` et `"memory"` sont implémentés (voir
|
|
`quiz_config.py`/`association_config.py`/`memory_config.py` ci-dessous) ;
|
|
les 3 autres gardent un panneau Propriétés minimal (emplacement réservé),
|
|
formulaires de contenu dédiés hors périmètre de cette passe.
|
|
|
|
## `ELEMENT_LIBRARY: dict[str, dict[str, Any]]`
|
|
Bibliothèque affichée dans le panneau gauche, groupée par catégorie
|
|
(`mise_en_page` / `contenu` / `minigames`), chaque entrée portant un
|
|
`label` et sa liste de `kinds`. `"row"` n'y apparaît jamais — créé
|
|
implicitement par le moteur de layout, jamais choisi directement dans la
|
|
bibliothèque.
|
|
|
|
## `ELEMENT_KIND_LABELS: dict[str, str]`
|
|
Libellé d'affichage pour chaque `kind`, y compris `"row"` (pour
|
|
l'affichage/debug hors bibliothèque).
|
|
|
|
## `element_default_attributes(kind: str) -> dict[str, Any]`
|
|
Attributs posés à la création d'un élément de ce type (voir
|
|
`document_engine/elements/add_document_element.py`).
|
|
- **Retour** : un dict d'attributs par défaut, dépendant du `kind` :
|
|
formes (`x/y/width/height/rotation/z_index/fill/stroke/stroke_width/label`),
|
|
texte (`content/style` + `bold/italic/underline/align/color`),
|
|
image (`src/alt`), bouton (`label/target`), rangée (`gap/align/justify`),
|
|
quiz (`DEFAULT_QUIZ_CONFIG`, voir `quiz_config.py`), association
|
|
(`DEFAULT_ASSOCIATION_CONFIG`, voir `association_config.py`), memory
|
|
(`DEFAULT_MEMORY_CONFIG`, voir `memory_config.py`), autre mini-jeu
|
|
(`theme_color`), ou `{}` pour un `kind` inconnu.
|
|
- **Exceptions** : aucune.
|
|
|
|
## `quiz_config.py` — modèle de données du mini-jeu Quiz
|
|
|
|
Seul mini-jeu réellement implémenté (les autres `MINIGAME_KINDS` restent
|
|
un emplacement réservé). Même convention `resolve_X`/`sanitize_X` que
|
|
`game_engine/rendering/quiz_box_config.py` côté jeu, mais sans aucun
|
|
import croisé (voir `docs/plan/PLAN.md`).
|
|
|
|
### `MIN_CHOICES`, `MAX_CHOICES`, `MIN_TIMER_SECONDS`, `MAX_TIMER_SECONDS`, `DEFAULT_TIMER_SECONDS: int`
|
|
Bornes de validation (`2`/`4` choix, `5`/`300` secondes, `30` par défaut).
|
|
|
|
### `DEFAULT_QUIZ_CONFIG: dict[str, Any]`
|
|
`{"theme_color": "#ff5f2e", "timer_enabled": False, "timer_seconds": 30, "questions": []}`.
|
|
|
|
### `sanitize_quiz_config(raw_config: Any) -> dict[str, Any]`
|
|
Valide/nettoie une config de quiz arbitraire (JSON venu du client) —
|
|
jamais lève, renvoie toujours un dict COMPLET fusionné sur
|
|
`DEFAULT_QUIZ_CONFIG`. Chaque question de `raw_config["questions"]` est
|
|
validée indépendamment (voir `_sanitize_question`, privée) : texte non
|
|
vide, au moins 2 choix non vides (tronqués à 4), `correct_index` remis à
|
|
0 s'il est absent/hors bornes/non-entier (un `bool` — qui est un `int` en
|
|
Python — est explicitement rejeté), `points` codé en entier ≥ 0. Une
|
|
question invalide est silencieusement supprimée de la liste (jamais une
|
|
levée qui ferait échouer tout le reste du quiz).
|
|
- **Retour** : dict complet (mêmes clés que `DEFAULT_QUIZ_CONFIG`).
|
|
- **Exceptions** : aucune.
|
|
|
|
### `quiz_total_points(config: dict[str, Any]) -> int`
|
|
Somme du `points` de toutes les questions d'une config déjà sanitizée —
|
|
mirroir de `db/dialogue_lines.py::sum_question_rewards` côté jeu, utile
|
|
le jour où un export calculera un score maximum.
|
|
- **Retour** : entier ≥ 0.
|
|
- **Exceptions** : aucune.
|
|
|
|
## `association_config.py` — modèle de données du mini-jeu Association
|
|
|
|
Deuxième mini-jeu implémenté : l'apprenant relie chaque carte de gauche
|
|
("terme") à sa correspondance de droite ("définition") par glisser-déposer
|
|
(voir `document_engine/rendering/render_document_element.py`::
|
|
`_render_association_player`). Même convention que `quiz_config.py`.
|
|
|
|
### `MIN_PAIRS`, `MAX_PAIRS: int`
|
|
Bornes de validation (`2`/`8` paires). `MIN_PAIRS` n'est pas imposé par
|
|
`sanitize_association_config` (une seule paire valide reste acceptée,
|
|
comme un quiz à une seule question) — c'est une recommandation pour le
|
|
panneau Propriétés, pas une contrainte technique du rendu.
|
|
|
|
### `DEFAULT_ASSOCIATION_CONFIG: dict[str, Any]`
|
|
`{"theme_color": "#ff5f2e", "pairs": []}`.
|
|
|
|
### `sanitize_association_config(raw_config: Any) -> dict[str, Any]`
|
|
Valide/nettoie une config d'association arbitraire (JSON venu du client)
|
|
— jamais ne lève, renvoie toujours un dict COMPLET fusionné sur
|
|
`DEFAULT_ASSOCIATION_CONFIG`. Chaque paire de `raw_config["pairs"]` est
|
|
validée indépendamment (voir `_sanitize_pair`, privée) : les deux côtés
|
|
(`left`/`right`) doivent être non vides une fois `.strip()`-és, sinon la
|
|
paire entière est silencieusement supprimée de la liste (jamais une
|
|
levée qui ferait échouer tout le reste du mini-jeu). La liste finale est
|
|
tronquée à `MAX_PAIRS`.
|
|
- **Retour** : dict complet (mêmes clés que `DEFAULT_ASSOCIATION_CONFIG`).
|
|
- **Exceptions** : aucune.
|
|
|
|
## `memory_config.py` — modèle de données du mini-jeu Memory
|
|
|
|
Troisième mini-jeu implémenté : l'apprenant retourne des cartes pour
|
|
constituer des paires identiques (mode `"paire"`) ou simplement révéler
|
|
chaque carte une fois (mode `"single"`, sans appariement — voir
|
|
`document_engine/rendering/render_document_element.py`::
|
|
`_render_memory_player`). Même convention que `quiz_config.py`.
|
|
|
|
### `MIN_CARDS`, `MAX_CARDS: int`
|
|
Bornes de validation (`2`/`8` cartes DÉFINIES par le créateur — en mode
|
|
`"paire"`, le plateau affiche le double, chaque carte étant dupliquée).
|
|
`MIN_CARDS` n'est pas imposé par `sanitize_memory_config` (même logique
|
|
que `MIN_PAIRS` côté Association) — recommandation pour le panneau
|
|
Propriétés, pas une contrainte technique du rendu.
|
|
|
|
### `CARD_MODES: tuple[str, ...]`
|
|
`("paire", "single")`.
|
|
|
|
### `DEFAULT_MEMORY_CONFIG: dict[str, Any]`
|
|
`{"theme_color": "#ff5f2e", "mode": "paire", "cards": []}`.
|
|
|
|
### `sanitize_memory_config(raw_config: Any) -> dict[str, Any]`
|
|
Valide/nettoie une config de memory arbitraire (JSON venu du client) —
|
|
jamais ne lève, renvoie toujours un dict COMPLET fusionné sur
|
|
`DEFAULT_MEMORY_CONFIG`. `mode` retombe sur `"paire"` s'il n'est pas dans
|
|
`CARD_MODES`. Chaque carte de `raw_config["cards"]` est validée
|
|
indépendamment (voir `_sanitize_card`/`_sanitize_card_face`, privées) :
|
|
chaque face (`recto`/`verso`) a un `image` et un `text` indépendants et
|
|
tous deux optionnels, MAIS le `verso` doit avoir au moins l'un des deux
|
|
non vide (rien à révéler/apparier sinon) — le `recto`, lui, peut rester
|
|
entièrement vide (dos de carte générique "?" par défaut côté rendu). Une
|
|
carte invalide est silencieusement supprimée de la liste. La liste finale
|
|
est tronquée à `MAX_CARDS`.
|
|
- **Retour** : dict complet (mêmes clés que `DEFAULT_MEMORY_CONFIG`).
|
|
- **Exceptions** : aucune.
|
|
|
|
## `mots_config.py` — modèle de données du mini-jeu Mots mêlés
|
|
|
|
Quatrième mini-jeu implémenté : l'apprenant retrouve chaque mot caché
|
|
dans une grille de lettres (horizontalement, verticalement, ou en
|
|
diagonale — voir `document_engine/rendering/render_document_element.py`::
|
|
`_render_mots_player`, qui construit la grille elle-même). Même
|
|
convention que `quiz_config.py`.
|
|
|
|
### `MIN_WORDS`, `MAX_WORDS: int`
|
|
Bornes de validation (`5`/`10` mots). `MIN_WORDS` n'est pas imposé par
|
|
`sanitize_mots_config` (même logique que `MIN_PAIRS`/`MIN_CARDS`
|
|
côté Association/Memory) — recommandation pour le panneau Propriétés,
|
|
pas une contrainte technique du rendu : un seul mot valide reste
|
|
accepté, la grille se construit quand même autour de lui.
|
|
|
|
### `MIN_WORD_LENGTH`, `MAX_WORD_LENGTH: int`
|
|
Bornes de longueur d'un mot individuel une fois nettoyé (`2`/`20`
|
|
lettres) — un mot trop court n'a pas de sens à chercher, un mot trop
|
|
long compliquerait inutilement le calcul de la taille de la grille
|
|
(voir `_mots_grid_size_for_words` dans `render_document_element.py`).
|
|
|
|
### `DEFAULT_MOTS_CONFIG: dict[str, Any]`
|
|
`{"theme_color": "#ff5f2e", "words": []}`.
|
|
|
|
### `sanitize_mots_config(raw_config: Any) -> dict[str, Any]`
|
|
Valide/nettoie une config de mots mêlés arbitraire (JSON venu du
|
|
client) — jamais ne lève, renvoie toujours un dict COMPLET fusionné sur
|
|
`DEFAULT_MOTS_CONFIG`. Chaque mot de `raw_config["words"]` est nettoyé
|
|
indépendamment (voir `_sanitize_word`, privée) : mis en MAJUSCULES,
|
|
les accents sont retirés (décomposition NFKD + filtrage ASCII, pour que
|
|
deux mots qui se croisent sur une même case de la grille puissent
|
|
partager exactement la même lettre), seules les lettres sont
|
|
conservées. Un mot qui ne contient plus rien d'exploitable (ou moins de
|
|
`MIN_WORD_LENGTH` lettres) une fois nettoyé est silencieusement
|
|
supprimé de la liste, de même qu'un doublon exact d'un mot déjà retenu
|
|
(un mot répété deux fois n'aurait rien de plus à faire trouver). La
|
|
liste finale est tronquée à `MAX_WORDS`.
|
|
- **Retour** : dict complet (mêmes clés que `DEFAULT_MOTS_CONFIG`).
|
|
- **Exceptions** : aucune.
|
|
|
|
## `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`.
|
|
|
|
### `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
|
|
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.
|
|
|
|
### `DEFAULT_SCENARIO_CONFIG: dict[str, Any]`
|
|
`{"theme_color": "#ff5f2e", "scenarios": []}`.
|
|
|
|
### `sanitize_scenario_config(raw_config: Any) -> dict[str, Any]`
|
|
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.
|
|
- **Retour** : dict complet (mêmes clés que `DEFAULT_SCENARIO_CONFIG`).
|
|
- **Exceptions** : aucune.
|