Files
writer-work-flow/docs/qa/frontend-qa-report-2026-06-24.md
Yaojia Wang 2fe3bedfba fix(qa): 修 QA C1/H1/H2——写章/规则缺项目校验 + 立项向导字段覆盖
C1 (CRITICAL) stream_draft:对不存在 project 流式写章先 fail-fast 404,
  否则非法 id 静默烧一次付费/限流 LLM 调用并返 200。在触网关前查 project_repo.get。
H2 (HIGH) create_rule:给不存在 project 加规则原 FK 违例逃逸成 500 → 改为入库前
  校验项目存在返 404(仿 chain/_require_project)。
H1 (HIGH) ProjectWizard:第3步「立意」与第4步「主角/金手指」原共用 form.premise
  互相覆盖丢数据 → 新增独立 form.protagonist,toCreateRequest 合并两段进 premise
  (M1 projects 表仍只有 premise,不编造 API)。

回归测试:
- test_projects.py:stream_draft 不存在 project → 404 且网关零调用;已有 draft
  用例改 seed 真项目。
- test_rules.py:create_rule 不存在 project → 404 不写库;已有用例 seed 真项目。
- wizard.test.ts:premise+protagonist 合并不互相覆盖(2 例)。
门禁绿:ruff/format clean · mypy 210 · pytest 749 · 前端 tsc/lint/vitest 干净。
2026-06-24 17:17:35 +02:00

