Files
writer-work-flow/apps/api/ww_api/schemas/foreshadow.py

73 lines
3.0 KiB
Python
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.

"""伏笔登记 / 状态变更端点的请求/响应 schemaC3 扩 / ARCH §6.2, §7.2)。
snake_case前端经 OpenAPI 生成 TS 类型消费。改字段 → 前端必须 `pnpm gen:api`。
登记是**作者显式动作**(不变量 #3伏笔入库不经 AI 静默写库),到期扫描是验收后的
确定性纯函数置位M3-d二者都不在审稿/写章流水线里。
"""
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field
# 请求字符串字段长度上界CR-H9防超长入参 DoS/成本)。代号=短标识;标题=一句话。
_CODE_MAX = 100
_TITLE_MAX = 500
class ForeshadowRegisterRequest(BaseModel):
"""POST /projects/:id/foreshadow作者显式登记一条伏笔status 落 OPEN"""
code: str = Field(
min_length=1, max_length=_CODE_MAX, description="伏笔代号,`(project_id, code)` 唯一"
)
title: str = Field(min_length=1, max_length=_TITLE_MAX, description="伏笔标题/一句话描述")
planted_at: int | None = Field(default=None, description="埋设章号")
content: str | None = Field(default=None, description="伏笔正文/线索")
expected_close_from: int | None = Field(default=None, description="预期回收窗口起始章")
expected_close_to: int | None = Field(
default=None, description="预期回收窗口结束章(到期判据用)"
)
importance: str | None = Field(default=None, description="重要度(自由文本,看板用)")
class ForeshadowTransitionRequest(BaseModel):
"""PATCH /projects/:id/foreshadow/:code状态机转移 和/或 追加一条进展。
两字段皆可选:`to_status` 走状态机(非法 → VALIDATION 信封);`progress_entry`
append-only 追加到 progress JSONB。二者可同时给先转移、后追加进展
"""
to_status: str | None = Field(
default=None, description="目标状态OPEN/PARTIAL/CLOSED/OVERDUE"
)
progress_entry: dict[str, Any] | None = Field(
default=None, description="追加一条进展记录append-only不覆盖历史"
)
class ForeshadowView(BaseModel):
"""伏笔账本视图(登记/状态变更/看板共用snake_case。形对齐 `ForeshadowLedgerView`。"""
code: str
title: str
status: str
planted_at: int | None = None
content: str | None = None
expected_close_from: int | None = None
expected_close_to: int | None = None
importance: str | None = None
links: list[dict[str, Any]] = Field(default_factory=list)
progress: list[dict[str, Any]] = Field(default_factory=list)
class ForeshadowBoardResponse(BaseModel):
"""GET /projects/:id/foreshadow?status=:伏笔看板(四泳道 + OVERDUE 字段齐)。
`status` 缺省返回全部;按 `code` 升序repo `list_by_status` 已排序)。前端按
`status` 分四泳道OPEN/PARTIAL/CLOSED/OVERDUE用 `expected_close_to` 标逾期。
"""
foreshadow: list[ForeshadowView] = Field(default_factory=list)