from pydantic import BaseModel, Field class CreateAssetRequest(BaseModel): project_id: str = Field(..., min_length=1) library_id: str = Field(..., min_length=1) name: str = Field(..., min_length=1, max_length=100) storage_key: str = Field(..., min_length=1, max_length=255) mime_type: str = Field(..., min_length=1, max_length=100) metadata: dict[str, object] = Field(default_factory=dict) file_size: int = Field(default=0, ge=0) thumbnail_url: str | None = None duration: float | None = Field(default=None, ge=0) width: int | None = Field(default=None, ge=0) height: int | None = Field(default=None, ge=0) fps: float | None = Field(default=None, ge=0) codec: str | None = None status: str = Field(default="uploading") classification_status: str = Field(default="pending") quality_score: float | None = Field(default=None, ge=0, le=100) uploaded_by_user_id: str = Field(default="", max_length=100) class UpdateAssetReviewRequest(BaseModel): review_status: str = Field(..., pattern="^(pending_review|approved|rejected)$") class UpdateAssetRequest(BaseModel): name: str | None = Field(default=None, min_length=1, max_length=100) metadata: dict[str, object] | None = None tags: list[str] | None = None class AssetResponse(BaseModel): id: str project_id: str library_id: str name: str storage_key: str mime_type: str metadata: dict[str, object] file_size: int file_url: str | None = None thumbnail_url: str | None = None duration: float | None = None width: int | None = None height: int | None = None fps: float | None = None codec: str | None = None status: str classification_status: str quality_score: float | None = None uploaded_by_user_id: str tag_ids: list[str] = Field(default_factory=list) class BatchDeleteRequest(BaseModel): """批量删除请求。""" ids: list[str] = Field(..., min_length=1, max_length=100, description="要删除的素材 ID 列表") class BatchDeleteResponse(BaseModel): """批量删除响应。""" deleted_count: int = Field(..., ge=0, description="实际删除数量") failed_ids: list[str] = Field(default_factory=list, description="删除失败的 ID 列表") class ListAssetsResponse(BaseModel): items: list[AssetResponse] total: int = Field(default=0, ge=0) skip: int = Field(default=0, ge=0) limit: int = Field(default=100, ge=1)