feat(sprint7): Phase 1 — notifications enhancement + push infrastructure

Phase 1 (Notification Enhancement):
- Extended NotificationType enum (ADMIN_MESSAGE, INFO_BOARD_POST, FORUM_REPLY, FORUM_MENTION)
- Extended StaffPermission enum (SEND_NOTIFICATIONS, MANAGE_INFO_BOARD, MODERATE_FORUM)
- Extended AuditEventType with Sprint 7 events
- Flyway V11: notification_sends + notification_send_recipients tables
- NotificationSend + NotificationSendRecipient entities
- NotificationSendRepository + NotificationSendRecipientRepository
- Extended NotificationService with sendBroadcast() and sendToSelected()
- NotificationComposeController (POST /compose, GET /sends)
- ComposeNotificationRequest DTO

Phase 1B (Push Infrastructure):
- Flyway V12: device_tokens + notification_preferences tables
- DeviceToken entity + DevicePlatform enum
- NotificationPreference entity + NotificationChannel enum
- DeviceTokenRepository + NotificationPreferenceRepository
- DeviceRegistrationService (register/unregister/list devices, max 10 per user)
- NotificationPreferenceService (get/create defaults, update, IN_APP always on)
- NotificationDispatchService (multi-channel fan-out: WebSocket, Web Push, FCM, Email)
- WebPushSender (VAPID-based, simplified for MVP)
- FcmPushSender (graceful degradation if not configured)
- PushPayload DTO
- DeviceRegistrationController (POST/GET/DELETE /devices, GET /vapid-key)
- NotificationPreferenceController (GET/PUT /preferences)
- ConsentType extended (NOTIFICATION_PUSH, NOTIFICATION_EMAIL)
- TargetType enum (ALL, SELECTED)

Frontend:
- Updated sw.js with push event handler + notification click handler
- push-subscription.ts (subscribeToPush, unsubscribe, permission helpers)
- notification-compose.ts service (compose, sends, devices, preferences APIs)
- i18n keys (de.json + en.json) for compose, preferences, push, devices

Configuration:
- application-docker.properties: VAPID + FCM push config properties
- MemberRepository: added findAllActiveUserIds() for broadcast
This commit is contained in:
Patrick Plate
2026-06-13 19:25:19 +02:00
parent 329b7abb18
commit 706a6e257b
43 changed files with 6635 additions and 76 deletions
+46 -1
View File
@@ -499,7 +499,52 @@
"QUOTA_WARNING": "Quota Warning",
"BATCH_RECALLED": "Batch Recalled",
"DISTRIBUTION_RECORDED": "Distribution Recorded",
"SUBSCRIPTION_EXPIRING": "Subscription Expiring"
"SUBSCRIPTION_EXPIRING": "Subscription Expiring",
"ADMIN_MESSAGE": "Club Message",
"INFO_BOARD_POST": "New Announcement",
"FORUM_REPLY": "Forum Reply",
"FORUM_MENTION": "Forum Mention"
},
"compose": {
"title": "Compose Notification",
"titleField": "Title",
"messageField": "Message",
"linkField": "Link (optional)",
"targetAll": "All Members",
"targetSelected": "Selected Members",
"selectMembers": "Select members",
"send": "Send",
"sending": "Sending...",
"sent": "Notification sent to {count} members",
"history": "History",
"sentAt": "Sent at",
"recipients": "Recipients",
"readCount": "Read"
},
"preferences": {
"title": "Notification Settings",
"inApp": "In-App (always active)",
"email": "Email",
"webPush": "Browser Push Notifications",
"mobilePush": "Mobile Push Notifications",
"enabled": "Enabled",
"disabled": "Disabled"
},
"push": {
"promptTitle": "Enable Push Notifications?",
"promptBody": "Get notified about distributions, events, and club news directly on your device.",
"accept": "Enable",
"decline": "Not now",
"granted": "Push notifications enabled",
"denied": "Push notifications denied"
},
"devices": {
"title": "Registered Devices",
"noDevices": "No devices registered",
"remove": "Remove",
"web": "Web Browser",
"ios": "iPhone/iPad",
"android": "Android Device"
}
},
"pwa": {