TorbatYar/backend/services/healthcare/app/schemas/appointments.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

183 lines
4.5 KiB
Python

"""Appointment DTOs — Phase 13.1."""
from __future__ import annotations
from datetime import datetime, time
from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field
from app.models.types import AppointmentStatus, DayOfWeek, LifecycleStatus
from app.schemas.common import ORMBase
_FORBID = ConfigDict(extra="forbid")
class ScheduleCreate(BaseModel):
model_config = _FORBID
clinic_id: UUID
doctor_id: UUID
department_id: UUID | None = None
code: str = Field(max_length=50)
name: str = Field(max_length=255)
day_of_week: DayOfWeek
start_time: time
end_time: time
slot_duration_minutes: int = Field(default=30, ge=5, le=480)
is_active: bool = True
metadata_json: dict | None = None
class ScheduleRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
doctor_id: UUID
department_id: UUID | None
code: str
name: str
day_of_week: DayOfWeek
start_time: time
end_time: time
slot_duration_minutes: int
is_active: bool
metadata_json: dict | None
is_deleted: bool
created_at: datetime
updated_at: datetime
class AvailabilityWindowCreate(BaseModel):
model_config = _FORBID
clinic_id: UUID
doctor_id: UUID
code: str = Field(max_length=50)
starts_at: datetime
ends_at: datetime
is_bookable: bool = True
metadata_json: dict | None = None
class AvailabilityWindowRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
doctor_id: UUID
code: str
starts_at: datetime
ends_at: datetime
is_bookable: bool
metadata_json: dict | None
is_deleted: bool
created_at: datetime
updated_at: datetime
class AppointmentTypeCreate(BaseModel):
model_config = _FORBID
clinic_id: UUID
code: str = Field(max_length=50)
name: str = Field(max_length=255)
description: str | None = None
default_duration_minutes: int = Field(default=30, ge=5, le=480)
status: LifecycleStatus = LifecycleStatus.ACTIVE
class AppointmentTypeRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
code: str
name: str
description: str | None
default_duration_minutes: int
status: LifecycleStatus
is_deleted: bool
created_at: datetime
updated_at: datetime
class AppointmentCreate(BaseModel):
model_config = _FORBID
clinic_id: UUID
doctor_id: UUID
patient_id: UUID
department_id: UUID | None = None
appointment_type_id: UUID | None = None
code: str = Field(max_length=50)
scheduled_start: datetime
scheduled_end: datetime
notes: str | None = None
metadata_json: dict | None = None
class AppointmentReschedule(BaseModel):
model_config = _FORBID
scheduled_start: datetime
scheduled_end: datetime
version: int = Field(ge=1)
reason: str | None = Field(default=None, max_length=500)
class AppointmentLifecycleRequest(BaseModel):
model_config = _FORBID
version: int = Field(ge=1)
reason: str | None = Field(default=None, max_length=500)
class AppointmentRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
doctor_id: UUID
patient_id: UUID
department_id: UUID | None
appointment_type_id: UUID | None
code: str
status: AppointmentStatus
scheduled_start: datetime
scheduled_end: datetime
notes: str | None
status_reason: str | None
status_changed_at: datetime | None
reminder_scheduled: bool
metadata_json: dict | None
version: int
is_deleted: bool
created_at: datetime
updated_at: datetime
class AppointmentListResponse(BaseModel):
items: list[AppointmentRead]
total: int
page: int
page_size: int
class WaitingListEntryCreate(BaseModel):
model_config = _FORBID
clinic_id: UUID
doctor_id: UUID | None = None
patient_id: UUID
appointment_type_id: UUID | None = None
code: str = Field(max_length=50)
preferred_date: str | None = Field(default=None, max_length=32)
notes: str | None = None
priority: int = Field(default=100, ge=1, le=1000)
class WaitingListEntryRead(ORMBase):
id: UUID
tenant_id: UUID
clinic_id: UUID
doctor_id: UUID | None
patient_id: UUID
appointment_type_id: UUID | None
code: str
preferred_date: str | None
notes: str | None
priority: int
is_deleted: bool
created_at: datetime
updated_at: datetime