fix: literal_error
This commit is contained in:
@@ -79,7 +79,22 @@ async def _is_system_admin(session: AsyncSession, user: Users) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
async def _load_role_by_code(session: AsyncSession, role_code: str) -> Roles:
|
async def _load_role_by_code(session: AsyncSession, role_code: str) -> Roles:
|
||||||
role = await session.scalar(select(Roles).where(Roles.role_code == role_code))
|
"""Load a live platform-scoped role by code; 422 if missing.
|
||||||
|
|
||||||
|
之所以把 ``is_deleted == 0`` 和 ``role_scope == "platform"`` 写进 helper,
|
||||||
|
是因为本 helper 的所有调用方(``employees`` create/update / 两个 count
|
||||||
|
helper)都需要的是 platform 角色。Workspace 角色不应被赋值到
|
||||||
|
``users.platform_role_id``,软删除的 role 也不应被新引用 —— 在 helper
|
||||||
|
层兜底一次,后续 schema 放宽 ``role_code`` 为 ``str`` 时不必每个端点
|
||||||
|
再补守卫。
|
||||||
|
"""
|
||||||
|
role = await session.scalar(
|
||||||
|
select(Roles).where(
|
||||||
|
Roles.role_code == role_code,
|
||||||
|
Roles.is_deleted == 0,
|
||||||
|
Roles.role_scope == "platform",
|
||||||
|
)
|
||||||
|
)
|
||||||
if role is None:
|
if role is None:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status.HTTP_422_UNPROCESSABLE_ENTITY,
|
status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ from backend.api.platform._deps import (
|
|||||||
system_admin_context,
|
system_admin_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 平台角色 code 的字符串约束:与 RoleCreate.role_code 一致。
|
||||||
|
# 之所以从 Literal["admin","developer"] 放宽为 str,是因为 ``listPlatformRoles``
|
||||||
|
# 现已返回用户自建的 platform 角色(``role_scope=="platform"`` 且 ``is_builtin==0``),
|
||||||
|
# 前端 dialog 用 ``listPlatformRoles()`` 渲染选项,提交非内置 code 时会被 Pydantic
|
||||||
|
# Literal 校验直接 422 拒掉。schema 不应枚举运行时数据;改用 ``_load_role_by_code``
|
||||||
|
# 做存在性 + 平台作用域校验(并隐式排除 is_deleted=1)。
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1/platform", tags=["platform"])
|
router = APIRouter(prefix="/api/v1/platform", tags=["platform"])
|
||||||
|
|
||||||
|
|
||||||
@@ -42,7 +49,7 @@ class PlatformEmployeeCreate(BaseModel):
|
|||||||
display_name: str = Field(min_length=1, max_length=100)
|
display_name: str = Field(min_length=1, max_length=100)
|
||||||
email: str | None = Field(default=None, max_length=255)
|
email: str | None = Field(default=None, max_length=255)
|
||||||
password: str = Field(min_length=8, max_length=72)
|
password: str = Field(min_length=8, max_length=72)
|
||||||
role_code: Literal["admin", "developer"] | None = None
|
role_code: str | None = Field(default=None, min_length=2, max_length=64)
|
||||||
|
|
||||||
|
|
||||||
# 修改平台用户资料、状态或平台角色的请求体。
|
# 修改平台用户资料、状态或平台角色的请求体。
|
||||||
@@ -52,7 +59,7 @@ class PlatformEmployeeUpdate(BaseModel):
|
|||||||
display_name: str | None = Field(default=None, min_length=1, max_length=100)
|
display_name: str | None = Field(default=None, min_length=1, max_length=100)
|
||||||
email: str | None = Field(default=None, max_length=255)
|
email: str | None = Field(default=None, max_length=255)
|
||||||
status: Literal["active", "disabled", "locked"] | None = None
|
status: Literal["active", "disabled", "locked"] | None = None
|
||||||
role_code: Literal["admin", "developer"] | None = None
|
role_code: str | None = Field(default=None, min_length=2, max_length=64)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user