Files
lislgosms/docs/code-quality-reassessment-20260828-v3.md
T

14 KiB
Raw Blame History

CMPP 平台代码质量复评报告 V3

  • 报告日期:2026-08-28
  • 复评时间:2026-08-28 15:3616:08Asia/Shanghai
  • 复评基线:3834d67a308acf89d0e6cb2e6009c89c93b2c139
  • 主要业务整改提交:ad27acad7e02b787185c972c710c73c867429c36
  • 锁文件修正提交:226527f1cef122e4dbd163da782485e8c0254dc5
  • 对比基线:V2 基线 3af145abe5eb8cae567bb18e29116b4940889258
  • Git 状态:本地 mainorigin/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 根审计 0API 风险降至 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 gzipChart 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 项公告。
  • API5 项公告,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.0Swagger、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.jsindex-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.ts2 个未使用变量。
    • api/src/open-api/open-api.service.ts1 个未使用 import。
    • src/api/client/client.api.ts2 个未使用 import。
    • src/apps/client/ClientUsersPage.test.tsx1 个未使用变量。
    • src/apps/LoginPage.tsxFast Refresh 导出警告、useEffect 缺少 refreshCaptcha 依赖警告。
  • Prettier 检查发现 api/src/auth/auth.service.spec.tsapi/src/open-api/open-api.service.spec.ts 未格式化。

影响

整改记录中的“ESLint/Prettier 门禁通过”不是当前可重复证据。CI 如果没有显式传入基线会漏检提交;Windows 本地即使传入基线也会无诊断失败。

关闭要求

  1. 门禁显式接收并验证 base/headCI 使用 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 / P2API 标准覆盖率脚本仍不是全源口径

标准 test:coverage 未配置 collectCoverageFrom,容易把 70.44% 误写为全源覆盖率;严格全源只有 60.46%。应在正式配置中固化全源 include/exclude,并保留增量覆盖作为第二道门禁。

CQ-MAINT-001 / P2SendChain 超大服务仍未拆分

send-inbound-entry.service.ts 约 84.2 KiBsend-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. 最终判定

  • 原始安全 P00 项未关闭
  • 当前 P00 项
  • 当前 P12 项——质量门禁假绿、客户端删除校验遗漏。
  • 当前 P2/验收边界:API 覆盖率口径、SendChain 重构、Git/锁文件治理、登录后与真实全链验收。
  • 自动化:前端 34 项、API 563 项、Gateway 全包测试均通过。
  • 构建与包体:通过。
  • 依赖:根项目 0API 5 项 Prisma CLI 风险已记录接受。
  • 测试环境公开入口:通过,存在一次短暂超时后连续 5 次快速恢复。
  • 代码质量:86/100,有条件通过
  • 持续治理闭环:未通过
  • 预生产发布建议:暂停

本报告只对应固定提交和本次可重复证据,不把整改记录、单元测试或公开 health 冒充真实后端全链与登录后功能验收。