from datetime import date, datetime from pydantic import BaseModel, field_validator READING_STATUSES = {"reading", "finished", "paused", "wishlist"} NOTE_VISIBILITIES = {"class", "private"} class ReadingBookCreate(BaseModel): title: str author: str | None = None cover_url: str | None = None total_pages: int = 0 current_page: int = 0 status: str = "reading" started_at: date | None = None finished_at: date | None = None personal_note: str | None = None @field_validator("status") @classmethod def validate_status(cls, value: str) -> str: if value not in READING_STATUSES: raise ValueError("Invalid reading status") return value class ReadingBookUpdate(BaseModel): title: str | None = None author: str | None = None cover_url: str | None = None total_pages: int | None = None current_page: int | None = None status: str | None = None started_at: date | None = None finished_at: date | None = None personal_note: str | None = None @field_validator("status") @classmethod def validate_status(cls, value: str | None) -> str | None: if value is not None and value not in READING_STATUSES: raise ValueError("Invalid reading status") return value class ReadingBookOut(BaseModel): id: int class_id: int owner_id: int owner_name: str title: str author: str | None cover_url: str | None total_pages: int current_page: int status: str started_at: date | None finished_at: date | None personal_note: str | None note_count: int public_note_count: int created_at: datetime updated_at: datetime class ReadingNoteCreate(BaseModel): title: str content: str page_ref: str | None = None visibility: str = "class" @field_validator("visibility") @classmethod def validate_visibility(cls, value: str) -> str: if value not in NOTE_VISIBILITIES: raise ValueError("Invalid note visibility") return value class ReadingNoteUpdate(BaseModel): title: str | None = None content: str | None = None page_ref: str | None = None visibility: str | None = None @field_validator("visibility") @classmethod def validate_visibility(cls, value: str | None) -> str | None: if value is not None and value not in NOTE_VISIBILITIES: raise ValueError("Invalid note visibility") return value class ReadingNoteOut(BaseModel): id: int book_id: int book_title: str book_author: str | None author_id: int author_name: str title: str content: str page_ref: str | None visibility: str created_at: datetime updated_at: datetime class ReadingSummary(BaseModel): reading_count: int finished_count: int total_pages_read: int month_score: int class ReadingRankingItem(BaseModel): user_id: int user_name: str score: int pages_read: int finished_books: int public_notes: int private_notes: int class ReadingRankingResponse(BaseModel): period: str items: list[ReadingRankingItem] class ReadingFeedItem(BaseModel): id: str type: str class_id: int user_id: int user_name: str book_id: int book_title: str book_author: str | None book_cover_url: str | None status: str current_page: int total_pages: int progress: int note_id: int | None = None note_title: str | None = None note_excerpt: str | None = None page_ref: str | None = None created_at: datetime