diff --git a/document_engine/document_engine.md b/document_engine/document_engine.md index c2e52ff6..0fe5692d 100644 --- a/document_engine/document_engine.md +++ b/document_engine/document_engine.md @@ -1,15 +1,19 @@ # document_engine/ Moteur du support de formation — entité racine séparée du jeu 2D (voir -`docs/plan/PLAN.md`). Package composé de trois sous-dossiers, chacun +`docs/plan/PLAN.md`). Package composé de cinq sous-dossiers, chacun documenté séparément : - [`elements/`](elements/elements.md) — CRUD des éléments du document (`_document_elements`). - [`labels/`](labels/labels.md) — catalogue statique des types d'éléments (bibliothèque, libellés, attributs par défaut). +- [`pages/`](pages/pages.md) — CRUD des pages d'un support + (`_document_pages`) et remplacement complet du contenu depuis un thème. - [`rendering/`](rendering/rendering.md) — rendu HTML du document (canevas d'édition et Mode Aperçu, même fonction). +- [`themes/`](themes/themes.md) — catalogue des thèmes visuels + applicables à un support (bouton "Utiliser un modèle"). `document_engine/__init__.py` ré-exporte l'intégralité de l'API publique du paquet (voir son `__all__`), pattern identique à `game_engine/__init__.py`. diff --git a/document_engine/pages/pages.md b/document_engine/pages/pages.md index e8959ea7..84c9d8fd 100644 --- a/document_engine/pages/pages.md +++ b/document_engine/pages/pages.md @@ -43,6 +43,24 @@ décalage un par un). - **Retour** : aucun. - **Exceptions** : aucune. +## `replace_document_content(slug: str, seed_pages: list[list[dict[str, Any]]]) -> None` +Remplace TOUT le contenu du support par `seed_pages` — utilisée +UNIQUEMENT quand le créateur choisit "utiliser le contenu du modèle" en +appliquant un thème (voir `routes/document/document_theme_apply.py` et +`document_engine/themes/`), jamais appelée sans confirmation explicite +côté client (action destructive, irréversible côté serveur). `seed_pages` +est une liste de pages, chaque page une liste de blocs +`{"kind", "attributes", "children"}` (`children` optionnel, uniquement +pour un bloc `kind="row"` — un seul niveau de profondeur, comme le moteur +de rangées lui-même). Les attributs fournis sont fusionnés sur +`element_default_attributes(kind)`, jamais un remplacement brut. Les +nouvelles pages sont créées AVANT que les anciennes soient supprimées +(jamais l'inverse) : passer par zéro page, même brièvement, déclenche le +filet de sécurité de `ensure_document_pages_schema` (un support a +toujours au moins une page), qui recréerait une "Page 1" vide parasite. +- **Retour** : aucun. +- **Exceptions** : aucune levée explicitement. + ## `delete_document_page(slug: str, page_id: int) -> None` Supprime une page ET ses éléments (`DELETE FROM _document_elements WHERE page_id = ?` explicite — la contrainte `FOREIGN KEY ... ON DELETE diff --git a/document_engine/themes/themes.md b/document_engine/themes/themes.md new file mode 100644 index 00000000..86e43964 --- /dev/null +++ b/document_engine/themes/themes.md @@ -0,0 +1,55 @@ +# document_engine/themes/ + +Catalogue des thèmes visuels applicables à un support (bouton "Utiliser +un modèle" à côté d'Aperçu, voir `templates/document/document_edit.html` +et `static/document/js/document-editor.js`). Décision du 24/09/2026 : le +moteur ne porte QUE contenu et mécanisme — chaque thème est une feuille +de style externe (`static/document/themes/.css`, servie telle quelle) +qui habille les classes FIXES du moteur (`.docPage`/`.docText`/ +`.docList`/`.docCard`/`.docBadge`/`.docButton`/`.docImage`/ +`.docMinigame`/...), jamais du code qui en changerait la structure. Une +centaine de thèmes est prévue à terme : ce découpage (données de +catalogue + CSS statique, aucun code Python par thème au-delà d'une +entrée de catalogue) est pensé pour rester gérable à cette échelle. + +## `DOCUMENT_THEMES: list[dict[str, Any]]` +Un dict par thème : `id` (identifiant stable, utilisé dans les URLs et +persisté via `db.set_document_theme`), `name`, `category`, `description` +(affichage dans la modale), `css_path` (chemin sous `static/`, passé à +`url_for('static', filename=...)`), `font_url` (optionnel, lien Google +Fonts), `seed_pages` (contenu de démonstration, voir +`document_engine.replace_document_content`). L'auteur d'un thème est +responsable de respecter les règles structurelles du moteur dans son +`seed_pages` (ex. un mini-jeu seul sur sa page — voir +`routes/document/document_element_add.py` — jamais revérifié +automatiquement puisque ce contenu vient du thème, pas de l'utilisateur ; +voir `tests/document/test_document_themes.py` pour la vérification +statique de cette règle sur tout le catalogue). + +## `get_document_theme_entry(theme_id: str) -> dict[str, Any] | None` +- **Retour** : l'entrée de `DOCUMENT_THEMES` dont `id == theme_id`, ou + `None` si aucun thème de ce catalogue ne porte cet id. +- **Exceptions** : aucune. + +## `seed_blocks_to_elements(blocks: list[dict[str, Any]]) -> list[dict[str, Any]]` +Convertit une liste de blocs de contenu-seed (`seed_pages[i]`) en une +liste d'éléments "à plat" (id/kind/parent_id/attributes) directement +exploitable par `document_engine.render_document` — ids synthétiques +NÉGATIFS, jamais persistés. Utilisée UNIQUEMENT pour l'aperçu d'un thème +(voir `routes/document/document_theme_preview.py`, destiné à un +`