TorbatYar/backend/services/beauty_business/app/schemas/foundation.py
Mortezakoohjani d579d0b142 feat(loyalty): add Loyalty Platform Frontend module
Add frontend/modules/loyalty with types, API client, design system, feature pages and thin App Router routes under app/loyalty/. BFF proxy at app/api/loyalty/. Include loyalty frontend docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 10:50:55 +03:30

302 lines
8.6 KiB
Python

"""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