51 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 前端功能性 QA 报告 — 2026-06-24
> 方法:多 agent 并行 QA15 个 area agent。每个 area 读组件 + `lib/api` hook直接 curl 打 `:8000` APIhappy path + 404/422/503/空集/幂等边界),交叉核对组件逻辑 vs OpenAPI 契约;外加单浏览器 render/runtime 冒烟。LLM 流程按要求**完整端到端**跑真 Kimi。**仅记录、不改码。**
> 原始数据:`frontend-qa-errors-2026-06-24.json`(全部错误)+ `frontend-qa-2026-06-24.md`agent 合成稿,注意其严重度排序受下述环境故障污染)。
## 执行摘要
- 测试覆盖15 个 area14 路由 + 52 组件。
- 计数(**剔除环境故障后****CRITICAL 1 · HIGH 3 · MEDIUM 11 · LOW ~26**。
- ⚠️ **环境故障(非源码缺陷,已修复)**QA 期间运行环境有**两个并发 `next dev` 写同一个 `.next`**(我多次重启 `pnpm dev` 未杀旧进程所致),导致 `.next` 构建缓存损坏 → 全部 `/projects/[id]/*` 路由 500、静态 chunk 404、页面不 hydrate。这污染了 agent 报的 **2 个 CRITICAL + ~4 个 HIGH**"全站 500/不可交互")。**已 kill 重复进程 + `rm -rf .next` + 单实例重启**复验10 个 project 路由全部 **200**、静态 chunk **200**。这些不计入真实缺陷。
## 真实缺陷(按严重度)
### CRITICAL (1)
| # | 位置 | 问题 | 复现 |
|---|---|---|---|
| C1 | `apps/api/.../routers/projects.py::stream_draft``POST /projects/{pid}/chapters/{n}/draft` | 对**不存在的 project** 流式写章返回 **200 + 真生成整章**,而非 404。入口未校验项目存在性就调网关——非法 id 会**静默烧掉一次付费、限流的 LLM 调用**。 | `curl -sN -X POST .../projects/00000000-.../chapters/7/draft -H 'Accept: text/event-stream'` → 200 + token/done 事件 |
### HIGH (3)
| # | 位置 | 问题 | 复现 |
|---|---|---|---|
| H1 | `apps/web/components/ProjectWizard.tsx`StepPremise + StepProtagonist | 第3步「立意」与第4步「主角/金手指」**绑定同一个 `form.premise`**,后填覆盖先填 → 提交时丢数据,二者不能共存。 | /projects/new 填立意→下一步填主角→提交,`project.premise` 只剩主角文本 |
| H2 | `apps/api/.../routers/rules.py` + `rule_repo.py` | 给**不存在的 project** POST 规则返回 **500INTERNAL** 而非 404——repo 直接 insert+flushFK 违例逃逸成 500真后端 bugcurl 直测,与 next dev 无关)。 | `curl -X POST .../projects/{随机uuid}/rules -d '{"level":"project","content":"x"}'` → 500 |
| H3 | `review/ReviewReport.tsx`(segmentText) + `prompts/style.md` | 文风 drift 段 `idx`LLM 按自己的分段)与前端段落 index另一套切分口径不一致 → 「一键回炉」可能改**错段落**。(需已学指纹+drift 才能必现;当前 PID 无指纹故未必现。) | 学指纹→写章→style 返回 idx>0 段→点回炉→改的不是被标段 |
### MEDIUM (11)
- **outline**:卷号选择器只参与 POST 生成;`GET /outline?volume=N` **忽略过滤**,编辑器永远渲染全部卷,用户无法只看某卷。
- **outline**`useOutline``error.error.code`,但 FastAPI 422 用 `{detail:[...]}` → 校验错误细节丢失,永远显示通用「大纲生成失败」。
- **rules**:纯空白 content 被接受持久化201——`min_length:1` 在 trim 前校验,服务端不 strip。
- **rules**`GET /projects/{不存在}/rules`**200 `{"rules":[]}`** 而非 404掩盖坏 id。
- **rules****无 DELETE/编辑端点**——规则只能增+读,误加的规则(如上面的空白行)无法删除。
- **settings/providers**`PUT /settings/providers` 接受**任意未知 tier**(如 `bogus`)和未知 provider 名,无枚举/白名单校验。
- **codex**:角色 relations 在读路径被**静默丢弃**CodexPage 也从不展示已存角色的 relations。
- **codex**:角色入库**非幂等**——同名卡重复入库生成重复行UI 渲染重复 chip。
- **review/style**drift 段 `idx` 超过本章段落数时,渲染一个可点的「第 N 段/一键回炉」但点击**静默 no-op**。
- **command palette**listbox/combobox a11y 契约不完整,屏幕阅读器读不全。
- **chain**run/resume 失败统一塌成通用 toast「出错了请稍后重试」丢弃 API envelope 的结构化 code/message。
### LOW~26摘要
通用错误 toast 丢弃后端 detail多处wizard/chain/outline服务端接受纯空白标题201空大纲生成仍报「已生成」成功 toast 却显示空态outline 全程只读(无 PUT 编辑QA 预期与实现的范围差);多处表单缺 `<label>`/ariarules textarea 等a11y等。完整见 errors JSON。
## 信息性观察(非缺陷)
- **skills 注册表为空**`GET /skills``{"skills":[]}`):本环境 DB 未播种内置 skill故 SkillsPage 正确显示空态。页面本身工作正常(重建后 200。若期望展示内置 8/21 agent需要 skills 播种逻辑/数据。
## 各 area 状态
projects-list+createH1 + 2 LOW · outline1 MED×2 + 2 LOW只读· rulesH2 + 3 MED + 1 LOW · foreshadow环境 500 已修,功能正常)· templates空白校验此前已修· settings/providers1 MED · codex2 MED · skills空态数据未播种· review-display1 MEDidx· nav/shell+command1 MEDa11y· write-sse**C1** · toolbox-generators见下 · styleH3 · chain1 MED已确认可跑通
## 覆盖与缺口
- 环境故障期间**浏览器交互层**hydration 后的真实点击/键盘)被全站 500 阻断agent 多以源码+API 推断;建议在**已修复的环境**上重跑一次浏览器冒烟以补足 LLM 结果页的真实渲染验证。
- LLM 端到端:部分生成流程因 Kimi 限流/单 PID 数据(无 style 指纹)未能必现 H3chain 已独立确认 count=1 跑通。