"""Formal acquisition domain objects. These models describe the cloud pipeline state used by the formal PostgreSQL repository layer. """ from __future__ import annotations from datetime import datetime from typing import Any, Literal from uuid import UUID from pydantic import BaseModel, ConfigDict, Field JsonDict = dict[str, Any] Platform = Literal["xiaohongshu", "weixin", "douyin"] ContentMode = Literal["image_post", "video_post", "article", "unsupported"] AcquisitionStatus = Literal[ "draft", "pending", "running", "candidate", "classified", "done", "failed", "testing", ] class DomainModel(BaseModel): model_config = ConfigDict(extra="forbid") class QueryBatch(DomainModel): id: UUID | None = None name: str source_type: str = "manual" generation_method: str | None = None target_platforms: list[str] = Field(default_factory=list) status: str = "draft" metadata: JsonDict = Field(default_factory=dict) error_message: str | None = None created_at: datetime | None = None updated_at: datetime | None = None class Query(DomainModel): id: UUID | None = None batch_id: UUID | None = None query_text: str axes: JsonDict = Field(default_factory=dict) keep: bool | None = None filter_reason: str | None = None status: str = "draft" sort_order: int = 0 metadata: JsonDict = Field(default_factory=dict) error_message: str | None = None created_at: datetime | None = None updated_at: datetime | None = None class AcquisitionRun(DomainModel): id: UUID | None = None batch_id: UUID | None = None run_key: str | None = None status: str = "pending" note: str | None = None metadata: JsonDict = Field(default_factory=dict) error_message: str | None = None started_at: datetime | None = None finished_at: datetime | None = None created_at: datetime | None = None updated_at: datetime | None = None class AcquisitionJob(DomainModel): id: UUID | None = None run_id: UUID query_id: UUID | None = None platform: str status: str = "pending" search_limit: int | None = None display_limit: int | None = None attempt_count: int = 0 metadata: JsonDict = Field(default_factory=dict) error_message: str | None = None started_at: datetime | None = None finished_at: datetime | None = None created_at: datetime | None = None updated_at: datetime | None = None class CandidateItem(DomainModel): id: UUID | None = None job_id: UUID | None = None query_id: UUID | None = None platform: str platform_item_id: str | None = None unique_key: str | None = None canonical_url: str | None = None content_type: str | None = None content_mode: ContentMode | None = None title: str | None = None author_name: str | None = None published_at: datetime | None = None body_text: str | None = None raw_summary: str | None = None status: str = "candidate" source_payload: JsonDict = Field(default_factory=dict) metadata: JsonDict = Field(default_factory=dict) error_message: str | None = None created_at: datetime | None = None updated_at: datetime | None = None class MediaAsset(DomainModel): id: UUID | None = None item_id: UUID media_type: str source_url: str | None = None oss_url: str | None = None cdn_url: str | None = None position: int = 0 status: str = "pending" source_payload: JsonDict = Field(default_factory=dict) metadata: JsonDict = Field(default_factory=dict) error_message: str | None = None created_at: datetime | None = None updated_at: datetime | None = None class ItemClassification(DomainModel): id: UUID | None = None item_id: UUID is_creation_knowledge: bool | None = None label: str | None = None confidence: float | None = None reason: str | None = None model_name: str | None = None prompt_version: str | None = None result_payload: JsonDict = Field(default_factory=dict) status: str = "pending" error_message: str | None = None created_at: datetime | None = None updated_at: datetime | None = None