TorbatYar/backend/services/hospitality/app/schemas/foundation.py
Mortezakoohjani 5c6a2e78cf feat(platform): seed service registry, deploy all modules, and fix homepage catalog.
Register all active platform services and base features in core DB so admin can manage them, add delivery/hospitality/sports-center backend phases, update apps catalog and production deploy tooling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 12:39:51 +03:30

484 lines
12 KiB
Python

"""Hospitality foundation DTOs — Phase 12.0."""
from __future__ import annotations
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, Field
from app.models.types import (
BundleKey,
BundleStatus,
LifecycleStatus,
MenuStatus,
TableStatus,
VenueFormat,
)
from app.schemas.common import ORMBase
class VenueCreate(BaseModel):
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.DRAFT
venue_format: VenueFormat = VenueFormat.RESTAURANT
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 VenueUpdate(BaseModel):
name: str | None = Field(default=None, max_length=255)
description: str | None = None
status: LifecycleStatus | None = None
venue_format: VenueFormat | 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 | None = None
class VenueRead(ORMBase):
id: UUID
tenant_id: UUID
code: str
name: str
description: str | None
status: LifecycleStatus
venue_format: VenueFormat
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 BranchCreate(BaseModel):
venue_id: UUID
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
address: dict | None = None
timezone: str | None = Field(default=None, max_length=64)
working_hours: dict | None = None
metadata_json: dict | None = None
class BranchUpdate(BaseModel):
name: str | None = Field(default=None, max_length=255)
description: str | None = None
status: LifecycleStatus | 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 BranchRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
code: str
name: str
description: str | None
status: LifecycleStatus
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 DiningAreaCreate(BaseModel):
venue_id: UUID
branch_id: UUID | None = None
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
sort_order: int = 0
metadata_json: dict | None = None
class DiningAreaRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
branch_id: UUID | None
code: str
name: str
description: str | None
status: LifecycleStatus
sort_order: int
metadata_json: dict | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class DiningTableCreate(BaseModel):
venue_id: UUID
dining_area_id: UUID | None = None
code: str = Field(max_length=50)
name: str = Field(max_length=255)
capacity: int = 2
status: TableStatus = TableStatus.AVAILABLE
qr_token: str | None = Field(default=None, max_length=100)
metadata_json: dict | None = None
class DiningTableRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
dining_area_id: UUID | None
code: str
name: str
capacity: int
status: TableStatus
qr_token: str | None
metadata_json: dict | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class MenuCreate(BaseModel):
venue_id: UUID
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: MenuStatus = MenuStatus.DRAFT
currency_code: str = Field(default="IRR", max_length=3)
is_default: bool = False
metadata_json: dict | None = None
class MenuUpdate(BaseModel):
name: str | None = Field(default=None, max_length=255)
description: str | None = None
status: MenuStatus | None = None
currency_code: str | None = Field(default=None, max_length=3)
is_default: bool | None = None
metadata_json: dict | None = None
version: int | None = None
class MenuRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
code: str
name: str
description: str | None
status: MenuStatus
currency_code: str
is_default: 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 MenuCategoryCreate(BaseModel):
venue_id: UUID
menu_id: UUID
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
sort_order: int = 0
class MenuCategoryRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
menu_id: UUID
code: str
name: str
description: str | None
status: LifecycleStatus
sort_order: int
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class MenuItemCreate(BaseModel):
venue_id: UUID
menu_id: UUID
category_id: UUID | None = None
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
base_price: int = 0
currency_code: str = Field(default="IRR", max_length=3)
is_available: bool = True
sort_order: int = 0
attributes: dict | None = None
preparation_minutes: int | None = None
calories: int | None = None
spicy_level: int = 0
is_vegetarian: bool = False
is_vegan: bool = False
is_gluten_free: bool = False
tags: list[str] | None = None
primary_media_ref: str | None = Field(default=None, max_length=255)
class MenuItemRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
menu_id: UUID
category_id: UUID | None
code: str
name: str
description: str | None
status: LifecycleStatus
base_price: int
currency_code: str
is_available: bool
sort_order: int
attributes: dict | None
preparation_minutes: int | None
calories: int | None
spicy_level: int
is_vegetarian: bool
is_vegan: bool
is_gluten_free: bool
tags: list | None
primary_media_ref: str | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class BundleDefinitionCreate(BaseModel):
code: str = Field(max_length=50)
bundle_key: BundleKey
name: str = Field(max_length=255)
description: str | None = None
status: BundleStatus = BundleStatus.AVAILABLE
feature_keys: list[str] | None = None
permission_prefixes: list[str] | None = None
api_prefixes: list[str] | None = None
metadata_json: dict | None = None
class BundleDefinitionRead(ORMBase):
id: UUID
tenant_id: UUID
code: str
bundle_key: BundleKey
name: str
description: str | None
status: BundleStatus
feature_keys: list | None
permission_prefixes: list | None
api_prefixes: list | None
metadata_json: dict | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class TenantBundleActivate(BaseModel):
bundle_definition_id: UUID
venue_id: UUID | None = None
metadata_json: dict | None = None
class TenantBundleRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID | None
bundle_definition_id: UUID
bundle_key: BundleKey
status: BundleStatus
activated_by: str | 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 FeatureToggleUpsert(BaseModel):
feature_key: str = Field(max_length=100)
enabled: bool = False
venue_id: UUID | None = None
bundle_key: BundleKey | None = None
metadata_json: dict | None = None
class FeatureToggleRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID | None
feature_key: str
enabled: bool
bundle_key: BundleKey | None
metadata_json: dict | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class HospitalityRoleCreate(BaseModel):
venue_id: UUID | None = None
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
permission_keys: list[str] | None = None
class HospitalityRoleRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID | None
code: str
name: str
description: str | None
status: LifecycleStatus
permission_keys: list | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class HospitalityPermissionCreate(BaseModel):
code: str = Field(max_length=100)
name: str = Field(max_length=255)
description: str | None = None
bundle_key: BundleKey | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
class HospitalityPermissionRead(ORMBase):
id: UUID
tenant_id: UUID
code: str
name: str
description: str | None
bundle_key: BundleKey | None
status: LifecycleStatus
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class HospitalityConfigurationCreate(BaseModel):
venue_id: UUID | None = None
branch_id: UUID | None = None
code: str = Field(max_length=50)
name: str = Field(max_length=255)
config: dict | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
class HospitalityConfigurationUpdate(BaseModel):
name: str | None = Field(default=None, max_length=255)
config: dict | None = None
status: LifecycleStatus | None = None
version: int | None = None
class HospitalityConfigurationRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID | None
branch_id: UUID | None
code: str
name: str
config: dict | None
status: LifecycleStatus
version: int
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class HospitalityEventCreate(BaseModel):
venue_id: UUID
event_type: str = Field(max_length=100)
title: str = Field(max_length=255)
payload: dict | None = None
status: LifecycleStatus = LifecycleStatus.ACTIVE
class HospitalityEventRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID
event_type: str
title: str
payload: dict | None
status: LifecycleStatus
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime
class HospitalitySettingUpsert(BaseModel):
key: str = Field(max_length=100)
value: dict | None = None
venue_id: UUID | None = None
class HospitalitySettingRead(ORMBase):
id: UUID
tenant_id: UUID
venue_id: UUID | None
key: str
value: dict | None
is_deleted: bool
created_by: str | None
updated_by: str | None
created_at: datetime
updated_at: datetime