Functional contract

Visits and whiteboard

A visit is the on-floor encounter after arrival. An appointment is only the booking. Walk-ins create a visit with no appointment.

Whiteboard shipped Source: docs/functional/visits.md

Domain

ModelWhat it is
VisitEncounter after arrival. Optional appointment, attending staff, current room
VisitStaffStaff on the visit (may differ from the booking)

Visit statuses: checked_in → in_room ⇄ waiting → ready_to_bill → completed.

StatusPlaceMeaning
checked_inWaiting roomArrived, not seen
in_roomA roomIn any room (exam, treatment, surgery), first time or again
waitingWaiting roomSeen, waiting for the next step
ready_to_billOff floorCare done, waiting for checkout
completedOff floorClosed

Place is derived (waiting room / a room / off floor), not a column. Illegal place+status pairs are rejected. Room → waiting room sets waiting; waiting room → a room sets in_room. place_changed_at records the last move. There is no “in treatment” status; who is with the patient is the visit’s staff.

Whiteboard

GET /app/whiteboard (visits.read). Query view: floor (default), pipeline, or list. /app/flowboard redirects here.

Check-in (from schedule), walk-in (New Visit), undo check-in (only while checked_in in the waiting room). Cards link to SOAP when the Staff may read patients.

RBAC

visits.read / visits.manage. Org admin, location admin, receptionist, and veterinarian may manage. Organization manager may read only. Veterinarian cannot book/cancel appointments.

Out of scope

Invoices (ready_to_bill is a board status only), reminders, mobile API, ActionCable. SOAP is separate — SOAP notes.

End-to-end billing flow: Appointment to invoice.

Full contract: docs/functional/visits.md.