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 干净。
This commit is contained in:
@@ -252,6 +252,7 @@ async def stream_draft(
|
||||
repos: MemoryReposDep,
|
||||
gateway: GatewayDep,
|
||||
injection_repo: InjectionRepoDep,
|
||||
project_repo: ProjectRepoDep,
|
||||
session: Annotated[AsyncSession, Depends(get_session)],
|
||||
body: DraftStreamRequest | None = None,
|
||||
) -> StreamingResponse:
|
||||
@@ -259,7 +260,12 @@ async def stream_draft(
|
||||
|
||||
`body.directive`(可选,T4-b)是临时本章指令,直通 assemble→volatile(不持久化);
|
||||
无 body 的旧调用方仍可用(向后兼容)。
|
||||
|
||||
项目不存在 → 404(在触网关前 fail-fast):否则非法 project_id 会静默烧一次付费/限流的
|
||||
LLM 调用并返回 200(QA C1)。
|
||||
"""
|
||||
if await project_repo.get(STUB_OWNER_ID, project_id) is None:
|
||||
raise AppError(ErrorCode.NOT_FOUND, f"project not found: {project_id}")
|
||||
request_id = getattr(request.state, "request_id", None)
|
||||
directive = body.directive if body else None
|
||||
override = await injection_repo.get(project_id, chapter_no)
|
||||
|
||||
Reference in New Issue
Block a user