from datetime import datetime from typing import Literal, Optional from pydantic import BaseModel, Field, model_validator # ---------- 局部块更新 ---------- class BlockUpdate(BaseModel): level: int = Field(..., ge=1, le=6, description="标题等级 1=H1 … 6=H6") index: int = Field(..., ge=0, description="该等级标题在文档中的顺序下标(从 0 开始)") content: str = Field(..., description="该块的新内容(含标题行本身)") # ---------- 请求 ---------- class CreateDocumentRequest(BaseModel): title: str = Field(..., max_length=255) content: str = Field(..., description="文档内容(Markdown),最大 200KB") format: Literal["markdown"] = "markdown" session_id: Optional[str] = Field(None, alias="sessionId") template_id: Optional[str] = Field(None, alias="templateId") model_config = {"populate_by_name": True} class UpdateDocumentRequest(BaseModel): title: Optional[str] = Field(None, max_length=255) content: Optional[str] = Field(None, description="全量更新内容,与 blocks 二选一") blocks: Optional[list[BlockUpdate]] = Field(None, description="局部块更新,与 content 二选一") @model_validator(mode="after") def check_content_or_blocks(self) -> "UpdateDocumentRequest": if self.content is not None and self.blocks is not None: raise ValueError("content 与 blocks 不能同时传入") return self # ---------- 响应 ---------- class DocumentResponse(BaseModel): id: str title: str content: str format: str session_id: Optional[str] = Field(None, serialization_alias="sessionId") template_id: Optional[str] = Field(None, serialization_alias="templateId") created_by: Optional[str] = Field(None, serialization_alias="createdBy") created_at: datetime = Field(..., serialization_alias="createdAt") updated_at: datetime = Field(..., serialization_alias="updatedAt") model_config = {"from_attributes": True, "populate_by_name": True} class DocumentListItem(BaseModel): id: str title: str template_id: Optional[str] = Field(None, serialization_alias="templateId") created_at: datetime = Field(..., serialization_alias="createdAt") updated_at: datetime = Field(..., serialization_alias="updatedAt") model_config = {"from_attributes": True, "populate_by_name": True} class Pagination(BaseModel): page: int page_size: int = Field(..., serialization_alias="pageSize") total: int total_pages: int = Field(..., serialization_alias="totalPages") model_config = {"populate_by_name": True}