# backend-dev - 任务计划 > 角色: 后端开发 > 状态: pending > 分配的任务: OPT-02, OPT-08, OPT-12, OPT-17 及相关 API ## 任务 - [ ] P0-1: OPT-02 轮询超时修复(WebSocket 推送) - [x] P1-5: OPT-08 后端 batch-generate API - [x] 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 静默失败 ```typescript // stage-manager.ts:98-121 if (result.count === 0) { // ... 状态冲突处理 console.warn(`[safeTransition] 章节 ${chapterId} 状态冲突...`); return; // ← 问题:调用方以为成功了,继续执行下游 } ``` **建议**:失败时 throw Error,或返回 `boolean` 让调用方判断。 ### BK-2 详情:书籍阶段一坏俱坏 ```typescript // 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 详情:父节点完成检查不递归 ```typescript // 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 详情:两阶段推进竞态 ```typescript // 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 模式强制禁用 ```typescript // tts.service.ts:95-97 export function shouldUseLongText(text: string): boolean { return false; // 强制返回 false,禁用 realtime 模式 } ``` 注释说 WebSocket 连接问题导致禁用,但 MiniMax 支持100万字符异步模式,长文本应优先走异步而非分段。 **建议**:修复 WebSocket 问题,启用 MiniMax 异步长文本模式。 ### BK-6 详情:无兜底 Provider ```typescript // tts.service.ts:537-538 throw new Error('所有 TTS Provider 都已尝试,均无法生成音频'); ``` **建议**:mock provider 作为最后兜底,保证服务可用性。 ### BK-7 详情:onComplete 回调状态推进失败 ```typescript // book-generator.store.ts:1326-1348 async (audioUrl: string, duration: number) => { await advanceChapter(chapterId, 'audio_completed'); // 可能失败 tryAutoMerge(chapterId, ...); // 失败则不会触发 } ``` **建议**:用 `tryAutoMerge` 替换 `advanceChapter` 失败的兜底逻辑,或在 `processTtsTask` 中等待回调完成后再推进状态。 ### BK-8 详情:LRC 英文硬切 ```typescript // 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 服务层) |