不要一份按执行顺序排列的计划,而是让它按你改动每一部分的可能性来排序——值得你关注的决策浮到最前面,机械性工作沉到最底下。
Write an implementation plan for annotation export as HTML, but lead with the decisions I'm most likely to tweak: data model changes, new type interfaces, and anything user-facing. Bury the mechanical refactoring at the bottom — I trust you on that part.
中文大意:为“标注导出”功能写一份 HTML 格式的实现计划,但把我最可能改动的决策放在最前面:数据模型变更、新的类型接口,以及所有面向用户的部分。把机械性的重构埋到最底下——那部分我信得过你。
Acme · 将一次审阅的标注导出为可分享的 PDF 或 CSV · 分支 feat/annotation-export
有三处我做了判断、而你可能不同意。每个被标记的选择都附有我考虑过的备选方案——点击切换对比。
代价:重度审阅约 40 KB/行;相对实时讨论串,快照可能过期。
适用场景:导出是工作文档,而不是存档记录。回我一句即可:“use live join.”(改用实时联表)
代价:需要管理 blob 生命周期;我会加一个 30 天 TTL 的清理任务(见 C 部分第 6 项)。
适用场景:存储或合规要求让保留副本变得麻烦。
'xlsx' 或 'srt',只需多一个联合类型成员 + 一个渲染器。TimecodeRange 让制片人可以只导出某一场戏的批注。如果没人提过这个需求,砍掉它能省约半天。'wont_fix',请告诉我。第 3 步为什么薄弱:大多数导出会在 3 秒内完成,“发完即忘”的 toast 可能显得小题大做——但一个带涂鸦、有 400 条标注的审阅需要约 20 秒,阻塞等待又太久。混合方案(原地最多等 4 秒,超时再转为通知)体验更好,但要多花约半天。由你决定。
我实际动手时会采用的顺序。每一步落地时 CI 都保持绿色;在第 5 步打开开关之前,用户看不到任何变化。
这个功能需要的重构和底层接线。这里没有需要判断取舍的地方——特意折叠起来。
AnnotationSerializer 从 api/annotations.ts 抽到 lib/serializers/,让导出 worker 可以复用。 纯移动,行为不变。CommentMarker → AnnotationMarker 的重命名——还有 3 个文件在引用已废弃的别名。annotation_exports 加进 fixture 加载器和 CI 数据库重置脚本。workers/index.ts 里注册 exports.render,并把它加入死信告警列表。flags.yaml 里创建功能开关 export_annotations,默认关闭。jobs/cleanup.ts 里为过期导出 blob 加一个每晚运行的 TTL 清理(仅当选择 ② 保持原样时需要)。openapi.yaml 里补充两个新端点并重新生成客户端。player/utils.ts 挪到 lib/time.ts——PDF 渲染器需要它,而且不应从播放器 bundle 引入。回复这几句话的杠杆率最高。复制一条,改一改,发给我——我会据此修订计划。(回复原文保留英文,便于直接发送。)