"""Convention de slug propre aux supports de formation — mirroir du principe de db/games/project_slug.py (slug composé "propriétaire_projet"), mais résolu vers un sous-espace totalement séparé (voir support_dir.py) pour qu'un support et un jeu du même propriétaire ne puissent jamais se collisionner sur un même nom de dossier, et pour qu'un support n'apparaisse jamais dans db.list_games() (qui ne scanne que le dossier propriétaire direct, jamais son sous-dossier _supports/).""" def build_slug(owner_folder: str, project_part: str) -> str: return f"{owner_folder}_{project_part}" def split_slug(slug: str) -> tuple[str, str | None]: """(owner_folder, project_part) si `slug` est bien composé, sinon (slug, None) — même repli que db/games/project_slug.py, un support n'a toutefois jamais vocation à exister sous forme "plate" (toujours créé avec un owner_folder).""" owner_folder, sep, project_part = slug.partition("_") if not sep: return slug, None return owner_folder, project_part