feat(tickets): Web-Push-Benachrichtigungen (PWA)
- Die Züchterin kann auf der Tickets-Seite Push-Benachrichtigungen aktivieren (🔔-Schalter). Service Worker ist BEWUSST push-only (kein fetch/Caching), damit das Laden der App nie beeinträchtigt wird. - Backend: WebPush-Bibliothek + VAPID; PushNotifier sendet an alle Abos, räumt veraltete (404/410) auf. Endpoints: GET /push/vapid-public-key, POST /push/subscribe|unsubscribe. - Ausgelöst über ein notify-Flag auf PUT /feedback: NUR die KI setzt es (z. B. neue Rückfrage / Ticket gelöst) → keine Selbst-Pushes durch Aktionen der Züchterin. Text wird aus dem Status abgeleitet, Klick öffnet das Ticket (?focus=). - Schalter/Logik blenden sich aus, wenn das Gerät kein Push kann oder der Server keine VAPID-Schlüssel hat (z. B. e2e-Mock). Migration WebPushSubscriptions. VAPID-Schlüssel in appsettings.json (lokale Single-User-App im Heimnetz — bewusste, vertretbare Vereinfachung). Tests: 264 Backend grün (+Push-Endpoints), e2e Tickets Desktop grün, vitest 149. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -447,6 +447,13 @@ export async function installMockApi(page: Page): Promise<MockDb> {
|
||||
}
|
||||
return json(route, 405)
|
||||
}
|
||||
// WEB-PUSH: im Mock deaktiviert (keine VAPID-Schlüssel) → PushToggle blendet sich aus.
|
||||
if (path === '/push/vapid-public-key' && method === 'GET') {
|
||||
return json(route, 200, { enabled: false, publicKey: null })
|
||||
}
|
||||
if ((path === '/push/subscribe' || path === '/push/unsubscribe') && method === 'POST') {
|
||||
return json(route, 200, {})
|
||||
}
|
||||
// FEEDBACK-ANHÄNGE: hochladen (POST /feedback/{id}/attachments).
|
||||
const attUpload = path.match(/^\/feedback\/([^/]+)\/attachments$/)
|
||||
if (attUpload && method === 'POST') {
|
||||
|
||||
Reference in New Issue
Block a user