task_plan.md 5.5 KB

backend-dev - 任务计划

角色: 后端开发 状态: pending 分配的任务: OPT-02, OPT-08, OPT-12, OPT-17 及相关 API

任务

  • P0-1: OPT-02 轮询超时修复(WebSocket 推送)
  • P1-5: OPT-08 后端 batch-generate API
  • P2-4: OPT-12 后端 feedback API
  • P3-3: OPT-17 歌词时间轴(LRC 格式支持)

后端配套

优化项 后端变更
OPT-02 WebSocket 推送 audio_generation_complete, video_generation_complete 事件
OPT-03 提供 /api/player/recent 最近播放记录 API
OPT-08 POST /api/book-generator/books/:id/batch-generate 编排接口
OPT-12 POST /api/feedback 反馈提交接口
OPT-17 TTS 生成时返回 LRC 格式时间戳

备注

  • 后端项目:server/
  • WebSocket 使用 ws 库
  • API 设计参考 docs/api-contracts.md

后端架构优化项(2026-05-16 审查发现)

文本内容生成和 TTS 音频生成逻辑审查,发现以下待优化问题

# 分类 问题 优先级 文件
BK-1 状态机 safeTransitionChapter 状态冲突时静默 return,调用方无法感知失败 P0 stage-manager.ts:98-121
BK-2 状态机 书籍阶段计算用"最落后章节",一坏俱坏,无法查看已完成章节 P0 book-generator.store.ts:24-75
BK-3 内容生成 父节点完成检查只验证直接子节点,不递归检查所有后代 P0 content.node.ts:22-59
BK-4 状态机 内容生成两阶段推进(content_generating → content_completed)存在竞态 P1 book-generator.store.ts:1600-1618
BK-5 TTS realtime 长文本模式被强制禁用(shouldUseLongText 恒返 false) P1 tts.service.ts:95-97
BK-6 TTS Provider 全部降级后无兜底,直接抛错无 fallback P1 tts.service.ts:537-538
BK-7 TTS processAudioGeneration 写 audioUrl 后 onComplete 再做 advanceChapter,任一失败导致 tryAutoMerge 不触发 P1 book-generator.store.ts:1326-1348
BK-8 TTS LRC 生成对无标点纯英文文本按40字硬切,LRC行数爆炸 P2 tts.service.ts:884-895

BK-1 详情:safeTransitionChapter 静默失败

// stage-manager.ts:98-121
if (result.count === 0) {
  // ... 状态冲突处理
  console.warn(`[safeTransition] 章节 ${chapterId} 状态冲突...`);
  return;  // ← 问题:调用方以为成功了,继续执行下游
}

建议:失败时 throw Error,或返回 boolean 让调用方判断。

BK-2 详情:书籍阶段一坏俱坏

// book-generator.store.ts:24-75
let minIdx = stageOrder.length;
for (const ch of chapters) {
  if (idx < minIdx) minIdx = idx;  // 取最小(最落后)阶段
}

影响:20章中1章 failed,整本书显示 failed,用户无法访问其他19章已完成的音频。

建议:增加 book.finishedChapters 字段,与 genStage 解耦;或改用 most_common 逻辑。

BK-3 详情:父节点完成检查不递归

// content.node.ts:22-59
const allChildrenDone = children.every(
  c => c.genStage === 'content_completed' || c.genStage === 'audio_generating' ...
);

只检查直接子节点(level+1),如果节(level=2)下还有小节(level=3)在 content_generating,节会被错误推进到 content_completed

建议:递归检查所有后代节点,或改用 BFS 收集叶节点后统一判断。

BK-4 详情:两阶段推进竞态

// book-generator.store.ts:1600-1618
if (currentChapter.genStage !== 'content_generating') {
  await advanceChapter(chapterId, 'content_generating').catch(() => {});
}
await advanceChapter(chapterId, 'content_completed');

两次 advanceChapter 之间如果有并发的音频生成任务抢占了 content_generating,第二次调用会失败。

建议:合并为单次 safeTransitionChapter(chapterId, curStage, 'content_completed') 调用。

BK-5 详情:realtime 模式强制禁用

// tts.service.ts:95-97
export function shouldUseLongText(text: string): boolean {
  return false; // 强制返回 false,禁用 realtime 模式
}

注释说 WebSocket 连接问题导致禁用,但 MiniMax 支持100万字符异步模式,长文本应优先走异步而非分段。

建议:修复 WebSocket 问题,启用 MiniMax 异步长文本模式。

BK-6 详情:无兜底 Provider

// tts.service.ts:537-538
throw new Error('所有 TTS Provider 都已尝试,均无法生成音频');

建议:mock provider 作为最后兜底,保证服务可用性。

BK-7 详情:onComplete 回调状态推进失败

// book-generator.store.ts:1326-1348
async (audioUrl: string, duration: number) => {
  await advanceChapter(chapterId, 'audio_completed');  // 可能失败
  tryAutoMerge(chapterId, ...);  // 失败则不会触发
}

建议:用 tryAutoMerge 替换 advanceChapter 失败的兜底逻辑,或在 processTtsTask 中等待回调完成后再推进状态。

BK-8 详情:LRC 英文硬切

// tts.service.ts:884-895
const chunkSize = 40;  // 纯英文按40字切分,万字文本=250+行

建议:增加英文句号 . 作为断句依据,与中文标点一致处理。


BK-* 任务分配

任务 建议处理人
BK-1, BK-4 backend-dev(状态机逻辑修复)
BK-2 backend-dev(数据库 schema 变更)
BK-3 backend-dev(递归检查逻辑)
BK-5, BK-6, BK-7, BK-8 backend-dev(TTS 服务层)