"""Component library DTOs — Phase 11.2.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field from app.models.types import ComponentKind, ComponentStatus, ComponentVersionStatus from app.schemas.common import ORMBase _FORBID = ConfigDict(extra="forbid") class ExperienceComponentCreate(BaseModel): model_config = _FORBID workspace_id: UUID code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None kind: ComponentKind = ComponentKind.CONTENT status: ComponentStatus = ComponentStatus.DRAFT category: str | None = Field(default=None, max_length=100) tags: list[str] | None = None metadata_json: dict | None = None class ExperienceComponentUpdate(BaseModel): model_config = _FORBID name: str | None = Field(default=None, max_length=255) description: str | None = None kind: ComponentKind | None = None status: ComponentStatus | None = None category: str | None = Field(default=None, max_length=100) tags: list[str] | None = None metadata_json: dict | None = None version: int = Field(ge=1) class ExperienceComponentRead(ORMBase): id: UUID tenant_id: UUID workspace_id: UUID code: str name: str description: str | None kind: ComponentKind status: ComponentStatus category: str | None tags: list | None latest_version_number: int published_version_id: UUID | None is_system: bool metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class ExperienceComponentVersionCreate(BaseModel): model_config = _FORBID workspace_id: UUID component_id: UUID definition_schema: dict | None = None props_defaults: dict | None = None render_hint: dict | None = None changelog: str | None = None metadata_json: dict | None = None class ExperienceComponentVersionUpdate(BaseModel): model_config = _FORBID definition_schema: dict | None = None props_defaults: dict | None = None render_hint: dict | None = None changelog: str | None = None metadata_json: dict | None = None version: int = Field(ge=1) class ExperienceComponentVersionRead(ORMBase): id: UUID tenant_id: UUID workspace_id: UUID component_id: UUID version_number: int status: ComponentVersionStatus definition_schema: dict | None props_defaults: dict | None render_hint: dict | None changelog: str | None is_immutable: bool published_at: datetime | None retired_at: datetime | None metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class PageComponentPlacementCreate(BaseModel): model_config = _FORBID workspace_id: UUID site_id: UUID page_id: UUID component_id: UUID component_version_id: UUID slot_key: str = Field(max_length=100) sort_order: int = Field(default=0, ge=0) props_override: dict | None = None is_visible: bool = True metadata_json: dict | None = None class PageComponentPlacementUpdate(BaseModel): model_config = _FORBID component_version_id: UUID | None = None slot_key: str | None = Field(default=None, max_length=100) sort_order: int | None = Field(default=None, ge=0) props_override: dict | None = None is_visible: bool | None = None metadata_json: dict | None = None version: int = Field(ge=1) class PageComponentPlacementRead(ORMBase): id: UUID tenant_id: UUID workspace_id: UUID site_id: UUID page_id: UUID component_id: UUID component_version_id: UUID slot_key: str sort_order: int props_override: dict | None is_visible: bool metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class ExperienceComponentListResponse(BaseModel): items: list[ExperienceComponentRead] total: int page: int page_size: int class ExperienceComponentVersionListResponse(BaseModel): items: list[ExperienceComponentVersionRead] total: int page: int page_size: int class PageComponentPlacementListResponse(BaseModel): items: list[PageComponentPlacementRead] total: int page: int page_size: int