Files
cannamanage/cannamanage-frontend/public/sw.js
T
Patrick Plate 706a6e257b 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
2026-06-13 19:25:19 +02:00

43 lines
1.3 KiB
JavaScript

// CannaManage Service Worker — PWA + Push Notifications
const CACHE_NAME = "cannamanage-v1"
// Cache static assets on install
self.addEventListener("install", (event) => {
self.skipWaiting()
})
self.addEventListener("activate", (event) => {
event.waitUntil(clients.claim())
})
// Handle incoming push messages
self.addEventListener("push", (event) => {
const data = event.data ? event.data.json() : {}
const options = {
body: data.body || "Neue Benachrichtigung",
icon: data.icon || "/icons/icon-192.png",
badge: "/icons/icon-192.png",
tag: data.type || "default",
data: { url: data.url || "/portal/notifications", ...data.data },
actions: data.actions || [{ action: "open", title: "Anzeigen" }],
vibrate: [100, 50, 100],
}
event.waitUntil(
self.registration.showNotification(data.title || "CannaManage", options)
)
})
// Handle notification click
self.addEventListener("notificationclick", (event) => {
event.notification.close()
const url = event.notification.data?.url || "/portal/notifications"
event.waitUntil(
clients.matchAll({ type: "window" }).then((windowClients) => {
for (const client of windowClients) {
if (client.url.includes(url) && "focus" in client) return client.focus()
}
return clients.openWindow(url)
})
)
})