"""笔记相关的请求/响应 schema。""" from datetime import datetime from pydantic import BaseModel, ConfigDict, Field from app.models.question import QuestionType class OptionIn(BaseModel): key: str = Field(max_length=8) # A/B/C/D 等 text_markdown: str class QuestionBase(BaseModel): # 默认未分类:拍照记下来就能存,不强制先想清楚题型 type: QuestionType = QuestionType.unclassified stem_markdown: str options: list[OptionIn] | None = None correct_answer: list[str] | None = None explanation_markdown: str | None = None my_note_markdown: str | None = None needs_review: bool = False difficulty: int | None = Field(default=None, ge=1, le=5) class QuestionCreate(QuestionBase): tags: list[str] = Field(default_factory=list) class QuestionUpdate(BaseModel): """全部可选,只更新提供的字段。""" type: QuestionType | None = None stem_markdown: str | None = None options: list[OptionIn] | None = None correct_answer: list[str] | None = None explanation_markdown: str | None = None my_note_markdown: str | None = None needs_review: bool | None = None difficulty: int | None = Field(default=None, ge=1, le=5) tags: list[str] | None = None class QuestionOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: str type: QuestionType stem_markdown: str options: list[dict] | None correct_answer: list[str] | None explanation_markdown: str | None my_note_markdown: str | None needs_review: bool difficulty: int | None source_image_id: str | None ocr_engine: str | None tags: list[str] = Field(default_factory=list) created_at: datetime | None = None updated_at: datetime | None = None @classmethod def from_model(cls, q) -> "QuestionOut": return cls( id=q.id, type=q.type, stem_markdown=q.stem_markdown, options=q.options, correct_answer=q.correct_answer, explanation_markdown=q.explanation_markdown, my_note_markdown=q.my_note_markdown, needs_review=q.needs_review, difficulty=q.difficulty, source_image_id=q.source_image_id, ocr_engine=q.ocr_engine, tags=[t.name for t in q.tags], created_at=q.created_at, updated_at=q.updated_at, ) class QuestionList(BaseModel): items: list[QuestionOut] total: int page: int page_size: int