Add Web Push notifications for task assignment

When a task is created or reassigned to a staff member, a push notification
is sent to any devices they have subscribed on. Keys are auto-generated on
first boot and stored in the config table (no manual VAPID setup needed).

- Backend: web-push dep, push_subscriptions table, lib/push.js (VAPID +
  send), routes/push.js (vapid-key / subscribe / unsubscribe endpoints),
  push notify wired into task-core createTask and tasks PATCH reassignment
- Frontend: switched vite-plugin-pwa to injectManifest strategy, custom
  sw.js handles precache + push event + notificationclick, usePushSubscription
  hook requests permission and registers subscription on login

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-20 22:59:16 +00:00
parent fc993c63bc
commit 43809b7460
11 changed files with 237 additions and 5 deletions

View file

@ -1,5 +1,6 @@
import { pool, getConfig } from '../db.js'
import { notifyAssignment, notifyUrgent } from './mailer.js'
import { notifyAssignmentPush } from './push.js'
export const PRIORITIES = ['low', 'medium', 'high', 'urgent']
export const STATUSES = ['submitted', 'in_progress', 'hold_parts', 'hold_scheduled', 'temporary_fix', 'fixed']
@ -67,6 +68,7 @@ export async function createTask(input, actor) {
if (config.notify_on_assign) {
if (task.assigned_type === 'staff' && task.assigned_to && task.assigned_to !== actor.email) {
notifyAssignment(task, locationName, task.assigned_to)
notifyAssignmentPush(task, locationName)
} else if (task.assigned_type === 'contractor' && task.contractor_id) {
const { rows: c } = await pool.query('SELECT email FROM contractors WHERE id = $1', [task.contractor_id])
if (c[0]?.email) notifyAssignment(task, locationName, c[0].email)