"""Job API schemas — Phase 8 任务 2.10.""" from __future__ import annotations from datetime import datetime from typing import Any, Optional from pydantic import BaseModel, Field class CreateJobRequest(BaseModel): """创建任务请求体。""" project_id: str = Field(..., min_length=1, description="项目 ID") job_type: str = Field( ..., description="任务类型: video_compose / render_edit_plan / asset_ingest / classification / voice_extraction / generation", ) payload: dict[str, Any] = Field(default_factory=dict, description="任务输入参数") source_id: str = Field(default="", description="关联的业务实体 ID(如 edit_plan_id)") max_retries: int = Field(default=3, ge=0, le=10, description="最大重试次数") class UpdateProgressRequest(BaseModel): """更新任务进度请求体。""" progress: float = Field(..., ge=0.0, le=100.0, description="进度百分比") current_stage: str = Field(default="", description="当前阶段描述") class CompleteJobRequest(BaseModel): """完成任务请求体。""" result: dict[str, Any] = Field(default_factory=dict, description="任务结果") class FailJobRequest(BaseModel): """标记任务失败请求体。""" error_message: str = Field(..., min_length=1, description="错误信息") class JobResponse(BaseModel): """任务响应体。""" id: str project_id: str job_type: str status: str progress: float current_stage: str payload: dict[str, Any] result: dict[str, Any] error_message: str retry_count: int max_retries: int celery_task_id: str source_id: str created_by_user_id: str is_retryable: bool started_at: Optional[datetime] = None completed_at: Optional[datetime] = None created_at: datetime updated_at: datetime model_config = {"from_attributes": True} class ListJobsResponse(BaseModel): """任务列表响应体。""" items: list[JobResponse] total: int class JobStatisticsResponse(BaseModel): """任务统计响应体。""" project_id: str total: int pending: int running: int success: int failed: int def job_to_response(job) -> JobResponse: """将 Job 领域对象转换为 API 响应。""" return JobResponse( id=job.id, project_id=job.project_id, job_type=job.job_type.value if hasattr(job.job_type, "value") else str(job.job_type), status=job.status.value if hasattr(job.status, "value") else str(job.status), progress=job.progress, current_stage=job.current_stage, payload=job.payload, result=job.result, error_message=job.error_message, retry_count=job.retry_count, max_retries=job.max_retries, celery_task_id=job.celery_task_id, source_id=job.source_id, created_by_user_id=job.created_by_user_id, is_retryable=job.is_retryable, started_at=job.started_at, completed_at=job.completed_at, created_at=job.created_at, updated_at=job.updated_at, )