Capstone 2 — Hospital Management System¶
Scope: a term's work · Prerequisites: Modules 1–15
1. Problem statement¶
A hospital runs outpatient clinics across several departments. Patients register once and may be seen by many departments. Each doctor has clinic sessions with a fixed capacity, and an appointment occupies one slot in one session.
The hard parts are not the lists; they are the rules. Appointment slots must not be double-booked. A patient cannot hold two appointments in the same session. Cancellations free a slot, and a slot freed within a day should be offered to a waiting list before it is offered to anyone else. Clinical records accrue entries that may be read by other departments but never edited — corrections are new entries, not changes to old ones. Billing depends on the department, the patient's insurance category and whether the visit was a follow-up.
The system is closed overnight and reopened each morning, and a data file that a clerk has edited by hand must not be able to corrupt a patient's record.
2. Actors¶
| Actor | What they do | What the system owes them |
|---|---|---|
| Receptionist | Registers patients, books and cancels appointments | A refusal that says why, never a double booking |
| Doctor | Runs a session, records notes, marks attendance and follow-ups | A session view in attendance order, and records that cannot be silently altered |
| Nurse | Records observations against a patient | The same append-only guarantee |
| Billing officer | Produces invoices per visit | Rates that vary by department and category, computed once and reproducibly |
| Administrator | Defines sessions, capacities and rates | Configuration without recompiling rules |
3. Use cases¶
- Register a patient, with a category (
private,insured,subsidised). - Create a doctor's clinic session: date, department, capacity.
- Book an appointment into a session, if a slot is free and the patient holds none in that session.
- Cancel an appointment, and offer a freed slot to the waiting list first.
- Add a clinical note to a patient's record, and read the record without being able to edit it.
- Mark an appointment attended, missed or followed up.
- Compute an invoice for a visit, per department and category.
- Produce a day's attendance sheet for a session.
- Save and load everything; refuse a corrupted file with a line number and no partial state.
4. Suggested classes¶
| Class | Responsibility, in one sentence | Notes |
|---|---|---|
Patient |
A person with an identifier, a category and a record | Enforces its own invariants |
ClinicalRecord |
An append-only sequence of entries | Owns its entries; exposes no mutator for an existing one |
RecordEntry |
One dated observation, by one author | Immutable once constructed |
Doctor |
A clinician who runs sessions | Holds sessions, not appointments directly |
Session |
A dated clinic with a capacity and a waitlist | Enforces its own capacity |
Appointment |
A patient's claim on one slot in one session | Aggregates a patient and a session |
WaitingList |
The queue for a session's freed slots | Ordered, with a documented rule |
Department |
A unit with its own rates and follow-up policy | Configuration carrier |
RatePolicy |
Turns a visit into an amount | An interface: the thing that varies |
Invoice |
One visit's charges, printed and storable | Owns its line items |
Hospital |
Coordinates operations and owns the collections | Where an operation is a transaction |
The class worth the most marks is ClinicalRecord. Its requirement — append-only, readable elsewhere,
never editable — is an encapsulation problem with a real consequence, and it has more than one defensible
solution (return copies, expose const ranges, or value-typed entries in an immutable container). Choose
one, state its cost, and demonstrate that the other departments cannot mutate it.
5. Relationships¶
Hospital ◆── vector<Patient> composition
Hospital ◆── vector<Doctor> composition
Patient ◆── ClinicalRecord composition: the record is the patient's
ClinicalRecord ◆── vector<RecordEntry> composition, and append-only
Doctor ◆── vector<Session> composition
Session ◆── vector<Appointment> composition: the appointment's lifetime is the session's
Appointment ────> Patient association: referred to, not owned
WaitingList ────> Session association
Session ┈┈> RatePolicy dependency, injected
Hospital ┈┈> Clock dependency: time is passed in, never read inside a rule
6. Design constraints¶
- A slot cannot be double-booked, and the rule is enforced in one place with one owner. Demonstrate it by a test that tries to book the same slot twice and fails to.
- Clinical records are append-only. Corrections are new entries. Justify your mechanism, and say what it costs a caller who wants a mutable view.
- Nothing reads the clock inside a rule. Pass "now" in, so a waiting-list rule can be tested without waiting a day.
- Rates vary by department and category — injected, not switched on inside the billing operation.
- The waiting-list rule is a decision, not a default. When a slot is freed, say who gets offered it and in what order, in the report, with the alternative you rejected.
- Money in integer pence; a visit's total is computed once and stored, so a later rate change cannot rewrite history.
- Format: one documented text format with a version marker, an escape rule for the separator, and refusal of a file whose marker is from a later version.
7. Milestones¶
| # | Milestone | Done when |
|---|---|---|
| 1 | Design | Diagram with multiplicities; responsibilities in one sentence each; the double-booking rule located in exactly one place |
| 2 | Patients and records | Registration and the append-only record work, with a demonstration that a record cannot be altered after the fact |
| 3 | Sessions and booking | Sessions with capacity; booking refuses double bookings and duplicates; cancellation frees a slot |
| 4 | Waiting lists and billing | Freed slots offered in the documented order; invoices computed from an injected policy |
| 5 | Persistence | Documented format, round trip including an empty hospital, three hand-edited corruptions rejected with line numbers |
| 6 | Tests and report | Invariants, boundaries and failure paths asserted; a deliberate bug caught; the report names the reversal and its cost |
8. Minimum requirements¶
- [ ] Patients, doctors, sessions and appointments, with invariants enforced inside their own classes
- [ ] Booking that refuses a double booking, a duplicate session booking, or a full session — each with a reason
- [ ] Cancellation that frees a slot, offered to the waiting list first
- [ ] A clinical record that cannot be edited once written, demonstrated
- [ ] Attendance marking: attended, missed, follow-up
- [ ] Rates varying by department and patient category, injected rather than hard-coded
- [ ] Persistence with a version marker and escape rule; a round trip preserving every field, including an empty hospital
- [ ] Three hand-edited corruptions rejected with line numbers, leaving the loaded state untouched
- [ ] At least two patterns, each justified by a named requirement; one declined, with the reason
- [ ] Tests with assertions covering invariants, boundaries and failure paths
- [ ] No warnings with
-Wall -Wextra -Werror
9. Advanced requirements¶
- [ ] Follow-up rules: a follow-up appointment within a window is charged at a reduced rate, with the window configurable
- [ ] Insurance categories added without editing the billing operation — the change-cost count in the report
- [ ] A second department with different session rules (for example two doctors per session)
- [ ] Reminders: patients notified of an appointment the day before, with the subscription lifetime answered
- [ ] Reports exported to CSV behind the same interface as the console report
- [ ] A day sheet in attendance order, with the ordering rule stated
- [ ] An audit trail of who changed which non-clinical record, append-only
10. Testing requirements¶
- Invariants: capacity is never exceeded; a patient holds at most one appointment per session; a record's entry count only grows; an invoice total equals the sum of its lines
- Boundaries: booking the last slot; cancelling on the day of the session; a follow-up exactly at the window's edge; a zero-capacity session; an empty waiting list
- Failure paths: booking an unknown session; cancelling an appointment that is not booked; loading a truncated file; a record entry with an invalid date
- Round trip: populated and empty hospitals, every field compared, including a name containing the separator
- One deliberate bug, introduced and caught, with the failing assertion kept
11. Extension ideas¶
- Room and equipment allocation, so a session needs both a doctor and a room.
- Emergency walk-ins that bypass the waiting list, with the rule stated.
- Recurring sessions generated for a term, and the design decision that follows (generated once, or computed on demand?).
- Patient history summarised across departments, and a measurement of how expensive that query is in your design.
- Discharge summaries that combine several departments' entries into one read-only document.
- A wait-time report, with the complexity of producing it from your data structures.
12. Evaluation checklist¶
- [ ] The diagram matches the declarations, including multiplicities
- [ ] No double booking is possible — demonstrated by a test that tries
- [ ] A clinical record cannot be edited by any caller — demonstrated, not asserted
- [ ] Nothing reads the clock inside a rule, and a date-dependent rule is testable without waiting
- [ ] Rates are injected, and two policies exist
- [ ] The waiting-list order is documented, with the alternative you rejected
- [ ] Money is integer pence, and a stored total is computed once
- [ ] The round trip preserves every field, including an empty hospital — output pasted
- [ ] Three corruptions rejected with line numbers, leaving the loaded state untouched
- [ ] The suite fails when a deliberate bug is introduced
- [ ] One pattern considered and declined, in writing
- [ ] The report names the decision I would reverse and what reversing it would cost
Related: Capstone options · Projects and the rubric · Module 16 — Capstone