用户管理 dialog: 管理员允许修改其他用户角色 #38

Closed
opened 2026-08-26 09:39:21 +08:00 by tao.chen · 1 comment
Owner

背景

UserManagementPage.tsx 的编辑用户 dialog 当前缺失 role_code 选择器 — form.role_code 在 state 里初始化为 editing.role_code 并随 PATCH 提交,但 UI 没暴露,管理员无法从界面修改用户角色。

范围 (L1 风险)

仅修改 frontend/app/features/admin/UserManagementPage.tsx 一个文件。

修改

  1. 在编辑 dialog({editing && (...)} 块)的状态 <label> 之前插入角色 <select> 字段
  2. 选项:admin / developer(role_name 通过现有 store 或留作后端返回;沿用 status 的简化格式)
  3. 禁用规则:仅当 editing.user_id === user?.user_id 时禁用(自降级由后端 409 拦截)
  4. 删除 submit handler 中的 targetIsAdmin && form.role_code !== editing.role_code 守卫(由后端 _count_active_system_admins + workspace-level last-admin 兜底)
  5. 保留 editingSelf && form.role_code !== editing.role_code 守卫(双重保护)

验收

  • pnpm typecheck 通过
  • 打开编辑 dialog 能看到角色下拉
  • 编辑自身时下拉禁用且 onChange 不触发
  • 修改其他用户(含其他管理员)角色后保存,PATCH 返回 200 + 列表刷新
  • 与现 status 选择器视觉一致

不做

  • 不改后端 API(已支持 role_code 字段)
  • 不改新建用户流程(create 仍硬编码 role_code="developer")
  • 不引入新依赖

Task: qwp3v51sokmuyp7evoeu9n3d

## 背景 `UserManagementPage.tsx` 的编辑用户 dialog 当前缺失 role_code 选择器 — `form.role_code` 在 state 里初始化为 `editing.role_code` 并随 PATCH 提交,但 UI 没暴露,管理员无法从界面修改用户角色。 ## 范围 (L1 风险) 仅修改 `frontend/app/features/admin/UserManagementPage.tsx` 一个文件。 ## 修改 1. 在编辑 dialog(`{editing && (...)}` 块)的状态 `<label>` **之前**插入角色 `<select>` 字段 2. 选项:`admin` / `developer`(`role_name` 通过现有 store 或留作后端返回;沿用 status 的简化格式) 3. 禁用规则:仅当 `editing.user_id === user?.user_id` 时禁用(自降级由后端 409 拦截) 4. 删除 submit handler 中的 `targetIsAdmin && form.role_code !== editing.role_code` 守卫(由后端 `_count_active_system_admins` + workspace-level last-admin 兜底) 5. 保留 `editingSelf && form.role_code !== editing.role_code` 守卫(双重保护) ## 验收 - `pnpm typecheck` 通过 - 打开编辑 dialog 能看到角色下拉 - 编辑自身时下拉禁用且 onChange 不触发 - 修改其他用户(含其他管理员)角色后保存,PATCH 返回 200 + 列表刷新 - 与现 status 选择器视觉一致 ## 不做 - 不改后端 API(已支持 `role_code` 字段) - 不改新建用户流程(create 仍硬编码 role_code="developer") - 不引入新依赖 --- <sub>Task: qwp3v51sokmuyp7evoeu9n3d</sub>
tao.chen added the priority:mediumstatus:in-progress labels 2026-08-26 09:39:23 +08:00
Author
Owner

tao.chen commented:

已实施。

改动:

  • frontend/app/features/admin/UserManagementPage.tsx 在编辑 dialog 中(role 在 email 之后、status 之前)新增角色 <select>,选项 admin/developer。
  • 编辑自身时 select 禁用 (editing.user_id === user?.user_id)。
  • 移除前端 "不能降级管理员账号" 守卫,后端 _count_active_system_admins + workspace-level last-admin guard 兜底;backend 409 通过 ApiRequestError.message 直接显示。
  • 保留 editingSelf && form.role_code !== editing.role_code 作为 defense-in-depth(且 select 禁用使其无法触发)。
  • UserManagementPage.tsx 一文件改动;create 流程未动(role_code 仍硬编码 "developer")。

验证:

  • pnpm typecheck 零错误
  • pnpm build 通过(client + SSR)
  • 与现 status 选择器样式一致(formFieldClass + formInputClass)
**tao.chen** commented: > 已实施。 改动: - `frontend/app/features/admin/UserManagementPage.tsx` 在编辑 dialog 中(role 在 email 之后、status 之前)新增角色 `<select>`,选项 admin/developer。 - 编辑自身时 select 禁用 (`editing.user_id === user?.user_id`)。 - 移除前端 "不能降级管理员账号" 守卫,后端 `_count_active_system_admins` + workspace-level last-admin guard 兜底;backend 409 通过 `ApiRequestError.message` 直接显示。 - 保留 `editingSelf && form.role_code !== editing.role_code` 作为 defense-in-depth(且 select 禁用使其无法触发)。 - 仅 `UserManagementPage.tsx` 一文件改动;create 流程未动(role_code 仍硬编码 "developer")。 验证: - `pnpm typecheck` 零错误 - `pnpm build` 通过(client + SSR) - 与现 status 选择器样式一致(`formFieldClass` + `formInputClass`)
tao.chen added status:done and removed status:in-progress labels 2026-08-26 09:41:21 +08:00
Sign in to join this conversation.