Notification Record Repository
Component Detail
Description
Data access component for persistent in-app notification records related to certificate expiry. Stores notification state, acknowledgement status, and threshold tracking to support the persistent banner and prevent duplicate dispatches.
notification-record-repository
Summaries
The Notification Record Repository is the persistence backbone of the entire certificate expiry alerting system. It ensures that coordinators receive timely, accurate alerts without being overwhelmed by duplicate notifications, and that acknowledgement actions are durably recorded for compliance purposes. By tracking which expiry thresholds have already triggered notifications, the system avoids sending redundant alerts that erode coordinator trust and create alert fatigue. The repository also enables clean state management upon certification renewal, automatically clearing outstanding alerts when a mentor's certification is updated.
This reliability and auditability directly supports organizational accountability in managing workforce compliance.
Medium complexity, backend-only, with no upstream repository dependencies—making it a high-priority early deliverable since it is depended upon by coordinator-acknowledgement-service and course-enrollment-prompt-service. The data model must support several distinct notification states (active, acknowledged, renewal-cleared, enrollment-triggered), and the threshold deduplication logic (getNotificationByThreshold) is the most nuanced piece requiring careful test coverage. Testing scope includes: create and retrieve active notifications, acknowledge flow, renewal-triggered clearance, threshold deduplication, and the markEnrollmentTriggered idempotency check. Confirm with stakeholders whether historical (cleared) notification records must be retained for audit purposes or can be hard-deleted, as this affects schema design and storage planning.
The repository manages a notifications table with columns for mentorId, coordinatorId, threshold (enum: 60d/30d/7d/expired), expiryDate, acknowledgedAt, acknowledgedBy, enrollmentTriggered, and clearedAt. createNotificationRecord inserts a new row only after getNotificationByThreshold confirms no record exists for that mentor+threshold combination—threshold deduplication is the core invariant. getActiveNotificationsForMentor and getActiveNotificationsForCoordinator filter on acknowledgedAt IS NULL AND clearedAt IS NULL. acknowledgeNotification sets acknowledgedAt and acknowledgedBy atomically.
clearNotificationsOnRenewal bulk-updates clearedAt for all active notifications for a mentorId, triggered by the renewal flow. markEnrollmentTriggered flips the enrollmentTriggered boolean. All mutations should use row-level locking or optimistic concurrency to prevent race conditions in the daily batch run. Indexes required on (mentorId, threshold), (coordinatorId, acknowledgedAt), and (mentorId, clearedAt).
Responsibilities
- Create and store in-app notification records for expiry events
- Retrieve active (unacknowledged) notifications for a mentor or coordinator
- Update notification status upon acknowledgement or renewal
- Track which thresholds have already triggered notifications
Interfaces
createNotificationRecord(mentorId: String, coordinatorId: String, threshold: NotificationThreshold, expiryDate: DateTime)
getActiveNotificationsForMentor(mentorId: String) -> List<ExpiryNotification>
getActiveNotificationsForCoordinator(coordinatorId: String) -> List<ExpiryNotification>
acknowledgeNotification(notificationId: String, coordinatorId: String)
clearNotificationsOnRenewal(mentorId: String)
getNotificationByThreshold(mentorId: String, threshold: NotificationThreshold) -> ExpiryNotification?
markEnrollmentTriggered(notificationId: String)
Relationships
Dependents (3)
Components that depend on this component