Skip to content

fix: 孤儿任务补写 completed_at 堵 retention 漏洞 + studio 裸 catch 收窄#149

Merged
KerroKapple merged 2 commits into
mainfrom
fix/orphan-completed-at
Jul 9, 2026
Merged

fix: 孤儿任务补写 completed_at 堵 retention 漏洞 + studio 裸 catch 收窄#149
KerroKapple merged 2 commits into
mainfrom
fix/orphan-completed-at

Conversation

@KerroKapple

Copy link
Copy Markdown
Owner

缺陷链条

1. fix(jobs) 孤儿回收不写 completed_at → 永久逃过 retention(REVIEW-2026-06-18 S6-2)

  • lib/services/job_queue_service.dart 启动孤儿回收(init()bulkTransition 把 pending/submitted/polling 批量转 cancelled)extra 只写 error_code/error_message不写 completed_at
  • 正常终态路径(同文件 :443/:552/:575/:666)都写 completedAt;batch 孤儿收敛 SQL 也写 completed_at = now()
  • postgres_job_repository.dartpurgeExpired 谓词 completed_at < now() - interval 对 NULL 恒假 → 被孤儿回收 cancel 的行永久逃过 30 天 retention(仅剩 purgePerCanvasCap 上限兜底)

修法:孤儿回收 extra 补 JobCol.completedAt = now() UTC ISO8601,对齐既有终态路径写法。

2. fix(studio) 项目卡打开画布裸 catch(REVIEW S1-3/S4-5 残留,#140 漏网)

  • studio_home_screen.dart 项目卡 onTap 的 catch (_) 违反捕获铁律(禁捕宽泛 Exception/dynamic),只弹 toast 不留日志——失败原因不可追溯,非预期异常被静默吞掉

修法:对齐 #140(d43266d)characters_controller 的收窄修法——捕获集 = try 体真实抛出集(仓储 guard 翻译边界只抛 InkError)→ on InkError catch (e, st),经 loggerProvider 写 error 日志(module studio.home,保留 cause/stackTrace)后照常弹 toast;非 InkError 不再被吞。

测试证据(TDD)

修复 1(test/services/job_queue_service_test.dart 孤儿回收用例加断言)

红(修前):

Expected: not null
  Actual: <null>
orphan-1 被孤儿回收后 completed_at 不能为 NULL
00:00 +0 -1: Some tests failed.

绿(修后):flutter test test/services/job_queue_service_test.dart33 全过

修复 2(test/features/studio/studio_home_test.dart 新增失败分支 widget 用例)

红(修前,toast 弹了但零日志):

Expected: an object with length of <1>
  Actual: []
打开画布失败必须写 error 日志,不能只弹 toast

绿(修后):flutter test test/features/studio/44 全过

全量验证

  • flutter analyze → No issues found!
  • flutter test --exclude-tags golden+1201 ~46 All tests passed!(1201 过 / 46 skip,pg-tag 集成测试 TEST_PG_URL 未设自动 skip)

🤖 Generated with Claude Code

Kerro and others added 2 commits July 9, 2026 14:28
启动孤儿回收(init 的 bulkTransition pending/submitted/polling → cancelled)
只写 error_code/error_message,不写 completed_at;而 purgeExpired 的
completed_at < now() - interval 谓词对 NULL 恒假,被回收的行永久逃过
30 天 retention(仅剩 purgePerCanvasCap 上限兜底)。

对齐正常终态路径(success/error/cancel/timeout 均写 completedAt):
孤儿回收 extra 补 JobCol.completedAt = now() UTC ISO8601。

REVIEW-2026-06-18 S6-2。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
studio_home_screen 项目卡 onTap 的 catch (_) 违反捕获铁律(禁捕宽泛
Exception/dynamic)且只弹 toast 不留日志——失败原因不可追溯,非预期
异常被静默吞掉。

对齐 #140(d43266d)characters_controller 的收窄修法:捕获集 = try 体
真实抛出集(仓储 guard 翻译边界只抛 InkError)→ on InkError catch (e, st),
经 loggerProvider 写 error 日志(module studio.home,保留 cause/stackTrace)
后照常弹 toast;非 InkError 不再被吞。

REVIEW S1-3/S4-5 残留。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@KerroKapple KerroKapple force-pushed the fix/orphan-completed-at branch from 4bc3b5e to a030790 Compare July 9, 2026 06:59
@KerroKapple KerroKapple merged commit 058ed00 into main Jul 9, 2026
5 checks passed
@KerroKapple KerroKapple deleted the fix/orphan-completed-at branch July 9, 2026 07:42
KerroKapple added a commit that referenced this pull request Jul 9, 2026
拍板(2026-07-09):
- D-7 d4/d5/d6 = 裁撤优先(左工具栏裁到有功能/▶avatar 裁+⌘K 留/footer settings 接真其余裁)→ CV-1 解锁
- D-8 = A 做真(⌘K 首版 ≤6 动作,随 CV-1 同分支交付 PL-1)
- D-BE-2 = A 仅携带 success-slot 终态 jobs(LB-11 卡面零改动)→ 导入链解锁
- D-10 = B 迁平台惯例路径(Win %LOCALAPPDATA%/mac Application Support)→ LB-10 解锁,
  新增 DIR-1 数据目录迁移卡(§3 末,LB-10 前置)

#164 回填(上轮 #150 漏账):
- BOARD P1-x2 转 ✅(JobQueuePanel 退役即清)
- MASTERPLAN §4 GAP-8 标已合 #164;§3 LB-05 标消解/LB-06 标在途 #166
- §0 现状行补 UI 线破零;§5 beta.1 硬阻塞名单剔除已拍的 D-4(换 QG-4)
- BOARD 近期落地表补 #148/#149/#150/#151/#164 + 拍板记录;头部日期 07-09

Co-authored-by: Kerro <TeddyBearvct@muslim.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant