Structure de dossiers par utilisateur : projects/<propriétaire>/<projet>/
Remplace le rangement plat projects/<slug>/ par une vraie arborescence par compte créateur, sans toucher aux routes existantes (aucune ne déclare de "/" dans son <slug> : le chemin composé "propriétaire_projet" reste un détail interne à db/, décodé par db/games/project_slug.py, seul fichier à modifier si la convention change un jour). - db/game_dir.py, create_game.py, delete_game.py, list_games.py, move_game.py : résolvent/construisent ce chemin composé. Bénéfice direct : deux comptes différents peuvent chacun avoir un projet nommé pareil sans collision (l'unicité ne se vérifie plus que par dossier propriétaire). move_game.py renomme désormais le dossier PROPRIÉTAIRE entier (changement d'email), prêt pour un futur multi-projet. - scripts/migrate_flat_project_slugs.py : migration des projets déjà créés sous l'ancien rangement plat (simulation par défaut, --apply pour exécuter). - routes/auth/profile.py, tests/conftest.py : suppression de compte/jeu de test via db.delete_game (nettoie aussi le dossier propriétaire devenu vide) plutôt qu'un shutil.rmtree direct du seul dossier projet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
d5a59bdbd8
commit
0f23024882
@@ -1,5 +1,4 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from flask import g, redirect, render_template, request, session, url_for
|
||||
|
||||
@@ -106,9 +105,12 @@ def profile_delete():
|
||||
# plusieurs jeux qui ne lui sont pas dédiés de la même façon : ses
|
||||
# projets restent intacts.
|
||||
if user["role"] != "admin" and user.get("project_slug"):
|
||||
game_dir = db.game_dir(user["project_slug"])
|
||||
if os.path.isdir(game_dir):
|
||||
shutil.rmtree(game_dir)
|
||||
if os.path.isdir(db.game_dir(user["project_slug"])):
|
||||
# db.delete_game (voir db/games/project_slug.py — structure de
|
||||
# dossiers par utilisateur) nettoie aussi le dossier
|
||||
# propriétaire s'il devient vide, contrairement à un simple
|
||||
# shutil.rmtree du dossier projet seul.
|
||||
db.delete_game(user["project_slug"])
|
||||
|
||||
auth.delete_user(user["id"])
|
||||
session.clear()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from flask import request, redirect, url_for
|
||||
from flask import g, request, redirect, url_for
|
||||
|
||||
import db
|
||||
|
||||
@@ -10,8 +10,12 @@ def games_new():
|
||||
name = request.form.get("name", "").strip()
|
||||
if not name:
|
||||
return redirect(url_for("index"))
|
||||
game_type = request.form.get("game_type", db.DEFAULT_GAME_TYPE)
|
||||
if game_type not in ("document", "jeu_2d"):
|
||||
game_type = db.DEFAULT_GAME_TYPE
|
||||
slug = db.create_game(name, game_type=game_type)
|
||||
# Fusion des moteurs (voir screens/screens_repo/ensure_schema.py) : un
|
||||
# jeu n'a plus de type propre — aucun écran créé d'office ici, comme
|
||||
# avant (l'admin en crée via "+ Nouvel écran" dans le dashboard, en
|
||||
# choisissant "document" ou "jeu_2d" pour chacun).
|
||||
# owner_folder (voir db/games/project_slug.py — structure de dossiers
|
||||
# par utilisateur) : posé par core/auth_guard.py pour tout compte
|
||||
# connecté, y compris l'admin qui utilise cette route.
|
||||
slug = db.create_game(name, owner_folder=db.slugify(g.current_user["email"]))
|
||||
return redirect(url_for("game_dashboard", slug=slug))
|
||||
|
||||
Reference in New Issue
Block a user