""" app.py — moteur Forge, point d'entrée. Lance un serveur web local. Fonctionnalités construites pour l'instant (le reste viendra au fur et à mesure) : 1. Créer un jeu (dossier + index.html/css/js + base de données dédiée). 2. Définir des "objets" (comme des tables de base de données, avec des champs typés, et des relations vers d'autres objets déjà définis). 3. Le moteur lit ces définitions et génère lui-même le formulaire adapté pour saisir des données et les enregistrer dans la vraie base SQLite. 4. CRUD complet sur les trois niveaux (jeu / objet / donnée) : renommer et supprimer un jeu, modifier une définition d'objet (ajouter/retirer des champs) et la supprimer, modifier et supprimer une ligne de données — avec blocage/avertissement quand une suppression casserait une relation existante. """ import os import threading import webbrowser import routes # noqa: F401 - enregistre toutes les routes sur `app` from core import ( auth_guard, # noqa: F401 - enregistre la garde de connexion (après les routes) csrf, # noqa: F401 - enregistre csrf_token() comme variable globale Jinja csrf_guard, # noqa: F401 - enregistre la vérification du jeton CSRF db_teardown_guard, # noqa: F401 - enregistre la fermeture des connexions SQLite fuitées jinja_filters, # noqa: F401 - enregistre les filtres Jinja recovery_codes_flash, # noqa: F401 - enregistre pop_recovery_codes() comme variable globale Jinja ) from core.flask_app import app def _open_browser() -> None: webbrowser.open("http://127.0.0.1:5050/") if __name__ == "__main__": threading.Timer(1.0, _open_browser).start() # threaded=True : le serveur de dev Werkzeug traite UNE requête à la # fois par défaut — un jeu 2D charge des dizaines d'images (sprites de # personnages, fonds...) en parallèle à chaque chargement de page, et # sans ce réglage elles se mettaient en file d'attente une par une # (bug remonté : un Ctrl+F5, qui recharge TOUT sans cache, laissait # l'éditeur de scène "vide" le temps que les images finissent par # arriver l'une après l'autre — un rechargement normal, servi surtout # depuis le cache navigateur, le cachait). # debug : jamais actif par defaut (Bandit B201 - le debogueur Werkzeug # permet l'execution de code arbitraire) — activable en local via # FORGE_DEBUG=1 dans .env, jamais utilise en production (gunicorn y # sert app:app directement, ce bloc __main__ n'y tourne pas). debug = os.environ.get("FORGE_DEBUG") == "1" app.run(host="127.0.0.1", port=5050, debug=debug, use_reloader=False, threaded=True)