"""Beauty Business foundation DTOs — Phase 14.0.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field from app.models.types import ( BusinessFormat, LifecycleStatus, ProviderKind, ProviderStatus, BookingEngineStatus, ) from app.schemas.common import ORMBase _FORBID = ConfigDict(extra="forbid") class BeautyOrganizationCreate(BaseModel): model_config = _FORBID code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.DRAFT business_format: BusinessFormat = BusinessFormat.SALON legal_name: str | None = Field(default=None, max_length=255) timezone: str = Field(default="Asia/Tehran", max_length=64) language: str = Field(default="fa", max_length=16) currency_code: str = Field(default="IRR", max_length=3) settings: dict | None = None class BeautyOrganizationUpdate(BaseModel): model_config = _FORBID name: str | None = Field(default=None, max_length=255) description: str | None = None status: LifecycleStatus | None = None business_format: BusinessFormat | None = None legal_name: str | None = Field(default=None, max_length=255) timezone: str | None = Field(default=None, max_length=64) language: str | None = Field(default=None, max_length=16) currency_code: str | None = Field(default=None, max_length=3) settings: dict | None = None version: int = Field(ge=1) class BeautyOrganizationRead(ORMBase): id: UUID tenant_id: UUID code: str name: str description: str | None status: LifecycleStatus business_format: BusinessFormat legal_name: str | None timezone: str language: str currency_code: str settings: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BeautyBranchCreate(BaseModel): model_config = _FORBID organization_id: UUID code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE business_format: BusinessFormat | None = None address: dict | None = None timezone: str | None = Field(default=None, max_length=64) working_hours: dict | None = None metadata_json: dict | None = None class BeautyBranchUpdate(BaseModel): model_config = _FORBID name: str | None = Field(default=None, max_length=255) description: str | None = None status: LifecycleStatus | None = None business_format: BusinessFormat | None = None address: dict | None = None timezone: str | None = Field(default=None, max_length=64) working_hours: dict | None = None metadata_json: dict | None = None class BeautyBranchRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID code: str name: str description: str | None status: LifecycleStatus business_format: BusinessFormat | None address: dict | None timezone: str | None working_hours: dict | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class ExternalProviderConfigCreate(BaseModel): model_config = _FORBID organization_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) provider_kind: ProviderKind = ProviderKind.CUSTOM adapter_key: str = Field(max_length=100) status: ProviderStatus = ProviderStatus.REGISTERED priority: int = Field(default=100, ge=0) credentials_ref: str | None = Field(default=None, max_length=255) config: dict | None = None capabilities: dict | None = None class ExternalProviderConfigUpdate(BaseModel): model_config = _FORBID name: str | None = Field(default=None, max_length=255) provider_kind: ProviderKind | None = None adapter_key: str | None = Field(default=None, max_length=100) status: ProviderStatus | None = None priority: int | None = Field(default=None, ge=0) credentials_ref: str | None = Field(default=None, max_length=255) config: dict | None = None capabilities: dict | None = None version: int = Field(ge=1) class ExternalProviderConfigRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID | None code: str name: str provider_kind: ProviderKind adapter_key: str status: ProviderStatus priority: int credentials_ref: str | None config: dict | None capabilities: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BookingEngineRegistrationCreate(BaseModel): model_config = _FORBID organization_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) adapter_key: str = Field(max_length=100) status: BookingEngineStatus = BookingEngineStatus.REGISTERED is_default: bool = False config: dict | None = None capabilities: dict | None = None class BookingEngineRegistrationUpdate(BaseModel): model_config = _FORBID name: str | None = Field(default=None, max_length=255) adapter_key: str | None = Field(default=None, max_length=100) status: BookingEngineStatus | None = None is_default: bool | None = None config: dict | None = None capabilities: dict | None = None version: int = Field(ge=1) class BookingEngineRegistrationRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID | None code: str name: str adapter_key: str status: BookingEngineStatus is_default: bool config: dict | None capabilities: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BeautyConfigurationCreate(BaseModel): model_config = _FORBID organization_id: UUID branch_id: UUID | None = None code: str = Field(max_length=50) working_hours: dict | None = None booking_policies: dict | None = None cancellation_policies: dict | None = None reminder_policies: dict | None = None custom_fields: dict | None = None timezone: str = Field(default="Asia/Tehran", max_length=64) language: str = Field(default="fa", max_length=16) currency_code: str = Field(default="IRR", max_length=3) class BeautyConfigurationUpdate(BaseModel): model_config = _FORBID branch_id: UUID | None = None working_hours: dict | None = None booking_policies: dict | None = None cancellation_policies: dict | None = None reminder_policies: dict | None = None custom_fields: dict | None = None timezone: str | None = Field(default=None, max_length=64) language: str | None = Field(default=None, max_length=16) currency_code: str | None = Field(default=None, max_length=3) version: int = Field(ge=1) class BeautyConfigurationRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID branch_id: UUID | None code: str working_hours: dict | None booking_policies: dict | None cancellation_policies: dict | None reminder_policies: dict | None custom_fields: dict | None timezone: str language: str currency_code: str version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BeautySettingUpsert(BaseModel): model_config = _FORBID organization_id: UUID | None = None branch_id: UUID | None = None key: str = Field(max_length=100) value: dict | None = None description: str | None = None class BeautySettingRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID | None branch_id: UUID | None key: str value: dict | None description: str | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BeautyAuditLogRead(ORMBase): id: UUID tenant_id: UUID entity_type: str entity_id: UUID action: str actor_user_id: str | None changes: dict | None message: str | None created_at: datetime