feat(push): native device-token registration + FCM/APNs senders

- /api/v1/devices (register) + /api/v1/devices/remove — auth-required, validates
  platform (ios|android), upserts by token; e2e covers register/validation/auth/remove.
- db device_tokens table + deviceTokens repo.
- push.js: FCM HTTP v1 (Android) and APNs token-based over HTTP/2 (iOS) folded into
  the single push.sendToUser path alongside Web Push; each transport independently
  config-gated and a silent no-op without creds. Dead tokens pruned on 404/410.
- docs: CLIENTS.md Phase B updated; DEPLOY.md env table adds FCM/APNs vars.

e2e 117/117.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 18:23:10 +05:30
parent 593a4677b6
commit 4c75db2029
7 changed files with 183 additions and 32 deletions
+3 -1
View File
@@ -51,7 +51,9 @@ secrets already documented:
| Group | Vars | Needed for |
|-------|------|-----------|
| Login / SSO | `BIZGAZE_LOGIN_URL`, `BIZGAZE_DIRECTORY_URL`, `BIZGAZE_DIRECTORY_TOKEN`, `SSO_SECRET` | BizGaze sign-in + directory search |
| Web Push | `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, `VAPID_SUBJECT` | Background push notifications (incl. iOS PWA) |
| Web Push | `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, `VAPID_SUBJECT` | Background push for browsers / installed PWA |
| Native push — Android | `FCM_SERVICE_ACCOUNT` (path to / inline Firebase service-account JSON) | FCM push to the Android app |
| Native push — iOS | `APNS_KEY` (path/inline `.p8`), `APNS_KEY_ID`, `APNS_TEAM_ID`, `APNS_BUNDLE_ID`, `APNS_PRODUCTION=1` | APNs push to the iOS app |
| Calls | `TURN_URLS` / `TURN_SECRET` (or `TURN_USERNAME`+`TURN_CREDENTIAL`) | Audio/video across NATs & mobile networks |
If the VAPID keys are missing, push silently no-ops (the app still runs). Push on