Functional contract

Patients and patient parents

Staff register an animal (the patient) with one or more patient parents (client contacts). Charts are Organization-scoped and visible from every Location. Required fields use in-form checks instead of the browser’s native validation bubble.

Admission chart extras shipped Source: docs/functional/patients.md

Records

ModelWhat it isScope
PatientThe animalOrganization
ClientPatient parent contact (not a User)Organization
PatientParentJoin of a patient to a parentPatient
BreedShared dog / cat / other catalogPlatform
PatientTagHandling / temperament tagPlatform defaults + Organization custom
PatientNoteDated chart note with authorPatient
PatientVaccineVaccine + certificate filePatient
VeterinarianPatient’s vet (staff or external): name, business, phone, emailPatient
MedicalConditionCondition catalogPlatform
PatientMedicalConditionReported conditionPatient

One primary client per patient (the first parent) plus optional additional parents. A client may have many patients. Admission searches existing parents by name, email, or phone, or creates new ones in the same form.

Patient — required: name, species. Dog / Cat / Other shortcuts on admission. Optional: profile photo (S3; tap the tile to choose a file, or use the Take photo menu: browse / camera on this device, or a single-use QR code (15 min) to upload from any phone without signing in; the photo appears live and is attached on save — see Architecture → Hands-off uploads), breed, hair type/color, DOB (or age in years → estimated DOB), sex, spayed (female only), neutered (male only), weight (kg stored; metric/imperial display), tags, notes, vaccines, veterinarian, and medical conditions. Sterilization checkboxes stay hidden until sex is chosen. Soft-delete via disabled_at; deceased via deceased_at. Default directory and booking pickers are enabled and living (Patient.bookable).

Client — required: first name, last name, and a phone number or email (one of the two). Optional remaining contact fields, address, geocoded when possible, email/SMS/SMS-marketing notification toggles (on by default; off is opt-out), and disabled_at (stays on charts, omitted from the existing-parent picker).

Workspace

Patients live at /app/patients. Super admins manage breeds at /admin/breeds.

RouteWhoBehavior
GET /app/patientspatients.readTable: avatar, name + badges, species / breed, age + sex, parent + contact, attention. Status filters with counts (enabled living by default)
GET/POST /app/patients/newpatients.manageAdmission form with chart-matching sub-menu sections (one form, client-side panels)
GET /app/patients/:idpatients.readIdentity card (avatar, badges, vitals, alerts) + chart tabs (?tab=): Overview, Vaccines, Medical conditions, Vets, Notes — see SOAP notes
GET/PATCH /app/patients/:id/editpatients.manageSame tabbed sections as admission

Destroy is not offered. Disabled and deceased are timestamp flags. Cross-organization ids return 404.

Reading order

The chart is read in one pass. The identity card answers who is this animal (avatar, name, status badges, species). The vitals strip answers what is stable (age, sex, weight, primary parent with contact). The alert strip answers what needs attention now and only appears when there is something: expired vaccines (danger), vaccines expiring within 60 days (caution), caution tags, and recorded medical conditions. The list repeats those alerts in its attention column.

Colour carries meaning, never decoration: danger for expired, caution for due soon, success for verified or opted in, brand for identity, neutral for plain facts. This section defines the shared layout for the rest of the platform — see Architecture → Section design.

RBAC

Org admin, location admin, receptionist, and veterinarian may read and manage. Organization manager may read only.

Out of scope

Voice-to-text, messaging, SMS, magic-link patient-parent access, drafts, hard-deleting patients, customer portal.

Full acceptance: docs/functional/patients.md.