diff --git a/docs/audit-checklist.md b/docs/audit-checklist.md index 0269ee8..eccb899 100644 --- a/docs/audit-checklist.md +++ b/docs/audit-checklist.md @@ -60,4 +60,4 @@ - [x] **L6** ty-crud 取消确认 rejection 未捕获 —— ✔ 已完成:catch 取消 - [x] **L9** @nestjs/mau 非常规依赖 —— ✔ 已完成:核实为 NestJS Mau 部署 CLI,已移除 + 删 deploy 脚本 - [x] **L10** 无 CI/Dockerfile/compose 部署编排 —— ✔ 已完成:docker-compose(MySQL/Redis)+ CI(前后端 build/test)+ 前后端 Dockerfile -- [ ] **新增** spec 覆盖补全 —— users/roles/orgs/tenants/configs 与前端多页无 spec 锚点。方案:补主 spec +- [x] **新增** spec 覆盖补全 —— users/roles/orgs/tenants/configs 与前端多页无 spec 锚点。✔ 已完成:backend 5 域 spec 已补(users/roles/orgs/tenants/configs);前端页面为薄容器,后续按需补 diff --git a/openspec/specs/backend/configs/spec.md b/openspec/specs/backend/configs/spec.md new file mode 100644 index 0000000..5fab196 --- /dev/null +++ b/openspec/specs/backend/configs/spec.md @@ -0,0 +1,14 @@ +# Configs Specification + +## Purpose + +定义参数配置域的行为:键值配置的分页查询与增删改。 + +## Requirements + +### Requirement: 配置 CRUD +系统 SHALL 支持配置项的增删改查;key 租户内唯一。 + +#### Scenario: 配置唯一性 +- **WHEN** 创建重复 key 的配置 +- **THEN** 返回 409 冲突 diff --git a/openspec/specs/backend/orgs/spec.md b/openspec/specs/backend/orgs/spec.md new file mode 100644 index 0000000..7bb30df --- /dev/null +++ b/openspec/specs/backend/orgs/spec.md @@ -0,0 +1,21 @@ +# Orgs Specification + +## Purpose + +定义组织域的行为:组织树查询(按数据权限过滤)、增删改、防环校验。 + +## Requirements + +### Requirement: 组织树查询 +系统 SHALL 返回组织树列表,按数据权限过滤可见部门。 + +#### Scenario: 部门管理员查看组织 +- **WHEN** 数据权限为「本部门及以下」的管理员查询组织 +- **THEN** 仅返回本部门及下级组织 + +### Requirement: 组织增删改防环 +创建/更新组织 SHALL 校验父组织存在且不构成环(父不能是自身或后代)。 + +#### Scenario: 防止成环 +- **WHEN** 将组织挂到自身或其子组织下 +- **THEN** 返回 400 拒绝 diff --git a/openspec/specs/backend/roles/spec.md b/openspec/specs/backend/roles/spec.md new file mode 100644 index 0000000..1584177 --- /dev/null +++ b/openspec/specs/backend/roles/spec.md @@ -0,0 +1,28 @@ +# Roles Specification + +## Purpose + +定义角色域的行为:分页查询、创建/编辑(保留角色码校验)、删除(级联清理关联)、资源分配(事务化、平台级权限隔离)。 + +## Requirements + +### Requirement: 角色增删改 +系统 SHALL 支持角色 CRUD;保留角色码(super_admin/tenant_super_admin)不可创建、不可删除。 + +#### Scenario: 保留角色保护 +- **WHEN** 尝试创建或删除保留角色码 +- **THEN** 返回 400 拒绝 + +### Requirement: 删除级联 +删除角色 SHALL 级联清理 user_role/role_resource/role_org 关联,并清该租户权限缓存。 + +#### Scenario: 删除角色 +- **WHEN** 删除某角色 +- **THEN** 其关联与权限缓存一并清理 + +### Requirement: 资源分配 +分配资源 SHALL 事务化替换;平台级权限(tenant:*)仅平台租户可授予。 + +#### Scenario: 业务租户分配 +- **WHEN** 非平台租户分配含 tenant:* 的资源 +- **THEN** 平台级权限被剥离 diff --git a/openspec/specs/backend/tenants/spec.md b/openspec/specs/backend/tenants/spec.md new file mode 100644 index 0000000..9353a44 --- /dev/null +++ b/openspec/specs/backend/tenants/spec.md @@ -0,0 +1,28 @@ +# Tenants Specification + +## Purpose + +定义租户域的行为:仅平台租户可管理租户;创建租户自动初始化(管理员/根组织/资源/字典),删除级联清理。 + +## Requirements + +### Requirement: 平台级管理 +租户管理 SHALL 仅平台租户(super_admin)可操作;tenant:* 权限仅平台授予。 + +#### Scenario: 业务租户越权 +- **WHEN** 业务租户管理员尝试管理租户 +- **THEN** 无 tenant:* 权限,返回 403 + +### Requirement: 租户 onboarding +创建租户 SHALL 自动初始化:根组织、tenant_super_admin 角色、管理员账号、全量资源(不含 tenant:*)、内置字典。 + +#### Scenario: 新租户可用 +- **WHEN** 创建新租户 +- **THEN** 其管理员可登录并访问菜单 + +### Requirement: 租户删除级联 +删除租户 SHALL 级联清理其全部业务数据。 + +#### Scenario: 删除租户 +- **WHEN** 删除租户 +- **THEN** 其用户/角色/资源/组织/字典/日志一并清理 diff --git a/openspec/specs/backend/users/spec.md b/openspec/specs/backend/users/spec.md new file mode 100644 index 0000000..8603a21 --- /dev/null +++ b/openspec/specs/backend/users/spec.md @@ -0,0 +1,35 @@ +# Users Specification + +## Purpose + +定义用户域的行为:分页查询(含数据权限过滤)、新增/编辑/删除(软删回收唯一键)、重置密码、分配角色,以及会话吊销。 + +## Requirements + +### Requirement: 用户分页查询 +系统 SHALL 支持按用户名/昵称/手机/状态分页查询用户;查询按数据权限过滤(仅本人/本部门/本部门及以下/自定义)。 + +#### Scenario: 部门管理员查看用户 +- **WHEN** 数据权限为「本部门」的管理员查询用户列表 +- **THEN** 仅返回本部门用户 + +### Requirement: 用户增删改 +系统 SHALL 支持新增/编辑用户;删除为软删并回收用户名唯一键(可重建同名)。 + +#### Scenario: 软删重建 +- **WHEN** 删除某用户后再创建同名用户 +- **THEN** 创建成功 + +### Requirement: 重置密码 +系统 SHALL 支持管理员重置用户密码;重置后吊销该用户所有会话(旧 token 失效)。 + +#### Scenario: 重置后踢下线 +- **WHEN** 管理员重置某用户密码 +- **THEN** 该用户旧 access/refresh token 立即失效 + +### Requirement: 分配角色 +系统 SHALL 支持为用户分配角色(整体替换),分配后清该用户权限缓存。 + +#### Scenario: 分配角色 +- **WHEN** 管理员为用户分配角色 +- **THEN** 该用户下次请求按新角色聚合权限