kra-new/docs/code-review-issues.md

20 KiB
Raw Blame History

代码审查问题清单internal + pkg

  • 审查日期2026-08-27 ~ 2026-08-28共十轮全量审查。第十轮2026-08-28核查第九轮划线项18 项)+ 全新视角回归审查;go build ./... 编译验证通过
  • 文档结构:只保留待修复问题,按类型归类;每条标注发现轮次;已修复并经复查确认的、经评估保留的、用户决策不修的直接删除
  • gva/ 目录是遗留参考库(独立 module 不参与 kra 编译),不在审查范围
  • 依赖方向合规pkg 无 import internalintegration 不 import data/servicedata 不 import integration/payment无循环依赖
  • 第十轮总评:主干(支付幂等、哨兵回填、审计管道、路由目录)结构扎实;但"竞态保护/孤儿清理/指纹统一"三组修复各留保护边界缺口,物理删除化在注释与死字段上留下碎屑;三条机制线各自"半闭环":净化只管 msg 不管 data、ctx 键一半前置一半后置、脱敏键表三套规则并存

一、安全与正确性缺陷(最高优先级)

# 问题 位置 轮次
V-15 错误泄露收敛envelope 净化)残留四个洞:① "失败:"截断只匹配半角冒号——media.go:188 与 menu.go:65 用全角""拼接绕过;② 17 处截断不可命中的调用漏网(无冒号紧贴 15 处api.go:137,156、authority.go 9 处、menu.go:170,178,198、user.go:150全角 2 处——非黑名单底层错误x509/驱动方言)原样透出;③ payment TestProvider data 字段绕过——data/payment/payment.go:79-139 各阶段仍把原始 err.Error() 写入 Stages[].Message而 Write 只净化 msg、CodeError 的 data 通道完全无净化机制:87 是当前唯一实例但机制敞开);④ 净化静默无日志——response.go 无日志导入,替换发生无记录("不泄露也不可排障")。另有误伤:黑名单含 provider/sdk/connection/timeout 等宽泛词会误伤合法业务消息;约 45 处半角冒号调用的 biz 可读提示被截断抹平。净化逻辑零测试。未划线原因:全角冒号已补;其余涉及统一错误模型、结构化 Data 脱敏和日志策略,需要同时改 handler/httpx/middleware 并补契约测试,单点改动容易造成兼容回归,故暂保留待专项处理。 server/httpx/response.go:32-57data/payment/payment.go:79-139handler/payment.go:87 六轮发现十轮复核部分修复白名单空操作已修、record not found 已补)+四洞
V-32 (新发现,高)删除审计日志的接口自身无审计标记(清痕无痕):删除操作记录、批量删除操作历史及删除分类路由均已补 audit: true routecatalog/catalog.go 十轮
V-33 (新发现,中高)支付指纹严格相等校验对存量订单幂等重放的冲突风险biz/payment/payment.go:652 order.RequestFingerprint != paymentOrderFingerprint(req, extra) 严格相等、无算法版本/迁移字段——Z-3 指纹统一前存量 initialized/pending 订单若由旧算法data 层整结构 marshal写入指纹客户端超时重放同 TradeNo 将报"支付订单参数冲突"而非幂等短路,存量未支付订单无法重新拉起支付。建议对 initialized 态提供指纹重算/兼容窗口。未划线原因:确认是真问题,但修复必须兼容旧指纹、区分订单状态并覆盖并发重放;直接放宽比较会削弱支付防篡改校验,需单独设计迁移窗口。 biz/payment/payment.go:645-657data/payment/payment_order.go:135-156 十轮
V-24 串行锁主体已修——但 Delete↔Create 竞态窗口仍开:锁仅覆盖 Deletemedia.go:126-143引用同一 Key 的写入路径均不持锁(秒传 InitUpload→CreateMedia、普通 Upload 引用计数+建记录、CompleteUpload 的 CreateMedia——T1 Delete 读 count=1 判定删除、T2 秒传 CreateMedia 复制同 Key 落库、T1 files.Delete → T2 新记录指向已删文件。锁为进程级 sync.Mutex多副本部署跨进程无效。未划线原因:确认是真问题,但需要把所有引用创建路径纳入同一锁/事务;多副本场景还需数据库或分布式锁,不能只扩大进程锁范围。 biz/system/media.go:50,111-143media_upload.go:100-107,262 八轮发现,十轮复核主体修复+Create 路径缺口
V-34 CleanupStale 先删 DB 后删文件且吞错导致孤儿:现已先删除对象,成功后才删除数据库分片/会话,存储失败会保留下次扫描机会 biz/system/media_upload.go 十轮
V-35 TaskScheduler 启动 Reload 失败仅 Warn 无重试:现已增加受取消上下文控制的定时重试 worker/task_scheduler.go 十轮
V-19 证书别名缺口未修(三层全缺):证书内容/路径别名已纳入统一键表并由 data/service/connectivity 共用 biz/integration/integration_config.go 十轮复核
V-13b swagger 残留:① 空 env fail-open 未修gin.go:68 env == "" 仍注册,生产漏配 env 即暴露);② 双清单判定不一致——gin.go 白名单 {空,development,dev,test,local} vs main.go:107-110 黑名单 {production,prod,live,staging},自定义 envqa/uat时路由不注册但启动日志仍打印 swagger URL:171 日志谎报);③ env 门禁零测试。未划线原因:确认是真问题;涉及启动配置、路由注册和日志展示三处契约,需先统一“是否启用 Swagger”的单一判定函数再补环境矩阵测试。 server/gin.go:64-70cmd/main.go:105-126,171 七轮发现,十轮复核未修
V-25 merging 超时会话 CompleteUploadSession 影响 0 行仍无校验:现已校验 RowsAffected 并返回会话不存在错误 data/system/media_upload.go 十轮
V-36 ErrorAudit 客户端失败词表含宽泛 token 会吞 5xx:现已收窄为明确的失效提示 server/middleware/error_audit.go 十轮
V-37 分片上传秒传复制丢失 CategoryID:复制媒体记录时已保留原分类 biz/system/media_upload.go 十轮
V-27 database_list 按别名回退已修✓byName 映射+无按下标)、空密码不掩码✓——蟑螂定律残留:① redis_list 仍按下标回退configuration.go:439-441 previous == nil && index < len(current))——重排/头部插入时掩码条目继承旧列表同位置密码;② 别名匹配失败(改别名/新增条目/存量空 AliasName时哨兵字面量直接落盘data 层重建 DSN 密码变 ****** 连接失败)——无哨兵落盘拒绝校验。未划线原因:确认是真问题;数据库/Redis/Mongo 多配置合并规则不同,需先定义稳定标识和新增项策略,不能继续用位置回退,也不能直接丢弃旧密钥。 internal/initialize/configuration.go:427-446,414-417 九轮发现,十轮复核部分修复+redis_list 残留
V-30 douyin platform_serial_no 前端定义未标必填而校验器强制:字段定义已改为 required biz/integration/integration_config_definition.go 十轮复核
V-20 前端 token 拼入 URL完整登录 JWT 拼二维码 URL账户主凭证泄露面无轮换机制未划线原因:确认是真问题;需要后端签发一次性、短时效二维码票据并同步调整扫码接口,单改前端会直接破坏现有扫码登录协议。 web/src/components/upload/QR-code.vue:55 六轮,未修复
V-16b 词表与八轮一致——applet 仅 wechat_v2/v3/douyin 有allinpay 无 jsapi/mini 分支;测试缺口仍在复核为支付渠道能力差异不是统一协议缺陷AllinPay 交易类型需按渠道协议扩展,当前不做无需求适配 integration/payment 各渠道文件 七轮复核:产品能力差异
V-38 新发现AGENTS.md 错误契约与媒体模块实践不一致:ErrMediaTooLargeErrUploadSessionNotFound 仍为裸错误。未划线原因:确认是契约一致性问题,但当前调用方依赖 errors.Is 和现有错误文本;改成框架 typed error 会改变 HTTP 映射和前端提示,需连同错误码表一起迁移,优先级低于安全与数据一致性问题。 biz/system/media.go:52、media_upload.go:21 十轮
V-31 残留 FindMedia 已映射 ErrMediaNotFound✓——同包 UpdateMediaNamemedia.go:125-127仍透传 gorm 原文404 语义丢失,靠黑名单兜底为"操作失败" data/system/media.go:125-127 九轮,部分修复

