from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime, timezone from enum import StrEnum from uuid import uuid4 class GenerationTaskStatus(StrEnum): PENDING = "pending" RUNNING = "running" COMPLETED = "completed" FAILED = "failed" CANCELLED = "cancelled" @dataclass(slots=True) class GenerationTask: id: str workspace_id: str project_id: str asset_library_id: str strategy_id: str = "" voice_library_id: str = "" edit_plan_id: str = "" status: GenerationTaskStatus = GenerationTaskStatus.PENDING progress: float = 0.0 result_count: int = 0 error_message: str = "" started_at: datetime | None = None completed_at: datetime | None = None created_by_user_id: str = "" created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) @classmethod def create( cls, workspace_id: str, project_id: str, asset_library_id: str, *, strategy_id: str = "", voice_library_id: str = "", edit_plan_id: str = "", created_by_user_id: str = "", ) -> "GenerationTask": if not workspace_id.strip(): raise ValueError("workspace_id 不能为空") if not project_id.strip(): raise ValueError("project_id 不能为空") if not asset_library_id.strip(): raise ValueError("asset_library_id 不能为空") return cls( id=uuid4().hex, workspace_id=workspace_id.strip(), project_id=project_id.strip(), asset_library_id=asset_library_id.strip(), strategy_id=strategy_id.strip(), voice_library_id=voice_library_id.strip(), edit_plan_id=edit_plan_id.strip(), created_by_user_id=created_by_user_id.strip(), )