# Class AI Report Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Replace the 3-bullet class summary with a streamed, tiered Markdown class-analysis report driven by per-sentence transcripts, word-level scores, and per-student dimension averages.
**Architecture:** Backend adds a new SSE endpoint that builds a rich per-student payload (Azure score averages + transcripts + word analysis + sentence comments), feeds it to a new streaming LLM evaluator with the tiered-report system prompt, and streams Markdown tokens. Frontend consumes the stream in `useClassSummary`, accumulates Markdown, and renders it (sanitized) in an expandable `AISummary` panel.
**Tech Stack:** Backend — FastAPI, SQLAlchemy async, OpenAI-compatible LLM (One-Hub), `EventSourceResponse`. Frontend — Vue 3 `
```
- [ ] **Step 2: Type-check**
Run: `npm run type-check`
Expected: FAIL — only `index.vue` still passes the old `AISummary` props. Fixed in Task 13.
- [ ] **Step 3: Commit**
```bash
git add src/views/Student/components/SpeakingClassPanel/AISummary.vue
git commit -m "feat(speaking): expandable streamed-report AISummary panel"
```
---
### Task 13: Wire `index.vue` + manual verification
**Files:**
- Modify: `src/views/Student/components/SpeakingClassPanel/index.vue`
- [ ] **Step 1: Update the destructure from `useClassSummary`**
In `index.vue`, change the `useClassSummary` destructure: replace `aiBullets, aiLoading, aiGeneratedAt, refreshAISummary` with:
```typescript
completionLine, reportMarkdown, reportStreaming, reportGeneratedAt, reportError, refreshReport,
```
- [ ] **Step 2: Update the `` usage**
Replace the `` element with:
```vue
```
- [ ] **Step 3: Type-check the whole project**
Run: `npm run type-check`
Expected: PASS — zero errors across the project.
- [ ] **Step 4: Manual verification**
Run: `npm run dev`, open a course with a `SpeakingClassPanel`, and confirm:
- Collapsed panel shows the live completion line + "查看完整分析报告 ▾".
- Expanding with no completed students shows the localized "waiting" message.
- With completed students, the report streams in progressively; tables render with borders; any `` shows red text.
- The "重新生成" button re-streams; while streaming it is disabled and shows the streaming label.
- Killing the backend mid-request surfaces the error bar with a working retry.
- Switch hostname/locale (zh / en / hk) and confirm the report language follows.
- [ ] **Step 5: Commit**
```bash
git add src/views/Student/components/SpeakingClassPanel/index.vue
git commit -m "feat(speaking): wire streamed class report into SpeakingClassPanel"
```
---
## Self-review notes
- **Spec coverage:** new SSE endpoint (T4), payload builder + 30-cap + Azure averaging (T2), `ClassReportEvaluator` with the prompt (T1), cache + waiting branch (T3), legacy removal (T5), `parseSSEStream` share (T7), `streamClassReport` (T8), DOMPurify dep (T6) + render util (T9), `useClassSummary` rework (T10), expandable `AISummary` (T12), i18n (T11), `index.vue` wiring (T13). The `形状词汇` → `目标词汇` generalization is applied in T1's prompt.
- **Deviation:** spec called for frontend unit tests; `PPT` has no test runner, so frontend tasks verify via `type-check` + the Task 13 manual checklist. Backend keeps full TDD.
- **Cross-task type consistency:** `streamClassReport(configId, students, locale)` yields `string`; `generate_class_report_stream` yields `(event_type, data)` tuples with `token`/`done`/`error`; `renderReportMarkdown(src: string): string`; `AISummary` props `{completionLine, markdown, streaming, generatedAt, error}` match `useClassSummary`'s exports and `index.vue`'s bindings.