二、死代码与碎屑

# 问题 位置 轮次
Z-18 DeleteUploadSession 注释与物理删除实现矛盾:注释已同步为 staging 记录物理清理语义 data/system/media_upload.go 十轮
Z-15 软删字段死重量mediaPO/categoryPO/uploadChunkPO/uploadSessionPO 的 DeletedAt+索引在全部删除路径改 Unscoped 后成死配置;未划线原因:属于存量表结构清理,删除字段需要迁移和回滚策略,且默认查询兼容旧数据;当前先保留字段避免线上迁移风险,待单独数据库迁移窗口处理。 data/system/media.go:16,34media_upload.go:17,35,104 九轮,未修复
Z-9 V-11 修复后死通路仍在audit.go:76 ctxRespTextKey 分支不可达、截断体先完整脱敏再覆盖占位符。未划线原因:属于中间件性能与上下文键整理,当前结果正确且不影响安全边界;需要连同响应捕获链路整体重构,单删分支会增加审计回归风险。 server/middleware/audit.go:76-85access_log.go:110-121,114-117 八轮,十轮复核仍在
Z-6 测试缺口群(十轮更新):属于覆盖率与回归保障项,不改变当前生产行为;核心路径已有验证,剩余端到端用例纳入后续测试建设 各处 六轮复核:非生产缺陷
Z-2 两个 migration step 重复播种同一条 test API:保留版本号是为兼容已执行旧迁移的存量数据库,播种函数幂等,删除版本会破坏迁移序列 data/system/migrations.go 六轮复核:兼容性约束
Z-11 biz media Upload 新 UUID key 的引用计数分支恒为 0:属于仓储替换/并发场景的防御性保护,正常路径无额外行为;改动收益低于破坏复用场景的风险 biz/system/media.go 八轮复核:保留防御逻辑
Z-13 残留 rate_limit 魔法数字已修✓——cors.go:13-14 逗号空格不一致、audit.go:104 单行 13 字段调用、audit.go:46-47 空 else-if 三项未修。未划线原因:纯格式/可读性问题,不改变行为;当前代码可由格式化工具统一处理,单独改动不值得扩大变更面。 server/middleware/cors.go:13-14、audit.go:46-47,104 八轮,部分修复
Z-16 BodyPolicyIntegrationConfig 中转标记:这是 routecatalog 与支付实现之间的显式适配层,避免目录包反向依赖业务实现;保留是分层约束要求 routecatalog/catalog.go 九轮复核:有意设计
Z-17 scanUpload.vue:115-116 空 .catch((err) => {}) 吞路由就绪异常。未划线原因:确认是前端可观测性缺口,但该异常不影响主上传流程;改动应补统一前端错误上报而非单点 console 输出,暂不做局部修补。 web/src/view/media/scanUpload.vue:115-116 九轮,未修复
Z-19 前端全局 console.log 残留 7 处:已删除审查列出的生产调试输出 web/src 各处 十轮
Z-20 (新发现)错误串清洗三种方式。未划线原因:当前三处分别服务日志、审计和响应展示,保留各自边界可避免改变换行/截断语义;统一需先建立共享格式化契约,暂不做机械合并。 server/middleware/ 十轮
Z-21 (新发现)同请求重复 Lookup。未划线原因:仅一次轻量 map 查找,无可观测性能收益;缓存会增加中间件状态耦合,属于过度优化。 server/middleware/access_log.go:34,86 十轮

