7fdeaadf5bd55cb2c386ac7eaefa6d7bd68656def43f3de0b2b7ed2a8764a2b68cec26bf5ade3f45codescan.issues_diff(增量问题对比)+ codescan.git_diff(变更面)+ codescan.quality_list(严重度核对)本文「修复 bug / 新增问题」两章完全基于
codescan.issues_diff的真实返回数据;变更面描述基于git_diff。未做任何推断性编造。
本版本是**「push 历史回填」特性**的完整落地(spec 2026-08-31-push-backfill),并顺带修复了数据缺口、钉钉推送白名单、分析时段多时段等问题。
| 文件 | 变更性质 | 主要内容 |
|---|---|---|
src/api/backfill.rs | 新增(381 行) | POST /api/v1/backfill 回填入口:Bearer 鉴权 → 解析 → 日期校验 → 读 cluster_gap_minutes → enumerate_and_backfill → 200 统计 |
src/orchestrator/backfill.rs | 新增(148 行) | 纯函数聚簇:cluster_commits 按 (author, 相邻 authored_at 间隔 ≤ gap) 把扁平 commit 聚成 push 簇 |
src/orchestrator/backfill_service.rs | 新增(418 行) | 回填服务主体 enumerate_and_backfill:白名单展开 → 枚举 Gitea commit → 过滤已分析 → 聚簇 → 幂等建任务 + 合成 push |
src/api/mod.rs | 修改 | 注册 backfill::build_router() 到 api/v1 |
src/orchestrator/mod.rs | 修改 |
issues_diff 给出的「修复」= base 有、head 无,共 654 条。
scheduler.rs、repos.rs、gitea.rs、insight_settings.rs 在本版本被大规模插入新代码,导致同一批存量告警的行号整体后移。质检按行号匹配问题,旧行号位置消失即被计入「修复」,新行号位置则被计入「新增」。直接证据(同一问题、仅行号偏移):
| 问题 | base 行号(被计为「修复」) | head 行号(被计为「新增」) | 偏移 |
|---|---|---|---|
scheduler.rs 嵌套深度过高 | 124 | 125 | +1 |
scheduler.rs 嵌套深度过高 | 280 | 289 | +9 |
scheduler.rs 函数过长 dispatch_queued | 124 | 125 | +1 |
repos.rs 无安全注释的 unwrap | 2536 | 2699 | +163 |
repos.rs 无安全注释的 unwrap | 2549 | 2712 | +163 |
insight_settings.rs 高耦合 | 61 | 62 | +1 |
| 无安全注释的 unwrap |
因此本章「修复 654 条」不宜解读为该版本真实修掉了 654 个缺陷。
repos.rs::insert_commits / insert_commit_files / insert_issues_with_commit)—— 新增「先 SELECT 已存在、再 INSERT」去重,修复重复执行 persist_insight 导致的提交量/代码产出/问题数重复计数(注释标注 2026-09-02 重复事故,既有 36 例同 push 重复 commit)。backfill_service.rs)—— 回填任务合成 push_id,使 persist_insight 不再早退,回填数据与正常 push 同口径落 commits/commit_files。repos.rs::bind_employee_username)—— 语义由「相同即返回」改为「仅当 username 为空才回填」,避免回填合成 push 的 pusher=backfill / 代推场景覆盖真实 Gitea login(2026-09-02 事故)。gitea.rs::list_personal_repos)—— /user/repos(仅 owner/协作者)改为 /repos/search?q=(admin 全量),补回「公开/非协作者」仓库。scheduler.rs + repos.rs::exists_queued_backfill_task)—— 管理员主动补数据动作豁免时段约束(2026-09-06 实测 36 任务 queued 8 分钟无派发)。insight_webhook.rs 测试)—— mock 改为 {"data":[...]},并同步 gitea.rs 新增 GiteaRepoSearchResult。issues_diff 给出的「新增」= head 有、base 无,共 716 条(严重度全部为 Medium / Low,无 Critical / High)。
| 类别 | 量级 | 主要聚集位置 |
|---|---|---|
| 无安全注释的 unwrap(ErrorHandling / Medium) | 最多(约七成) | store/repos.rs、orchestrator/scheduler.rs 的测试域 |
| 依赖高耦合 / 扇入扇出异常(Dependency) | 次多 | scheduler.rs、repos.rs、gitea.rs |
| 函数过长 / 嵌套深度过高 / 圈复杂度过高(Complexity) | 中 | scheduler.rs::persist_insight/generate_report_inner、backfill_service.rs |
| 重复代码块 / 行过长 / 参数过多 / 注释代码过多(Maintainability / Complexity) | 少 | 各新文件 |
以下条目确实落在本次新增文件/新增函数上,不属于行号漂移:
① src/api/backfill.rs(新文件,14 条)
[Medium/Dependency] 高耦合 @104:backfill handler 直接依赖 12 个函数(超阈值 10)[Low/Maintainability] 重复代码块 @125 / @232 / @245:401/400/JSON 错误响应块重复 3~5 次 → 建议抽 render_error(res, status, msg) 帮助函数[Medium/ErrorHandling] 无安全注释的 unwrap @237/238/333/334/348/349/363/364/378/379:集中在 #[cfg(test)] 域(take_json().unwrap()、as_str().unwrap()),生产代码本身未新增 unwrap② src/orchestrator/backfill_service.rs(新文件,17 条)
[Medium/Complexity] 函数过长 @53:enumerate_and_backfill 135 行 + 嵌套过深[Low/Dependency] 扇入扇出异常 / [Medium/Dependency] 高耦合 @53:fan-out 26(组织展开 + 枚举 + 过滤 + 聚簇 + upsert 项目 + 建任务 + 合成 push 全塞一处)→ 建议按「枚举层 / 落库层」拆函数[Low/Maintainability] 重复代码块 @106、行过长 @144[Medium/ErrorHandling] 无安全注释的 unwrap @292/304/305/307/308/314/316/317/391:均在 #[cfg(test)] 测试域③ src/orchestrator/backfill.rs(新文件,1 条)
[Medium/ErrorHandling] 无安全注释的 unwrap @81:测试域④ src/client/gitea.rs(新增 commits() + 改造 list_personal_repos,约 41 条)
[Medium/Dependency] 高耦合:commits @413 依赖 15 个函数;list_personal_repos @369 依赖 15 个;list_orgs @320 依赖 16 个[Low/Dependency] 扇入扇出异常:mock_server @492(fan-in 19 / fan-out 16)[Low/Maintainability] 行过长 @513[Medium/ErrorHandling] 无安全注释的 unwrap @496/501/532/…/752/753(约 29 条,绝大多数为测试断言 unwrap)⑤ src/orchestrator/scheduler.rs(新增 notify_push_task_types 等)
[Medium/Dependency] 高耦合 @436:notify_push_task_types 依赖 12 个函数[Medium/Complexity] 函数过长:complete_task @454(95 行)、persist_insight @560(314 行 / 圈复杂度 24)——注意 persist_insight 的膨胀与本次无关,属存量[Low/Maintainability] 注释代码过多 @191、重复代码块 @262⑥ src/store/repos.rs(新增 3 个回填函数 + 幂等改造)
[Medium/Dependency] 高耦合 @263:create_backfill_task 依赖 17 个函数(幂等判定 + 建任务链路过长)[Low/Complexity] 参数过多:upsert_version(9) @571、upsert_push_by_delivery(8) @712#[cfg(test)] 域(@2699 起)说明:
scheduler.rs(约 300 条)与repos.rs(约 350 条)的「新增」绝大部分是测试域 unwrap 告警的位移(见第二章证据),并非新逻辑引入,故归于行号漂移,仅其中少量挂在新函数上。
以下为人工读码观察,不在质检问题清单内,仅提示:
insert_commits / insert_commit_files / insert_issues_with_commit 采用「SELECT 已存在 → INSERT」而非 DB 唯一约束。注释针对的是 persist_insight 重复(串行)执行;若同一 push 被并发触发两次,两次 SELECT 可能都通过,仍会双写。建议补 (push_id, sha) / (commit_id, path) / 问题键唯一索引兜底。backfill_service.rs 中合成 push 失败时仍 report.tasks_created += 1(注释声明为有意,任务已建、仅该簇落库跳过)。调用方(insight)若以 tasks_created 为「成功回填数」展示,需知悉口径。base_sha 为空的簇 continue(初始提交无法增量扫描),注释说明为「可接受缺口」,建议在响应 BackfillResponse 中显式暴露 skipped_root 计数,避免用户误以为全量覆盖。backfill.rs::backfill 用 expect("AppState 未注入"):与其余 handler 风格一致(依赖注入保证),非阻塞项。enumerate_and_backfill(135 行 / fan-out 26)与 create_backfill_task(17 依赖)抽函数/分层,降低耦合;insert_* 幂等路径补唯一索引,消除并发双写竞态;backfill.rs 抽公共错误渲染函数,消除 3 处重复块;BackfillResponse 增补 skipped_root 字段,提升回填结果可观测性。注册 backfill、backfill_service 模块 |
src/client/gitea.rs | 修改 | 新增 commits()(枚举仓库 commit);list_personal_repos 数据源由 /user/repos 改为 /repos/search;新增 GiteaRepoCommit 等结构 |
src/store/repos.rs | 修改 | 新增 create_backfill_task / exists_queued_backfill_task / find_analyzed_commit_shas;insert_commits / insert_commit_files / insert_issues_with_commit 加幂等去重;bind_employee_username 语义收紧 |
src/orchestrator/scheduler.rs | 修改 | backfill 归入 push 桶;回填豁免分析时段闸;钉钉推送改为白名单 hub.notify.push_task_types;回填跳过报告生成 |
src/orchestrator/analysis_window.rs | 修改 | 分析时段支持多时段 slots(命中任一即派发),兼容旧 start/end 单时段 |
src/api/insight_settings.rs | 修改 | 可写 key 前缀新增 hub.notify. |
src/api/trigger.rs | 修改(测试) | Incremental/BaselineTriggerRequest 新增 actor 字段 |
src/api/insight_webhook.rs | 修改(测试) | gitea-user-repos mock 由裸数组改为 {"data":[...]},对齐 /repos/search |
insight_settings.rs| 303 |
| 307 |
| +4 |