# 代码审查问题清单（internal + pkg）

- 审查日期：2026-08-27 ~ 2026-08-28，共十一轮全量审查。第十一轮（2026-08-28）：核查第十轮划线项（22 项）+ 全新视角回归审查；`go build ./...` 编译验证通过
- 文档结构：只保留待修复问题，按**类型**归类；每条标注发现轮次与处置状态（专项待修/待修）；已修复并经复查确认的、经评估决定保留的、用户决策不修的直接删除
- gva/ 目录是遗留参考库（独立 module 不参与 kra 编译），不在审查范围
- 依赖方向合规：pkg 无 import internal；integration 不 import data/service；data 不 import integration/payment；无循环依赖
- 第十一轮总评：核心分层契约、日志防循环、CleanupStale 顺序反转、调度器重试、微文件合并等历轮修复验收干净；当前风险集中在**边缘入口的防护不对称**——公开写接口无治理、TTL 语义错位、停机路径无超时、前端凭证存储薄弱

---

## 一、安全与正确性缺陷

### 专项设计待修（用户已确认需专项处理）

| # | 问题 | 位置 | 状态 |
|---|------|------|------|
| V-39 | **（新发现，高）公开无限流写接口 `/sysError/createSysError`**：挂在 public.Group 无认证（router/audit.go:32）；SecurityRateLimit 仅覆盖 /base/login 与 /base/captcha（rate_limit.go:16）；handler 直接绑定落库无内容限制（handler/audit.go:305-315）；dto Info *string 无长度 binding（dto/audit.go:67-73）——未登录者可无限速 POST 超大 Info 入库（该路径无 MaxBytesReader）→ sys_error 表膨胀 DoS + 伪造错误记录污染排障视图 | server/router/audit.go:32；middleware/rate_limit.go:16；handler/audit.go:305-315；dto/audit.go:67-73 | 十一轮 |
| V-33 | 支付指纹严格相等校验对存量订单幂等重放的冲突风险（initialized/pending 存量订单重放报参数冲突而非幂等短路）——修复需兼容旧指纹、区分订单状态、覆盖并发重放，直接放宽会削弱防篡改 | biz/payment/payment.go:645-657 | 十轮发现，专项 |
| V-24 | Delete↔Create 竞态窗口仍开（锁仅覆盖 Delete，秒传/上传/Complete 的 CreateMedia 路径不持锁）；多副本需数据库/分布式锁 | biz/system/media.go:50,111-143；media_upload.go:100-107,262 | 八轮发现，专项 |
| V-13b | swagger：空 env fail-open（gin.go:68 仍注册）；gin 白名单 vs main.go 黑名单双清单不一致（qa/uat 时日志谎报）；env 门禁零测试——需统一单一判定函数+环境矩阵测试 | server/gin.go:64-70；cmd/main.go:105-126,171 | 七轮发现，专项 |
| V-27 | redis_list 仍按下标回退（configuration.go:439-441，database_list 已修✓）；别名匹配失败时哨兵字面量落盘无拒绝校验——需重新定义配置项稳定标识与密钥继承规则 | internal/initialize/configuration.go:427-446 | 九轮发现，专项 |
| V-20 | 前端 token 拼入 URL（完整 JWT 拼二维码 URL）——需后端一次性短时效票据+扫码协议迁移 | web/src/components/upload/QR-code.vue:55 | 六轮发现，专项 |
| V-15 | **envelope 净化剩余三洞**（全角冒号已修✓——response.go:53 分隔符已扩 ["失败:","失败："]）：① 17 处无冒号/紧贴拼接调用截断不可命中（api.go:137,156、authority.go 9 处、menu.go:170,178,198、user.go:150），非黑名单错误原样透出；② **CodeError data 通道完全无净化**——payment TestProvider Stages[].Message 原始 err 随 data 到前端；③ 净化静默无日志（"不泄露也不可排障"）。另有误伤：宽泛词 marker+约 45 处截断吞 biz 可读提示——需统一错误模型+结构化 Data 脱敏+日志策略 | server/httpx/response.go:32-59；data/payment/payment.go:79-139 | 六轮发现，专项 |
| V-19 | **证书别名缺口仍在（三层同源✓但键表未补别名——"已纳入键表"声称不实）**：app_cert_content/root_cert_content/pkcs12_content/cert_content/key_content/cert_path 等仍不命中 IsIntegrationSecretKey（后缀表无 *_content/*_path 项，integration_config.go:402-413）→ API 直连提交明文落库并回显，日志 resp_data 同泄；修法：剥后缀匹配词干或显式枚举（勿用裸 content/path 后缀防误伤） | biz/integration/integration_config.go:402-413,329-332,427-435 | 六轮发现，十轮部分+十一轮复核未闭合 |
| V-30 | **douyin platform_serial_no 仍 required=false（"已改 required"声称不实）**——definition.go:167 第三参 false，校验器 :348-351 仍强制；正确修法需通用 required 循环感知别名（platform_cert_serial）再置 true，否则别名用例（payment_config_test.go:25-33）会被拒 | biz/integration/integration_config_definition.go:166-167；integration_config.go:348-351 | 九轮发现，声称不实 |
| V-38 | 媒体域裸错误（ErrMediaTooLarge/ErrUploadSessionNotFound）vs AGENTS typed errors 契约——需连同错误码表与 HTTP 映射一起迁移 | biz/system/media.go:52、media_upload.go:21 | 十轮发现，专项 |

### 待修（正确性缺陷）

| # | 问题 | 位置 | 状态 |
|---|------|------|------|
| V-40 | **（新发现，中）上传会话 TTL 按"创建时间"而非"最后活动时间"**：StaleUploadSessionIDs 用 session.updated_at 判陈旧（data:127-131），但 UpsertChunk 只写 chunk 表不 touch 会话行（data:106-112）——大文件跨天续传（创建超 24h 但持续活动）被判 stale 整体清除，续传报"会话不存在" | data/system/media_upload.go:106-112,127-131 | 十一轮 |
| V-41 | （新发现，中低）merging 仅 1h 宽限（data:129），远程存储 Compose 超 1h 的合法合并被清理并整体失败（有回滚无泄漏，功能误杀） | data/system/media_upload.go:129 | 十一轮 |
| V-42 | **（新发现，中）dataScopeAuditWriter.Close 无超时且 MySQL DSN 无网络超时**：Close 无限期 `<-w.done`（:67-73）、flush 用 context.Background 无 deadline（:88）、DSN 无 readTimeout/writeTimeout（config.yaml:9,15）——DB 故障时 cleanup 链（data.go:191-198 先 auditLog.Close 后关 DB）被挂起 flush 永久阻塞，进程无法优雅退出 | data/data_scope_audit.go:67-73,88；configs/config.yaml:9,15 | 十一轮 |
| V-43 | **（新发现，中）前端 token 存 localStorage（7 天长期凭证 XSS 可窃）+ 401 登出回调可被并发弹窗吞掉**（application/index.vue:16 已有弹窗时 show-error 被忽略、handleClose 置 null cb 不执行 → 401 后 token 残留循环） | web/src/pinia/modules/user.js:23；components/application/index.vue:16；utils/request.js:231-241 | 十一轮 |
| V-44 | （新发现，低）V-36 词表收窄的噪音回归："导出token无效或已过期"（export.go:222）不再命中词表——该路由 public（catalog.go:107,109），匿名坏 token 请求以 200+CodeError 进 ErrorAudit 落 sys_error 表，可被匿名刷量 | handler/export.go:222；middleware/error_audit.go:26-45,73 | 十一轮 |
| V-45 | （新发现，低）sysError 写路径自身失败无日志：isSelfAudit 豁免（error_audit.go:25-27）声称"handler 已记录"，但 CreateError 失败仅 Fail（handler/audit.go:305-315）无任何日志——静默失败盲区 | middleware/error_audit.go:25-27；handler/audit.go:305-315 | 十一轮 |
| V-46 | （新发现，低）调度器启动重试无上限无退避：永久性错误（cron 解析失败整批 return err，task_scheduler.go:204-207）会每 5s 重试永不成功+刷 Warn 日志（约 720 条/小时）——需区分永久/暂时性错误 | worker/task_scheduler.go:93-112,204-207 | 十一轮（V-35 修复残留） |
| V-47 | （新发现，低）PersistRuntimeConfig 三段写非原子（先 storage 再 email 再 config，任一失败返回）——前面已写的集成配置与未替换的 runtime 出现不一致窗口 | data/initialization_backend.go:74-83 | 十一轮 |
| V-31 残留 | UpdateMediaName 仍透传 gorm 原文（404 语义丢失） | data/system/media.go:125-127 | 九轮，部分修复 |

## 二、死代码与碎屑

| # | 问题 | 位置 | 状态 |
|---|------|------|------|
| Z-15 | 软删字段死重量（4 个 PO 的 DeletedAt+索引在删除路径全 Unscoped 后成死配置）——存量表结构清理需迁移与回滚策略，待数据库迁移窗口 | data/system/media.go:16,34；media_upload.go:17,35,104 | 九轮，专项 |
| Z-9 | audit.go:76/83 ctxRespTextKey/ctxRespTruncatedKey 消费分支生产链路不可达（后置键）；access_log 先对截断体完整脱敏再覆盖（白做功）——需连同响应捕获链路整体重构 | server/middleware/audit.go:76-85；access_log.go:110-121 | 八轮，专项 |
| Z-13 残留 | cors.go:13-14 逗号空格、audit.go:104 单行 13 字段、audit.go:46-47 空 else-if——纯格式问题（用户评估：格式化工具统一处理） | server/middleware/ | 八轮，评估暂缓 |
| Z-17 | scanUpload.vue 空 catch 吞路由就绪异常——需统一前端错误上报 | web/src/view/media/scanUpload.vue:115-116 | 九轮，专项 |
| Z-22 | （新发现）Z-19 清理后前端死代码残留：image.js:32-35 空 if 块+未使用 newImgSize；global.js:51,54 未使用 allKeys+悬空比较表达式；另 3 处已注释 console 代码（cropper.vue:198、upload.vue:363、menus.vue:302） | web/src/utils/image.js:32-35；core/global.js:51,54 | 十一轮 |
| Z-23 | （新发现，V-30 关联）douyin 别名分支放错校验器：integration_config.go:247-249 在 validateCommunicationIntegrationConfig（仅 MQ/WS 走入）里写 douyin 支付的别名回退——该分支不可达，死代码 | biz/integration/integration_config.go:247-249 | 十一轮 |
| Z-24 | （新发现）秒传分支变量名 `copy` 遮蔽内置函数（可读性） | biz/system/media_upload.go:100 | 十一轮 |

## 三、重复实现 / 双轨残留

| # | 问题 | 位置 | 状态 |
|---|------|------|------|
| Y-7 | 掩码三套实现+键表多层漂移（data Secret∪IsIntegrationSecretKey / service 仅后者 / redact.go 第四张表）；哨兵双轨（****** vs ***）——需先定义跨层协议（专项） | data/integration:225-245；service/integration:69-96；redact.go:18-27 | 九轮，专项 |
| Y-12 | **（新发现，中低）redact 键表误伤非机密标识符，审计记录失去回放价值**：redact.go:22 精确项 "key"、:24-25 platformserialno/webhookid 是序列号/ID 非秘密——实证误伤 dto/menu.go:26,90（菜单路由 key）、dto/media.go:15,76（存储 key）、settings.go:45,56,117、version.go:39，这些写接口的操作审计响应中 key 全为 `***`，菜单/媒体/设置类审计基本无法回放排障（安全无泄漏，可用性受损） | server/middleware/redact.go:22,24-25；dto/menu.go:26 等 | 十一轮 |
| Y-5 | 集成配置校验双重执行（biz 层对掩码值总通过半失效）——用户评估：分层防线保留 | biz/integration:122-129 | 八轮，评估保留 |
| Y-2 剩余 | capture.go JSON 成功路径先 marshal 后判超限（超长白做）——用户评估：安全优先保留现状 | middleware/capture.go:49-76 | 六轮，评估保留 |
| Y-10 | 前端两套动态路由注册逻辑（登录整树 vs 守卫扁平化+redirect）——需先补路由矩阵测试 | web/src/pinia/modules/user.js:85-87；permission.js:78-146 | 十轮，专项 |

## 四、文档漂移

| # | 问题 | 位置 | 状态 |
|---|------|------|------|
| F-37 | **CLAUDE.md:19 integration 描述仍为 "(cache, email, payment, storage)" 4 项（"已同步"声称不实——实际目录 8 个模块，AGENTS.md 版本已含全部）** | CLAUDE.md:19 | 十轮发现，声称不实 |
| F-39 | （新，微）根 README.md:7-18 目录树缺 internal/{integration,modules,paymentkit,routecatalog,logging,utils} 与 pkg/（AGENTS.md 为权威无错，README 属简化版） | README.md:7-18 | 十一轮 |

## 处置建议（按优先级）

1. **V-39 公开写接口治理**（限流覆盖/长度 binding/或移入鉴权组——安全优先）+ **V-44/V-45 ErrorAudit 噪音与盲区**（词表补导出 token 文案或改 4xx；CreateError 失败补日志）
2. **V-40 TTL 改活动时间**（UpsertChunk touch 会话 updated_at——一行修复）+ **V-42 Close/DSN 超时** + **V-46 重试上限/退避**
3. **V-19 键表补别名**（剥后缀匹配词干——一处三层受益；连带 Z-23 死分支归位）+ **V-30 douyin required**（通用循环感知别名后置 true）
4. **V-43 前端凭证**（401 回调修复+token 存储评估）+ **F-37 一行同步**（本轮声称不实项）
5. **V-41/V-47/V-31 残留 + Z-22/23/24 碎屑 + Y-12 redact 误伤面收敛**（与 Y-7 专项一并设计）
6. **专项批次**：V-15 错误模型统一、V-33 指纹兼容窗口、V-24 分布式锁、V-13b 单一判定函数、V-27 稳定标识、V-20 短时票据、V-38 错误码迁移、Z-15 迁移窗口、Z-9 响应链重构、Y-7 跨层协议、Y-10 路由矩阵
