System_Management/docs/spec-conventions.md
liuyun b8fa107d24 docs: drop mock, integrate with real api
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-10 14:34:13 +08:00

147 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Spec 约定(Spec Conventions)
通用系统管理脚手架 openspec spec 的**组织、粒度、编号、模块划分**唯一权威。
**新会话、新 change 必须遵守,违反即返工。**
> 本文是 spec 相关约定的**唯一事实源**;`CLAUDE.md` / `AGENTS.md` / `openspec/config.yaml`
> 只引用本文、不重复本文内容。改 spec 约定只改这里。
## 1. 事实源
- 本项目是**脚手架**,无外部 PRD;**单一事实源 = `openspec/specs/`**,其中
`shared/data-model`(字段字典)是字段一致性唯一锚点,`shared/api-contract`(接口契约)
是前后端联调唯一锚点。
- **功能文档**边实现边补,存 `docs/requirements/`(模块说明/产品方案),仅作说明,不凌驾于 spec。
- 原型仅作视觉参考。
## 2. 技术栈
| 端 | 工程 | 栈 |
|---|---|---|
| 后端 | `sources/sysmgr-nest` | NestJS 12 · TypeScript · Vitest |
| 管理后台前端 | `sources/sysmgr-admin` | Vue 3 · Vite · TypeScript · Pinia · UnoCSS |
- 运行时 Node 22.23.1,包管理 pnpm 12.10.1(以 `engines` / `packageManager` / `.nvmrc` 为准)。
- 前后端工程以 **Git submodule** 形式纳入主仓管理。
## 3. spec 三层结构
```
specs/
├── shared/ ← 跨前后端公共契约(粘合剂)
│ ├── platform/ 全局规范(设计令牌/文案/URL 契约/隐私红线)
│ ├── data-model/ 数据模型(实体 + 枚举 + 状态机 = 字段字典)
│ └── api-contract/ API 契约(endpoint + 请求/响应 shape)
├── frontend/ ← 前端 spec(按 SH-AC 契约验收)
│ └── AD/ 管理后台(当前唯一前端端)
└── backend/ ← 后端 spec(API 独立验收)
└── <域>/ 按 §9 域码清单
```
## 4. 粒度规则
- **前端**:细到「功能块」级。一个 spec = 一个可独立验收的功能单元。每页保留一个薄
「页面级 spec」作容器(定位/导航/布局/流转)。
- 判断标准:这个块能不能**独立验收、独立打勾**。能就拆,不能就合;简单页不强拆。
- 同一页面 PC 与移动可合并为同一 spec(布局差异写在 spec 内部)。
- **后端**:按实体/域(见 §9 域码清单)。
- **共享**:platform / data-model / api-contract 三个。
## 5. 编号规则
格式:`<层>-<端/域>-<页面/实体>[.<功能块>]`
| 段 | 取值 |
|---|---|
| 层 | `SH` shared / `FE` frontend / `BE` backend |
| 端(FE) | `AD` 管理后台(当前唯一;将来用户端为 `FE`) |
| 域(BE) | 见 §9 域码清单 |
| 域(SH) | `PLT` platform / `DM` data-model / `AC` api-contract |
| 页面(FE) | 功能页英文 kebab-case(如 `user`、`role`、`resource`) |
| 功能块 | `.01` `.02` …(页面级 spec 无后缀) |
**顺序(读取即构建顺序)**:
1. 层序:`SH` → `FE` → `BE`
2. FE 内端序:`AD`(将来加 `FE` 用户端时排 `AD` 之后)
3. 域序按 §9 核心域顺序;块序 `.01` → `.02` …
**目录命名**:功能块目录带序号,如 `specs/frontend/AD/<页面>/03-<功能块>/`。
**例子**:`SH-DM`(数据模型,最前)· `FE-AD-<页面>.<块>`(前端功能块)· `BE-<域码>`(后端域)
## 6. 铁律
1. **单一事实源 = `openspec/specs/`**(无 PRD 权威);冲突以 `shared/data-model` / `shared/api-contract` 为准。
2. **数据库 schema 是字段一致性的唯一锚点**:`data-model` 字段字典先行,前后端引用同一字段名,禁止各自命名。
3. **契约先行,联调走真实 API**:前后端各自按 `SH-AC` 契约实现,完成后直接联调,不另造 Mock。
4. **字段/接口变更先改 `shared/`,再改对应 spec。**
5. **多租户**:业务实体一律带 `tenant_id`,查询统一按租户过滤(见 §9.2-1)。
6. **资源表统一授权**:菜单/按钮/接口统一为「资源」表,RBAC 授权锚点(见 §9.2-2)。
7. **数据权限**:行级可见性由 `ROLE.data_scope` 控制(见 §9.2-3)。
## 7. 构建顺序(Phase)
- **Phase 0 地基**:`sources/` 脚手架 + `shared/` 三层 spec(含 DB 设计)
- **Phase 1 前端**:管理后台按 `SH-AC` 契约实现
- **Phase 2 后端**:按 `SH-AC` 契约实现
- **Phase 3 联调与上线**:前后端对真实 API 联调 → 端到端验证 → 上线
## 8. spec 文档结构(四段式,每个 spec 必含)
**每个 spec 是独立开发单元**:可独立开发、独立测试、独立交付。文档必须含以下四段:
### ① 模块边界(Scope)
- 包含什么功能 / **不包含什么功能**(明确列出「非目标」,防范围蔓延)
- 依赖声明:本 spec 引用哪些 `SH-*`(字段名 → data-model、接口 → api-contract、全局规则 → platform)
### ② 核心场景(Scenarios)
- 用 **WHEN / THEN / AND** 格式,覆盖**正常路径 + 异常路径**
- 与 openspec 原生 `#### Scenario:` 格式对齐
### ③ 数据结构(Data)
按层适配:
| 层 | 数据结构内容 |
|---|---|
| 前端 FE | 组件 Props(props 名 / 类型 / 必填 / 默认值 / 约束)+ 页面状态 |
| 后端 BE | 实体字段 + DTO(请求/响应字段、类型、校验约束)+ 状态机 |
| 共享 SH | data-model = 字段字典(实体/枚举/状态机);api-contract = 接口 shape |
### ④ 验收标准(Acceptance)
- **ACCEPTANCE Checklist,可勾选**(`- [ ]` 形式)
- 每条对应一个可验证行为,锚定 `SH-AC` 契约或功能点编号
## 9. 模块清单与设计决策
### 9.1 域码清单(后端 spec 按此拆分)
| 层 | 域码 | 模块 | 说明 |
|---|---|---|---|
| 核心 | `TENANT` | 租户 | 仅 `tenant_id` 隔离,不做计费/SaaS 复杂化 |
| 核心 | `AUTH` | 认证 | 登录/登出、token、验证码、密码策略(横切:落 `SH-AC` + 守卫) |
| 核心 | `USER` | 用户 | CRUD、启停/锁定、密码重置、头像、关联角色/部门 |
| 核心 | `ROLE` | 角色 | 授权(资源)+ 数据权限范围 |
| 核心 | `RES` | 资源 | 菜单/按钮/接口统一资源表,RBAC 授权锚点 |
| 核心 | `ORG` | 组织 | 部门树、层级、负责人 |
| 核心 | `DICT` | 字典 | 类型 + 项,运行时 lookup |
| 建议 | `CONFIG` | 参数配置 | 系统键值参数 |
| 建议 | `AUDIT` | 操作日志 | 审计:谁/何时/对什么/做了什么 |
| 建议 | `LOGIN` | 登录日志 | 登录成功/失败、IP、UA |
| 建议 | `SESSION` | 在线会话 | 活跃会话、强退 |
| 扩展 | `POST` | 岗位 | 比「角色」更细的职位维度 |
| 扩展 | `NOTICE` | 通知公告 | 站内公告 |
| 扩展 | `JOB` | 定时任务 | 任务调度 |
| 扩展 | `FILE` | 文件存储 | 附件/OSS |
| 扩展 | `MSG` | 消息通知 | 邮件/短信/推送 |
### 9.2 三大设计决策
1. **多租户**:单租户式简单实现——所有业务实体带 `tenant_id`,后端统一租户过滤切面;
登录时按账号/租户域识别当前租户。**不做**按量付费、套餐、租户配额。
2. **资源表(RES)**:菜单与权限合一为「资源」表,`type ∈ {菜单 MENU, 按钮 BUTTON, 接口 API}`;
「目录」不设独立类型,由「菜单节点是否拥有菜单子节点」推导。
- 后端鉴权三级:公开接口无需 token → 未登记接口仅校验登录 → 登记为「接口」资源的接口校验 token + 权限标识。
- **约定**:写操作/敏感查询一律登记为「接口」资源,仅真正公开的留白。
3. **数据权限**:`ROLE.data_scope ∈ {全部 / 本部门 / 本部门及以下 / 本人 / 自定义}`;
自定义时经 `role_org`(角色-部门)关联表;后端列表查询统一按可见部门过滤。