dzs-admin v1.0.104 增量质检报告
增量区间:8cf7013235afb2b77430affeff7b291fd16dc29f(上一 Release,v1.0.103)→ f5da644ba4724fabf776bda1a572758f4b946a22(当前版本,v1.0.104)
项目 / 分支:dzs/dzs-admin / v1.0.104
数据来源:codescan_git_diff(变更面)、codescan_issues_diff(修复 10 / 新增 15,真实对比数据)、codescan_quality_list(全量 1713 条中定位本次相关项)、codescan_source_read(源码核验)
结论速览:本次为功能改版型增量(文章编辑器「插入数据」由 7 步向导改为一屏联动面板),源码侧无新增 Critical/High;新增问题全部为 Medium/Low 的复杂度与可维护性问题;安全面未引入新的高危项。
一、版本与变更面
1.1 变更主题
文章编辑器「插入数据」改版(需求/工单 #33 v2):7 步向导 → 一屏 7 项联动面板;新增可用性只读接口("没有数据的不出现");占位符第 8 段取值由 3 项扩为 7 项(服务端零改动);数据卡支持原位编辑(同一长码全部出现一并替换);面板/卡片/抽屉用词统一。
1.2 变更文件清单(按类型)
| 类型 | 文件 | 性质 |
|---|
| 源码(核心) | src/lib/placeholder-panel.ts | 新增(384 行,联动引擎纯函数) |
| 源码(核心) | src/app/api/admin/placeholder-availability/route.ts | 新增(151 行,可用性接口) |
| 源码(核心) | src/components/articles/MarkdownEditor.tsx | 重写(向导 → 面板;净删多于净增) |
| 源码 | src/lib/placeholder.ts | 小改(取值表扩 7 项 + 标签用词统一 + 卡片加「编辑」入口) |
| 测试 | e2e/pages/article-editor.page.ts、e2e/specs/24-article-editor-preview.spec.ts | 新增页面对象方法 + 10 条用例(101–112) |
| 校验脚本 | scripts/verify-placeholder-panel.ts | (9 组断言) |
变更面高度集中:源码仅 4 个文件,其中 2 个为新增纯逻辑/接口文件,1 个为编辑器组件重写。
二、质检问题对比总览(真实数据)
codescan_issues_diff 结果:修复 10 条 / 新增 15 条。
| 严重度 | 修复 | 新增 |
|---|
| Critical / High | 0 / 0 | 0 / 0 |
| Medium | 6 | 10 |
| Low | 4 | 5 |
| 合计 | 10 | 15 |
⚠️ 判读口径提醒:MarkdownEditor.tsx 本次为整体重写,行号发生大范围位移。因此部分"修复/新增"实为同一文件的同类问题在新旧代码上的重新归位(旧向导辅助函数被删 → 对应问题消失;新面板组件体量增大 → 同类问题在别处出现),并非"一修一坏"的严格对偶。下文按文件逐一核验。
三、修复的问题明细(10 条,均为旧向导代码退场)
| # | 严重度 | 类型 | 位置 | 说明 |
|---|
| 1 | Low | 重复代码块 | MarkdownEditor.tsx:115(旧) | 旧向导选项渲染重复逻辑,随向导删除而消失 |
| 2 | Medium | 圈复杂度过高 | MarkdownEditor.tsx:288(旧) | 旧 getDimensionOptions 系列 |
| 3 | Medium | 圈复杂度过高 | MarkdownEditor.tsx:391(旧) | 旧步骤联动 handleNext 一带 |
| 4 | Medium | 嵌套深度过高 | MarkdownEditor.tsx:391(旧) | 同上 |
| 5 | Medium | 函数过长 | MarkdownEditor.tsx:391(旧) |
小结:修复项全部落在被删除的 7 步向导实现上,属于"删代码带来的自然收敛",方向正确。所有修复项均为 Medium/Low,无安全/正确性修复。
四、新增问题明细与逐条研判(15 条)
| # | 严重度 | 类型 | 位置 | 研判 |
|---|
| 1 | Medium | 圈复杂度过高 (32) | src/lib/placeholder-panel.ts:265 | 真问题(可接受):derivePanelState 单函数串起 7 项收敛,120 行 |
| 2 | Medium | 函数过长 (120 行) | src/lib/placeholder-panel.ts:265 | 同上,同一函数 |
| 3 | Medium | 圈复杂度过高 (12) | src/lib/placeholder-panel.ts:225 | 真问题:targetIdsFor 双分支 + 可选链嵌套 |
| 4 | Medium | 圈复杂度过高 (25) | src/components/articles/MarkdownEditor.tsx:819 | 真问题:describeInspectPlaceholder 多路反查/回退 |
分布:新增 10 Medium + 5 Low,0 Critical / 0 High。集中在"组件/引擎单函数过大、嵌套偏深"这一类维护性问题,无正确性与安全性新增项。
五、重点问题深入研判(附源码证据)
5.1 主组件膨胀(新增项 #6/#7,最值得关注)
MarkdownEditor.tsx 主函数经本次重写后达 952 行、嵌套深度过高(codescan_source_read 行 244 起)。本次改版把面板状态机、可用性拉取、指标候选拉取、编辑回填、渲染都收敛进单一组件:
- 状态声明显式扩张:
panelOpen / editingKey / editingBlockedReason / selection / availability / availabilityReady / metricList / metricLoading / inspectKey …;
- 两块
useEffect(可用性、指标候选)与多个 useCallback(updateSelection / openPanel / openPanelForEdit / handlePanelSubmit)耦合在同一函数体内。
风险:可读性/可维护性下降,后续改动易误伤。建议:将「面板状态 + 两个数据加载 effect + 提交逻辑」抽成自定义 Hook(如 usePlaceholderPanel),组件只保留编排与渲染;此为非阻塞改进项。
5.2 route.ts:51 "未使用参数" —— 判定为疑似误报
复核 src/app/api/admin/placeholder-availability/route.ts:
async function loadAvailability(nature: string, canPrice: boolean, canMetric: boolean) {
...
const priceResult = await db.execute(sql`
SELECT ...
FROM dzs_public_price
WHERE source_type = ${nature} // ← nature 在此使用
GROUP BY commodity_id
`);
nature 明确用于 WHERE source_type = ${nature}(参数化模板)。静态规则很可能未把 sql\`` 模板字面量内的插值识别为参数使用,故报"未使用"。结论:误报,无功能影响。
5.3 联动引擎复杂度(新增项 #1/#2/#3)
derivePanelState(placeholder-panel.ts:265)CC=32 / 120 行,需在一次调用内完成 7 项收敛 + 7 项可选列表(数据性质→数据类型→口径→品类→时间→排列形式→展示形式),并内含两处 IIFE 兜底。targetIdsFor(:225)CC=12。
- 可读性:单函数职责偏重,但与设计文档明确要求"引擎为唯一规则出处、组件只渲染"一致,属有意集中;
- 正确性:
defaultFormatFor/encodeDimension/isRepresentableSelection 已拆为独立纯函数并被 verify-placeholder-panel.ts 9 组断言覆盖;
- 建议:可进一步把"每项 options 计算"拆为 7 个小函数(各返回
PanelOption[]),主函数只做串联,降低 CC。
5.4 安全性(无新增高危)
- 可用性接口使用 **Drizzle
sql\` 参数化模板**(WHERE source_type = ${nature})与 inArray(...)`,无字符串拼接;
- 权限门控沿用
withAnyReadPermission(['spot-price','metric']),无权限类别不出现在响应;
codescan_quality_list 全量中的唯一 Critical(SQL 注入)位于 e2e/helpers/db.ts:78——该文件不在本次 diff 内(e2e/helpers 未变更),属存量测试辅助代码,非本版本引入,本次不纳入增量结论。
5.5 降级 / 收敛逻辑(设计关注点,未见缺陷)
MarkdownEditor 中 panelCtx.availability = availabilityReady ? availability : null,接口失败/未就绪 → null → 引擎按全量列出(不出现空面板);getAvailability 采用 60s 进程内缓存 + 单飞 + 异常返回 fallback:true。与 e2e 用例 TC-EDT-110(接口 500 降级)、TC-EDT-104(无死循环/无请求风暴)对应,逻辑自洽,未发现新增缺陷。
六、结论与建议
6.1 结论
- 本版本为功能改版型增量,源码侧无新增 Critical/High,安全面未新增高危项;
- 新增 15 条问题全部为 Medium/Low 的复杂度与可维护性问题,集中在:
MarkdownEditor.tsx 主组件过大(952 行);
placeholder-panel.ts derivePanelState 单函数职责过重(CC=32);
- 若干重复块 / 超长行 / 断言脚本导入面偏宽(低影响);
- 修复的 10 条均来自被移除的 7 步向导代码,方向正确;
- 发现 2 条疑似误报(
route.ts:51 未使用参数、verify-placeholder-panel.ts:36 注释代码),建议登记为误报基线,避免重复噪音。
6.2 建议(按优先级)
| 优先级 | 建议 |
|---|
| P2(可维护性) | 抽 usePlaceholderPanel Hook,收敛 MarkdownEditor 的面板状态与两个加载 effect |
| P2(可维护性) | 拆分 derivePanelState 的"每项 options 计算"为独立小函数 |
| P3 | 提取 e2e/pages/article-editor.page.ts 的下拉浮层 locator 为私有方法,消除重复块 |
| P3 | 收敛 verify-placeholder-panel.ts 的导入面(按需引 formatLabel/formatBaseShape) |
| 基线 | 将 §5.2、§5.4 两处登记为误报 / 超出本次范围,防止下次误判 |
附录 A:数据与工具
- 变更面:
codescan_git_diff(base=8cf7013, head=f5da644)
- 问题对比:
codescan_issues_diff(...) → 修复 10 / 新增 15
- 全量问题:
codescan_quality_list(1713 条,未变;本次仅关注增量相关项)
- 源码核验:
src/app/api/admin/placeholder-availability/route.ts、src/lib/placeholder-panel.ts、src/components/articles/MarkdownEditor.tsx、src/lib/placeholder.ts、e2e/pages/article-editor.page.ts、scripts/verify-placeholder-panel.ts
附录 B:本次新增/变更的严重度分布
新增:Critical 0 | High 0 | Medium 10 | Low 5
修复:Critical 0 | High 0 | Medium 6 | Low 4