""" In-memory data store for the Veterinary Clinic example. This module is NOT thread-safe and is intended for demos and scaffolds only. It provides minimal, process-local data stores for the five veterinary clinic entities. Each store exposes standard CRUD operations backed by a simple dictionary. This module intentionally avoids: - persistence - concurrency guarantees - transactional semantics - validation beyond what Pydantic provides This module is not part of the ``openapi_first`` library API surface. """ from datetime import date, datetime, timezone from models import ( Parent, ParentCreate, Vet, VetCreate, Treatment, TreatmentCreate, Pet, PetCreate, Appointment, AppointmentCreate, ) def _now(): return datetime.now(timezone.utc).isoformat() # --------------------------------------------------------------------------- # Parents # --------------------------------------------------------------------------- _parents: dict[int, Parent] = {} _parents_next_id = 1 def list_parents() -> list[Parent]: return list(_parents.values()) def get_parent(parent_id: int) -> Parent: return _parents[parent_id] def create_parent(payload: ParentCreate) -> Parent: global _parents_next_id now = _now() parent = Parent( id=_parents_next_id, name=payload.name, email=payload.email, phone=payload.phone, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, ) _parents[_parents_next_id] = parent _parents_next_id += 1 return parent def update_parent(parent_id: int, payload: ParentCreate) -> Parent: if parent_id not in _parents: raise KeyError(parent_id) now = _now() current = _parents[parent_id] updated = Parent( id=parent_id, name=payload.name, email=payload.email, phone=payload.phone if payload.phone is not None else current.phone, metadata={"createdOn": current.metadata["createdOn"] if current.metadata else None, "updatedOn": now}, ) _parents[parent_id] = updated return updated def delete_parent(parent_id: int) -> None: del _parents[parent_id] # --------------------------------------------------------------------------- # Vets # --------------------------------------------------------------------------- _vets: dict[int, Vet] = {} _vets_next_id = 1 def list_vets() -> list[Vet]: return list(_vets.values()) def get_vet(vet_id: int) -> Vet: return _vets[vet_id] def create_vet(payload: VetCreate) -> Vet: global _vets_next_id now = _now() vet = Vet( id=_vets_next_id, name=payload.name, specialty=payload.specialty, email=payload.email, phone=payload.phone, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, ) _vets[_vets_next_id] = vet _vets_next_id += 1 return vet def update_vet(vet_id: int, payload: VetCreate) -> Vet: if vet_id not in _vets: raise KeyError(vet_id) now = _now() current = _vets[vet_id] updated = Vet( id=vet_id, name=payload.name, specialty=payload.specialty if payload.specialty is not None else current.specialty, email=payload.email, phone=payload.phone if payload.phone is not None else current.phone, metadata={"createdOn": current.metadata["createdOn"] if current.metadata else None, "updatedOn": now}, ) _vets[vet_id] = updated return updated def delete_vet(vet_id: int) -> None: del _vets[vet_id] # --------------------------------------------------------------------------- # Treatments # --------------------------------------------------------------------------- _treatments: dict[int, Treatment] = {} _treatments_next_id = 1 def list_treatments() -> list[Treatment]: return list(_treatments.values()) def get_treatment(treatment_id: int) -> Treatment: return _treatments[treatment_id] def create_treatment(payload: TreatmentCreate) -> Treatment: global _treatments_next_id now = _now() treatment = Treatment( id=_treatments_next_id, label=payload.label, description=payload.description, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, ) _treatments[_treatments_next_id] = treatment _treatments_next_id += 1 return treatment def update_treatment(treatment_id: int, payload: TreatmentCreate) -> Treatment: if treatment_id not in _treatments: raise KeyError(treatment_id) now = _now() current = _treatments[treatment_id] updated = Treatment( id=treatment_id, label=payload.label, description=payload.description if payload.description is not None else current.description, metadata={"createdOn": current.metadata["createdOn"] if current.metadata else None, "updatedOn": now}, ) _treatments[treatment_id] = updated return updated def delete_treatment(treatment_id: int) -> None: del _treatments[treatment_id] # --------------------------------------------------------------------------- # Pets # --------------------------------------------------------------------------- _pets: dict[int, Pet] = {} _pets_next_id = 1 def list_pets() -> list[Pet]: return list(_pets.values()) def get_pet(pet_id: int) -> Pet: return _pets[pet_id] def create_pet(payload: PetCreate) -> Pet: global _pets_next_id now = _now() parents = [_parents[pid] for pid in payload.parent_ids] pet = Pet( id=_pets_next_id, name=payload.name, species=payload.species, age=payload.age, weight=payload.weight, birthDate=payload.birthDate, photo=payload.photo, parents=parents, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, ) _pets[_pets_next_id] = pet _pets_next_id += 1 return pet def update_pet(pet_id: int, payload: PetCreate) -> Pet: if pet_id not in _pets: raise KeyError(pet_id) now = _now() parents = [_parents[pid] for pid in payload.parent_ids] current = _pets[pet_id] updated = Pet( id=pet_id, name=payload.name, species=payload.species, age=payload.age if payload.age is not None else current.age, weight=payload.weight if payload.weight is not None else current.weight, birthDate=payload.birthDate if payload.birthDate is not None else current.birthDate, photo=payload.photo if payload.photo is not None else current.photo, parents=parents, metadata={"createdOn": current.metadata["createdOn"] if current.metadata else None, "updatedOn": now}, ) _pets[pet_id] = updated return updated def delete_pet(pet_id: int) -> None: del _pets[pet_id] # --------------------------------------------------------------------------- # Appointments # --------------------------------------------------------------------------- _appointments: dict[int, Appointment] = {} _appointments_next_id = 1 def list_appointments() -> list[Appointment]: return list(_appointments.values()) def get_appointment(appointment_id: int) -> Appointment: return _appointments[appointment_id] def create_appointment(payload: AppointmentCreate) -> Appointment: global _appointments_next_id now = _now() appointment = Appointment( id=_appointments_next_id, date=payload.date, notes=payload.notes, pet=_pets[payload.pet_id], vet=_vets[payload.vet_id], treatment=_treatments[payload.treatment_id], metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, ) _appointments[_appointments_next_id] = appointment _appointments_next_id += 1 return appointment def update_appointment(appointment_id: int, payload: AppointmentCreate) -> Appointment: if appointment_id not in _appointments: raise KeyError(appointment_id) now = _now() current = _appointments[appointment_id] updated = Appointment( id=appointment_id, date=payload.date, notes=payload.notes if payload.notes is not None else current.notes, pet=_pets.get(payload.pet_id, current.pet), vet=_vets.get(payload.vet_id, current.vet), treatment=_treatments.get(payload.treatment_id, current.treatment), metadata={"createdOn": current.metadata["createdOn"] if current.metadata else None, "updatedOn": now}, ) _appointments[appointment_id] = updated return updated def delete_appointment(appointment_id: int) -> None: del _appointments[appointment_id] # --------------------------------------------------------------------------- # Seed data — populate stores so the UI isn't empty on startup # --------------------------------------------------------------------------- def _seed_data(): now = _now() meta = {"createdOn": now, "updatedOn": now} global _parents_next_id, _vets_next_id, _treatments_next_id global _pets_next_id, _appointments_next_id _parents[1] = Parent(id=1, name="Alice Johnson", email="alice@example.com", phone="555-0101", metadata=meta) _parents[2] = Parent(id=2, name="Bob Smith", email="bob@example.com", phone="555-0102", metadata=meta) _parents[3] = Parent(id=3, name="Carol Williams", email="carol@example.com", phone="555-0103", metadata=meta) _parents[4] = Parent(id=4, name="Dave Brown", email="dave@example.com", phone="555-0104", metadata=meta) _parents_next_id = 5 _vets[1] = Vet(id=1, name="Sarah Connor", specialty="Surgery", email="sarah@clinic.com", phone="555-0201", metadata=meta) _vets[2] = Vet(id=2, name="James Wilson", specialty="Dentistry", email="james@clinic.com", phone="555-0202", metadata=meta) _vets[3] = Vet(id=3, name="Emily Davis", specialty="General Practice", email="emily@clinic.com", phone="555-0203", metadata=meta) _vets_next_id = 4 _treatments[1] = Treatment(id=1, label="Annual Checkup", description="Full physical examination", metadata=meta) _treatments[2] = Treatment(id=2, label="Vaccination", description="Core vaccines for common diseases", metadata=meta) _treatments[3] = Treatment(id=3, label="Dental Cleaning", description="Scaling, polishing, and oral exam", metadata=meta) _treatments[4] = Treatment(id=4, label="Spay/Neuter", description="Surgical sterilization", metadata=meta) _treatments[5] = Treatment(id=5, label="Blood Panel", description="Complete blood count and chemistry", metadata=meta) _treatments_next_id = 6 _pets[1] = Pet(id=1, name="Max", species="dog", age=4, weight=25.5, birthDate=date(2022, 3, 15), parents=[_parents[1]], metadata=meta) _pets[2] = Pet(id=2, name="Luna", species="cat", age=2, weight=4.2, birthDate=date(2024, 1, 10), parents=[_parents[1], _parents[2]], metadata=meta) _pets[3] = Pet(id=3, name="Charlie", species="dog", age=7, weight=18.0, birthDate=date(2019, 8, 22), parents=[_parents[2]], metadata=meta) _pets[4] = Pet(id=4, name="Bella", species="bird", age=1, weight=0.3, birthDate=date(2025, 5, 1), parents=[_parents[3]], metadata=meta) _pets[5] = Pet(id=5, name="Rocky", species="dog", age=3, weight=30.0, birthDate=date(2023, 11, 5), parents=[_parents[4]], metadata=meta) _pets_next_id = 6 _appointments[1] = Appointment(id=1, date=datetime(2026, 6, 18, 9, 0, tzinfo=timezone.utc), notes="Annual checkup", pet=_pets[1], vet=_vets[1], treatment=_treatments[1], metadata=meta) _appointments[2] = Appointment(id=2, date=datetime(2026, 6, 18, 10, 30, tzinfo=timezone.utc), notes="Dental cleaning", pet=_pets[2], vet=_vets[2], treatment=_treatments[3], metadata=meta) _appointments[3] = Appointment(id=3, date=datetime(2026, 6, 19, 11, 0, tzinfo=timezone.utc), notes="Vaccination booster", pet=_pets[3], vet=_vets[3], treatment=_treatments[2], metadata=meta) _appointments[4] = Appointment(id=4, date=datetime(2026, 6, 20, 14, 0, tzinfo=timezone.utc), notes="Follow-up after surgery", pet=_pets[5], vet=_vets[1], treatment=_treatments[4], metadata=meta) _appointments_next_id = 5 _seed_data()