706a6e257b
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
43 lines
1.3 KiB
JavaScript
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)
|
|
})
|
|
)
|
|
})
|