ADDED Requirements
Requirement: Message status lifecycle
每条对话消息 SHALL 拥有独立的状态字段,使用 3 个状态:
loading: 处理中(发送/转录/流式输出)
done: 完成
error: 失败
Scenario: Student message sent successfully
- WHEN 学生完成录音并发送消息
- THEN 消息状态从
loading 变为 done,消息内容来自 ASR 转写结果
Scenario: AI reply streams in
- WHEN 学生消息发送成功后触发 AI 回复
- THEN AI 消息进入
loading 状态(显示 typing 动画),收到 token 后逐字渲染,流结束后变为 done
Scenario: Request fails at any stage
- WHEN 网络异常或后端错误导致请求失败(不区分 ASR/LLM 阶段)
- THEN 出错的消息状态变为
error,显示「重试」按钮
Requirement: Message retry
系统 SHALL 支持对 error 状态的消息进行重试操作。重试按钮 SHALL 显示在出错消息的下方。
Scenario: Retry a failed student message
- WHEN 用户点击学生消息下方的「重试」按钮
- THEN 系统用缓存的 audioBlob 重新调用
/speak,整个流程重走
Scenario: Retry a failed AI message (stream interrupted)
- WHEN AI 消息流式中断,用户点击 AI 消息下方的「重新生成」按钮
- THEN 系统清空 AI 消息内容,重新调用
/speak(后端幂等,不重复存学生消息),重新流式填充
Scenario: User chooses to re-record instead of retry
- WHEN 学生消息发送失败后,用户直接点击录音按钮录新音频
- THEN 系统丢弃失败消息,用新录音发起新的
/speak 请求
Requirement: AudioBlob lifecycle
录音 Blob SHALL 在该轮对话成功完成前保持缓存,以支持重试。
Scenario: Retain blob until round completes
- WHEN 学生完成录音
- THEN audioBlob 保持在内存中,直到该轮 AI 回复
done 后才可释放
Requirement: Round progression
对话引擎 SHALL 按轮次推进对话。每轮结束由后端 SSE done 事件触发。
Scenario: Normal round progression
- WHEN 收到 SSE
done 事件且 isComplete 为 false
- THEN 录音按钮恢复可用,等待学生下一轮录音;下一轮的 AI 消息由后端在
done 事件中返回
Scenario: Dialogue complete
- WHEN 收到 SSE
done 事件且 isComplete 为 true
- THEN 触发
complete 事件,前端转到报告页
Scenario: First round initialization
- WHEN 调用
POST /session 创建对话
- THEN 后端返回 AI 开场白,前端显示第一条 AI 消息,学生进入可录音状态
Requirement: Input locking
系统 SHALL 在消息处理过程中禁用录音按钮,保证一次只能有一条处理中的消息。
Scenario: Lock during processing
- WHEN 有任何消息处于
loading 状态
- THEN 录音按钮处于禁用状态
Scenario: Unlock after completion or error
- WHEN 当前轮所有消息都是
done 或 error 状态
- THEN 录音按钮恢复可用
Requirement: Auto scroll
消息列表 SHALL 在新内容到达时自动滚动到底部。
Scenario: Auto scroll on new content
- WHEN 新消息添加或流式输出产生新内容
- THEN 自动滚动到底部