update: auth

update auth api
This commit is contained in:
tao.chen
2026-08-07 14:41:20 +08:00
parent 984894d797
commit 2ee36b48ec
4 changed files with 88 additions and 68 deletions
+20 -13
View File
@@ -45,7 +45,8 @@
- 缺失或过期 → HTTP `401`
- 有效但用户不在 workspace → HTTP `403`(由 Nginx `auth_request` 透传给客户端)。
> `/api/v1/auth/me` 与 `/api/v1/auth/login` 响应中的 `data.user` 对象额外携带以下个字段:
> `/api/v1/auth/me` 与 `/api/v1/auth/login` 响应中的 `data.user` 对象额外携带以下个字段:
> - `role_code: string | null` —— 用户的**平台角色**(`users.platform_role_id` 指向的 Roles 行的 `role_code`),取值为 `admin` / `developer` / `null`(未分配)。**注意:本字段同时也是该用户在所有 workspace 中的角色**——workspace 角色始终继承自平台角色,本端点不再返回 workspace 级独立角色码。
> - `is_system_admin: bool` —— 派生自 `users.platform_role_id` 指向的角色 `role_code == 'admin'` 且用户状态为 `active`。前端据此决定是否渲染"系统管理"入口。
> - `permissions: string[]` —— 当前用户通过其平台角色(`platform_role_id`)间接持有的菜单权限码列表(`permission_code`),按字典序排列;未分配平台角色时为空数组。前端据此过滤菜单与 `<RequirePermission>` 路由守卫。**仅控制前端展示,不参与后端 endpoint 鉴权**——后端鉴权继续由 `system_admin_context`(`role_code == 'admin'`)与 workspace membership 负责。详见 §7.12-7.14。
@@ -512,7 +513,7 @@ Base 前缀 `/api/v1/admin`。
| `DELETE` | `/api/v1/platform/workspaces/{workspace_id}` | 软删 workspace;级联软删其成员 |
| `GET` | `/api/v1/platform/workspaces/{workspace_id}/members` | 列成员 |
| `POST` | `/api/v1/platform/workspaces/{workspace_id}/members` | 添加成员(返回 201) |
| `PATCH` | `/api/v1/platform/workspaces/{workspace_id}/members/{user_id}` | 改成员角色/状态 |
| `PATCH` | `/api/v1/platform/workspaces/{workspace_id}/members/{user_id}` | 改成员 `member_status`;**不能改 role_code**(workspace 角色继承自平台角色) |
| `DELETE` | `/api/v1/platform/workspaces/{workspace_id}/members/{user_id}` | 软删成员 |
| `GET` | `/api/v1/platform/roles` | 列全部 `role_scope='platform'` 的角色及其 `permission_codes`(仅系统管理员) |
| `GET` | `/api/v1/platform/roles/{role_code}/permissions` | 单个平台角色的 `permission_codes`(仅系统管理员) |
@@ -597,28 +598,31 @@ Base 前缀 `/api/v1/admin`。
添加成员。
> **Workspace 角色继承平台角色**:本端点不接受 `role_code`,新成员的 `workspace_members.role_id` 始终等于其 `users.platform_role_id` 指向的角色行。**不可填** `system_admin`(那是用户级身份,不是 workspace 角色)。要改某成员的 workspace 角色,请改 `users.platform_role_id`,即 `PATCH /api/v1/platform/employees/{user_id}`。
- **请求体字段**:
| 字段 | 类型 | 必填 | 限制 | 说明 |
|---|---|---|---|---|
| `user_id` | string | 是 | 26 字符 ULID | |
| `role_code` | string | 是 | `admin` \| `developer` | **不可填 `system_admin`**(那是用户级身份,不是 workspace 角色) |
- 服务端默认 `member_status='active'`。
- 用户不存在或已软删除 → 404;用户状态不是 `active` → 409;用户已是该 workspace 成员 → 409
- 新员工必须先通过 `POST /api/v1/platform/employees` 或现有 workspace 员工创建接口建立用户账号
- 用户不存在或已软删除 → 404;用户状态不是 `active` → 409;用户**尚未分配平台角色**(`users.platform_role_id IS NULL`)→ 409 "目标用户尚未分配平台角色,无法加入 workspace"
- 用户已是该 workspace 成员 → 409
- 新员工必须先通过 `POST /api/v1/platform/employees` 建立账号(可以同时传 `role_code=admin|developer`)。
### 7.6 `PATCH /api/v1/platform/workspaces/{workspace_id}/members/{user_id}`
修改成员的角色或状态。
修改成员的状态。**不能通过本端点修改 role_code**——workspace 角色始终继承自 `users.platform_role_id`;要改角色请 `PATCH /api/v1/platform/employees/{user_id}`
- **请求体字段**(全部可选):
| 字段 | 类型 | 限制 | 说明 |
|---|---|---|---|
| `role_code` | string | `admin` \| `developer` | 降级最后 admin → 409 |
| `member_status` | string | `active` \| `disabled` \| `locked` | 停用 / 锁定最后 admin → 409 |
- 提交 `role_code` 字段 → 422(Pydantic `extra='forbid'`),不是静默忽略。
### 7.7 `DELETE /api/v1/platform/workspaces/{workspace_id}/members/{user_id}`
软删除成员。
@@ -669,13 +673,15 @@ Base 前缀 `/api/v1/admin`。
| `display_name` | string | 是 | 1~100 字符 | 显示名称 |
| `email` | string | 否 | ≤255 字符 | 邮箱,全平台唯一 |
| `password` | string | 是 | 8~72 字符 | 登录密码 |
| `role_code` | string | 否 | `admin` \| `developer` | 平台角色;不传或 `null` 表示**不分配角色**(用户无法加入任何 workspace,见 §7.5) |
- 新用户状态固定为 `active`,且不分配平台角色
- 新用户状态固定为 `active`;`role_code` 决定 `users.platform_role_id` 指向 `role_code='admin'` / `'developer'` 的 Roles 行,未传则 `platform_role_id=NULL`
- 平台**仅**有 `admin` / `developer` 两个平台角色;不存在第三个角色枚举值。
- 密码使用 bcrypt 哈希保存;响应不包含 `password` 或 `password_hash`。
- 用户名或邮箱重复 → 409。
- 创建成功后,可调用 `POST /api/v1/platform/workspaces/{workspace_id}/members` 将用户加入指定 workspace。
- 用户名或邮箱重复 → 409;`role_code` 取值非法 → 422
- 创建成功后,可调用 `POST /api/v1/platform/workspaces/{workspace_id}/members` 将用户加入指定 workspace(会要求用户已有 `platform_role_id`,否则 409)
- **响应 201**:字段与 §7.8 的员工元素一致,其中 `role_code``role_name` 均为 `null`,`meta` 为空对象。
- **响应 201**:字段与 §7.8 的员工元素一致;当 `role_code` 传入时,`role_code` / `role_name` 反映 `platform_role_id`;未传入时均为 `null``meta` 为空对象。
### 7.10 `PATCH /api/v1/platform/employees/{user_id}`
@@ -691,11 +697,12 @@ Base 前缀 `/api/v1/admin`。
| `role_code` | string | `admin` \| `developer` | 同步设置 `users.platform_role_id`;`admin` 指向 `role_code='admin'` 的 Roles 行,`developer` 指向 `role_code='developer'` 的 Roles 行 |
- 禁止通过该端点修改:`username`、`password`、`password_hash`、`platform_role_id`;请求体中包含这些字段 → 422。
- `role_code` 只能取 `admin` / `developer`;不能通过本端点把 `platform_role_id` 置为 `null`。
- `role_code` 只能取 `admin` / `developer`;**不能通过本端点把 `platform_role_id` 置为 `null`**(降级为"无平台角色"须走单独的内部流程,前端不要尝试)
- `role_code` 改动会**立即影响**该用户在**所有** workspace 中的角色——因为 `workspace_members.role_id` 在 §7.5/§7.6 不再被端点改写,workspace 角色始终等于 `users.platform_role_id` 指向的 Roles 行。本端点是调整任何成员 workspace 角色的**唯一**入口。
- 自保护:
- 修改自身 `status` 为非 `active` → 409 "不能停用当前登录账号"。
- 修改自身 `role_code` 为 `developer`(即降级系统管理员身份)→ 409 "不能降级自身管理员角色"。
- 最后系统管理员保护:当目标用户当前为 active 系统管理员,本次变更会让其离开"active 系统管理员"集合(降级角色 / 停用账号)时,平台必须仍保留至少一名 active 系统管理员,否则 → 409 "platform 必须保留至少一个 active 系统管理员"。
- 最后系统管理员保护:当目标用户当前为 active 系统管理员,本次变更会让其离开"active 系统管理员"集合(降级角色 / 停用账号)时,平台必须仍保留至少一名 active 系统管理员,否则 → 409 "platform 必须保留至少一个 active 系统管理员"。**自保护在前、last-admin 计数在后**(参考 CLAUDE.md 工程笔记)。
- 目标用户不存在或已软删除 → 404 "用户不存在";`role_code` 对应的角色行不存在 → 422。
- **响应 200**:返回更新后的 `PlatformEmployeePayload`,`role_code` / `role_name` 反映最新的 `platform_role_id`。