feat: PWA push notifications — service worker, VAPID, subscription management

- Add web-push VAPID backend with push_subscriptions table (migration 078)
- Backend push module with sendPushToUser/sendPushToRoom helpers
- Push routes: GET vapid-key, POST subscribe, DELETE unsubscribe
- Trigger push on new chat messages in direct/group rooms
- PWA manifest, service worker, and icons (72–512px)
- Frontend push lib: SW registration, subscribe/unsubscribe helpers
- Push API in api.ts, SW registered in main.tsx
- usePushSubscription hook for auto-subscribe on permission grant
- PushPermissionRow component in ChatWidget settings view

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-15 12:14:03 +03:00
parent 756a71bf2f
commit 1641b14f29
27 changed files with 1056 additions and 7 deletions

View File

@@ -34,6 +34,7 @@ import notificationsRoutes from './routes/notifications'
import scheduleRoutes from './routes/schedule'
import loyaltyRoutes from './routes/loyalty'
import chatRoutes from './routes/chat'
import pushRoutes from './routes/push'
import workstationRoutes from './routes/workstations'
import agentReleaseRoutes from './routes/agent-release'
import wifiSettingsRoutes, { wifiAuthVerify } from './routes/wifi-settings'
@@ -48,6 +49,7 @@ import publicWidgetRoutes from './routes/publicWidget'
import yookassaWebhookRoutes from './routes/yookassaWebhook'
import { setupAgentWsRoute } from './agent-ws'
import { startJobs } from './jobs'
import { initWebPush } from './push'
export async function buildApp() {
const fastify = Fastify({
@@ -131,6 +133,7 @@ export async function buildApp() {
await fastify.register(scheduleRoutes)
await fastify.register(loyaltyRoutes)
await fastify.register(chatRoutes)
await fastify.register(pushRoutes)
await fastify.register(workstationRoutes)
await fastify.register(agentReleaseRoutes)
await fastify.register(wifiSettingsRoutes)
@@ -147,6 +150,7 @@ export async function buildApp() {
await fastify.register(setupAgentWsRoute)
startJobs()
initWebPush()
return fastify
}