Workflow: Appointments
The appointment lifecycle is central to how a clinic runs its day.
Status machine
Only the four "final" states — completed, cancelled, no_show, and void (for invoices) — block further transitions in the UI today.
Create an appointment
Fields
| Field | Required | Notes |
|---|---|---|
pet_id | ✓ | Pet being seen |
client_id | ✓ | Usually inferred from pet's client |
veterinarian_user_id | optional | FK → users.id |
appointment_type | ✓ | Free text — vaccination, consult, surgery, etc. |
booking_source | default clinic_portal | clinic_portal / owner_app / phone / walk_in |
scheduled_start | ✓ | datetime |
scheduled_end | ✓ | datetime, must be after start |
reason | optional | text |
notes | optional | text |
Confirm / check-in / complete an appointment
The only write endpoint to change status is:
PATCH /api/v1/tenant/{tenant}/appointments/{appointment}
Content-Type: application/json
{ "status": "checked_in" }
This is intentionally narrow — callers can't accidentally overwrite other fields. The UI's per-row action buttons each map to one of the valid transitions above.
Cancel
Same endpoint, set status to cancelled. No cancellation reason column yet — add one if your clinic wants to report on reasons.
Read appointments
GET /api/v1/tenant/{tenant}/appointments— paginated 20 per page, withpet,client,veterinarianeager-loaded. Used by the AppointmentsModule and Dashboard.GET /api/v1/owner/me/appointments?owner_user_id=…— owner-side portal.
UI touchpoints
| Component | What it does |
|---|---|
AppointmentsModule.js | Full list with status badges + row actions |
AppointmentForm.js | Create/edit form |
Dashboard.js | Pulls the next 10 upcoming as a summary card |
PatientProfile.js | Per-pet history |
Example timeline
Mon 10:00 scheduled — Staff creates via phone
Mon 10:05 confirmed — Owner confirms via email link
Wed 09:30 checked_in — Receptionist checks pet in
Wed 10:00 completed — Vet closes the visit, invoice generated
Analytics hooks (future)
- Attribution —
booking_sourcelets you report on channel mix (clinic_portal vs walk_in vs phone vs owner_app). - Lead time —
created_atvsscheduled_starttells you how far in advance people book. - No-show rate — count of
no_show/ total.