Web Push Subscription (VAPID)
ID: PA-001 · Service: push-alerts · Status: 🟢 aktiv · Use Case: UC-PA-001, UC-PA-002
Der Service verwaltet Push-Subscriptions der Benutzer über zwei Kanäle: Web Push API mit VAPID-Authentifizierung (Browser/PWA, Web-Touchpoint) und Firebase Cloud Messaging (FCM, Trading Companion App, siehe APP-003). Eine Subscription identifiziert ein bestimmtes Gerät und ermöglicht gezielte Push-Nachrichten an diesen Endpunkt, unabhängig vom Kanaltyp.
Typ
functional
Vapid
Key Generation: einmalig auf dem Server (py_vapid CLI oder Python)
Env Vars
- VAPID_PRIVATE_KEY
- VAPID_PUBLIC_KEY
- VAPID_SUBJECT
Fcm
Beschreibung
Zweiter Zustellkanal, genutzt ausschließlich von der Trading Companion App (nicht vom Web-Touchpoint). Erfordert ein Firebase-Projekt und ein Service-Account-Credential auf dem Server (Firebase Admin SDK).
Env Vars
- FIREBASE_SERVICE_ACCOUNT_JSON (Pfad oder Inline-Credential)
Registrierungs Flow
Die App holt sich einen FCM-Token vom Google-Dienst (nativ, kein Service Worker) und übergibt ihn an denselben Endpunkt wie Web-Push- Subscriptions (siehe api.endpoints, unterschieden über das Feld type).
Frontend
Service Worker
Datei: public/sw.js
Events
Eintrag 1
| Feld | Wert |
|---|---|
| Push | Empfang und Anzeige der Nachricht |
Eintrag 2
| Feld | Wert |
|---|---|
| Notificationclick | Navigation zur Ziel-URL |
Subscription Flow
| Feld | Wert |
|---|---|
| 1 | navigator.serviceWorker.register('/sw.js') |
| 2 | pushManager.subscribe({ userVisibleOnly, applicationServerKey }) |
| 3 | POST /api/alerts/subscription mit |
API
Endpoints
Eintrag 1
Methode: POST
Path: /api/alerts/subscription
Beschreibung
Neue Subscription speichern oder vorhandene reaktivieren. Ein Endpunkt für beide Kanaltypen, unterschieden über das Feld type.
Auth: required
Body Web Push
| Feld | Wert |
|---|---|
| Typ | web_push |
| Endpoint | string |
| P256Dh | string |
| Auth | string |
| User Agent | string (optional) |
Body Fcm
| Feld | Wert |
|---|---|
| Typ | fcm |
| Fcm Token | string |
| Device Info | string (optional, z.B. Gerätemodell) |
Eintrag 2
Methode: DELETE
Path: /api/alerts/subscription
Beschreibung: Aktive Subscription deaktivieren
Auth: required
Body
| Feld | Wert |
|---|---|
| Typ | web_push |
| Endpoint | string (nur bei type=web_push) |
| Fcm Token | string (nur bei type=fcm) |
Eintrag 3
| Feld | Wert |
|---|---|
| Methode | GET |
| Path | /api/alerts/subscriptions |
| Beschreibung | Alle aktiven Subscriptions des Benutzers auflisten (inkl. type je Eintrag) |
| Auth | required |
Eintrag 4
| Feld | Wert |
|---|---|
| Methode | GET |
| Path | /api/alerts/vapid-public-key |
| Beschreibung | VAPID Public Key ans Frontend übermitteln (kein Auth nötig, nur für type=web_push relevant) |
| Auth | none |
Versand Weiche
Beim tatsächlichen Versand (ausgelöst aus PA-002, PA-003 sowie den bestehenden Frontend-Integration-Komponenten aus PA-005) wird je aktiver Subscription des Empfängers nach type verzweigt: web_push → pywebpush (VAPID, wie bisher), fcm → Firebase Admin SDK. Beide Zweige erhalten denselben Payload (title/body/url/actions, siehe APP-004); nur der Versandmechanismus unterscheidet sich. Ein Nutzer mit mehreren Geräten unterschiedlichen Typs (z.B. Browser + App) erhält die Nachricht auf beiden.
Datenspeicherung
Tabelle: push_subscriptions
Neue Felder
| Feld | Wert |
|---|---|
| Subscription Type | enum [web_push, fcm] |
| Fcm Token | text, nullable – nur bei subscription_type=fcm gesetzt |
Bestehende Felder Nullable
endpoint, p256dh, auth werden nullable (nur bei subscription_type=web_push gesetzt), da eine Zeile jetzt entweder Web-Push- oder FCM-Daten trägt, nie beides
Unique Constraint: (user_id, endpoint) für subscription_type=web_push, (user_id, fcm_token) für subscription_type=fcm
On Duplicate: reaktivieren (active = true, keys/token aktualisieren)
Abnahmekriterien
- [ ] Subscription wird user-gebunden gespeichert, für beide Kanaltypen
- [ ] Mehrere Geräte pro Benutzer möglich, auch gemischt (Browser + App gleichzeitig)
- [ ] Doppelte Registrierung desselben Endpoints/Tokens reaktiviert statt Fehler
- [ ] VAPID Public Key ist ohne Auth abrufbar (wird beim SW-Start benötigt)
- [ ] Abgelaufene Web-Push-Subscriptions werden beim Versand automatisch deaktiviert (HTTP 410, wie bisher)
- [ ] Ungültige/zurückgezogene FCM-Tokens werden beim Versand analog deaktiviert (Firebase liefert eigenen Fehlercode dafür)
- [ ] GET /api/alerts/subscriptions zeigt den type je Eintrag
Depends On
- AUTH-001
- USER-001
Changelog
Eintrag 1
Version: 1.0
Changes: Initiale Version
Eintrag 2
Version: 1.1
Changes
Um FCM als zweiten Kanaltyp erweitert (subscription_type: web_push | fcm), ausgelöst durch die Trading Companion App (APP-003). Bestehende Web-Push-Subscriptions und ihr Verhalten bleiben unverändert – abwärtskompatible Erweiterung, kein Breaking Change für den Web-Touchpoint.