Phase 3: Appointment model & booking API with timezone fix

This commit is contained in:
counterweight 2025-12-21 00:03:34 +01:00
parent f6cf093cb1
commit 06817875f7
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
9 changed files with 946 additions and 9 deletions

View file

@ -183,6 +183,51 @@ class CopyAvailabilityRequest(BaseModel):
target_dates: list[date]
# =============================================================================
# Booking Schemas
# =============================================================================
class BookableSlot(BaseModel):
"""A bookable 15-minute slot."""
start_time: datetime
end_time: datetime
class AvailableSlotsResponse(BaseModel):
"""Response for available slots on a given date."""
date: date
slots: list[BookableSlot]
class BookingRequest(BaseModel):
"""Request to book an appointment."""
slot_start: datetime
note: str | None = None
@field_validator("note")
@classmethod
def validate_note_length(cls, v: str | None) -> str | None:
if v is not None and len(v) > 144:
raise ValueError("Note must be at most 144 characters")
return v
class AppointmentResponse(BaseModel):
"""Response model for an appointment."""
id: int
user_id: int
user_email: str
slot_start: datetime
slot_end: datetime
note: str | None
status: str
created_at: datetime
cancelled_at: datetime | None
PaginatedAppointments = PaginatedResponse[AppointmentResponse]
# =============================================================================
# Meta/Constants Schemas
# =============================================================================