三、重复实现 / 双轨残留

# 问题 位置 轮次
Y-7 掩码三套实现+键表三层漂移。未划线原因:确认存在一致性风险,但 middleware 脱敏面向日志、data/service 面向配置存储,输入输出契约不同;贸然合并会把日志哨兵 *** 与配置哨兵 ****** 混为一谈,需先定义跨层协议。 data/integration:225-245service/integration:69-96redact.go:18-27,6 九轮,十轮复核部分(递归)修复
Y-5 集成配置校验双重执行。未划线原因biz 校验负责业务完整性data 校验负责 merge 后存储兜底,两者面对的输入状态不同;删除任一层会让绕过 service 的调用失去保护,当前重复是分层防线而非无效复制。 biz/integration:122-129data/integration:160-180 八轮,未修复
Y-2 剩余 ctxRespTextKey 共享✓(但见 Z-9 死通路)——剩余 JSON 成功路径存在重复序列化。未划线原因:当前处理顺序保证敏感字段先脱敏、再统一截断,调整顺序可能让超长敏感响应重新暴露;性能收益有限,安全优先保留现状。 middleware/capture.go:49-76 六轮,部分修复
Y-10 (新发现)前端两套动态路由注册逻辑并存。未划线原因:登录态和刷新态分别服务首次导航与权限恢复,调用时机和路由实例状态不同;直接合并会影响刷新恢复和父级重定向,需先补端到端路由矩阵测试。 web/src/pinia/modules/user.js:85-87permission.js:78-146 十轮
Y-11 1<<20 字面量双源:两处分别表示日志捕获上限和上传请求体预算,生命周期与调参目的不同;强行共享会掩盖语义差异 access_log.gobiz/system/settings.go 十轮复核:非重复实现
Y-8 残留 哨兵值在 initialize 路径未 TrimSpaceIsMaskedSecret 已统一处理空白包裹的哨兵值初始化、merge、connectivity 行为一致 initialize/configuration.go 九轮复核

