背景: - 部门管理已实现(独立页面 /system/departments、只停用不删除、 有成员/启用子部门禁止停用),需要同步计划、规范与实施报告。 改动: - 开发计划:新增 WBS A1-BE-05(部门接口)与 A1-FE-04(部门管理页), A1 进度更新为 10/10、测试计数与「补强」说明;附录 C 增加 /system/departments,§7.1 页面/接口清单更新;版本记录增补。 - A1 实施报告:范围表、契约/后端/前端交付物、测试计数与验证表补充 部门管理;新增 §2.5 部门管理补强(口径、规则、覆盖范围)与遗留项。 - 11-前端路由与目录规范:管理中心模块表补 /system/departments (pages/system/departments/),版本 V1.1。 影响面: - 仅文档;与已提交的代码行为一致,不改变其它批次范围。 回滚方式: - 回滚本提交即恢复文档原状;不影响代码。 验证证据: - pnpm format:check 通过; - 文档中的测试计数、接口与页面路径与 feat(identity) 提交一致。
This commit is contained in:
1 parent
6661c42e84
commit
981757b76c
3 files changed
+31
-12
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
| 项 | 内容 |
|
| 项 | 内容 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 文档版本 | V1.0(2026-11-03) |
|
| 文档版本 | V1.1(2026-11-03) |
|
||||||
| 依据 | 技术架构 §6 / §10、[04 · API 与路由规范](04-API与路由规范.md) §8、`AGENTS.md` §5 |
|
| 依据 | 技术架构 §6 / §10、[04 · API 与路由规范](04-API与路由规范.md) §8、`AGENTS.md` §5 |
|
||||||
| 适用范围 | `apps/web` 全部页面路由、导航配置与页面目录 |
|
| 适用范围 | `apps/web` 全部页面路由、导航配置与页面目录 |
|
||||||
| 强制级别 | 强制 |
|
| 强制级别 | 强制 |
|
||||||
@@ -116,10 +116,11 @@ apps/web/src/pages/
|
|||||||
| 素材 | `/material/image-compose`、`/material/video`、`/material/tasks`、`/material/quick-review`、`/material/preview` |
|
| 素材 | `/material/image-compose`、`/material/video`、`/material/tasks`、`/material/quick-review`、`/material/preview` |
|
||||||
| 资产 | `/assets/library`、`/assets/templates`、`/assets/pools`、`/assets/prompts` |
|
| 资产 | `/assets/library`、`/assets/templates`、`/assets/pools`、`/assets/prompts` |
|
||||||
| 交付 | `/delivery/export`、`/delivery/records`、`/delivery/manifests` |
|
| 交付 | `/delivery/export`、`/delivery/records`、`/delivery/manifests` |
|
||||||
| 管理中心 | `/system/users`、`/system/roles`、`/system/customers`、`/system/industries`、`/system/dicts`、`/system/audit-logs`、`/system/ai`、`/system/settings`、`/system/industry-packs`、`/system/forms`、`/system/customer-fields`、`/system/compliance` |
|
| 管理中心 | `/system/users`、`/system/departments`、`/system/roles`、`/system/customers`、`/system/industries`、`/system/dicts`、`/system/audit-logs`、`/system/ai`、`/system/settings`、`/system/industry-packs`、`/system/forms`、`/system/customer-fields`、`/system/compliance` |
|
||||||
|
|
||||||
## 7 修订记录
|
## 7 修订记录
|
||||||
|
|
||||||
| 版本 | 日期 | 变更 |
|
| 版本 | 日期 | 变更 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| V1.0 | 2026-11-03 | 初版:模块表、路径语法、目录映射、路由注册、旧链重定向与检查清单;管理中心由「平台」改名,A1 用户页迁移至 `/system/users` 与 `pages/system/users/` |
|
| V1.0 | 2026-11-03 | 初版:模块表、路径语法、目录映射、路由注册、旧链重定向与检查清单;管理中心由「平台」改名,A1 用户页迁移至 `/system/users` 与 `pages/system/users/` |
|
||||||
|
| V1.1 | 2026-11-03 | 管理中心补充部门管理 `/system/departments`(`pages/system/departments/`),作为 A1 组织架构补强 |
|
||||||
@@ -19,8 +19,10 @@
|
|||||||
| A1-BE-03 | Jwt → Permission → SpecialPermission → Scope 守卫链、`@Audit` 与请求上下文 | ✅(Scope 骨架) |
|
| A1-BE-03 | Jwt → Permission → SpecialPermission → Scope 守卫链、`@Audit` 与请求上下文 | ✅(Scope 骨架) |
|
||||||
| A1-BE-04 | `/me` 用户 / 角色 / 权限 / 数据范围 / 可见客户;权限即时生效 | ✅(dataScope 仅 all / 本部门及下级,六类留 A2) |
|
| A1-BE-04 | `/me` 用户 / 角色 / 权限 / 数据范围 / 可见客户;权限即时生效 | ✅(dataScope 仅 all / 本部门及下级,六类留 A2) |
|
||||||
| A1-FE-01 | 登录页、token 存储刷新、登出、过期跳转、路由回跳 | ✅ |
|
| A1-FE-01 | 登录页、token 存储刷新、登出、过期跳转、路由回跳 | ✅ |
|
||||||
| A1-FE-02 | 用户列表(游标分页 / 筛选 / 排序)、新建 / 编辑、停用确认、部门树、角色多选、客户转交入口 | ✅ |
|
| A1-FE-02 | 用户列表(游标分页 / 筛选 / 排序)、新建 / 编辑、停用确认、部门筛选、角色多选、客户转交入口 | ✅ |
|
||||||
| A1-FE-03 | `/me` 缓存、`usePermission` / `<Can>`、路由与按钮级控制、403 页 | ✅ |
|
| A1-FE-03 | `/me` 缓存、`usePermission` / `<Can>`、路由与按钮级控制、403 页 | ✅ |
|
||||||
|
| A1-BE-05 | 部门管理补强:树(含停用)、新建 / 改名 / 负责人 / 排序、停用 / 启用、停用拦截 | ✅(2026-11-03 补强) |
|
||||||
|
| A1-FE-04 | 部门管理页 `/system/departments`:两级树 + 详情/编辑 + 停用启用确认 | ✅(2026-11-03 补强) |
|
||||||
| A1-QA-01 | 登录 / 刷新 / 登出 / 停用 / 角色变更 / 越权 6 类用例 | ✅(接口 int + 浏览器 e2e) |
|
| A1-QA-01 | 登录 / 刷新 / 登出 / 停用 / 角色变更 / 越权 6 类用例 | ✅(接口 int + 浏览器 e2e) |
|
||||||
|
|
||||||
口径确认(用户拍板):初始密码由管理员设定、首次登录强制修改;手机号列表掩码、详情全号仅 `user:manage` 可见;路由按开发计划附录 C 使用 `/system/users`(2026-11-03 路由规范调整后)。
|
口径确认(用户拍板):初始密码由管理员设定、首次登录强制修改;手机号列表掩码、详情全号仅 `user:manage` 可见;路由按开发计划附录 C 使用 `/system/users`(2026-11-03 路由规范调整后)。
|
||||||
@@ -31,7 +33,7 @@
|
|||||||
|
|
||||||
### 2.1 契约(`packages/shared`)
|
### 2.1 契约(`packages/shared`)
|
||||||
|
|
||||||
- 新增 `src/schemas/identity.ts`(+ spec):`UserSummary`(`phoneMasked`,永不含全号)、`UserDetail`(`phone?` 仅授权时返回)、`UserListQuery`(`cursor/limit/keyword/department_id/role_id/status/sort/order`)、`CreateUserInput`、`UpdateUserInput`、`DisableUserInput`、`TransferCustomersInput`、`LoginInput`、`RefreshInput`、`LoginResponse = tokenPair + me`、`MeResponse`、`DepartmentNode`、`RoleSummary`。
|
- 新增 `src/schemas/identity.ts`(+ spec):`UserSummary`(`phoneMasked`,永不含全号)、`UserDetail`(`phone?` 仅授权时返回)、`UserListQuery`(`cursor/limit/keyword/department_id/role_id/status/sort/order`)、`CreateUserInput`、`UpdateUserInput`、`DisableUserInput`、`TransferCustomersInput`、`LoginInput`、`RefreshInput`、`LoginResponse = tokenPair + me`、`MeResponse`、`DepartmentNode`(`status / sortOrder / memberCount / directMemberCount`)、`CreateDepartmentInput`、`UpdateDepartmentInput`、`DepartmentTreeQuery`、`RoleSummary`。
|
||||||
- `permissions.ts` 新增 `USER_VIEW = 'user:view'`;保留 `USER_MANAGE`。
|
- `permissions.ts` 新增 `USER_VIEW = 'user:view'`;保留 `USER_MANAGE`。
|
||||||
- 写 body camelCase、query snake_case;写接口 `.strict()`;错误码沿用 A0 统一表。
|
- 写 body camelCase、query snake_case;写接口 `.strict()`;错误码沿用 A0 统一表。
|
||||||
|
|
||||||
@@ -41,7 +43,8 @@
|
|||||||
- 迁移:`prisma/migrations/20261102143519_a1_identity`(expand):`departments`、`users`、`roles`、`user_roles`、`role_permissions`、`refresh_tokens`。
|
- 迁移:`prisma/migrations/20261102143519_a1_identity`(expand):`departments`、`users`、`roles`、`user_roles`、`role_permissions`、`refresh_tokens`。
|
||||||
- 种子(幂等):8 角色 + 角色权限映射、3 个一级部门 + 6 个小组、11 个用户(`admin` 超管 + 10 位示例成员),统一初始密码 `lingxi2026`、`must_change_password=true`。
|
- 种子(幂等):8 角色 + 角色权限映射、3 个一级部门 + 6 个小组、11 个用户(`admin` 超管 + 10 位示例成员),统一初始密码 `lingxi2026`、`must_change_password=true`。
|
||||||
- identity 模块(`apps/api/src/modules/identity`):
|
- identity 模块(`apps/api/src/modules/identity`):
|
||||||
- `POST /auth/login|refresh|logout|change-password`、`GET /me`、`GET/POST /users`、`GET/PATCH /users/{id}`、`POST /users/{id}/disable|enable|transfer-customers`、`GET /departments/tree`、`POST/PATCH /departments`、`GET /roles`。
|
- `POST /auth/login|refresh|logout|change-password`、`GET /me`、`GET/POST /users`、`GET/PATCH /users/{id}`、`POST /users/{id}/disable|enable|transfer-customers`、`GET /departments/tree?include_disabled=`、`POST/PATCH /departments`、`POST /departments/{id}/disable|enable`、`GET /roles`。
|
||||||
|
- 部门:两级组织树;新建 / 改名 / 负责人 / 排序;只停用不删除;有在职成员、启用中的下级小组或下级在职成员时禁止停用(42201 带数量);启用时上级必须启用;负责人必须是启用用户。
|
||||||
- refresh token 旋转:jti + token_hash + family,旧 token 原子吊销;重放整族吊销。
|
- refresh token 旋转:jti + token_hash + family,旧 token 原子吊销;重放整族吊销。
|
||||||
- 登录失败 Redis 计数,达阈值锁定 15 分钟(42901)。
|
- 登录失败 Redis 计数,达阈值锁定 15 分钟(42901)。
|
||||||
- 权限每请求从 DB 解析,角色变更下一次请求生效。
|
- 权限每请求从 DB 解析,角色变更下一次请求生效。
|
||||||
@@ -57,6 +60,7 @@
|
|||||||
- 登录:方案 B 左右分屏(左 560 品牌 + 能力 + CSS 规格缩略,右表单卡);真实 `POST /auth/login`;错误 / loading / 锁定态;首次登录强改在登录页内完成,成功后清会话要求用新密码重登。
|
- 登录:方案 B 左右分屏(左 560 品牌 + 能力 + CSS 规格缩略,右表单卡);真实 `POST /auth/login`;错误 / loading / 锁定态;首次登录强改在登录页内完成,成功后清会话要求用新密码重登。
|
||||||
- 用户列表 / 详情:左 400 列表 + 右 760 详情(基本资料 / 角色权限 / 负责客户 / 登录与安全 / 操作记录);搜索、部门、角色、状态、排序、游标分页;停用 / 启用 / 客户转交 / 调整角色 / 超管授予均「对象卡 → 后果 → 勾选」二次确认;编辑资料弹窗;空 / 加载 / 错误三态;1024 / 1280 适配。
|
- 用户列表 / 详情:左 400 列表 + 右 760 详情(基本资料 / 角色权限 / 负责客户 / 登录与安全 / 操作记录);搜索、部门、角色、状态、排序、游标分页;停用 / 启用 / 客户转交 / 调整角色 / 超管授予均「对象卡 → 后果 → 勾选」二次确认;编辑资料弹窗;空 / 加载 / 错误三态;1024 / 1280 适配。
|
||||||
- 新建用户:单栏三段(账号信息 / 组织与角色 / 初始设置),Semi Form + 共享 Zod 同源校验,部门两级联动、角色多选、超管二次确认。
|
- 新建用户:单栏三段(账号信息 / 组织与角色 / 初始设置),Semi Form + 共享 Zod 同源校验,部门两级联动、角色多选、超管二次确认。
|
||||||
|
- 部门管理(补强):`/system/departments`,左两级组织树(人数 / 负责人 / 状态、显示已停用、`?id=` 选中)+ 右详情/内联编辑(名称、上级只读、负责人、排序、直属/含下级人数、下级小组);新建部门/小组、停用/启用二次确认;无 `user:manage` 只读;树/表单/接口封装均有单测。
|
||||||
- 样式:`--lx-*` token + Semi 组件 + `styles/users.css`;未引入其他组件库/图标库。
|
- 样式:`--lx-*` token + Semi 组件 + `styles/users.css`;未引入其他组件库/图标库。
|
||||||
|
|
||||||
### 2.4 测试(`e2e`)
|
### 2.4 测试(`e2e`)
|
||||||
@@ -64,6 +68,13 @@
|
|||||||
- `e2e/a1-identity.spec.ts`:6 条浏览器端到端用例(`A1_E2E=1` 门控,CI 无依赖时 skip),真实 API + 真实 PG/Redis;测试数据自建自清。
|
- `e2e/a1-identity.spec.ts`:6 条浏览器端到端用例(`A1_E2E=1` 门控,CI 无依赖时 skip),真实 API + 真实 PG/Redis;测试数据自建自清。
|
||||||
- `e2e/README.md`:运行前置、环境变量、CORS 说明。
|
- `e2e/README.md`:运行前置、环境变量、CORS 说明。
|
||||||
|
|
||||||
|
### 2.5 A1 补强:部门管理(2026-11-03)
|
||||||
|
|
||||||
|
- **口径**:独立页面 `/system/departments`;只停用不删除;有在职成员 / 启用中的下级小组 / 下级在职成员时禁止停用;负责人/排序可改;上级关系创建后不可移动;权限复用 `user:view` / `user:manage`,不新增权限点。
|
||||||
|
- **后端**:`GET /departments/tree?include_disabled`、`POST/PATCH /departments`、`POST /departments/{id}/disable|enable`;无 DELETE;`@Audit` 覆盖写操作;成员统计只算在职。
|
||||||
|
- **前端**:管理中心新增「部门管理」;两级树 + 详情/编辑 + 新建/停用启用确认;停用前本地预判 + 服务端文案兜底。
|
||||||
|
- **测试**:shared 契约(节点字段/新建/更新 strict);api 单测 + int 覆盖两级/重名/负责人/三类停用拦截/启用联动/DELETE 404;web 单测覆盖树、约束、表单、接口封装;真实账号 + 真实 API 手工联调通过(新建部门/小组、改名、停用空小组、重名提示、截图 `70-departments.png`)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3 验证结果
|
## 3 验证结果
|
||||||
@@ -73,10 +84,11 @@
|
|||||||
| 格式 | `pnpm format:check` | ✅ |
|
| 格式 | `pnpm format:check` | ✅ |
|
||||||
| Lint | `pnpm lint` | ✅ 0 warning |
|
| Lint | `pnpm lint` | ✅ 0 warning |
|
||||||
| 类型 | `pnpm typecheck` | ✅ 10/10 tasks |
|
| 类型 | `pnpm typecheck` | ✅ 10/10 tasks |
|
||||||
| 单测 | `pnpm test` | ✅ shared 95 / api 60 / web 55,共 210 |
|
| 单测 | `pnpm test` | ✅ shared 121 / api 90 / web 120,共 331 |
|
||||||
| 集成 | `pnpm test:int` | ✅ 2 files / 7 tests(真实 PG + Redis) |
|
| 集成 | `pnpm test:int` | ✅ 4 files / 33 tests(真实 PG + Redis,含部门 6 例) |
|
||||||
| OpenAPI | `pnpm openapi:export` | ✅ 新增 14 条 identity 路径,`apps/web/src/api/generated/openapi.d.ts` 已更新 |
|
| OpenAPI | `pnpm openapi:export` | ✅ identity 路径(含部门 5 条)导出,`apps/web/src/api/generated/openapi.d.ts` 已更新 |
|
||||||
| 浏览器 e2e | `A1_E2E=1 pnpm exec playwright test e2e/a1-identity.spec.ts` | ✅ 6/6(登录+强改、刷新旋转、登出、停用、角色变更、越权 403) |
|
| 浏览器 e2e | `A1_E2E=1 pnpm exec playwright test e2e/a1-identity.spec.ts` | ✅ 6/6(登录+强改、刷新旋转、登出、停用、角色变更、越权 403) |
|
||||||
|
| 部门管理联调 | 真实 API + 浏览器(jiang.lan) | ✅ 新建一级/小组、改名、停用空小组、重名 40903、树/详情/停用确认均正常 |
|
||||||
|
|
||||||
联调截图:`design/a1-ui-v1/shots/impl/`(登录、强改、用户列表、详情、角色 Tab、停用弹窗、命中真实接口);e2e 截图:`design/a1-ui-v1/shots/impl/e2e/`。
|
联调截图:`design/a1-ui-v1/shots/impl/`(登录、强改、用户列表、详情、角色 Tab、停用弹窗、命中真实接口);e2e 截图:`design/a1-ui-v1/shots/impl/e2e/`。
|
||||||
|
|
||||||
@@ -111,6 +123,8 @@ pnpm dev # API :3000 + Web :5173(日常启动不需要任何 DB
|
|||||||
| 8 | CORS / e2e | API `WEB_ORIGIN` 仅允许 `http://127.0.0.1:5173`;e2e 跑在 dev 5173。若改用 preview 4173,需把该 origin 加进 `WEB_ORIGIN`。 |
|
| 8 | CORS / e2e | API `WEB_ORIGIN` 仅允许 `http://127.0.0.1:5173`;e2e 跑在 dev 5173。若改用 preview 4173,需把该 origin 加进 `WEB_ORIGIN`。 |
|
||||||
| 9 | 本地账号状态 | 联调过程中曾修改本地 admin/jiang.lan 口令并触发锁定;交付前已 `pnpm db:reset` 恢复种子(`lingxi2026`)。 |
|
| 9 | 本地账号状态 | 联调过程中曾修改本地 admin/jiang.lan 口令并触发锁定;交付前已 `pnpm db:reset` 恢复种子(`lingxi2026`)。 |
|
||||||
| 10 | 客户转交必填 | PRD 要求离职停用前必须转交名下客户;当前因 A3 未落地,停用弹窗的转交为可选项,A3 之后应收紧为有客户时必填。 |
|
| 10 | 客户转交必填 | PRD 要求离职停用前必须转交名下客户;当前因 A3 未落地,停用弹窗的转交为可选项,A3 之后应收紧为有客户时必填。 |
|
||||||
|
| 11 | 部门管理 e2e | 部门管理暂无独立浏览器 e2e,由 api int(6 例)+ web 单测 + 真实账号手工联调覆盖;后续补 e2e 时建议覆盖「有成员禁止停用」与「停用后不可再选」。 |
|
||||||
|
| 12 | 部门删除 | 按口径不提供删除,仅停用;如后续确需删除空部门,需先补 PRD/接口口径。 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
| V0.1(进度回写) | 2026-11-02 | A0 工程骨架与契约基线完成:批次总览增加状态列、A0 WBS 标注完成、回写执行证据与偏差;不改变原计划范围与验收口径 |
|
| V0.1(进度回写) | 2026-11-02 | A0 工程骨架与契约基线完成:批次总览增加状态列、A0 WBS 标注完成、回写执行证据与偏差;不改变原计划范围与验收口径 |
|
||||||
| V0.1(进度回写 A1) | 2026-11-03 | A1 身份认证与用户管理完成:批次总览更新 A1 状态、A1 WBS 标注完成、回写执行证据与遗留;不改变原计划范围与验收口径 |
|
| V0.1(进度回写 A1) | 2026-11-03 | A1 身份认证与用户管理完成:批次总览更新 A1 状态、A1 WBS 标注完成、回写执行证据与遗留;不改变原计划范围与验收口径 |
|
||||||
| V0.1(路由规范回写) | 2026-11-03 | 「平台」更名「管理中心」,前端路由统一为 `/<模块>/<功能>`(A1 用户页改为 `/system/users`);同步附录 C 页面清单与前端目录约定,不改变功能范围与验收口径 |
|
| V0.1(路由规范回写) | 2026-11-03 | 「平台」更名「管理中心」,前端路由统一为 `/<模块>/<功能>`(A1 用户页改为 `/system/users`);同步附录 C 页面清单与前端目录约定,不改变功能范围与验收口径 |
|
||||||
|
| V0.1(A1 部门管理补强) | 2026-11-03 | 补 `/system/departments` 部门管理:WBS 增 A1-BE-05 / A1-FE-04,补页面与接口清单;只停用不删除、有成员/启用子部门禁止停用;不改变其它批次范围 |
|
||||||
|
|
||||||
### 0.2 引用约定
|
### 0.2 引用约定
|
||||||
|
|
||||||
@@ -394,7 +395,7 @@ flowchart LR
|
|||||||
|
|
||||||
> **A0 进度(2026-11-02)**:✅ 已完成。10/10 项 WBS 通过;本批门禁 `format:check / lint / typecheck / test / build / test:int / openapi:export / openapi:diff / e2e` 与本地 CI `pnpm ci:local` 全绿;`/health`、`/api/docs`、web 布局与登录壳、worker 启动均实测通过。实现记录与偏差见 [A0 实施报告](./灵犀_A0工程骨架与契约基线_实施报告_V0.1.md)。环境适配:本地 PG/Redis 复用已有 Docker、对象存储使用公网 RustFS、种子仅 `system_configs`(`Q-A0-01`)、Gitea 暂无 runner 时以 `pnpm ci:local` 为准。
|
> **A0 进度(2026-11-02)**:✅ 已完成。10/10 项 WBS 通过;本批门禁 `format:check / lint / typecheck / test / build / test:int / openapi:export / openapi:diff / e2e` 与本地 CI `pnpm ci:local` 全绿;`/health`、`/api/docs`、web 布局与登录壳、worker 启动均实测通过。实现记录与偏差见 [A0 实施报告](./灵犀_A0工程骨架与契约基线_实施报告_V0.1.md)。环境适配:本地 PG/Redis 复用已有 Docker、对象存储使用公网 RustFS、种子仅 `system_configs`(`Q-A0-01`)、Gitea 暂无 runner 时以 `pnpm ci:local` 为准。
|
||||||
>
|
>
|
||||||
> **A1 进度(2026-11-03)**:✅ 已完成。8/8 项 WBS 通过;`format:check / lint / typecheck / test` 全绿(shared 95 / api 60 / web 55),`test:int` 7 项(真实 PG / Redis),A1-QA-01 浏览器 e2e 6/6;登录 → 首次登录强改 → 用户列表 / 新建 / 详情 / 停用启用 / 角色调整 / 客户转交占位全链路实测。实现记录、口径与遗留见 [A1 实施报告](./灵犀_A1身份认证与用户管理_实施报告_V0.1.md)。已知遗留:六类数据范围(A2)、客户转交真实接口(A3)、审计落库(A5)。
|
> **A1 进度(2026-11-03)**:✅ 已完成。10/10 项 WBS 通过;`format:check / lint / typecheck / test` 全绿(shared 121 / api 90 / web 120),`test:int` 33 项(真实 PG / Redis),A1-QA-01 浏览器 e2e 6/6;登录 → 首次登录强改 → 用户列表 / 新建 / 详情 / 停用启用 / 角色调整 / 客户转交占位全链路实测。**补强**:`/system/departments` 部门管理(两级组织树、负责人/排序、只停用不删除、停用拦截)已落地并联调。实现记录、口径与遗留见 [A1 实施报告](./灵犀_A1身份认证与用户管理_实施报告_V0.1.md)。已知遗留:客户转交真实接口(A3)、审计落库(A5)。
|
||||||
>
|
>
|
||||||
> **A2 进度(2026-11-03)**:✅ 已完成。8/8 项 WBS 通过;H1 权限门已确认并记录 [ADR-001](../adr/ADR-001-权限点目录与六类数据范围.md);UI 门三套原型独立评审 A 8 / B 8 / C 7,用户选定 **B 主从分栏**。`format:check / lint / typecheck / test` 全绿(shared 119 / api 85 / web 102),`test:int` 27 项(真实 PG / Redis),A2-QA-01 浏览器 e2e 1/1(复跑通过);角色可配、SoD 40304、特殊权限默认关闭、六类范围解析与 `ScopeContext` 全链路、系统角色保护、变更审计与 outbox 均实测。实现记录、口径与遗留见 [A2 实施报告](./灵犀_A2角色权限与数据范围_实施报告_V0.1.md)。已知遗留:A3 前客户目录为空集、A5 审计落库、DP-14 两项特殊权限、导航模块级权限口径。
|
> **A2 进度(2026-11-03)**:✅ 已完成。8/8 项 WBS 通过;H1 权限门已确认并记录 [ADR-001](../adr/ADR-001-权限点目录与六类数据范围.md);UI 门三套原型独立评审 A 8 / B 8 / C 7,用户选定 **B 主从分栏**。`format:check / lint / typecheck / test` 全绿(shared 119 / api 85 / web 102),`test:int` 27 项(真实 PG / Redis),A2-QA-01 浏览器 e2e 1/1(复跑通过);角色可配、SoD 40304、特殊权限默认关闭、六类范围解析与 `ScopeContext` 全链路、系统角色保护、变更审计与 outbox 均实测。实现记录、口径与遗留见 [A2 实施报告](./灵犀_A2角色权限与数据范围_实施报告_V0.1.md)。已知遗留:A3 前客户目录为空集、A5 审计落库、DP-14 两项特殊权限、导航模块级权限口径。
|
||||||
|
|
||||||
@@ -541,9 +542,11 @@ PRD §7 把 **M-27(素材元素级拆解)** 与「自动字幕 → TTS 配
|
|||||||
| A1-BE-02 | 认证与会话 | BE | 账号密码登录(Argon2)、JWT access + refresh 旋转、`jti` 吊销、登出、失败次数限制、密码策略;SSO 适配器接口(不实现) | A0-BE-02 | 登录 → 刷新 → 登出全链路;旧 refresh 立即失效;错误码 40101 / 40102 正确 | 1.0 | ✅ |
|
| A1-BE-02 | 认证与会话 | BE | 账号密码登录(Argon2)、JWT access + refresh 旋转、`jti` 吊销、登出、失败次数限制、密码策略;SSO 适配器接口(不实现) | A0-BE-02 | 登录 → 刷新 → 登出全链路;旧 refresh 立即失效;错误码 40101 / 40102 正确 | 1.0 | ✅ |
|
||||||
| A1-BE-03 | 守卫链与审计拦截 | BE | `JwtGuard` → `PermissionGuard` → `SpecialPermissionGuard` → `ScopeGuard` 骨架 → 业务校验;`@Audit()` 装饰器与请求上下文(用户、客户、trace_id) | A1-BE-02、A0-SH-01 | 无 token 401;无权限点 40301;守卫顺序可单测 | 1.0 | ✅ |
|
| A1-BE-03 | 守卫链与审计拦截 | BE | `JwtGuard` → `PermissionGuard` → `SpecialPermissionGuard` → `ScopeGuard` 骨架 → 业务校验;`@Audit()` 装饰器与请求上下文(用户、客户、trace_id) | A1-BE-02、A0-SH-01 | 无 token 401;无权限点 40301;守卫顺序可单测 | 1.0 | ✅ |
|
||||||
| A1-BE-04 | `/me` 与权限上下文 | BE | 当前用户、角色、权限点集合、数据范围、可见客户集合;权限变更即时生效(不缓存旧权限) | A1-BE-03 | `/me` 与登录返回一致;角色变更后下一次请求生效 | 0.5 | ✅ |
|
| A1-BE-04 | `/me` 与权限上下文 | BE | 当前用户、角色、权限点集合、数据范围、可见客户集合;权限变更即时生效(不缓存旧权限) | A1-BE-03 | `/me` 与登录返回一致;角色变更后下一次请求生效 | 0.5 | ✅ |
|
||||||
|
| A1-BE-05 | 部门管理补强 | BE | `GET /departments/tree?include_disabled`、`POST/PATCH /departments`、`POST /departments/{id}/disable|enable`;负责人/排序;只停用不删除;有在职成员或启用子部门禁止停用 | A1-BE-01 | 两级/超两级/重名/负责人校验;停用三类拦截;无 DELETE | 0.5 | ✅ |
|
||||||
| A1-FE-01 | 登录与会话 | FE | 登录页、token 存储与刷新、登出、会话过期跳转、路由回跳 | A0-FE-03 | 登录 → 刷新页面仍在线;token 过期自动刷新一次;刷新失败回登录 | 0.5 | ✅ |
|
| A1-FE-01 | 登录与会话 | FE | 登录页、token 存储与刷新、登出、会话过期跳转、路由回跳 | A0-FE-03 | 登录 → 刷新页面仍在线;token 过期自动刷新一次;刷新失败回登录 | 0.5 | ✅ |
|
||||||
| A1-FE-02 | 用户管理页 | FE | 用户列表(游标分页 / 筛选)、新建 / 编辑、停用确认、部门树、角色多选、客户转交入口 | A0-FE-02 | 列表可分页筛选;停用需二次确认;页面按 `user:manage` 隐藏写操作 | 1.0 | ✅ |
|
| A1-FE-02 | 用户管理页 | FE | 用户列表(游标分页 / 筛选)、新建 / 编辑、停用确认、部门筛选、角色多选、客户转交入口 | A0-FE-02 | 列表可分页筛选;停用需二次确认;页面按 `user:manage` 隐藏写操作 | 1.0 | ✅ |
|
||||||
| A1-FE-03 | 权限上下文与路由守卫 | FE | `/me` 全局缓存、权限点 Hook(`usePermission`)、路由级与按钮级控制、403 页 | A1-FE-01 | 无权限路由被拦截;按钮级无权限不渲染(非 `removeChild` 式隐藏) | 0.5 | ✅ |
|
| A1-FE-03 | 权限上下文与路由守卫 | FE | `/me` 全局缓存、权限点 Hook(`usePermission`)、路由级与按钮级控制、403 页 | A1-FE-01 | 无权限路由被拦截;按钮级无权限不渲染(非 `removeChild` 式隐藏) | 0.5 | ✅ |
|
||||||
|
| A1-FE-04 | 部门管理页 | FE | `/system/departments` 两级组织树 + 详情/内联编辑 + 新建部门/小组 + 停用/启用二次确认;显示已停用、`?id=` 选中可恢复 | A1-FE-01、A1-FE-03 | 无 `user:manage` 只读;停用被拒有明确提示;刷新恢复选中 | 0.5 | ✅ |
|
||||||
| A1-QA-01 | 账号生命周期用例 | QA | 登录 / 刷新 / 登出 / 停用 / 角色变更 / 越权 6 类用例 | A1-BE-04 | 用例全部通过并进 CI | 0.5 | ✅ |
|
| A1-QA-01 | 账号生命周期用例 | QA | 登录 / 刷新 / 登出 / 停用 / 角色变更 / 越权 6 类用例 | A1-BE-04 | 用例全部通过并进 CI | 0.5 | ✅ |
|
||||||
|
|
||||||
**本批门禁**:登录闭环;用户生命周期可演示;权限有 / 无用例通过(范围外 ScopeContext 随 A2 补齐);审计已记录登录与用户变更(当前为结构化日志,落库随 A5)。
|
**本批门禁**:登录闭环;用户生命周期可演示;权限有 / 无用例通过(范围外 ScopeContext 随 A2 补齐);审计已记录登录与用户变更(当前为结构化日志,落库随 A5)。
|
||||||
@@ -917,8 +920,8 @@ PRD §7 把 **M-27(素材元素级拆解)** 与「自动字幕 → TTS 配
|
|||||||
|
|
||||||
| 项 | 内容 |
|
| 项 | 内容 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 页面 | `/login`、`/system/users`、`/system/users/new`、`/system/users/:id`、部门树(内嵌用户页) |
|
| 页面 | `/login`、`/system/users`、`/system/users/new`、`/system/users/:id`、`/system/departments`(部门管理) |
|
||||||
| 接口 | `POST /auth/login`、`/auth/refresh`、`/auth/logout`、`GET /me`、`GET /users`、`POST /users`、`PATCH /users/{id}`(含角色分配)、`POST /users/{id}/transfer-customers` |
|
| 接口 | `POST /auth/login`、`/auth/refresh`、`/auth/logout`、`GET /me`、`GET /users`、`POST /users`、`PATCH /users/{id}`(含角色分配)、`POST /users/{id}/transfer-customers`;`GET /departments/tree`、`POST/PATCH /departments`、`POST /departments/{id}/disable`、`/enable`(不提供删除) |
|
||||||
| 关键规则 | 部门最多两级;手机号唯一;一人可多角色;离职**停用不删**,名下客户必须转交;超管建议 ≤ 2 人、授予二次确认并审计;停用即时生效 |
|
| 关键规则 | 部门最多两级;手机号唯一;一人可多角色;离职**停用不删**,名下客户必须转交;超管建议 ≤ 2 人、授予二次确认并审计;停用即时生效 |
|
||||||
| 页面状态 | 空态(无用户 / 无搜索结果)、加载骨架、错误重试、无权限 403;停用用户列表默认隐藏、可筛选查看 |
|
| 页面状态 | 空态(无用户 / 无搜索结果)、加载骨架、错误重试、无权限 403;停用用户列表默认隐藏、可筛选查看 |
|
||||||
| 验收 | ① 新建用户 → 分配角色 → 登录成功;② 停用后无法登录且在线会话失效;③ 删除按钮不存在,只有停用;④ 部门超两级被拒;⑤ 用户变更进审计 |
|
| 验收 | ① 新建用户 → 分配角色 → 登录成功;② 停用后无法登录且在线会话失效;③ 删除按钮不存在,只有停用;④ 部门超两级被拒;⑤ 用户变更进审计 |
|
||||||
@@ -1374,6 +1377,7 @@ infra/:compose、Nginx、监控、备份脚本占位
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `/login` | 登录 | 公开 | A1 |
|
| `/login` | 登录 | 公开 | A1 |
|
||||||
| `/system/users`、`/system/users/new`、`/system/users/:id` | 用户与部门 | `user:view` / `user:manage` | A1 |
|
| `/system/users`、`/system/users/new`、`/system/users/:id` | 用户与部门 | `user:view` / `user:manage` | A1 |
|
||||||
|
| `/system/departments` | 部门管理(两级组织树、停用/启用) | `user:view` / `user:manage` | A1 |
|
||||||
| `/system/roles`、`/system/roles/:id` | 角色管理 | `role:view` / `role:manage` | A2 |
|
| `/system/roles`、`/system/roles/:id` | 角色管理 | `role:view` / `role:manage` | A2 |
|
||||||
| `/system/industries` | 行业管理 | `industry_pack:view` / `customer:manage` | A3 |
|
| `/system/industries` | 行业管理 | `industry_pack:view` / `customer:manage` | A3 |
|
||||||
| `/system/customers`、`/system/customers/new`、`/system/customers/:id` | 客户管理 | `customer:view` / `customer:manage` | A3 |
|
| `/system/customers`、`/system/customers/new`、`/system/customers/:id` | 客户管理 | `customer:view` / `customer:manage` | A3 |
|
||||||
|
|||||||
Reference in new issue
Block a user