from __future__ import annotations import re from typing import Literal AccessRole = Literal["authenticated", "member", "admin"] MEMBER_GET_PATHS = frozenset( { "/api/screener/setup", "/api/screener/tracking", "/api/mentors/setup", "/api/mentors/messages", "/api/heaven/setup", "/api/heaven/readings", "/api/assistant/messages", } ) MEMBER_POST_PATHS = frozenset( { "/api/screener/sync", "/api/screener/compile", "/api/screener/strategies", "/api/screener/run", "/api/screener/tracking", "/api/screener/tracking/refresh", "/api/mentors/chat", "/api/mentors/preferences", "/api/heaven/hexagram", "/api/heaven/personal", "/api/heaven/interpret", "/api/assistant/chat", } ) ADMIN_POST_PATHS = frozenset( { "/api/backfill", "/api/reasons", "/api/seat-aliases", "/api/heaven/sector-phases", } ) def required_role(method: str, path: str) -> AccessRole: method = method.upper() if path.startswith("/api/admin/"): return "admin" if method == "GET" and path in MEMBER_GET_PATHS: return "member" if method == "POST": if path in ADMIN_POST_PATHS: return "admin" if path in MEMBER_POST_PATHS: return "member" if method == "DELETE": if re.fullmatch(r"/api/heaven/sector-phases/.+", path): return "admin" if path in {"/api/mentors/messages", "/api/assistant/messages"} or re.fullmatch( r"/api/screener/strategies/\d+", path ): return "member" if re.fullmatch(r"/api/heaven/readings/\d+", path): return "member" if re.fullmatch(r"/api/screener/tracking/\d+", path): return "member" return "authenticated"