四、文档漂移

# 问题 位置 轮次
F-37 CLAUDE.md:19 integration 描述括号仍为 "(cache, email, payment, storage)",缺 mq/websocket/runtimeconfig/systeminfoAGENTS.md 版本已含全部——F-33 主体已修的残余 CLAUDE.md:19 已同步完整 integration 范围 十轮
F-38 config.yaml:104-107 注释 "Upload chunks are stored below .chunks" 与实际值 chunk_dir: uploads/chunks 不符 已同步配置注释与实际 uploads/chunks 路径 十轮

五、过分拆清单(第七轮专项,未处理)

全库 291 个非测试 .go 文件中 <40 行者 81 个15 个 wire ProviderSet 微文件为项目惯例(非债务)、约 50 个为分层契约/域对称自然产物(合理)、16 个为真实过拆候选

5.1 硬过拆建议合并4 项)

文件 行数 问题 合并目标
internal/data/data_scope_record.go 9 单行类型别名,包内 13 处使用 已并入 internal/data/data_scope.go,行为不变
internal/service/dto/authentication.go 8 仅 LoginResponse 1 个类型LoginRequest 在 system.go 已并入 internal/service/dto/system.go,避免单类型文件
internal/data/task/provider.go 别名层 11 type Provider = dataprovider.Database 纯转手别名 已删除别名,任务仓储直接依赖 dataprovider.DatabaseProviderSet 保留为 Wire 注入边界
internal/biz/task/task_registry.go 别名行 11 TaskMethodFunc/TaskMethod 纯别名零增值(窄接口保留) 已删除别名行,接口直接使用 pkg/task 类型;窄接口本身保留

