42 lines
1.5 KiB
Python
42 lines
1.5 KiB
Python
"""规则端点的请求/响应 schema(C3 扩 / PRODUCT_SPEC §7 POST /rules)。
|
||
|
||
snake_case;前端经 OpenAPI 生成 TS 类型消费。改字段 → 前端必须 `pnpm gen:api`。
|
||
`level` ∈ global/genre/style/project(四级合并优先级,见 memory `merge_rules`)。
|
||
加规则是作者显式动作——审稿发现的问题/亮点随手沉淀为规则(非 AI 静默写库,不变量 #3)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import uuid
|
||
from typing import Annotated, Literal
|
||
|
||
from pydantic import BaseModel, Field, StringConstraints
|
||
|
||
RuleLevel = Literal["global", "genre", "style", "project"]
|
||
|
||
# 规则正文长度上界(CR-H9:防超长入参 DoS/成本)。
|
||
_RULE_CONTENT_MAX = 10_000
|
||
|
||
# 先 strip 再校验长度:纯空白内容(" ")strip 后为空 → 422(QA MEDIUM:此前被接受入库)。
|
||
RuleContent = Annotated[
|
||
str, StringConstraints(strip_whitespace=True, min_length=1, max_length=_RULE_CONTENT_MAX)
|
||
]
|
||
|
||
|
||
class RuleCreateRequest(BaseModel):
|
||
"""POST /projects/:id/rules:新增一条规则。"""
|
||
|
||
level: RuleLevel = Field(description="规则级别(global/genre/style/project,越具体越优先)")
|
||
content: RuleContent = Field(description="规则正文(首尾空白会被裁剪,不可全空白)")
|
||
|
||
|
||
class RuleView(BaseModel):
|
||
"""规则视图(创建后回显 + 列表项;snake_case)。
|
||
|
||
`id` 是该规则行的稳定主键——前端规则页用它作删除 handle(DELETE /rules/{rule_id})。
|
||
"""
|
||
|
||
id: uuid.UUID
|
||
level: str
|
||
content: str
|