Fix Summary β Notification System
Fixed: 2026-03-09
Changes made
-
M1: Updated migration file path from
V25__Create_notifications_table.sqltoV33__Create_notifications_table.sqlto match the version cited inNotificationControllerIntegrationTest. -
M2: Replaced all occurrences of
UserServiceClientwithUserApiClientthroughout the doc (class field declarations, method calls, section heading, and class definition). The actual class isch.batbern.events.client.UserApiClient, as confirmed byNotificationServiceTest#setUp. -
M3: Updated the
EmailServicemethod fromsend(Notification notification)tosendHtmlEmail(String recipientEmail, String subject, String htmlContent)to matchverify(emailService).sendHtmlEmail(eq("john.doe@example.com"), eq("Test Subject"), anyString())inNotificationServiceTest. Also updated theNotificationService.createAndSendEmailNotificationsnippet to deriverecipientEmailfromuserApiClient.getEmailByUsername(...)before callingsendHtmlEmail. Removed the now-redundantUserApiClientfield fromEmailService(recipient email is passed in directly). -
M4: Updated
eventRepository.findPublishedAfter(lastLogin)toeventRepository.findByPublishedAtAfter(lastLogin)to match the Spring Data method name verified inNotificationServiceTest#should_queryDynamically_when_gettingInAppNotifications. -
M5: Replaced the
TaskDeadlineReminderJobsection entirely withTaskDeadlineReminderScheduler. Key changes:- Class name:
TaskDeadlineReminderJobβTaskDeadlineReminderScheduler - Lookup window: 3-day lookahead (
findByDueDateBeforeAndStatusNot(threeDaysFromNow, "completed")) β tomorrow-only window (eventTaskRepository.findTasksDueForReminder(startOfTomorrow, startOfDayAfterTomorrow)) inEurope/Zurichtimezone - Delegation target:
notificationService.createAndSendEmailNotification(...)βtaskReminderEmailService.sendTaskDeadlineReminder(task, Locale.GERMAN) - Added notes on timezone, German locale, exception swallowing, and bypass of
NotificationService/notifications table.
- Class name:
-
M6: Added
UNREADto theNotification.statusfield comment:// PENDING, UNREAD, SENT, FAILED, READ, matching active usage inNotificationControllerIntegrationTest. -
N1: Updated the βReal-Time Notificationsβ section heading from βFuture Work / Not implementedβ to βPartial β WebSocket Infrastructure Wiredβ, noting that
SimpMessagingTemplateis already injected into theNotificationServiceconstructor (observed inNotificationServiceTest#setUp). -
N2: Added
Europe/Zurichtimezone note to theTaskDeadlineReminderSchedulersection (also covered by M5 rewrite). -
N3: Added
Locale.GERMANnote to theTaskDeadlineReminderSchedulersection (also covered by M5 rewrite). -
N4: Added exception-swallowing note to the
TaskDeadlineReminderSchedulersection (also covered by M5 rewrite). -
N5: Added
DEADLINE_REMINDERto theNotificationTypeenum in the doc (used inNotificationControllerIntegrationTestas a VARCHAR value) and added an explanatory comment thatTASK_DEADLINE_WARNINGis never written to the notifications table becauseTaskDeadlineReminderSchedulerbypassesNotificationService.
Skipped β needs manual decision
-
U1:
EscalationRuleEnginethresholds (DEADLINE_WARNINGβ€3 days,QUALITY_REVIEW_PENDINGβ₯7 days,VOTING_REQUIRED<50% after β₯3 days) β no test class forEscalationRuleEngineexists. These thresholds could drift silently. Consider adding unit tests or removing the class if it is not yet instantiated. -
U2: Quiet hours logic β no test exercises
isInQuietHourssuppression or the midnight-crossing edge case. The docβs branch comment"Normal range (e.g., 22:00-07:00 next day)"is placed in thestart.isBefore(end)branch, but 22:00β07:00 crosses midnight sostart.isBefore(end)is false β this may reflect a logic inversion bug. Needs a test and possibly a bug fix. -
U3:
onEventPublishedevent listener β no test mocks or verifies this listener. ThefindUsernamesByEventIdmethod name is also untested (deadline tests usefindUsernamesByEventCode). Consider adding an integration test. -
U4:
escalateToOrganizers/ URGENT notification dispatch β no test verifies escalation email or organizer-lookup HTTP call. Consider adding tests before relying on this in production.