allOf and oneOf
This commit is contained in:
@@ -22,7 +22,9 @@ from models import (
|
|||||||
Parent, ParentCreate,
|
Parent, ParentCreate,
|
||||||
Vet, VetCreate,
|
Vet, VetCreate,
|
||||||
Treatment, TreatmentCreate,
|
Treatment, TreatmentCreate,
|
||||||
Procedure, ProcedureNotes,
|
Procedure,
|
||||||
|
BasicNote, HeartRateNote, DentalNote,
|
||||||
|
VaccineNote, PreOpNote, SurgeryNote,
|
||||||
Pet, PetCreate,
|
Pet, PetCreate,
|
||||||
Appointment, AppointmentCreate,
|
Appointment, AppointmentCreate,
|
||||||
)
|
)
|
||||||
@@ -339,16 +341,29 @@ def _seed_data():
|
|||||||
_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",
|
_appointments[1] = Appointment(id=1, date=datetime(2026, 6, 18, 9, 0, tzinfo=timezone.utc), notes="Annual checkup",
|
||||||
procedures=[Procedure(name="Physical Exam", cost=50.0), Procedure(name="Heart Rate", notes=ProcedureNotes(summary="Normal rhythm"))],
|
procedures=[
|
||||||
|
Procedure(name="Physical Exam", cost=50.0, notes=BasicNote(summary="Normal findings", details="Heart rate and temperature within normal range")),
|
||||||
|
Procedure(name="Heart Rate", notes=HeartRateNote(summary="Normal rhythm", bpm=65)),
|
||||||
|
],
|
||||||
pet=_pets[1], vet=_vets[1], treatment=_treatments[1], metadata=meta)
|
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",
|
_appointments[2] = Appointment(id=2, date=datetime(2026, 6, 18, 10, 30, tzinfo=timezone.utc), notes="Dental cleaning",
|
||||||
procedures=[Procedure(name="Scaling", cost=80.0), Procedure(name="Polishing", cost=40.0, notes=ProcedureNotes(summary="High-speed polish"))],
|
procedures=[
|
||||||
|
Procedure(name="Scaling", cost=80.0, notes=DentalNote(summary="Moderate tartar removed", procedureType="scaling", teeth="all")),
|
||||||
|
Procedure(name="Polishing", cost=40.0, notes=DentalNote(summary="High-speed polish applied", procedureType="polishing", teeth="all")),
|
||||||
|
],
|
||||||
pet=_pets[2], vet=_vets[2], treatment=_treatments[3], metadata=meta)
|
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",
|
_appointments[3] = Appointment(id=3, date=datetime(2026, 6, 19, 11, 0, tzinfo=timezone.utc), notes="Vaccination booster",
|
||||||
procedures=[Procedure(name="DHPP Vaccine", cost=35.0), Procedure(name="Rabies Vaccine", cost=45.0)],
|
procedures=[
|
||||||
|
Procedure(name="Vaccine", cost=35.0, notes=VaccineNote(summary="Administered", medicine="DHPP", leg="hind_left")),
|
||||||
|
Procedure(name="Vaccine", cost=45.0, notes=VaccineNote(summary="Administered", medicine="Rabies", leg="hind_right")),
|
||||||
|
],
|
||||||
pet=_pets[3], vet=_vets[3], treatment=_treatments[2], metadata=meta)
|
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",
|
_appointments[4] = Appointment(id=4, date=datetime(2026, 6, 20, 14, 0, tzinfo=timezone.utc), notes="Follow-up after surgery",
|
||||||
procedures=[Procedure(name="Pre-op Exam", cost=30.0), Procedure(name="Surgery", cost=200.0), Procedure(name="Post-op Care", cost=50.0)],
|
procedures=[
|
||||||
|
Procedure(name="PreOp", cost=30.0, notes=PreOpNote(summary="Pre-op clearance", heartRate=80, temperature=38.5)),
|
||||||
|
Procedure(name="Neuter", cost=200.0, notes=SurgeryNote(summary="Surgery completed", surgeryType="neuter", complications="None")),
|
||||||
|
Procedure(name="PostOp", cost=50.0, notes=BasicNote(summary="Recovering well", details="Eating and drinking normally")),
|
||||||
|
],
|
||||||
pet=_pets[5], vet=_vets[1], treatment=_treatments[4], metadata=meta)
|
pet=_pets[5], vet=_vets[1], treatment=_treatments[4], metadata=meta)
|
||||||
_appointments_next_id = 5
|
_appointments_next_id = 5
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from pydantic import BaseModel
|
from typing import Annotated, Literal
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
class Metadata(BaseModel):
|
class Metadata(BaseModel):
|
||||||
@@ -38,11 +39,50 @@ class Vet(VetBase):
|
|||||||
id: int
|
id: int
|
||||||
|
|
||||||
|
|
||||||
class ProcedureNotes(BaseModel):
|
class ProcedureNoteBase(BaseModel):
|
||||||
summary: str | None = None
|
summary: str | None = None
|
||||||
details: str | None = None
|
details: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class BasicNote(ProcedureNoteBase):
|
||||||
|
noteType: Literal["basic"] = "basic"
|
||||||
|
|
||||||
|
|
||||||
|
class HeartRateNote(ProcedureNoteBase):
|
||||||
|
noteType: Literal["heart_rate"] = "heart_rate"
|
||||||
|
bpm: int
|
||||||
|
|
||||||
|
|
||||||
|
class DentalNote(ProcedureNoteBase):
|
||||||
|
noteType: Literal["dental"] = "dental"
|
||||||
|
procedureType: Literal["scaling", "polishing"]
|
||||||
|
teeth: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class VaccineNote(ProcedureNoteBase):
|
||||||
|
noteType: Literal["vaccine"] = "vaccine"
|
||||||
|
medicine: Literal["Rabies", "DHPP", "Tricat", "Deworming"]
|
||||||
|
leg: Literal["front_left", "front_right", "hind_left", "hind_right"]
|
||||||
|
|
||||||
|
|
||||||
|
class PreOpNote(ProcedureNoteBase):
|
||||||
|
noteType: Literal["preop"] = "preop"
|
||||||
|
heartRate: int
|
||||||
|
temperature: float
|
||||||
|
|
||||||
|
|
||||||
|
class SurgeryNote(ProcedureNoteBase):
|
||||||
|
noteType: Literal["surgery"] = "surgery"
|
||||||
|
surgeryType: Literal["neuter", "spay"]
|
||||||
|
complications: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
ProcedureNotes = Annotated[
|
||||||
|
BasicNote | HeartRateNote | DentalNote | VaccineNote | PreOpNote | SurgeryNote,
|
||||||
|
Field(discriminator="noteType"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Procedure(BaseModel):
|
class Procedure(BaseModel):
|
||||||
name: str | None = None
|
name: str | None = None
|
||||||
description: str | None = None
|
description: str | None = None
|
||||||
|
|||||||
@@ -45,9 +45,8 @@ components:
|
|||||||
x-order: 4
|
x-order: 4
|
||||||
x-label: "Notes"
|
x-label: "Notes"
|
||||||
|
|
||||||
ProcedureNotes:
|
ProcedureNoteBase:
|
||||||
type: object
|
type: object
|
||||||
x-display-format: "{summary}"
|
|
||||||
properties:
|
properties:
|
||||||
summary:
|
summary:
|
||||||
type: string
|
type: string
|
||||||
@@ -58,6 +57,139 @@ components:
|
|||||||
x-order: 2
|
x-order: 2
|
||||||
x-label: "Details"
|
x-label: "Details"
|
||||||
|
|
||||||
|
ProcedureNotes:
|
||||||
|
x-display-format: "{summary}"
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/BasicNote'
|
||||||
|
- $ref: '#/components/schemas/HeartRateNote'
|
||||||
|
- $ref: '#/components/schemas/DentalNote'
|
||||||
|
- $ref: '#/components/schemas/VaccineNote'
|
||||||
|
- $ref: '#/components/schemas/PreOpNote'
|
||||||
|
- $ref: '#/components/schemas/SurgeryNote'
|
||||||
|
discriminator:
|
||||||
|
propertyName: noteType
|
||||||
|
mapping:
|
||||||
|
basic: BasicNote
|
||||||
|
heart_rate: HeartRateNote
|
||||||
|
dental: DentalNote
|
||||||
|
vaccine: VaccineNote
|
||||||
|
preop: PreOpNote
|
||||||
|
surgery: SurgeryNote
|
||||||
|
|
||||||
|
BasicNote:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ProcedureNoteBase'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
noteType:
|
||||||
|
type: string
|
||||||
|
enum: [basic]
|
||||||
|
x-order: 0
|
||||||
|
x-label: "Type"
|
||||||
|
required: [noteType]
|
||||||
|
|
||||||
|
HeartRateNote:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ProcedureNoteBase'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
noteType:
|
||||||
|
type: string
|
||||||
|
enum: [heart_rate]
|
||||||
|
x-order: 0
|
||||||
|
x-label: "Type"
|
||||||
|
bpm:
|
||||||
|
type: integer
|
||||||
|
x-order: 3
|
||||||
|
x-label: "Heart Rate (bpm)"
|
||||||
|
required: [noteType, bpm]
|
||||||
|
|
||||||
|
DentalNote:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ProcedureNoteBase'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
noteType:
|
||||||
|
type: string
|
||||||
|
enum: [dental]
|
||||||
|
x-order: 0
|
||||||
|
x-label: "Type"
|
||||||
|
procedureType:
|
||||||
|
type: string
|
||||||
|
enum: [scaling, polishing]
|
||||||
|
x-order: 3
|
||||||
|
x-label: "Procedure"
|
||||||
|
teeth:
|
||||||
|
type: string
|
||||||
|
enum: [all, upper_only, lower_only]
|
||||||
|
x-order: 4
|
||||||
|
x-label: "Teeth"
|
||||||
|
required: [noteType, procedureType]
|
||||||
|
|
||||||
|
VaccineNote:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ProcedureNoteBase'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
noteType:
|
||||||
|
type: string
|
||||||
|
enum: [vaccine]
|
||||||
|
x-order: 0
|
||||||
|
x-label: "Type"
|
||||||
|
medicine:
|
||||||
|
type: string
|
||||||
|
enum: [Rabies, DHPP, Tricat, Deworming]
|
||||||
|
x-order: 3
|
||||||
|
x-label: "Medicine"
|
||||||
|
leg:
|
||||||
|
type: string
|
||||||
|
enum: [front_left, front_right, hind_left, hind_right]
|
||||||
|
x-order: 4
|
||||||
|
x-label: "Injection Leg"
|
||||||
|
required: [noteType, medicine, leg]
|
||||||
|
|
||||||
|
PreOpNote:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ProcedureNoteBase'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
noteType:
|
||||||
|
type: string
|
||||||
|
enum: [preop]
|
||||||
|
x-order: 0
|
||||||
|
x-label: "Type"
|
||||||
|
heartRate:
|
||||||
|
type: integer
|
||||||
|
x-order: 3
|
||||||
|
x-label: "Heart Rate (bpm)"
|
||||||
|
temperature:
|
||||||
|
type: number
|
||||||
|
format: float
|
||||||
|
x-order: 4
|
||||||
|
x-label: "Temperature (°C)"
|
||||||
|
required: [noteType, heartRate, temperature]
|
||||||
|
|
||||||
|
SurgeryNote:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ProcedureNoteBase'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
noteType:
|
||||||
|
type: string
|
||||||
|
enum: [surgery]
|
||||||
|
x-order: 0
|
||||||
|
x-label: "Type"
|
||||||
|
surgeryType:
|
||||||
|
type: string
|
||||||
|
enum: [neuter, spay]
|
||||||
|
x-order: 3
|
||||||
|
x-label: "Surgery Type"
|
||||||
|
complications:
|
||||||
|
type: string
|
||||||
|
x-order: 4
|
||||||
|
x-label: "Complications"
|
||||||
|
required: [noteType, surgeryType]
|
||||||
|
|
||||||
Call:
|
Call:
|
||||||
type: object
|
type: object
|
||||||
x-primary-key: _received_at
|
x-primary-key: _received_at
|
||||||
|
|||||||
Reference in New Issue
Block a user