12 KiB
开发质量与前后端架构规范设计
- 功能编号:GOV-010
- 设计版本:0.1
- 状态:approved
- 日期:2026-08-13
1. 决策摘要
采用“规范文档 + 功能模板 + 自动门禁”的可执行治理方案。安全、性能、GitNexus 影响和同步修改进入设计、测试与 Review;实际完成事实进入独立 development-summary.md。前端将现有 openapi-fetch 请求实现迁移为统一 Axios 封装,继续使用 OpenAPI 生成类型。后端采用业务模块垂直组织、模块内部按需分层,不强制空目录或透传层。
2. 方案比较
方案 A:文档、模板与关键门禁结合(采用)
优点是关键证据可以自动阻断,架构职责仍保留工程判断空间;既不会让规范沦为建议,也不会因为一个固定目录生成器迫使小模块过度设计。成本是治理脚本和边界校验需要测试,并且后端分层仍需认真 Review。
方案 B:只更新规范文档
实施成本最低,但无法防止缺少开发总结、空安全评估和页面直连 HTTP。随着功能增加,违反约定往往只能在人工 Review 后期发现,不符合项目要求的可追溯和可执行治理目标。
方案 C:固定目录生成器与全面架构 lint
自动化最强,但会要求每个模块凑齐 Controller、Service、DTO、Repository 和 Adapter,容易制造无意义转发、文件碎片和错误抽象。当前业务模块尚未充分展开,固定全部结构为时过早。
3. 治理证据链
Schema 发布基线
↓
governance:start + GitNexus 开发前分析
↓
PRD / requirements / design / test-plan
↓
测试先行 → 实现 → 完整验证
↓
GitNexus detect_changes + 前后对比
↓
development-summary
↓
代码 Review + 规范 Review
↓
governance:finish
开发前影响计划必须显式列出 HTTP/OpenAPI、Web API、消息、数据库、缓存、三个服务进程、部署、测试和文档的同步修改结论。开发后变更检测将实际符号和执行流与计划对照,避免只分析主要模块而漏掉消费者。
安全和性能采用贯穿式记录,不额外拆成孤立文件:
design.md记录威胁、缓解、残余风险、性能目标和取舍。test-plan.md记录验证方法和风险相称的测试强度。review/*.md记录实现证据、问题、处置和遗留风险。development-summary.md记录实际需求完成、缺陷和验证结果。
4. 独立开发总结
新增 docs/templates/development-summary-template.md,并把 development-summary.md 加入所有后续功能档案的完成清单。固定章节为:
- 原始开发需求。
- 需求与范围变化。
- 实际完成需求。
- 修复缺陷。
- 未完成与延期项。
- 关键提交。
- 验证证据。
自动校验验证标题存在且正文有实质说明。对于没有缺陷或延期项的功能,仍需说明“没有”的依据,不允许删除章节或只填写无解释的占位词。历史已发布档案不因新规则被批量改写;门禁以 GOV-010 生效范围和新建档案为边界,GOV-010 自身也提供该文件。
5. 后端架构
server/apps/api/src/modules/
└── market-overview/
├── market-overview.module.ts
├── controllers/
├── services/
├── dto/
├── domain/
├── repositories/
├── adapters/
├── types/
└── utils/
业务模块是第一组织边界,目录只在有对应职责时创建。依赖方向为:
Controller → Service / use case → Domain + Repository port
↑
Infrastructure Adapter
- Controller 处理协议、校验后的输入和响应映射,不包含市场计算或数据访问。
- Service 编排用例、事务边界和降级,不成为所有逻辑的集中地。
- Domain 保持纯 TypeScript 规则、口径和模型,不依赖 NestJS 或基础设施 SDK。
- Repository 是业务所需的持久化端口;Adapter 实现 MySQL、Redis、RocketMQ、免费数据源或 AI Provider。
- DTO、领域模型和数据库实体分别服务传输、业务和持久化,不互相冒充。
- 模块间共享只有在重复已经出现、语义稳定且所有者明确后才上移到
server/libs。
现有健康检查是脚手架基础能力,本功能不为展示目录形式而迁移其后端文件。新的业务模块从本规范开始执行;后续触及健康检查模块时再基于影响分析判断是否垂直归档。
6. 前端架构与 Axios 数据流
web/src/
├── utils/
│ └── request.ts
├── api/
│ ├── generated/
│ │ └── schema.ts
│ ├── health/
│ │ └── index.ts
│ ├── market-overview/
│ │ └── index.ts
│ ├── sectors/
│ │ └── index.ts
│ └── stocks/
│ └── index.ts
└── features/
└── <business-domain>/
├── adapters/
├── components/
├── composables/
├── stores/
└── views/
实际数据流为:
NestJS DTO 与 Swagger 元数据
↓
server/openapi/openapi.json
↓ openapi-typescript
web/src/api/generated/schema.ts
↓ 类型约束
api/<业务域>/index.ts
↓ 调用
utils/request.ts(Axios)
↓
业务 adapter → ViewModel → 页面/组件
request.ts 创建唯一 Axios 实例,负责 base URL 规范化、超时、通用请求头、取消信号、错误归一化和后续认证扩展。响应拦截器只返回响应数据,API 函数不向功能层泄漏 AxiosResponse。错误类型保留稳定的用户安全消息,并可携带不敏感的错误分类和 HTTP 状态供界面决定重试或降级;原始配置、请求头、内网地址和上游正文不进入展示消息。
业务 API 文件从生成 Schema 中提取请求与响应类型,并使用封装后的 request。Vue 页面、组件、Store 和 Composable 不得直接导入 Axios、调用浏览器 fetch 或拼接业务 URL。DTO 到 ViewModel 的转换保留在功能适配层,使后端传输字段不会扩散到展示组件。
7. Axios 迁移与依赖评估
迁移现有健康请求客户端脚手架,并建立业务 API 样例。当前页面尚未消费健康接口,现有 client.ts 只有直接单元测试,Playwright 则从测试进程直接请求后端;因此本次不虚构页面调用方:
- 删除
openapi-fetch依赖,新增锁定版本的axios。 - 以测试先行创建
web/src/utils/request.ts,覆盖根地址、超时、数据解包、取消和脱敏错误。 - 创建
web/src/api/health/index.ts,使用生成的HealthResponseDto类型调用/api/v1/health。 - 更新旧客户端测试,并为健康业务 API 增加测试;保留 DTO 到
HealthViewModel的适配器,暂不为了展示调用链而把健康状态接入页面。 - 删除不再使用的
web/src/api/client.ts及对应旧测试。 - 扩展项目边界校验,拒绝 API 目录外直接使用 Axios/fetch,并拒绝 API 模块绕过统一 request。
OpenAPI 文档与 OpenAI 兼容 API 是不同概念:前者是 NestJS 对本项目 HTTP 契约的机器可读描述;后者是未来后端 AI Provider 需要兼容的外部调用协议。本功能只改变浏览器到本项目 API 的 Axios 实现。
Axios 依赖评估
- 用途:Axios 1.19.0 作为浏览器到本项目 API 的唯一 HTTP 请求实现,由
web/src/utils/request.ts封装。 - 来源与维护:npm 包元数据指向官方仓库
https://github.com/axios/axios.git,许可证为 MIT;版本写入web/package.json并由pnpm-lock.yaml锁定。 - 替代方案:原生
fetch依赖最少,但拦截器、超时和错误策略需自行维护;旧openapi-fetch能直接消费 OpenAPI paths 类型,但不符合本项目已确认的 Axios 请求范式。 - 选择理由:统一拦截器、取消信号和错误归一化能力成熟,能让业务 API 只返回类型化 DTO,同时继续由
openapi-typescript提供契约类型。 - 成本与风险:增加前端构建体积和一项供应链依赖;以生产构建字节数和
pnpm audit --prod记录实际证据,不以主观估计代替。 - 退出方式:保留稳定的
RequestClient接口;若后续需要移除 Axios,可在utils/request.ts内切换到原生fetch,业务域 API 无需改为直接 HTTP 调用。
8. 安全策略与评估
资产与信任边界
- 浏览器输入和网络响应均不可信;Axios 封装是浏览器 HTTP 错误边界,业务 API 是传输契约边界。
- OpenAPI 生成文件是可提交的公开契约,不得包含内部消息、实体或密钥。
- 治理工具读取仓库文档和 Git 状态,不读取生产环境;Schema 门禁仍只允许既定开发库边界。
主要风险与控制
- 错误泄漏:统一转换网络和 HTTP 错误,用户消息不包含 URL、凭据、响应正文或底层异常。
- 绕过请求策略:边界校验限制 Axios 实例和直接 fetch,减少遗漏超时、认证、错误处理和日志脱敏。
- 供应链:Axios 使用固定版本并提交锁文件;安装前核对官方包、许可证、维护状态和依赖变化。
- 注入与浏览器攻击:本功能不渲染远程 HTML、不添加认证 Cookie、不生成动态 SQL;后续涉及这些边界时仍必须分别评估 XSS、CSRF、SSRF 和注入。
- 伪造治理证据:完成门禁检查必备章节及理由,Review 仍核对内容与 Git diff、测试输出是否一致。
残余风险是自动校验无法判断文字结论是否真实,因此保留结构化人工 Review;Axios 响应数据的运行时 Schema 校验不在本次引入,现有健康适配器继续拒绝未知枚举,后续高风险接口按具体功能决定是否引入运行时校验。
9. 性能目标与评估
- Axios 替代
openapi-fetch会增加有限前端依赖体积,但换取项目已确认的统一请求范式、成熟拦截器和取消能力;构建产物记录迁移前后体积并在 Review 中评估变化。 - 统一请求层不得默认无限重试,避免行情刷新时形成放大流量;本次不加入自动重试。
- 超时采用有限默认值,业务域可在设计批准后缩短,但不得无上限等待。
- API 函数返回解包后的 DTO,避免重复转换与组件订阅 Axios 对象;该差异不是性能热点,主要价值是边界稳定。
- 治理扫描只在开发与发布验证执行,不进入线上请求路径;文件扫描保持线性遍历,当前仓库规模不要求负载测试。
- 本功能不查询 MySQL、Redis 或行情数据,不改变 Scheduler/Worker 吞吐;这些项不适用于运行时性能验证,边界是后续业务功能必须重新评估。
10. 自动校验边界
适合自动化的规则:必备文件、必填章节、Review 固定结论、前端非法依赖、直接 HTTP 调用和生成契约泄漏。后端目录是否需要某一层、重复是否足以抽取、注释是否真正解释原因等需要语义判断,进入规范 Review,不用脆弱的固定目录规则代替。
内容校验以结构为主:确认标题、标题下非空正文、明确的不适用理由格式;不通过搜索“安全”“性能”等零散词语来推定证据完整。校验函数保持纯函数并由 fixture 测试覆盖,finish.mjs 只负责编排。
11. 错误与回退
- 门禁失败必须列出具体文件和缺失章节,不能只返回布尔值。
- Axios 遇到取消请求时保留可识别取消语义,不错误展示为服务故障。
- 非取消错误转换为项目错误类型;调试细节只允许进入受控开发日志且必须脱敏,本次默认不记录原始错误。
- 若迁移回归,可用中文回退提交恢复
openapi-fetch客户端、依赖和调用方;规范、模板和校验必须作为一致变更回退,避免规范与基础代码不一致。
12. 验证与完成标准
- 治理单元测试覆盖开发总结和章节校验的通过、缺失和伪占位失败场景。
- 边界测试覆盖 Axios/fetch 的非法与合法路径、Vue 脚本和路径别名。
- Web 单元测试覆盖请求 URL、响应解包、网络错误、HTTP 错误和取消。
- OpenAPI 生成、格式、lint、类型检查、全量测试、构建、Playwright 和源码发布门禁通过。
- 现有页面在桌面与移动视口完成视觉回归,证明请求基础设施迁移没有造成布局或交互旁路变化。
- GitNexus 开发后变更检测与前置计划一致,两类 Review 最终结论均为
passed。