From 61f85e5fa49154db661c014c9551451e08d89cf9 Mon Sep 17 00:00:00 2001 From: Citrons <909229731@qq.com> Date: Thu, 13 Aug 2026 23:35:50 +0800 Subject: [PATCH] =?UTF-8?q?docs(GOV-010):=20=E8=AE=B0=E5=BD=95=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E9=9C=80=E6=B1=82=E4=B8=8E=E5=AE=8C=E6=88=90=E7=BB=93?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design.md | 15 +++- .../development-summary.md | 69 ++++++++++++++++ .../gitnexus/impact-plan.md | 4 +- .../implementation-plan.md | 80 +++++++++++-------- .../manifest.yaml | 2 +- .../release-notes.md | 24 ++++++ 6 files changed, 153 insertions(+), 41 deletions(-) create mode 100644 docs/features/GOV-010-development-quality-architecture/development-summary.md create mode 100644 docs/features/GOV-010-development-quality-architecture/release-notes.md diff --git a/docs/features/GOV-010-development-quality-architecture/design.md b/docs/features/GOV-010-development-quality-architecture/design.md index 0e49407..5823b49 100644 --- a/docs/features/GOV-010-development-quality-architecture/design.md +++ b/docs/features/GOV-010-development-quality-architecture/design.md @@ -145,7 +145,7 @@ utils/request.ts(Axios) 业务 API 文件从生成 Schema 中提取请求与响应类型,并使用封装后的 request。Vue 页面、组件、Store 和 Composable 不得直接导入 Axios、调用浏览器 `fetch` 或拼接业务 URL。DTO 到 ViewModel 的转换保留在功能适配层,使后端传输字段不会扩散到展示组件。 -## 7. Axios 迁移 +## 7. Axios 迁移与依赖评估 迁移现有健康请求客户端脚手架,并建立业务 API 样例。当前页面尚未消费健康接口,现有 `client.ts` 只有直接单元测试,Playwright 则从测试进程直接请求后端;因此本次不虚构页面调用方: @@ -158,7 +158,16 @@ utils/request.ts(Axios) OpenAPI 文档与 OpenAI 兼容 API 是不同概念:前者是 NestJS 对本项目 HTTP 契约的机器可读描述;后者是未来后端 AI Provider 需要兼容的外部调用协议。本功能只改变浏览器到本项目 API 的 Axios 实现。 -## 8. 安全设计 +### 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. 安全策略与评估 ### 资产与信任边界 @@ -176,7 +185,7 @@ OpenAPI 文档与 OpenAI 兼容 API 是不同概念:前者是 NestJS 对本项 残余风险是自动校验无法判断文字结论是否真实,因此保留结构化人工 Review;Axios 响应数据的运行时 Schema 校验不在本次引入,现有健康适配器继续拒绝未知枚举,后续高风险接口按具体功能决定是否引入运行时校验。 -## 9. 性能设计 +## 9. 性能目标与评估 - Axios 替代 `openapi-fetch` 会增加有限前端依赖体积,但换取项目已确认的统一请求范式、成熟拦截器和取消能力;构建产物记录迁移前后体积并在 Review 中评估变化。 - 统一请求层不得默认无限重试,避免行情刷新时形成放大流量;本次不加入自动重试。 diff --git a/docs/features/GOV-010-development-quality-architecture/development-summary.md b/docs/features/GOV-010-development-quality-architecture/development-summary.md new file mode 100644 index 0000000..a26ecf6 --- /dev/null +++ b/docs/features/GOV-010-development-quality-architecture/development-summary.md @@ -0,0 +1,69 @@ +# 开发质量与前后端架构规范开发总结 + +- 功能编号:GOV-010 +- 总结版本:0.1 +- 日期:2026-08-13 +- 发布状态:未发布,当前处于验证阶段 + +## 原始开发需求 + +用户要求把安全性、性能优化、GitNexus 跨功能影响分析、基于真实重复的复用抽取和开发需求/完成需求/缺陷记录纳入强制开发规范与流程;后端参考成熟 NestJS 与 RuoYi 职责边界,按业务模块在模块内分层;前端参考 RuoYi Vue3 分离版的组织方式,统一封装 Axios,并在 `api` 目录按业务域管理接口。用户进一步确认 OpenAI 兼容仅指未来 AI Provider 的外部协议,浏览器请求继续使用 Axios,前后端架构规范采用独立文件维护。 + +## 需求与范围变化 + +- 需求确认过程中澄清了 `openapi-fetch`、OpenAPI 文档和 OpenAI 兼容 API 的职责:移除前端 `openapi-fetch` 执行器,但保留 `openapi-typescript` 生成契约;未来 AI Provider 不属于 GOV-010。 +- 后端分层从“固定生成完整目录树”收敛为“业务模块内按需建立职责层”,避免为了目录外观创建空层或透传层。 +- 当前 Vue 页面没有消费健康接口,因此本次只建立统一 request 和健康业务域 API 样例,没有制造页面调用链。 +- 开发环境、MySQL、Redis、RocketMQ、API、Scheduler、Worker 和源码部署行为均不在本次修改范围;没有访问生产数据库或生产配置。 + +## 实际完成需求 + +| 需求 | 状态 | 实际结果与证据 | +|---|---|---| +| FR-001 GitNexus 直接、间接和跨模块影响 | 已完成 | `gitnexus/impact-plan.md` 与完成门禁要求记录消费者、执行流、风险和同步修改;开始流程会生成影响计划骨架。 | +| FR-002 安全策略与评估 | 已完成 | 设计、测试、代码 Review 模板和规范 Review 模板均有固定安全证据章节;请求错误测试覆盖内部地址、凭据和响应正文脱敏。 | +| FR-003 性能目标与验证 | 已完成 | 设计和测试计划记录包体、超时、重试及治理扫描边界;最终生产构建字节数在 `qa/test-results.md` 补充。 | +| FR-004 独立开发总结 | 已完成 | 新增本文件和通用模板,`governance:finish` 将其列为必备文件并校验七个固定章节。 | +| FR-005 后端业务模块内按需分层 | 已完成(规范) | 代码规范和系统架构明确 Controller、Service、Domain、Repository、Adapter、DTO 的职责与依赖方向;现有健康模块未为目录外观迁移。 | +| FR-006 统一 Axios 与业务域 API | 已完成 | 新增 `web/src/utils/request.ts` 和 `web/src/api/health/index.ts`;AST 边界拒绝页面、组件、Store 或 Composable 直接 HTTP。 | +| FR-007 保留 OpenAPI 类型 | 已完成 | 健康 API 使用生成的 `HealthResponseDto`,契约生成与校验流程保持不变,没有 `any` 回退。 | +| FR-008 真实重复后再抽取 | 已完成(规范与 Review 门禁) | 规范禁止预测性抽象;本次只抽取真实的统一 HTTP 边界,没有创建未被使用的后端层。 | +| FR-009 新依赖评估 | 已完成 | 设计记录 Axios 1.19.0、MIT、官方来源、替代、成本、维护与退出方式;最终 audit 和包体证据进入 QA。 | +| FR-010 自动阻断缺证据完成声明 | 已完成 | 治理测试覆盖缺文件、缺章节、空正文、裸占位词和未通过 Review;边界测试覆盖 HTTP 绕过。 | + +当前页面仍未接入健康 API,后端 AI Provider 尚未实现,市场概览、用户、会员和订阅功能也未由 GOV-010 实现。这些均为明确非目标,不计作本功能完成项。 + +## 修复缺陷 + +本次没有修复既有市场业务缺陷,因为仓库尚处基础治理与脚手架阶段。本次修复的是工程治理缺口:此前开发总结不是独立必备证据、安全与性能章节缺少结构化门禁、前端请求库和业务 API 边界未按用户确认的 Axios 范式落实、项目边界无法阻断直接 HTTP 绕过。对应回归测试位于治理规则、请求封装、Vite 配置、健康 API 和项目边界测试中。 + +验证阶段使用 npm 官方审计端点发现 `@nestjs/swagger 11.4.6` 精确依赖的 `js-yaml 5.2.1` 存在 GHSA-pm4m-ph32-ghv5 高危拒绝服务漏洞;当前最新版 Swagger 仍锁定该版本。项目采用 pnpm 精确覆盖,仅把 `@nestjs/swagger>js-yaml` 更新到同补丁线修复版本 5.2.2,不影响其他 `js-yaml` 消费者。修复前 audit 失败输出与修复后 audit、OpenAPI、后端测试和构建结果将进入 QA 证据。 + +## 未完成与延期项 + +- 最终全量测试、浏览器视觉回归、GitNexus 开发后对比和两类 Review 正在验证阶段完成,证据将写入本功能档案后再执行完成门禁。 +- AI Provider 延期到独立功能设计,届时兼容 OpenAI API 协议;本次没有预留虚假实现或前端密钥。 +- 当前页面接入真实健康或市场概览 API 将随对应页面功能实施;本次不为了展示请求层而增加无产品价值调用。 +- 后端新业务模块会在实际出现职责时遵循按需分层;现有健康模块未迁移,避免没有业务收益的结构调整。 +- GOV-010 保持 `unreleased`,不创建版本标签;发布仍受 GOV-009 架构复核和用户确认约束。 + +## 关键提交 + +| 提交 | 中文摘要 | 推送状态 | +|---|---|---| +| `a8dcd06` | `docs(GOV-010): 制定开发质量治理实施计划` | 已推送 `origin/main` | +| `e12c572` | `feat(GOV-010): 强制校验开发质量证据` | 已推送 `origin/main` | +| `3a22fde` | `docs(GOV-010): 完善安全性能与架构规范` | 已推送 `origin/main` | +| `4105336` | `refactor(GOV-010): 统一封装前端 Axios 请求` | 已推送 `origin/main` | +| `d2c1863` | `feat(GOV-010): 建立前端 API 分域边界` | 已推送 `origin/main` | +| `e992edc` | `fix(GOV-010): 修复 Swagger 传递依赖漏洞` | 已推送 `origin/main` | + +每个阶段提交后均核对本地 `HEAD` 与 Gitea `refs/heads/main`。本总结提交和最终验证提交将在成功推送后补充最终 SHA,禁止以计划中的摘要冒充已推送事实。 + +## 验证证据 + +- 已完成的局部证据:治理测试 9 项通过;请求与配置测试 10 项通过;Web 测试 11 项通过;项目边界测试 16 项通过;Web/Server 类型检查、lint、格式和 OpenAPI 契约检查均在对应阶段通过。 +- GitNexus 阶段检测:治理、规范和 Axios 请求层为 LOW;边界工具为 MEDIUM,原因是唯一的项目边界验证执行流发生变化,不进入生产运行时。该结果必须在最终比较与 Review 中复核。 +- 安全证据:请求错误脱敏、取消语义、有限超时和 HTTP 边界已有单元测试;依赖 audit、构建产物敏感字符串扫描和最终 Git diff 检查将在 `qa/test-results.md` 保存。 +- 性能证据:迁移前 Web 构建基线为 JS 163908 字节、CSS 805 字节;最终构建体积、增量和 10 秒默认超时/无自动重试结论将在 `qa/test-results.md` 保存。 +- 完整测试、源码发布验证和桌面/移动视觉证据将在 `qa/` 与 `screenshots/iterations/` 保存;代码 Review 和规范 Review 将保存于 `review/`。 diff --git a/docs/features/GOV-010-development-quality-architecture/gitnexus/impact-plan.md b/docs/features/GOV-010-development-quality-architecture/gitnexus/impact-plan.md index 84ec94c..7285c8b 100644 --- a/docs/features/GOV-010-development-quality-architecture/gitnexus/impact-plan.md +++ b/docs/features/GOV-010-development-quality-architecture/gitnexus/impact-plan.md @@ -15,7 +15,7 @@ GitNexus 查询了三类概念:功能档案完成门禁、前端 HTTP/OpenAPI - API 端由 `HealthController.getHealth` 调用 `HealthService.check`;本次不改后端路由和 DTO。 - 项目边界由 `verifyProjectBoundaries` 扫描 TypeScript 与 Vue 脚本,适合扩展前端 HTTP 边界规则。 -## 上游影响 +## 直接与间接影响 - `getRequiredFeatureFiles`:GitNexus 风险 LOW;图谱遍历返回 0 个影响但上下文明确存在两个直接调用者,因此必须同步修改测试和完成门禁验证。 - `createApiClient`:风险 LOW、结果为 `partial`;静态引用确认只需迁移旧客户端测试并新增健康 API 样例,当前没有页面调用方需要改动。 @@ -31,7 +31,7 @@ GitNexus 查询了三类概念:功能档案完成门禁、前端 HTTP/OpenAPI - OpenAPI 生成流程:生成工具与输出协议不变,前端仍消费 `schema.ts`,仅请求执行器由 `openapi-fetch` 改为 Axios。 - 项目边界验证流程:增加 Axios/fetch 使用位置检查,生产运行时不受影响。 -## 同步修改清单 +## 跨模块同步修改 | 领域 | 是否修改 | 计划 | |---|---|---| diff --git a/docs/features/GOV-010-development-quality-architecture/implementation-plan.md b/docs/features/GOV-010-development-quality-architecture/implementation-plan.md index 8506b69..a8f479a 100644 --- a/docs/features/GOV-010-development-quality-architecture/implementation-plan.md +++ b/docs/features/GOV-010-development-quality-architecture/implementation-plan.md @@ -73,6 +73,8 @@ ### Task 1: 治理档案与证据校验 +**实施状态:已完成。** 对应提交 `e12c572`,治理测试 9 项通过并已推送 Gitea。 + **Files:** - Modify: `tools/governance/feature-record.test.mjs` @@ -88,7 +90,7 @@ - Produces: `buildImpactPlanTemplate(featureId: string): string`,生成包含影响范围、风险和同步修改清单的 Markdown 骨架。 - Completion behavior: `finish.mjs` 在文件存在校验后调用证据校验,并一次列出全部无效章节。 -- [ ] **Step 1: 先对现有治理符号执行 GitNexus 影响分析** +- [x] **Step 1: 先对现有治理符号执行 GitNexus 影响分析** Run: @@ -99,7 +101,7 @@ gitnexus_impact(target="getUnpassedReviewFiles", direction="upstream", includeTe Expected: LOW 或 MEDIUM;直接同步范围至少包含 `feature-record.test.mjs` 和 `finish.mjs`。若结果为 `partial`,记录限制并继续使用静态引用交叉核对。 -- [ ] **Step 2: 写治理规则失败测试** +- [x] **Step 2: 写治理规则失败测试** 在 `feature-record.test.mjs` 中加入以下结构化样例。完整有效档案必须包含: @@ -148,7 +150,7 @@ assert.deepEqual(getInvalidFeatureEvidence(validReports), []); 再逐一删除章节、提供空正文、提供裸 `无`、裸 `不适用`、`N/A`,断言返回对应的 `文件:章节`。提供 `不适用:本功能不进入生产请求路径,边界仅为开发门禁。`,断言可以通过。 -- [ ] **Step 3: 运行测试确认按预期失败** +- [x] **Step 3: 运行测试确认按预期失败** Run: @@ -158,7 +160,7 @@ npm run test:governance Expected: FAIL,原因是 `development-summary.md` 尚未在清单中,且 `getInvalidFeatureEvidence`、`buildImpactPlanTemplate` 尚未导出。 -- [ ] **Step 4: 实现最小 Markdown 章节校验** +- [x] **Step 4: 实现最小 Markdown 章节校验** 在 `feature-record.mjs` 中保持单文件职责,加入固定规则: @@ -186,7 +188,7 @@ const REQUIRED_EVIDENCE_SECTIONS = Object.freeze({ 章节解析允许标题前带数字序号,例如 `## 8. 安全策略与评估` 与 `## 安全策略与评估` 视为同一标题;正文截止下一个二级标题。有效正文至少包含一个非标题、非注释、非空白的说明行;若规范化后仅为 `无`、`不适用`、`N/A` 或 `none` 则无效。不要解析业务结论真伪,也不要依赖包含“安全”或“性能”的任意散文。 -- [ ] **Step 5: 让开始门禁生成影响计划骨架** +- [x] **Step 5: 让开始门禁生成影响计划骨架** 导出并测试: @@ -210,7 +212,7 @@ export function buildImpactPlanTemplate(featureId) { `start.mjs` 在创建 `before.md` 的同一目录创建 `impact-plan.md`;若任一目标文件已存在则在写入前失败,禁止覆盖历史。GOV-010 已有人工影响计划,因此只影响后续功能。 -- [ ] **Step 6: 接入完成门禁** +- [x] **Step 6: 接入完成门禁** `finish.mjs` 读取全部必备文件形成 `Map`,先报告缺失文件,再调用: @@ -223,7 +225,7 @@ if (invalidEvidence.length > 0) { 已发布 GOV-001 至 GOV-008 不批量修改;它们是不可变历史,也不再重新执行新的完成门禁。仍为 `unreleased` 的 GOV-009、FEAT-MO-001 以及后续档案,在将来完成时必须满足新规则。 -- [ ] **Step 7: 运行治理测试** +- [x] **Step 7: 运行治理测试** Run: @@ -233,7 +235,7 @@ npm run test:governance Expected: PASS,覆盖必备清单、有效章节、空章节、裸占位词、带理由不适用和影响计划骨架。 -- [ ] **Step 8: 检测变化并提交推送** +- [x] **Step 8: 检测变化并提交推送** Run GitNexus `detect_changes(scope="all")`,确认只影响治理完成路径。然后: @@ -249,6 +251,8 @@ Expected: 本地 HEAD 与 `refs/heads/main` 远程 SHA 一致。 ### Task 2: 规范、模板与架构事实 +**实施状态:已完成。** 对应提交 `3a22fde`,格式、治理和环境相关验证通过并已推送 Gitea。 + **Files:** - Create: `docs/templates/development-summary-template.md` @@ -270,11 +274,11 @@ Expected: 本地 HEAD 与 `refs/heads/main` 远程 SHA 一致。 - Produces: 后续功能可直接复制的开发总结、安全、性能、GitNexus 和 Review 模板。 - Produces: 前端 Axios/OpenAPI 分工与后端业务模块内按需分层的正式架构事实。 -- [ ] **Step 1: 对入口规范和架构文档执行影响检查** +- [x] **Step 1: 对入口规范和架构文档执行影响检查** Run GitNexus 对 `AGENTS.md`、`code-development-standards.md`、`development-workflow.md` 和 `system-architecture.md` 文件执行 upstream impact。Expected: 文档变化不影响生产执行流;若工具只能返回文件级 LOW/partial,记录限制。 -- [ ] **Step 2: 建立与门禁完全一致的模板** +- [x] **Step 2: 建立与门禁完全一致的模板** `development-summary-template.md` 必须包含 Task 1 的七个二级标题,并在每节说明应记录的事实。PRD 模板新增: @@ -290,7 +294,7 @@ Run GitNexus 对 `AGENTS.md`、`code-development-standards.md`、`development-wo 代码 Review 模板新增 `安全与残余风险`、`性能与资源影响`、`GitNexus 与同步修改`;规范 Review 模板新增 `安全、性能与架构检查`、`GitNexus 与开发总结检查`。标题必须与 Task 1 校验规则一致。 -- [ ] **Step 3: 更新代码开发规范** +- [x] **Step 3: 更新代码开发规范** 明确写入: @@ -301,7 +305,7 @@ Run GitNexus 对 `AGENTS.md`、`code-development-standards.md`、`development-wo - 前端 `utils/request.ts` 独占 Axios;业务接口位于 `api/<业务域>/index.ts`;页面、组件、Store、Composable 禁止直接 HTTP;生成 OpenAPI 类型继续作为契约来源。 - 新依赖安装前记录用途、替代、安全、许可证、体积/成本、维护和退出方案。 -- [ ] **Step 4: 更新流程与追溯规范** +- [x] **Step 4: 更新流程与追溯规范** 开发前流程要求 GitNexus 同时回答影响其他功能/模块和是否需要同步修改;缺陷修复不例外。开发后流程要求先填写开发总结,再做两类 Review。追溯树加入: @@ -311,11 +315,11 @@ Run GitNexus 对 `AGENTS.md`、`code-development-standards.md`、`development-wo 并明确 PRD、开发总结、release notes 三者分别记录目标、实际完成和面向版本使用者的变化。 -- [ ] **Step 5: 更新系统架构与代理入口** +- [x] **Step 5: 更新系统架构与代理入口** `system-architecture.md` 增加 Axios/OpenAPI 数据流和业务模块内分层;修正当前仓库结构中不存在的顶层 `contracts/` 表述,使用实际的 `server/openapi`、`server/libs/http-contracts` 和 `server/libs/message-contracts`。`AGENTS.md` 增加强制安全/性能、GitNexus 同步修改、独立开发总结、前后端架构边界。`CHANGELOG.md` 的 Unreleased 增加 GOV-010 条目。 -- [ ] **Step 6: 校验标题与格式** +- [x] **Step 6: 校验标题与格式** Run: @@ -327,7 +331,7 @@ npm run test:governance Expected: 所有门禁标题均出现在对应模板或 GOV-010 档案中,格式与治理测试通过。 -- [ ] **Step 7: 检测变化并提交推送** +- [x] **Step 7: 检测变化并提交推送** Run GitNexus `detect_changes(scope="all")`,然后: @@ -341,6 +345,8 @@ git push origin main ### Task 3: Axios 请求封装与路径别名 +**实施状态:已完成。** 对应提交 `4105336`,请求、配置、类型、lint 和格式验证通过并已推送 Gitea。 + **Files:** - Create: `web/src/utils/request.test.ts` @@ -364,7 +370,7 @@ git push origin main - Produces: 默认导出 `request`,其 base URL 为 `import.meta.env.VITE_API_BASE_URL || ''`,默认超时 `10_000` 毫秒。 - Produces: `@/*` 同时在 TypeScript、Vite 和 Vitest 解析为 `web/src/*`。 -- [ ] **Step 1: 对旧请求符号和 Vite 配置执行影响分析** +- [x] **Step 1: 对旧请求符号和 Vite 配置执行影响分析** Run: @@ -376,7 +382,7 @@ gitnexus_impact(target="readDevelopmentPublicEnv", direction="upstream", include Expected: 旧请求符号风险 LOW/partial,直接引用仅旧测试;Vite 配置影响开发服务器和配置测试,保持现有 `/api` 代理。 -- [ ] **Step 2: 记录依赖评估和构建基线** +- [x] **Step 2: 记录依赖评估和构建基线** 在后续 `qa/test-results.md` 预留并最终记录:Axios 1.19.0、MIT、官方仓库、替代项 `fetch/openapi-fetch`、选择原因、退出方式。当前构建基线记录为 JS `163908` 字节、CSS `805` 字节;最终构建使用实际产物重新测量。依赖元数据查询若使用 npm,指定任务临时缓存,避免本机 `~/.npm` 的既有权限问题: @@ -384,7 +390,7 @@ Expected: 旧请求符号风险 LOW/partial,直接引用仅旧测试;Vite npm_config_cache=/tmp/a-share-analysis-gov010-npm-cache pnpm view axios version license repository.url --json ``` -- [ ] **Step 3: 安装 Axios 并移除旧请求库** +- [x] **Step 3: 安装 Axios 并移除旧请求库** Run: @@ -395,7 +401,7 @@ pnpm --filter @a-share-analysis/web add axios@1.19.0 Expected: `web/package.json` 只保留 Axios 作为浏览器 HTTP 请求库,锁文件不再含 `openapi-fetch`。 -- [ ] **Step 4: 写 Axios 封装失败测试** +- [x] **Step 4: 写 Axios 封装失败测试** 使用自定义 `AxiosAdapter` 返回确定响应,覆盖: @@ -419,7 +425,7 @@ await expect( 另外让 adapter 抛出包含 `mysql://root:secret@internal` 的 `AxiosError`,断言最终错误只含 `API 请求失败,请稍后重试`、`kind` 和非敏感 `status`。使用已取消的 `AbortController.signal` 断言取消错误保持 `axios.isCancel(error) === true`。 -- [ ] **Step 5: 运行 Web 测试确认失败** +- [x] **Step 5: 运行 Web 测试确认失败** Run: @@ -429,7 +435,7 @@ pnpm --filter @a-share-analysis/web test -- src/utils/request.test.ts Expected: FAIL,原因是 `web/src/utils/request.ts` 尚不存在。 -- [ ] **Step 6: 实现类型化 request 包装器** +- [x] **Step 6: 实现类型化 request 包装器** 核心行为: @@ -461,14 +467,14 @@ export function createRequestClient({ 请求拦截器保留为后续认证扩展点,但不提前实现 Token 刷新。`toApiRequestError` 不保存原始错误消息、URL、请求头或响应正文。HTTP 状态只允许保存数字状态码。 -- [ ] **Step 7: 增加 `@` 别名并保留现有代理** +- [x] **Step 7: 增加 `@` 别名并保留现有代理** - `web/tsconfig.json`: `baseUrl: "."`,`paths: { "@/*": ["src/*"] }`。 - `web/vite.config.ts`: `resolve.alias['@'] = path.resolve(webDirectory, 'src')`。 - `web/vitest.config.ts`: 使用 `fileURLToPath(new URL('./src', import.meta.url))` 配置同一别名。 - `vite-config.test.ts`: 同时断言 `resolve.alias` 和原有 `/api` 代理,禁止迁移时破坏同源策略。 -- [ ] **Step 8: 删除旧客户端并运行局部验证** +- [x] **Step 8: 删除旧客户端并运行局部验证** Run: @@ -480,7 +486,7 @@ pnpm --filter @a-share-analysis/web typecheck Expected: `rg` 无匹配;请求与 Vite 测试、类型检查通过。 -- [ ] **Step 9: 检测变化并提交推送** +- [x] **Step 9: 检测变化并提交推送** Run GitNexus `detect_changes(scope="all")`,确认只影响 Web 请求基础设施与配置。然后: @@ -494,6 +500,8 @@ git push origin main ### Task 4: 健康 API 分域与 HTTP 架构边界 +**实施状态:已完成。** 对应提交 `d2c1863`,边界测试 16 项、Web 测试 11 项及契约验证通过并已推送 Gitea。 + **Files:** - Create: `web/src/api/health/index.test.ts` @@ -509,7 +517,7 @@ git push origin main - Boundary: 只有 `web/src/utils/request.ts` 可以导入 `axios` 或创建 Axios 实例;`web/src` 的其他运行时代码禁止调用全局 `fetch`。 - Boundary: `/api/...` 业务路径字符串只能出现在 `web/src/api/` 或 `web/src/utils/request.ts`;测试和自动生成文件按各自 fixture 验证,不放宽生产源码。 -- [ ] **Step 1: 对边界校验符号执行影响分析** +- [x] **Step 1: 对边界校验符号执行影响分析** Run: @@ -520,7 +528,7 @@ gitnexus_impact(target="verifyProjectBoundaries", direction="upstream", includeT Expected: LOW;只影响项目验证和其测试,不进入线上执行流。 -- [ ] **Step 2: 写健康 API 失败测试** +- [x] **Step 2: 写健康 API 失败测试** 使用 Vitest mock `@/utils/request`: @@ -538,7 +546,7 @@ expect(request).toHaveBeenCalledWith({ 让 mock 返回完整 `HealthResponseDto`,并通过类型断言证明 `getHealth` 返回 DTO 而不是 `AxiosResponse`。 -- [ ] **Step 3: 写边界失败测试** +- [x] **Step 3: 写边界失败测试** fixture 覆盖以下违规: @@ -550,7 +558,7 @@ fixture 覆盖以下违规: 合法 fixture 包含 `utils/request.ts` 导入 Axios、`api/health/index.ts` 导入统一 request、页面只导入 `getHealth`。继续保留 Web 禁止导入 Server 和内部消息契约测试。 -- [ ] **Step 4: 运行测试确认失败** +- [x] **Step 4: 运行测试确认失败** Run: @@ -561,7 +569,7 @@ npm run test:boundaries Expected: 健康 API 测试因文件不存在失败;边界违规 fixture 因当前校验未识别 Axios/fetch 而失败。 -- [ ] **Step 5: 实现健康业务域 API** +- [x] **Step 5: 实现健康业务域 API** ```ts import type { components } from '@/api/generated/schema'; @@ -581,7 +589,7 @@ export function getHealth(signal?: AbortSignal): Promise { 保留现有 `api/adapters/health.adapter.ts`;它负责 DTO 到 ViewModel,不移动到全局工具目录,也不接入当前页面。 -- [ ] **Step 6: 实现 AST 边界校验** +- [x] **Step 6: 实现 AST 边界校验** 在现有 TypeScript AST 遍历中收集: @@ -594,7 +602,7 @@ export function getHealth(signal?: AbortSignal): Promise { 按 `path.relative(webSourceRoot, sourcePath)` 判断允许位置,错误格式必须包含源码路径和违规种类。不要扫描注释或普通展示文本;业务 URL 只检查 CallExpression 参数中的字符串字面量。 -- [ ] **Step 7: 运行局部与契约验证** +- [x] **Step 7: 运行局部与契约验证** Run: @@ -607,7 +615,7 @@ pnpm typecheck Expected: 全部 PASS;OpenAPI 输出无业务字段变化,Web 仍不依赖 Server 源码。 -- [ ] **Step 8: 检测变化并提交推送** +- [x] **Step 8: 检测变化并提交推送** Run GitNexus `detect_changes(scope="all")`,然后: @@ -621,6 +629,8 @@ git push origin main ### Task 5: GOV-010 档案、依赖评估与开发总结 +**实施状态:进行中。** 开发总结、发布说明、依赖评估和档案状态已补齐;安全审计发现并通过 `e992edc` 修复 Swagger 的 `js-yaml` 传递依赖漏洞,等待本阶段档案提交。 + **Files:** - Create: `docs/features/GOV-010-development-quality-architecture/development-summary.md` @@ -635,13 +645,13 @@ git push origin main - Consumes: Task 1 的固定开发总结章节和 Task 2 模板。 - Produces: 与实际代码、依赖版本、范围变化和测试结果一致的功能档案。 -- [ ] **Step 1: 对照 Git diff 更新实际完成事实** +- [x] **Step 1: 对照 Git diff 更新实际完成事实** `development-summary.md` 必须逐条列出 FR-001 至 FR-010 的实际状态;原始需求和需求变化分别记录。明确写出:当前页面仍未接入健康 API、AI Provider 未实现、后端现有健康模块没有为目录外观迁移。 同时把已批准档案的章节标题规范化为 Task 1 的门禁标题:设计使用 `安全策略与评估`、`性能目标与评估`,测试计划使用 `安全验证`、`性能验证`,GitNexus 影响计划使用 `直接与间接影响`、`跨模块同步修改`。只调整标题和组织,不改变用户已经批准的结论。 -- [ ] **Step 2: 完成安全与依赖评估** +- [x] **Step 2: 完成安全与依赖评估** 在设计和总结中记录 Axios 1.19.0、MIT、官方来源、锁文件、替代方案、前端体积增量、维护状态和可回退到原生 fetch 的退出方式。运行: @@ -657,7 +667,7 @@ git status --short 构建后记录实际 JS/CSS 文件字节数,与 Task 3 基线 `163908/805` 比较;确认 request 没有默认重试,默认超时为 10 秒。治理校验只在开发/发布路径运行,不做生产负载测试,并在“不适用”结论中写清边界。 -- [ ] **Step 4: 更新清单与发布说明** +- [x] **Step 4: 更新清单与发布说明** `manifest.yaml` 状态改为 `verifying`,保留 `release: unreleased`。`release-notes.md` 说明治理门禁、架构规范和 Axios 迁移,不宣称市场概览、AI 或用户功能已完成。 diff --git a/docs/features/GOV-010-development-quality-architecture/manifest.yaml b/docs/features/GOV-010-development-quality-architecture/manifest.yaml index 2ec2c49..161b344 100644 --- a/docs/features/GOV-010-development-quality-architecture/manifest.yaml +++ b/docs/features/GOV-010-development-quality-architecture/manifest.yaml @@ -1,7 +1,7 @@ id: GOV-010 name: 开发质量与前后端架构规范 slug: development-quality-architecture -status: approved +status: verifying owner: project created_at: 2026-08-13 prd: prd.md diff --git a/docs/features/GOV-010-development-quality-architecture/release-notes.md b/docs/features/GOV-010-development-quality-architecture/release-notes.md new file mode 100644 index 0000000..e4e39bb --- /dev/null +++ b/docs/features/GOV-010-development-quality-architecture/release-notes.md @@ -0,0 +1,24 @@ +# GOV-010 未发布变更说明 + +- 状态:验证中,未发布 +- 日期:2026-08-13 + +## 新增 + +- 新功能档案必须提供独立开发总结,以及安全、性能、GitNexus 同步修改和 Review 证据。 +- 前端新增统一 Axios 请求封装和 `api/<业务域>/index.ts` 分域边界,健康 API 作为类型化样例。 +- 项目边界校验可阻断运行时代码绕过统一 request 直接使用 Axios、fetch 或业务 API URL。 + +## 调整 + +- 后端正式采用业务模块为一级目录、模块内部按真实职责分层的规范,不要求空目录或透传层。 +- 前端继续使用 OpenAPI 生成 TypeScript 类型,但 HTTP 执行器由 `openapi-fetch` 调整为 Axios 1.19.0。 +- 开发流程要求功能和缺陷修复在编码前评估跨功能、跨模块和跨进程同步修改,完成后记录实际需求、缺陷、安全、性能与 GitNexus 证据。 + +## 安全修复 + +- 将 `@nestjs/swagger` 精确依赖的 `js-yaml` 从存在 GHSA-pm4m-ph32-ghv5 的 5.2.1 覆盖到修复版本 5.2.2;不改变 Swagger 或 OpenAPI 业务契约。 + +## 范围说明 + +本变更不实现市场概览、AI Provider、用户、会员或订阅功能,不改变 HTTP 业务字段、MySQL Schema、Redis、RocketMQ、API/Scheduler/Worker 行为或 Ubuntu 源码部署方式。当前页面仍未消费健康 API。