"""Application user session and permission scaffolding for the warehouse app.""" from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime from typing import FrozenSet ALL_ACTIONS: FrozenSet[str] = frozenset( { "launcher.open_reset_corsie", "launcher.open_layout", "launcher.open_multi_udc", "launcher.open_search", "launcher.open_pickinglist", "reset_corsie.view", "search.view", "multi_udc.view", "layout.view", "layout.carico", "layout.scarico", "layout.prenota", "layout.libera_prenotazione", "layout.disabilita_cella", "layout.abilita_cella", "pickinglist.view", "pickinglist.prenota", "pickinglist.sprenota", } ) def build_allowed_actions(_privilegio: int | None) -> FrozenSet[str]: """Return the currently enabled action set for the given operator profile. For this first iteration every authenticated operator can execute every function, but the explicit action map already exists so that a future admin UI can refine profiles without refactoring the whole application. """ return ALL_ACTIONS @dataclass(frozen=True) class UserSession: """Minimal in-memory representation of one authenticated application user.""" operator_id: int login: str nominativo: str privilegio: int | None = None codice_unita: str = "" session_started_at: datetime = field(default_factory=datetime.now) allowed_actions: FrozenSet[str] = field(default_factory=lambda: ALL_ACTIONS) def can(self, action: str) -> bool: """Return whether the current user can execute one named action.""" return action in self.allowed_actions @property def display_name(self) -> str: """Return the best human-readable identity for the current session.""" if str(self.nominativo or "").strip(): return str(self.nominativo).strip() return str(self.login or "").strip() def create_user_session( *, operator_id: int, login: str, nominativo: str, privilegio: int | None, codice_unita: str, ) -> UserSession: """Create one user session with the current default action set.""" return UserSession( operator_id=int(operator_id), login=str(login or "").strip(), nominativo=str(nominativo or "").strip(), privilegio=int(privilegio) if privilegio is not None else None, codice_unita=str(codice_unita or "").strip(), allowed_actions=build_allowed_actions(privilegio), )