spec.md 3.3 KB

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 当前轮所有消息都是 doneerror 状态
  • THEN 录音按钮恢复可用

Requirement: Auto scroll

消息列表 SHALL 在新内容到达时自动滚动到底部。

Scenario: Auto scroll on new content

  • WHEN 新消息添加或流式输出产生新内容
  • THEN 自动滚动到底部