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

5.9 KiB
Raw Blame History

前端功能性 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.mdagent 合成稿,注意其严重度排序受下述环境故障污染)。

执行摘要

  • 测试覆盖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_draftPOST /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.tsxStepPremise + 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 段 idxLLM 按自己的分段)与前端段落 index另一套切分口径不一致 → 「一键回炉」可能改错段落。(需已学指纹+drift 才能必现;当前 PID 无指纹故未必现。) 学指纹→写章→style 返回 idx>0 段→点回炉→改的不是被标段

MEDIUM (11)

  • outline:卷号选择器只参与 POST 生成;GET /outline?volume=N 忽略过滤,编辑器永远渲染全部卷,用户无法只看某卷。
  • outlineuseOutlineerror.error.code,但 FastAPI 422 用 {detail:[...]} → 校验错误细节丢失,永远显示通用「大纲生成失败」。
  • rules:纯空白 content 被接受持久化201——min_length:1 在 trim 前校验,服务端不 strip。
  • rulesGET /projects/{不存在}/rules200 {"rules":[]} 而非 404掩盖坏 id。
  • rules无 DELETE/编辑端点——规则只能增+读,误加的规则(如上面的空白行)无法删除。
  • settings/providersPUT /settings/providers 接受任意未知 tier(如 bogus)和未知 provider 名,无枚举/白名单校验。
  • codex:角色 relations 在读路径被静默丢弃CodexPage 也从不展示已存角色的 relations。
  • codex:角色入库非幂等——同名卡重复入库生成重复行UI 渲染重复 chip。
  • review/styledrift 段 idx 超过本章段落数时,渲染一个可点的「第 N 段/一键回炉」但点击静默 no-op
  • command palettelistbox/combobox a11y 契约不完整,屏幕阅读器读不全。
  • chainrun/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-sseC1 · toolbox-generators见下 · styleH3 · chain1 MED已确认可跑通

覆盖与缺口

  • 环境故障期间浏览器交互层hydration 后的真实点击/键盘)被全站 500 阻断agent 多以源码+API 推断;建议在已修复的环境上重跑一次浏览器冒烟以补足 LLM 结果页的真实渲染验证。
  • LLM 端到端:部分生成流程因 Kimi 限流/单 PID 数据(无 style 指纹)未能必现 H3chain 已独立确认 count=1 跑通。