seed data

This commit is contained in:
2026-06-16 18:15:43 +05:30
parent 808ffa8fed
commit 0f591b666b
4 changed files with 84 additions and 74 deletions

View File

@@ -52,7 +52,9 @@ def create_parent(payload: ParentCreate) -> Parent:
now = _now() now = _now()
parent = Parent( parent = Parent(
id=_parents_next_id, id=_parents_next_id,
**payload.model_dump(exclude={"id", "metadata"}), name=payload.name,
email=payload.email,
phone=payload.phone,
metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None,
) )
_parents[_parents_next_id] = parent _parents[_parents_next_id] = parent
@@ -64,13 +66,13 @@ def update_parent(parent_id: int, payload: ParentCreate) -> Parent:
if parent_id not in _parents: if parent_id not in _parents:
raise KeyError(parent_id) raise KeyError(parent_id)
now = _now() now = _now()
parent = _parents[parent_id] current = _parents[parent_id]
updated = parent.model_copy( updated = Parent(
update={ id=parent_id,
**payload.model_dump(exclude={"id", "metadata"}), name=payload.name,
"metadata": {"createdOn": parent.metadata.get("createdOn", now), "updatedOn": now} email=payload.email,
if parent.metadata else None, 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 _parents[parent_id] = updated
return updated return updated
@@ -101,7 +103,10 @@ def create_vet(payload: VetCreate) -> Vet:
now = _now() now = _now()
vet = Vet( vet = Vet(
id=_vets_next_id, id=_vets_next_id,
**payload.model_dump(exclude={"id", "metadata"}), name=payload.name,
specialty=payload.specialty,
email=payload.email,
phone=payload.phone,
metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None,
) )
_vets[_vets_next_id] = vet _vets[_vets_next_id] = vet
@@ -113,13 +118,14 @@ def update_vet(vet_id: int, payload: VetCreate) -> Vet:
if vet_id not in _vets: if vet_id not in _vets:
raise KeyError(vet_id) raise KeyError(vet_id)
now = _now() now = _now()
vet = _vets[vet_id] current = _vets[vet_id]
updated = vet.model_copy( updated = Vet(
update={ id=vet_id,
**payload.model_dump(exclude={"id", "metadata"}), name=payload.name,
"metadata": {"createdOn": vet.metadata.get("createdOn", now), "updatedOn": now} specialty=payload.specialty if payload.specialty is not None else current.specialty,
if vet.metadata else None, 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 _vets[vet_id] = updated
return updated return updated
@@ -150,7 +156,8 @@ def create_treatment(payload: TreatmentCreate) -> Treatment:
now = _now() now = _now()
treatment = Treatment( treatment = Treatment(
id=_treatments_next_id, id=_treatments_next_id,
**payload.model_dump(exclude={"id", "metadata"}), label=payload.label,
description=payload.description,
metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None,
) )
_treatments[_treatments_next_id] = treatment _treatments[_treatments_next_id] = treatment
@@ -162,13 +169,12 @@ def update_treatment(treatment_id: int, payload: TreatmentCreate) -> Treatment:
if treatment_id not in _treatments: if treatment_id not in _treatments:
raise KeyError(treatment_id) raise KeyError(treatment_id)
now = _now() now = _now()
treatment = _treatments[treatment_id] current = _treatments[treatment_id]
updated = treatment.model_copy( updated = Treatment(
update={ id=treatment_id,
**payload.model_dump(exclude={"id", "metadata"}), label=payload.label,
"metadata": {"createdOn": treatment.metadata.get("createdOn", now), "updatedOn": now} description=payload.description if payload.description is not None else current.description,
if treatment.metadata else None, metadata={"createdOn": current.metadata["createdOn"] if current.metadata else None, "updatedOn": now},
}
) )
_treatments[treatment_id] = updated _treatments[treatment_id] = updated
return updated return updated
@@ -197,9 +203,16 @@ def get_pet(pet_id: int) -> Pet:
def create_pet(payload: PetCreate) -> Pet: def create_pet(payload: PetCreate) -> Pet:
global _pets_next_id global _pets_next_id
now = _now() now = _now()
parents = [_parents[pid] for pid in payload.parent_ids]
pet = Pet( pet = Pet(
id=_pets_next_id, id=_pets_next_id,
**payload.model_dump(exclude={"id", "metadata"}), 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, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None,
) )
_pets[_pets_next_id] = pet _pets[_pets_next_id] = pet
@@ -211,13 +224,18 @@ def update_pet(pet_id: int, payload: PetCreate) -> Pet:
if pet_id not in _pets: if pet_id not in _pets:
raise KeyError(pet_id) raise KeyError(pet_id)
now = _now() now = _now()
pet = _pets[pet_id] parents = [_parents[pid] for pid in payload.parent_ids]
updated = pet.model_copy( current = _pets[pet_id]
update={ updated = Pet(
**payload.model_dump(exclude={"id", "metadata"}), id=pet_id,
"metadata": {"createdOn": pet.metadata.get("createdOn", now), "updatedOn": now} name=payload.name,
if pet.metadata else None, 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 _pets[pet_id] = updated
return updated return updated
@@ -248,7 +266,11 @@ def create_appointment(payload: AppointmentCreate) -> Appointment:
now = _now() now = _now()
appointment = Appointment( appointment = Appointment(
id=_appointments_next_id, id=_appointments_next_id,
**payload.model_dump(exclude={"id", "metadata"}), 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, metadata={"createdOn": now, "updatedOn": now} if payload.metadata else None,
) )
_appointments[_appointments_next_id] = appointment _appointments[_appointments_next_id] = appointment
@@ -260,13 +282,15 @@ def update_appointment(appointment_id: int, payload: AppointmentCreate) -> Appoi
if appointment_id not in _appointments: if appointment_id not in _appointments:
raise KeyError(appointment_id) raise KeyError(appointment_id)
now = _now() now = _now()
appointment = _appointments[appointment_id] current = _appointments[appointment_id]
updated = appointment.model_copy( updated = Appointment(
update={ id=appointment_id,
**payload.model_dump(exclude={"id", "metadata"}), date=payload.date,
"metadata": {"createdOn": appointment.metadata.get("createdOn", now), "updatedOn": now} notes=payload.notes if payload.notes is not None else current.notes,
if appointment.metadata else None, 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 _appointments[appointment_id] = updated
return updated return updated
@@ -304,17 +328,17 @@ def _seed_data():
_treatments[5] = Treatment(id=5, label="Blood Panel", description="Complete blood count and chemistry", metadata=meta) _treatments[5] = Treatment(id=5, label="Blood Panel", description="Complete blood count and chemistry", metadata=meta)
_treatments_next_id = 6 _treatments_next_id = 6
_pets[1] = Pet(id=1, name="Max", species="dog", age=4, weight=25.5, birthDate=date(2022, 3, 15), parent_ids=[1], metadata=meta) _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), parent_ids=[1, 2], 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), parent_ids=[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), parent_ids=[3], 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), parent_ids=[4], 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 _pets_next_id = 6
_appointments[1] = Appointment(id=1, date=datetime(2026, 6, 18, 9, 0, tzinfo=timezone.utc), notes="Annual checkup", pet_id=1, vet_id=1, treatment_id=1, metadata=meta) _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_id=2, vet_id=2, treatment_id=3, 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_id=3, vet_id=3, treatment_id=2, 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_id=5, vet_id=1, treatment_id=4, 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 _appointments_next_id = 5

View File

@@ -1,19 +1,3 @@
"""
Pydantic domain models for the Veterinary Clinic example.
This module defines Pydantic models representing the five domain
entities used by the veterinary clinic service. These models are
referenced by the OpenAPI specification for request and response
schemas.
The models are declarative and framework-agnostic. They contain no
persistence logic, validation beyond type constraints, or business
behavior.
This module is not part of the ``openapi_first`` library API surface.
It exists solely to support the example application template.
"""
from datetime import date, datetime from datetime import date, datetime
from pydantic import BaseModel from pydantic import BaseModel
@@ -75,30 +59,32 @@ class PetBase(BaseModel):
weight: float | None = None weight: float | None = None
birthDate: date | None = None birthDate: date | None = None
photo: str | None = None photo: str | None = None
parent_ids: list[int] = []
metadata: Metadata | None = None metadata: Metadata | None = None
class PetCreate(PetBase): class PetCreate(PetBase):
pass parent_ids: list[int] = []
class Pet(PetBase): class Pet(PetBase):
id: int id: int
parents: list[Parent] = []
class AppointmentBase(BaseModel): class AppointmentBase(BaseModel):
date: datetime date: datetime
notes: str | None = None notes: str | None = None
pet_id: int
vet_id: int
treatment_id: int
metadata: Metadata | None = None metadata: Metadata | None = None
class AppointmentCreate(AppointmentBase): class AppointmentCreate(AppointmentBase):
pass pet_id: int
vet_id: int
treatment_id: int
class Appointment(AppointmentBase): class Appointment(AppointmentBase):
id: int id: int
pet: Pet
vet: Vet
treatment: Treatment

View File

@@ -326,9 +326,9 @@ def list_appointments(limit: int = 20, offset: int = 0, date: str = None, vet: i
if date: if date:
items = [a for a in items if a.date.startswith(date)] items = [a for a in items if a.date.startswith(date)]
if vet is not None: if vet is not None:
items = [a for a in items if a.vet_id == vet] items = [a for a in items if a.vet.id == vet]
if pet is not None: if pet is not None:
items = [a for a in items if a.pet_id == pet] items = [a for a in items if a.pet.id == pet]
return {"total": len(items), "items": items[offset:offset + limit]} return {"total": len(items), "items": items[offset:offset + limit]}

View File

@@ -140,7 +140,7 @@ def test_full_appointment_lifecycle():
response = client.create_appointment(body=payload) response = client.create_appointment(body=payload)
assert response.status_code == 201 assert response.status_code == 201
appointment = response.json() appointment = response.json()
assert appointment["pet_id"] == pet["id"] assert appointment["pet"]["id"] == pet["id"]
# Fetch it back # Fetch it back
get_resp = client.get_appointment(path_params={"id": appointment["id"]}) get_resp = client.get_appointment(path_params={"id": appointment["id"]})