"""用 Pydantic 2 定义并导出工单契约；只处理本地教学数据，不调用模型。"""
import json
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field

class Ticket(BaseModel):
    # 严格模式拒绝常见隐式转换；额外字段也拒绝，避免混入 approved 等字段。
    model_config = ConfigDict(strict=True, extra="forbid", allow_inf_nan=False)
    category: Literal["billing", "security", "general", "unknown"]
    urgency: Literal["low", "medium", "high"]
    # 没有 default，所以字段必须出现；联合 None 则允许显式 null。
    order_id: str | None = Field(min_length=1, description="原文订单号；缺失为 null")
    requested_amount: float | None = Field(ge=0, description="原文请求的人民币元金额")
    summary: str = Field(min_length=1, max_length=40, description="不添加事实的简短摘要")

if __name__ == "__main__":
    # 同一个定义导出 Schema 和执行校验，降低两份契约分别维护造成的漂移。
    print(json.dumps(Ticket.model_json_schema(), ensure_ascii=False, indent=2))
    # 这是作者编写的响应，用来展示 null 合法且字段没有缺失。
    raw = '{"category":"billing","urgency":"medium","order_id":null,"requested_amount":null,"summary":"申请退款但未提供订单号"}'
    ticket = Ticket.model_validate_json(raw)
    print(ticket.model_dump_json(indent=2))
