"""角色定义与管理员判定 —— 单一事实来源 背景:角色字符串此前散落在至少三处 —— task_service.ADMIN_ROLES、 products.py 的内联判断、以及前端 constants/task.ts。同一份规则抄多份的后果 已经发生过:前端 constants/task.ts:233 的注释记录了一次「移动端只判了 SUPER_ADMIN、漏了 SUPERVISOR,导致主管被误挡」的事故。 本模块把**角色常量与管理员判定**先收敛到一处,供后端统一引用。 完整的「角色 × 权限点」可配置矩阵是后续工作;但任何推进都应从这里出发, 不要再新增第四份副本。 """ from __future__ import annotations SUPER_ADMIN = "SUPER_ADMIN" SUPERVISOR = "SUPERVISOR" # 注意:MOM 登录返回的默认角色是小写 operator(见 auth_service.login) OPERATOR = "OPERATOR" # 管理员角色:可执行收口、审计查看等高权限动作 ADMIN_ROLES: frozenset[str] = frozenset({SUPER_ADMIN, SUPERVISOR}) ROLE_LABELS: dict[str, str] = { SUPER_ADMIN: "超级管理员", SUPERVISOR: "主管", OPERATOR: "操作员", } def is_admin(role: str | None) -> bool: """role 为 None / 未知值一律视为无权限(fail-closed,不做兜底放行)""" return role in ADMIN_ROLES