TorbatYar/backend/services/healthcare/app/schemas/foundation.py
Mortezakoohjani 625275e55b feat(healthcare): add backend service and finalize frontend build
Add the Healthcare platform backend (phases 13.0–13.7) with Alembic migration revision fix, production deploy script, validation reports, shared UI exports, and loyalty list page client directives so Next.js build succeeds.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 11:38:31 +03:30

285 lines
7.9 KiB
Python

"""Healthcare foundation DTOs — Phase 13.0."""
from __future__ import annotations
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field
from app.models.types import LifecycleStatus, ProviderKind, ProviderStatus
from app.schemas.common import ORMBase
_FORBID = ConfigDict(extra="forbid")
class ClinicCreate(BaseModel):
model_config = _FORBID
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
status: LifecycleStatus = LifecycleStatus.DRAFT
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 ClinicUpdate(BaseModel):
model_config = _FORBID
name: str | None = Field(default=None, max_length=255)
description: str | None = None
status: LifecycleStatus | 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 ClinicRead(ORMBase):
id: UUID
tenant_id: UUID
code: str
name: str
description: str | None
status: LifecycleStatus
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):
model_config = _FORBID
clinic_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):
model_config = _FORBID
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
clinic_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 DepartmentCreate(BaseModel):
model_config = _FORBID
clinic_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
specialty: str | None = Field(default=None, max_length=100)
metadata_json: dict | None = None
class DepartmentUpdate(BaseModel):
model_config = _FORBID
branch_id: UUID | None = None
name: str | None = Field(default=None, max_length=255)
description: str | None = None
status: LifecycleStatus | None = None
specialty: str | None = Field(default=None, max_length=100)
metadata_json: dict | None = None
class DepartmentRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
branch_id: UUID | None
code: str
name: str
description: str | None
status: LifecycleStatus
specialty: str | 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
clinic_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
clinic_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 HealthcareConfigurationCreate(BaseModel):
model_config = _FORBID
clinic_id: UUID
branch_id: UUID | None = None
code: str = Field(max_length=50)
working_hours: dict | None = None
clinical_policies: dict | None = None
privacy_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 HealthcareConfigurationUpdate(BaseModel):
model_config = _FORBID
branch_id: UUID | None = None
working_hours: dict | None = None
clinical_policies: dict | None = None
privacy_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 HealthcareConfigurationRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
branch_id: UUID | None
code: str
working_hours: dict | None
clinical_policies: dict | None
privacy_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 HealthcareSettingUpsert(BaseModel):
model_config = _FORBID
clinic_id: UUID | None = None
branch_id: UUID | None = None
key: str = Field(max_length=100)
value: dict | None = None
description: str | None = None
class HealthcareSettingRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_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 HealthcareAuditLogRead(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