197 lines
14 KiB
Markdown
197 lines
14 KiB
Markdown
# CMPP 平台代码质量复评报告 V3
|
||
|
||
- 报告日期:2026-08-28
|
||
- 复评时间:2026-08-28 15:36~16:08(Asia/Shanghai)
|
||
- 复评基线:`3834d67a308acf89d0e6cb2e6009c89c93b2c139`
|
||
- 主要业务整改提交:`ad27acad7e02b787185c972c710c73c867429c36`
|
||
- 锁文件修正提交:`226527f1cef122e4dbd163da782485e8c0254dc5`
|
||
- 对比基线:V2 基线 `3af145abe5eb8cae567bb18e29116b4940889258`
|
||
- Git 状态:本地 `main` 比 `origin/main` 超前 3 个提交;当前提交尚未推送
|
||
- 工作区保护:保留既有 `docs/code-quality-reassessment-20260828-v2.md` 修改、未跟踪 `=` 和 `pnpm-lock.yaml`
|
||
- 明确未执行:提交、推送、部署、服务重启、数据库业务写入、短信发送、压力测试、预生产或生产操作
|
||
|
||
## 1. 执行摘要
|
||
|
||
本轮综合判定为:**代码质量有条件通过,持续治理尚未闭环;不建议仅凭本报告进入预生产发布。**
|
||
|
||
与 V2 相比,本轮取得了明确进步:
|
||
|
||
- 客户端凭据、Webhook、日志导出、文件上传、用户维护等写接口补充 class DTO、严格运行时校验和负向测试。
|
||
- 浏览器客户端请求不再发送或回退租户 ID,服务端可信租户边界进一步收紧。
|
||
- 登录保护从账号维度扩展为账号、来源 IP、账号+IP 和验证码请求频率,并使用 Redis 原子计数和摘要键。
|
||
- 建立 Vitest/Testing Library/jsdom/MSW 前端测试基座,4 个测试文件、34 项测试通过。
|
||
- API 增至 51 个测试套件、563 项测试并全部通过。
|
||
- 根依赖审计保持 0;API 审计从 V2 的 7 项降至 5 项,剩余项均位于 Prisma CLI 开发/迁移链。
|
||
- npm 10.9.4、两份正式 `package-lock.json`、ESLint flat config 和 Prettier 配置已建立。
|
||
- 测试环境已部署 `226527f...`;本次独立读取到的远端前端资源与本地构建资源一致,外部 API health 最终连续 5 次返回 200。
|
||
|
||
但本次独立复测发现两项不能忽略的问题:
|
||
|
||
1. **增量 lint/format 门禁存在假绿。** 默认比较 `HEAD` 时,提交后的整改文件不会进入检查;显式设置基线后,Windows 包装器又无错误信息地退出 1。绕过包装器直接检查 37 个整改代码文件,发现 6 个 ESLint error、2 个 warning,以及 2 个文件未通过 Prettier。
|
||
2. **客户端删除接口仍缺严格 DTO。** `ClientDeletionGovernanceController` 使用 TypeScript type `DeleteTargetDto`,没有 `strictValidationPipe`,额外字段、格式和长度仍不会按本轮统一规则拒绝。
|
||
|
||
综合参考分:**86/100**,较 V2 的 82/100 提升 4 分。P0 为 0,但仍有 2 项 P1 和若干 P2/验收边界。
|
||
|
||
## 2. 质量评级
|
||
|
||
| 维度 | V2 | V3 | 结论 |
|
||
|---|---:|---:|---|
|
||
| 业务正确性与并发设计 | B+ | B+ | API/Gateway 全量回归通过;未重跑真实 CMPP 全链。 |
|
||
| 安全性 | B+ | A- | 客户端租户边界、DTO 和登录保护明显增强;删除接口仍有校验缺口。 |
|
||
| 自动化测试 | B- | B+ | 前端 34 项、API 563 项通过;API “全源”指标仍未成为标准脚本默认口径。 |
|
||
| 前端性能 | B+ | B+ | 路由分包保持,入口 107.28 KiB gzip,图表异步包 181.65 KiB gzip。 |
|
||
| 可维护性 | C+ | C+ | 引入 ESLint/Prettier,但门禁未真实通过;两个 SendChain Service 未拆分。 |
|
||
| 数据库工程 | B+ | B+ | Prisma schema 和 95 项迁移发布记录正常;本轮未独立执行真实数据查询计划。 |
|
||
| 依赖与仓库卫生 | B- | B | 根审计 0,API 风险降至 Prisma CLI 5 项;正式包管理器已固定,旧未跟踪 pnpm 锁仍在。 |
|
||
| 运行与发布就绪 | B- | B | 测试环境公开入口及资源匹配;内部服务/队列状态仅有发布记录,本次 SSH 未独立复核。 |
|
||
|
||
## 3. V2 遗留项复核
|
||
|
||
| V2 项目 | V3 状态 | 复评结论 |
|
||
|---|---|---|
|
||
| 客户端写接口严格校验不完整 | **大部分关闭,仍有缺口** | 凭据、Webhook、导出、文件、用户等已补齐;客户端删除接口遗漏。 |
|
||
| 前端自动化测试为 0 | **已关闭** | 4 个文件、34 项通过;覆盖登录、请求错误、租户头、路由异常和用户列表关键状态。 |
|
||
| API 依赖公告 2 moderate/5 high | **部分关闭** | 当前为 2 moderate/3 high,共 5 项;均聚合在 Prisma CLI 链并有风险矩阵。 |
|
||
| 无真实 ESLint/Prettier | **实现未验收通过** | 配置与脚本已增加,但增量包装器有缺陷,整改代码本身仍有 lint/format 失败。 |
|
||
| SendChain 超大服务 | **未处理,按方案延期** | 文件仍约 86,253 和 53,421 字节;需要独立行为锁定与重构任务。 |
|
||
| 双锁文件口径 | **部分关闭** | `packageManager` 固定 npm 10.9.4,正式仅跟踪两份 npm lock;旧未跟踪 pnpm lock 仍受保护保留。 |
|
||
| 测试环境与登录后验收 | **部分关闭** | 测试环境已部署并健康;登录后深层页面和真实 CMPP 全链仍未复验。 |
|
||
|
||
## 4. 本轮独立验证结果
|
||
|
||
### 4.1 构建与自动化测试
|
||
|
||
| 检查项 | 结果 |
|
||
|---|---|
|
||
| 前端 TypeScript | 通过 |
|
||
| Vite production build | 通过 |
|
||
| Bundle budget | 通过;入口 107.28 KiB gzip,Chart 181.65 KiB gzip |
|
||
| 前端 Vitest | 4/4 文件、34/34 项通过 |
|
||
| 前端纳入覆盖范围的核心模块 | statements 88.34%、branches 84.71%、functions 84.00%、lines 88.02% |
|
||
| API TypeScript build | 通过 |
|
||
| Prisma validate | 通过;仓库 95 项 migration |
|
||
| API Jest | 51/51 套、563/563 项通过 |
|
||
| API 默认 coverage 脚本口径 | 70.44% / 53.77% / 71.76% / 73.61% |
|
||
| API 显式全源口径 | 60.46% / 51.54% / 60.75% / 63.04% |
|
||
| API 增量覆盖配置 | 86.92% / 77.03% / 95.91% / 90.07% |
|
||
| Gateway `go test ./... -count=1` | 通过 |
|
||
| Gateway `go vet ./...` | 通过 |
|
||
| Gateway 队列契约 | 5/5 通过 |
|
||
| 结构质量/依赖缓解/安全部署门禁 | 通过 |
|
||
| `npm ci --dry-run --include=dev` | 根项目与 API 均通过 |
|
||
|
||
覆盖率顺序均为 statements / branches / functions / lines。
|
||
|
||
首次并发执行前端测试时,4 个 Vitest worker 因本机同时运行多个高负载任务而启动超时,未执行测试;资源释放后以单 worker 串行重跑全部通过。首次从仓库根目录直接启动 API Jest 时误扫描受保护的 `outputs/` 历史快照;改为在 `api/` 目录按项目配置运行后全部通过。两次错误执行均未计为产品失败。
|
||
|
||
### 4.2 覆盖率口径校正
|
||
|
||
`api/jest.config.cjs` 仍未配置 `collectCoverageFrom`,因此标准 `test:coverage` 的 70.44% 只统计测试实际加载的源码,不能称为严格“全源覆盖率”。本报告显式加入 `src/**/*.ts` 后的全源结果为 60.46% / 51.54% / 60.75% / 63.04%,较 V2 的 59.84% / 51.29% / 60.15% / 62.60% 小幅提升,并继续满足 59% / 50% / 60% / 62% 门槛。
|
||
|
||
增量配置确实对指定新增模块建立了 80% / 70% / 80% / 80% 门槛,但运行时仍执行全部 51 套测试;覆盖率只收集列出的 7 个文件。该机制有效,但文档应准确称为“指定整改模块覆盖率”,不应与全源口径混用。
|
||
|
||
### 4.3 依赖审计
|
||
|
||
使用项目固定的 npm 10.9.4 直接审计正式锁文件:
|
||
|
||
- 根项目:0 项公告。
|
||
- API:5 项公告,2 moderate、3 high。
|
||
- 5 项均为 `prisma -> @prisma/config/@prisma/dev -> deepmerge-ts/valibot` 聚合路径,不进入 NestJS HTTP 请求运行时。
|
||
- 自动修复建议是 Prisma 7.9.0 降级到 6.12.0,属于破坏性主版本变更,本轮不执行 `audit fix --force` 的决定合理。
|
||
- `api/package-lock.json` 已实际解析 UUID 11.1.1、find-my-way 9.7.0;Swagger、js-yaml、fast-uri、brace-expansion 的既有公告已关闭。
|
||
|
||
判定:供应链风险已从“未治理”转为“有记录的开发工具链风险接受”,但仍需监控 Prisma 上游修复。
|
||
|
||
### 4.4 测试环境只读探测
|
||
|
||
- `curl --noproxy '*'` 绕过系统代理后,第一组 `/api/health` 3 次均为 HTTP 200。
|
||
- 同组客户端登录页、运营登录页和验证码接口均返回 200;运营登录页有一次总耗时约 9 秒。
|
||
- 随后一次 health 请求发生 10 秒连接超时;立即复测 5 次均返回 200,总耗时约 17~19 ms。
|
||
- 远端登录 HTML 引用 `index-BvZGIM6l.js` 和 `index-DyAqoJbu.css`,与本地 V3 构建产物一致。
|
||
- SSH 当前仍认证失败,无法独立读取 `.deployed-commit`、systemd、Redis Stream、migration 和服务器日志。
|
||
- 发布记录显示测试环境部署标记为 `226527f...`,95 项迁移一致、11 项服务 active、三条 Stream `pending=0/lag=0`、发布窗口 error 日志为 0;这些内部状态本次未独立复核。
|
||
|
||
判定:外部入口总体健康,单次超时暂记为网络瞬态,不设 P0;预生产前仍需用可用只读凭据复核内部状态。
|
||
|
||
边界说明:外部 smoke 曾请求一次验证码 GET 接口,该接口会在 Redis 写入一个 5 分钟 TTL 的一次性验证码记录;未提交登录、未创建用户或业务数据,未触发短信、余额、应用、通道或 MinIO 业务写入。
|
||
|
||
## 5. 当前问题清单
|
||
|
||
### CQ-QG-001 / P1:增量 lint/format 门禁假绿且整改代码未通过
|
||
|
||
**证据**
|
||
|
||
- `tools/quality/run-changed-code-quality.mjs:7-14` 默认基线为 `HEAD`,正常提交后执行 `npm run lint` 时不会检查已提交整改代码。
|
||
- 本次默认运行输出 `No changed code files require lint/format`,不能证明 `ad27aca` 中的代码通过。
|
||
- 设置 `QUALITY_BASE_REF=3af145a...` 后,Windows 包装器无错误信息退出 1;脚本没有输出 `spawnSync` 的 error。
|
||
- 绕过包装器直接对 37 个整改文件执行 ESLint,发现 6 个 error、2 个 warning:
|
||
- `api/src/auth/auth.controller.ts`:2 个未使用变量。
|
||
- `api/src/open-api/open-api.service.ts`:1 个未使用 import。
|
||
- `src/api/client/client.api.ts`:2 个未使用 import。
|
||
- `src/apps/client/ClientUsersPage.test.tsx`:1 个未使用变量。
|
||
- `src/apps/LoginPage.tsx`:Fast Refresh 导出警告、`useEffect` 缺少 `refreshCaptcha` 依赖警告。
|
||
- Prettier 检查发现 `api/src/auth/auth.service.spec.ts`、`api/src/open-api/open-api.service.spec.ts` 未格式化。
|
||
|
||
**影响**
|
||
|
||
整改记录中的“ESLint/Prettier 门禁通过”不是当前可重复证据。CI 如果没有显式传入基线会漏检提交;Windows 本地即使传入基线也会无诊断失败。
|
||
|
||
**关闭要求**
|
||
|
||
1. 门禁显式接收并验证 base/head,CI 使用 merge-base;本地提供全量或最近提交模式。
|
||
2. Windows 调用方式可执行,并在 spawn 失败时输出 `result.error`。
|
||
3. 修复 6 个 error、2 个 warning 和 2 个格式文件后,直接 ESLint/Prettier 与包装脚本均通过。
|
||
4. 为“无变更”“有错误”“Windows 启动失败”和“CI 基线”增加脚本测试。
|
||
|
||
### CQ-API-001 / P1:客户端删除接口仍未纳入严格运行时校验
|
||
|
||
`api/src/deletion-governance/deletion-governance.controller.ts:34-38` 的客户端删除接口使用 `DeleteTargetDto`,但没有 `@UsePipes(strictValidationPipe)`;`api/src/deletion-governance/deletion-governance.service.ts:10-18` 的 DTO 仍为 TypeScript type,没有 class-validator 规则。请求中的额外字段、超长 reason、错误布尔类型、非法时间和幂等键格式不会按统一客户端策略拒绝。
|
||
|
||
关闭要求:建立 client deletion class DTO、严格管道和负向测试,并把结构门禁扩展为检查所有 `@Controller('client...')` 的 body 写接口,而不是仅靠人工清单。
|
||
|
||
### CQ-COV-001 / P2:API 标准覆盖率脚本仍不是全源口径
|
||
|
||
标准 `test:coverage` 未配置 `collectCoverageFrom`,容易把 70.44% 误写为全源覆盖率;严格全源只有 60.46%。应在正式配置中固化全源 include/exclude,并保留增量覆盖作为第二道门禁。
|
||
|
||
### CQ-MAINT-001 / P2:SendChain 超大服务仍未拆分
|
||
|
||
`send-inbound-entry.service.ts` 约 84.2 KiB,`send-gateway-submit.service.ts` 约 52.2 KiB。本轮明确延期是合理的风险控制,但不能记为质量治理完成。后续需先补行为锁定和性能基线,再分职责重构。
|
||
|
||
### CQ-REPO-001 / P2:本地提交尚未推送且旧 pnpm 锁仍存在
|
||
|
||
本地比 `origin/main` 超前 3 个提交,远端凭据拒绝已在进度文档记录;测试环境部署了代码提交 `226527f...`,但远端 Git 仍停留在 V2 基线。灾备、协作和可追溯性因此不完整。另有未跟踪旧 `pnpm-lock.yaml`,虽未纳入正式流程,仍可能误导人工命令。
|
||
|
||
### CQ-ACC-001 / P2:登录后浏览器和真实全链仍未复验
|
||
|
||
测试环境只验证了公开页面、验证码和 health;没有输入密码或代解验证码,没有验证登录后 loading/empty/error/refresh、权限和关键写操作,也没有重跑 PostgreSQL/Redis/MinIO/Gateway/CMPP 模拟器全链。自动化测试不能替代这些最终验收证据。
|
||
|
||
## 6. 发布建议
|
||
|
||
当前建议:**允许继续整改和测试环境验证,暂停预生产发布。**
|
||
|
||
最小充分关闭顺序:
|
||
|
||
1. 修复增量 lint/format 包装器并清零当前 lint/format 失败。
|
||
2. 补齐客户端删除 DTO、严格校验和负向测试。
|
||
3. 把 API 严格全源覆盖率固化为标准门禁,修正文档口径。
|
||
4. 使用可用只读凭据复核测试环境部署标记、11 项服务、95 项迁移、Redis Stream 和 error 日志。
|
||
5. 在真实登录态下完成客户端/运营端关键页面和请求状态验收。
|
||
6. 取得授权后解决远端 Git 凭据并推送;推送不是本次复评授权范围。
|
||
7. SendChain 拆分继续作为独立高风险任务,不与上述门禁修复混合。
|
||
|
||
## 7. 最终判定
|
||
|
||
- 原始安全 P0:**0 项未关闭**。
|
||
- 当前 P0:**0 项**。
|
||
- 当前 P1:**2 项**——质量门禁假绿、客户端删除校验遗漏。
|
||
- 当前 P2/验收边界:API 覆盖率口径、SendChain 重构、Git/锁文件治理、登录后与真实全链验收。
|
||
- 自动化:前端 34 项、API 563 项、Gateway 全包测试均通过。
|
||
- 构建与包体:通过。
|
||
- 依赖:根项目 0;API 5 项 Prisma CLI 风险已记录接受。
|
||
- 测试环境公开入口:通过,存在一次短暂超时后连续 5 次快速恢复。
|
||
- 代码质量:**86/100,有条件通过**。
|
||
- 持续治理闭环:**未通过**。
|
||
- 预生产发布建议:**暂停**。
|
||
|
||
本报告只对应固定提交和本次可重复证据,不把整改记录、单元测试或公开 health 冒充真实后端全链与登录后功能验收。
|