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

197 lines
14 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.
# CMPP 平台代码质量复评报告 V3
- 报告日期:2026-08-28
- 复评时间:2026-08-28 15:3616:08Asia/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 | 根审计 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.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/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 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 全包测试均通过。
- 构建与包体:通过。
- 依赖:根项目 0API 5 项 Prisma CLI 风险已记录接受。
- 测试环境公开入口:通过,存在一次短暂超时后连续 5 次快速恢复。
- 代码质量:**86/100,有条件通过**。
- 持续治理闭环:**未通过**。
- 预生产发布建议:**暂停**。
本报告只对应固定提交和本次可重复证据,不把整改记录、单元测试或公开 health 冒充真实后端全链与登录后功能验收。