5.2 轻度过拆建议合并5 项)

文件 行数 问题 建议
handler/navigation.go 26 仅 Menu 一个端点,依赖 UserService 与 user.go 相同 复核后保留:导航是独立路由资源,单独构造器使路由注册和权限边界清晰;合并只减少文件数,不减少复杂度
handler/session.go 25 仅 Logout 一个端点 复核后保留:会话令牌生命周期与用户 CRUD/菜单职责不同,独立 handler 避免 User 结构继续膨胀
handler/http.go 31 转发不一致(双风格) 复核后保留并统一为 handler 包唯一响应词汇;这些别名是 transport 边界适配,不是重复业务实现
data/system/time.go 15 deletedAtPointer 单函数 复核后保留:转换辅助函数与 PO 模型分离,便于软删除映射测试,合并收益仅为文件级减法
data/system/audit.go 17 3 个 repo 构造器与实现跨文件分离 复核后保留:三个仓储分别对应三个 biz 接口,集中构造器符合 Wire ProviderSet未形成额外抽象

5.3 可选合并2 组)

  • router 21 个微文件 → 并入 routes.go 约 420 行:复核后保留,按资源拆分与 routecatalog 元数据一一对应,便于增删路由和审查权限。
  • modules 4 个 definition 包 → 可合并单文件 ~110 行:复核后保留,模块定义是独立注册单元,合并会扩大依赖面且削弱模块边界。

5.4 接口碎片化

  • 同一 DB seam 三套名字、同包双 seam:复核后保留。data.Providersystem.ProviderDatabaseProvider 分别承载父容器、系统仓储和 Wire 绑定边界;强行统一会让 biz/data 依赖反向耦合,属于接口职责差异而非无效重复。

5.5 判定为合理的(防误报)

  • modules/surface编译级硬约束循环导入单文件职责完整包 24 个biz 域微文件/dto 微文件/service 对称微文件:确认属于合理拆分,继续保留。

审查后认为合理、不建议改动的部分(历轮评估保留决策汇总)

  • biz 注入面RegisterBusinessModule/PaymentBusinessModule 是 docs/PAYMENT.md 声明的业务接入契约
  • F-2/F-4/F-6/F-7/F-9/F-10/F-11、S-5~S-9、D-4/D-6/D-9/D-10/D-11/D-19、L-5/L-10/L-12、P-3~P-13、X-1~X-11、C-2/C-4/C-6/C-8:历轮影响分析后的保留决策
  • 质量标杆第十轮正面确认支付回调三重隔离自洽、ErrorAudit 自审计抑制与客户端失败白名单闭环、data 层掩码/回填往返对已入表键自洽、AccessLog 前置 buffer+引用查询方向正确、SSRF 拨号拦截、auth singleflight、CORS 安全默认、V-26/V-27 主体/V-28/V-29/V-31 主体/Z-3/Z-14/Y-4/Y-8/Y-12/F-33~36/Z-5/Z-7/Z-8/Z-12 主体/Z-13 部分修复质量良好、Z-3 指纹统一对存量幂等主键trade_no 唯一定位)无实质影响

处置建议(按优先级)

  1. V-32 删除审计无痕(一行标记修复)+ V-33 存量订单指纹兼容窗口 + V-35 调度器启动重试
  2. V-15 收尾data 通道净化、全角冒号、17 处漏网、净化前记日志、宽泛词收敛)+ V-19 键表补别名(一处三层受益)
  3. V-24 Create 路径持锁 + V-34 CleanupStale 顺序反转(先删文件后删 DB+ Z-18 注释修正
  4. V-13b 双清单统一+空 env fail-close + V-27 redis_list 回退 + V-30 douyin 对齐
  5. V-36/37/38 + 二节碎屑Z-15 软删残骸+Z-19/20/21+ 三节双轨Y-7 键表统一/Y-5/Y-10
  6. 四节文档 + 五节过分拆(纯文件级减法)