Skip to content

Recalls — events ​

Per-module slice of docs/events-catalog.md (auto-generated). Update both files when adding or removing events.

Published ​

EventWhenPayloadSubscribers
recall.createdRecallService.create; transactional (db=db).recall_id, clinic_id, patient_id, reason, due_month, priority, status, … (_build_event_payload)activity_journal, recall_reminders
recall.snoozedsnooze — due month pushed forward.the recall payload + snoozed_months—
recall.cancelledcancel.the recall payload—
recall.completedmark_done.the recall payload—

Subscribed ​

All state-changing handlers except the payload-only stub are transactional (ADR 0019): a recall mirrors an appointment, and linked_appointment_id is an FK to a row that only exists in the publisher's transaction (issue #183).

EventHandlerModeEffect
appointment.scheduledevents.on_appointment_scheduledtransactionalAuto-link the single matching pending recall (bails out when ambiguous).
appointment.completedevents.on_appointment_completedtransactionalMark the linked recall done.
appointment.cancelledevents.on_appointment_cancelledtransactionalUnlink and send the recall back to pending.
patient.archivedevents.on_patient_archivedtransactionalMove active recalls to needs_review.
treatment_plan.treatment_completedevents.on_treatment_plan_completedown-session (payload-only)Logs only — suggestions are pulled by the frontend.

GDPR erasure is not an event subscription: the module exposes a RecallsErasureContributor (erasure.py), pulled by gdpr inside the erasure transaction (ADR 0038, #546).

Adding a new event ​

  1. Add the constant to backend/app/core/events/types.py (EventType).
  2. Publish from a service method after flush() — the bus runs handlers inline, before the request commits. Pass db=db so transactional subscribers can join the transaction (ADR 0019, issue #183).
  3. Add the row to the table(s) above.
  4. Run python backend/scripts/generate_catalogs.py to refresh the global catalog.