"""文件接口 DTO。""" from __future__ import annotations from datetime import datetime from pydantic import BaseModel, Field class UploadedFileOut(BaseModel): id: int storage_path: str original_filename: str content_type: str size_bytes: int sha256: str source: str uploaded_by: str uploaded_at: datetime model_config = {"from_attributes": True} class FileUploadResponse(BaseModel): id: int = Field(..., description="新写入的数据库行 ID") filename: str = Field(..., description="客户端原始文件名") size_bytes: int sha256: str storage_path: str uploaded_at: datetime deduplicated: bool = Field( False, description="true=服务端已有同 sha256 文件,直接返回旧行,未重复落盘" ) class FileListResponse(BaseModel): total: int items: list[UploadedFileOut] class PdfJobBrief(BaseModel): """文件关联到的 PDF 转换任务摘要(供合并管理页展示)。 一个 uploaded_file 可能同时被多个 job 引用(罕见),故为列表; 通常每行 0 或 1 条。 """ job_id: int role: str = Field(..., description='"source"=该文件是 epub 源文件;"output"=该文件是产物 PDF') status: str = Field(..., description="pending / converting / done / failed") progress: int = Field(0, description="转换进度 0-100") user_deleted: bool = Field(False, description="用户是否已软删该任务") deleted_at: datetime | None = Field(None, description="用户软删时间") class UploadedFileWithPdfOut(UploadedFileOut): """带 PDF 任务关联信息的文件视图(合并管理页用)。""" pdf_jobs: list[PdfJobBrief] = Field(default_factory=list, description="关联到的 PDF 转换任务") class FileWithPdfListResponse(BaseModel): """合并管理页列表响应:以 uploaded_files 为基础,附带 pdf_jobs 关联。""" total: int items: list[UploadedFileWithPdfOut]