"""Team-Scoping (Mandantenfähigkeit). Jeder Datensatz gehört zu genau einem Team; jede Abfrage filtert nach dem Team des eingeloggten Nutzers (siehe CLAUDE.md). Das aktive Team wird beim Login in die Session geschrieben und hier zentral ausgelesen. Faustregel für alle Routen: NIE Model.query direkt verwenden, sondern team_query(Model) — so kann keine Abfrage versehentlich Teamgrenzen überschreiten. """ from flask import session SESSION_TEAM_KEY = "team_id" SESSION_USER_KEY = "user_id" def get_active_team_id(): """team_id des aktiven Teams aus der Session (oder None).""" return session.get(SESSION_TEAM_KEY) def current_team(): """Das aktive Team-Objekt (oder None), abgeleitet aus der Session.""" from .models import Team team_id = get_active_team_id() if team_id is None: return None return Team.query.get(team_id) def team_query(model): """Query auf ein Modell, fest auf das aktive Team eingegrenzt. Wirft ohne aktives Team bewusst, damit team-vergessende Aufrufe früh auffallen. """ team_id = get_active_team_id() if team_id is None: raise RuntimeError("Kein aktives Team in der Session – Login erforderlich.") return model.query.filter_by(team_id=team_id) def set_active_session(user_id, team_id): """Beim Login: Nutzer und sein Team in die Session schreiben.""" session[SESSION_USER_KEY] = user_id session[SESSION_TEAM_KEY] = team_id def clear_session(): """Beim Logout: Session leeren.""" session.clear()