Intègre un chat IA capable de manipuler la scène via les mêmes fonctions que l'éditeur manuel (objets, variables, déclencheurs, images générées), avec conversations multiples par écran façon Claude. Corrige au passage le rafraîchissement pjax hors-ordre, l'onglet IA/déclencheurs vide après sélection d'un objet, la comparaison de booléens dans les conditions, et le blocage du glisser-déposer hors du cadre caméra après un redimensionnement de fond par l'IA. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
63 lines
2.9 KiB
Python
63 lines
2.9 KiB
Python
"""Constantes partagées de la couche données."""
|
|
|
|
import os
|
|
|
|
# Surchargeable via FORGE_PROJECTS_DIR (même schéma que
|
|
# auth/connection.py::FORGE_USERS_DB_PATH). Résolu ici, à l'IMPORT (pas
|
|
# par un appel de fonction) : la variable d'environnement doit donc déjà
|
|
# être posée avant le tout premier `import db`.
|
|
PROJECTS_DIR = os.environ.get("FORGE_PROJECTS_DIR") or os.path.join(
|
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "projects"
|
|
)
|
|
|
|
# "Mes assets" (voir auth/user_assets/) : stockage PAR UTILISATEUR, pas
|
|
# par jeu — distinct de PROJECTS_DIR/<owner>/<projet>/uploads (voir
|
|
# routes/uploads/upload_file.py), pour qu'une image reste réutilisable
|
|
# d'un projet à l'autre du même compte. Même schéma de surcharge que
|
|
# PROJECTS_DIR ci-dessus.
|
|
USER_ASSETS_DIR = os.environ.get("FORGE_USER_ASSETS_DIR") or os.path.join(
|
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "user_assets"
|
|
)
|
|
|
|
# Types de champ exposés dans l'interface -> type de colonne SQLite réel.
|
|
FIELD_TYPES = {
|
|
"texte": {"label": "Texte court", "sql": "TEXT"},
|
|
"texte_long": {"label": "Texte long", "sql": "TEXT"},
|
|
"nombre_entier": {"label": "Nombre entier", "sql": "INTEGER"},
|
|
"nombre_decimal": {"label": "Nombre décimal", "sql": "REAL"},
|
|
"booleen": {"label": "Oui / Non", "sql": "INTEGER"},
|
|
"date": {"label": "Date", "sql": "TEXT"},
|
|
"relation": {"label": "Relation vers un autre objet", "sql": "INTEGER"},
|
|
}
|
|
|
|
# Types disponibles pour une variable globale (voir db/global_vars/) — un
|
|
# sous-ensemble de FIELD_TYPES : ni "relation" (une variable globale n'a pas
|
|
# d'objet à pointer) ni "texte_long"/"date" (pas gérés par
|
|
# apply_variable_action.py, qui ne coerce que ces 4 types). "objet"/
|
|
# "tableau" sont, eux, propres aux variables (pas de colonne SQL réelle,
|
|
# contrairement à un champ d'objet) : la valeur est stockée telle quelle
|
|
# (colonne TEXT) sous forme de JSON, lue via un chemin ".champ"/"[index]"
|
|
# (voir _resolve_variable_path dans screens/rendering/filter_repeater_rows.py).
|
|
GLOBAL_VARIABLE_TYPES = {
|
|
"texte": FIELD_TYPES["texte"],
|
|
"nombre_entier": FIELD_TYPES["nombre_entier"],
|
|
"nombre_decimal": FIELD_TYPES["nombre_decimal"],
|
|
"booleen": FIELD_TYPES["booleen"],
|
|
"objet": {"label": "Objet (JSON)"},
|
|
"tableau": {"label": "Tableau (JSON)"},
|
|
}
|
|
|
|
# Statuts de partie (voir db/scoring/) — préalable aux exports SCORM/xAPI,
|
|
# qui ont besoin d'un signal "terminé"/"réussi" propre plutôt que d'une
|
|
# convention sur une variable choisie par le créateur (voir le plan
|
|
# "Feuille de route produit"). "non_commence" est le défaut d'un joueur
|
|
# qui n'a encore rien écrit (voir db/scoring/get_score.py).
|
|
SCORE_STATUS_CHOICES = [
|
|
("non_commence", "Non commencée"),
|
|
("en_cours", "En cours"),
|
|
("termine", "Terminée"),
|
|
("reussi", "Réussie"),
|
|
("echoue", "Échouée"),
|
|
]
|
|
SCORE_STATUS_LABELS = dict(SCORE_STATUS_CHOICES)
|