"""多章工作流链端点的请求/响应 schema(chain-workflow 设计 §6)。 snake_case(命名契约,见 memory/gotchas)。前端经 OpenAPI→TS 客户端消费——改字段 须 `pnpm gen:api` 重生成。 - `ChainRunRequest`:发起一条链(起始章 + 章数)。`count` 1..50(系统边界校验,fail fast)。 - `ChainRunAccepted`:202 受理回执(job_id + 回显请求参数,供前端轮询 `GET /jobs/{id}`)。 - `ChainResumeRequest`:裁决续跑(复用 `ConflictDecision`,对 awaiting 章的冲突逐条裁决)。 """ from __future__ import annotations import uuid from pydantic import BaseModel, Field from ww_api.schemas.projects import ConflictDecision # 链一次最多写 K 章(系统边界,避免一条 run 无界占用;§6 校验)。 MAX_CHAIN_COUNT = 50 MIN_CHAIN_COUNT = 1 class ChainRunRequest(BaseModel): """发起多章链:从 `start_chapter_no` 起循环写 `count` 章(区间含两端)。 `count` 1..50(>50 → 422 VALIDATION,由 Field 约束在边界拦下,不进 BackgroundTask); `start_chapter_no >= 1`。 """ start_chapter_no: int = Field(ge=1, description="起始章号(含),>=1") count: int = Field( ge=MIN_CHAIN_COUNT, le=MAX_CHAIN_COUNT, description="本 run 连续写的章数(1..50,含起始章)", ) class ChainRunAccepted(BaseModel): """链受理回执(202):job_id + 回显请求参数(前端走 `GET /jobs/{id}` 轮询进度/awaiting)。""" job_id: uuid.UUID chain_key: str start_chapter_no: int count: int class ChainResumeRequest(BaseModel): """裁决续跑:对 awaiting 章最近审稿的每个冲突逐条裁决(复用 `ConflictDecision`)。""" decisions: list[ConflictDecision] = Field( default_factory=list, description="对 awaiting 章冲突的裁决清单(采纳/忽略/手改)", )