|
|
@@ -1299,3 +1299,54 @@ echo "frontend: $(git -C /Users/buoy/Development/gitrepo/PPT rev-parse --short H
|
|
|
- Task 6 实际走 plan 的 Branch C(实现完整 adapter),投资成本略高于 Branch A 的一行 pass-through。发现:`TopicDiscussionPreview.vue` 当前展示的是 `mockEvaluation` 硬编码数据,真实 `getReport()` 并未被 UI 消费。adapter 是结构性就位,真正"打开结果页看到 LLM 评语"需要后续把 UI 切换到走 `DialogueAPI.getReport`——该切换不在本 MVP 范围,留给后续任务
|
|
|
- 未做端到端 smoke(真实后端 + 真实浏览器操作),仅静态验证(单测 + 类型检查)。进入真实联调时需先在后端启动 `.env` 里配好 `AZURE_SPEECH_KEY` 和 `ONEHUB_API_KEY`
|
|
|
- 评审中提出的几个 non-blocking 改进项(content_evaluator 的 AsyncOpenAI 生命周期、`_StubDB` 断言说明、`pron_scores` TypedDict、adapter 错误容忍)均标记为后续迭代,未纳入本次 MVP
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2026-04-24 补充:UI 接入 + 跨仓全量 Code Review 发现
|
|
|
+
|
|
|
+本轮继续完成了"UI 切换到真实 getReport"(原遗留项),并对后端/前端分别跑了一次完整 code review。对话主流程尚未跑通到结果页,下次回到本 MVP 前先让对话链路能走完 N 轮进入 completed 态,再基于真实数据验证下列修复。
|
|
|
+
|
|
|
+**新增 commit**:
|
|
|
+- 前端 `d1186cb` — `DialogueChatView` emit `complete` 携带 `DialogueReport | null`;`TopicDiscussionPreview` 用 `displayEvaluation` 优先真实数据、mock 作为 fallback
|
|
|
+- 前端最新 HEAD:`d1186cb`;后端 HEAD 未变(仍 `7d192be`)
|
|
|
+- vue-tsc 通过
|
|
|
+
|
|
|
+### 下次回来必须先修(Critical + Important)
|
|
|
+
|
|
|
+- **[BACKEND CRITICAL] `/speak-stream` WebSocket 路径完全绕过 ContentEvaluator**
|
|
|
+ - `app/api/dialogue.py:159-184` 的 `_background_evaluate_pronunciation` 只跑 Azure,从未调用 content evaluator
|
|
|
+ - 前端录音主路径是 WebSocket(`useDialogueEngine.ts:256+ beginStudentStream`),HTTP `/speak` 只是 fallback
|
|
|
+ - 后果:真实用户的 `content_feedback` 永远 NULL
|
|
|
+ - 修复方向:让 `/speak-stream` 统一走 `DialogueService._evaluate_pronunciation`,或把 evaluator 调用复制进去
|
|
|
+
|
|
|
+- **[FRONTEND CRITICAL] `getReport` 轮询不识别 `status === 'evaluating'`**
|
|
|
+ - `useDialogueEngine.ts:190-202` 的 poll 只对 reject 重试;后端 200 返 `status='evaluating'` 且部分 round `contentFeedback=null` 时直接 resolve
|
|
|
+ - 设计文档 §2.6 已预告此情况但实现未处理
|
|
|
+ - `BackendReportResponse.status` 类型已声明却从未被读取
|
|
|
+ - 修复方向:把 `status === 'evaluating'` 视为"未完成"继续 poll
|
|
|
+
|
|
|
+- **[FRONTEND IMPORTANT] `getReport` 失败悄悄回落到 `mockEvaluation`(I2)**
|
|
|
+ - `fetchReportSafe → null → displayEvaluation → mockEvaluation`(熊猫/竹子那份假数据)
|
|
|
+ - 用户会把虚构报告当作自己的
|
|
|
+ - 修复方向:真实模式下失败必须显示错误态 UI,不回落 mock
|
|
|
+
|
|
|
+- **[FRONTEND IMPORTANT] "结束并查看报告" 阻塞最多 30s(I3)**
|
|
|
+ - `handleExitConfirm` 里 `await fetchReportSafe()` 串在 modal 关闭后,期间 chat view 冻结
|
|
|
+ - 修复方向:先切到 `completed` stage 显示 loading,getReport 后台拉
|
|
|
+
|
|
|
+- **[FRONTEND IMPORTANT] `pending/failed` 轮次 0 分污染 `overallScore`(I5)**
|
|
|
+ - `llmService.ts:90-97` 用 `?? 0` 把未完成轮次填 0,`.filter(s.pronunciation)` 仍会保留
|
|
|
+ - 修复方向:adapter 里只有 `status === 'completed'` 且 score 非 null 才填 `pronunciation`
|
|
|
+
|
|
|
+- **[FRONTEND IMPORTANT] Axis 映射语义不对(I4)**
|
|
|
+ - `prosody → intonation`、`completeness → stress`:completeness 是"读完整度",stress 是"重音"
|
|
|
+ - 修复方向:MVP 先加注释标记为债,后续扩展 `SentenceEvaluation.pronunciation` 为 Azure 四维
|
|
|
+
|
|
|
+### 下下轮改进(Non-blocking)
|
|
|
+
|
|
|
+- Backend I1:`DialogueService.__init__` 每请求 new `AsyncOpenAI`(`get_dialogue_service` 在 `Depends` 里),改 module-level 单例
|
|
|
+- Backend I2:`prior_ai_turn` 依赖"学生消息已 flush 但 AI 未写入"的时序脆弱,加 `role='ai' AND round < current_round` 显式过滤
|
|
|
+- Backend I4:`pron_scores: dict` 缺 TypedDict
|
|
|
+- Backend I5/I6:`test_content_evaluator` 缺 prompt payload 断言;`test_dialogue_service_report` 契约镜像嫌疑
|
|
|
+- Backend M1-6:corrections 内部结构未校验、prompt 注入、migration 非幂等、model 无专用配置、f-string 日志
|
|
|
+- Frontend M1-5:非空断言可避免、`Math.max(...arr)` 栈风险、`dimensions/statistics/aiComment` 占位零未标 TODO、id 方案不统一、`status` 类型不含 `'evaluating'`
|