from typing import Any from flask import jsonify, request from werkzeug.wrappers import Response import db import document_engine from core.flask_app import app @app.route("/document//elements//update", methods=["POST"]) def document_element_update(slug: str, element_id: int) -> Response | tuple[Response, int]: """Remplace les attributs d'un élément — un formulaire du panneau Propriétés (voir static/document/js/document-editor.js) envoie systématiquement l'état complet de ses champs. Quiz, Association, Memory, Mots mêlés et Scénario sont les seuls kinds revalidés côté serveur (document_engine.sanitize_element_attributes, même convention que game_engine/rendering/quiz_box_config.py côté jeu) : leur forme (liste de questions/choix, liste de paires, liste de cartes, liste de mots, arbre de scénarios) doit rester structurellement correcte pour que le rendu ne plante jamais, contrairement aux autres kinds (texte/forme/image...) dont les attributs sont de simples valeurs scalaires sans structure à garantir. Même sanitizer utilisé en LECTURE par document_edit.py/ document_render.py — un élément dont les attributs stockés datent d'un schéma devenu obsolète est ainsi normalisé partout, jamais seulement à l'écriture.""" element = document_engine.get_document_element(slug, element_id) if element is None: return jsonify({"error": "élément introuvable"}), 404 attributes: dict[str, Any] = request.get_json(force=True) or {} attributes = document_engine.sanitize_element_attributes(element["kind"], attributes) document_engine.update_document_element_attributes(slug, element_id, attributes) element = db.assert_not_none( document_engine.get_document_element(slug, element_id), "element_id verifie present juste au-dessus, aucune suppression concurrente possible entre-temps ici", ) elements_by_parent: dict[int | None, list[dict[str, Any]]] = {} for el in document_engine.list_document_elements(slug): elements_by_parent.setdefault(el["parent_id"], []).append(el) return jsonify( { "ok": True, "attributes": element["attributes"], "rendered_html": document_engine.render_document_element(element, elements_by_parent), } )