import { Router } from 'express'; import { dispatchPushToUser, listDeviceTokensForUser, upsertDeviceToken } from '../services/push-dispatch.service'; import { requireAuth } from '../middleware/require-auth'; export interface DeviceTokenRecord { userId: string; platform: 'ios' | 'android'; token: string; updatedAt: number; } const router = Router(); router.use(requireAuth); router.post('/', async (req, res) => { const { userId, platform, token } = req.body as Partial; if (!userId || !token || (platform !== 'ios' && platform !== 'android')) { return res.status(400).json({ error: 'Missing or invalid userId/platform/token' }); } if (userId !== req.authUserId) { return res.status(403).json({ error: 'Not authorized', errorCode: 'NOT_AUTHORIZED' }); } await upsertDeviceToken({ userId, platform, token }); res.status(201).json({ ok: true }); }); router.get('/:userId', async (req, res) => { if (req.params.userId !== req.authUserId) { return res.status(403).json({ error: 'Not authorized', errorCode: 'NOT_AUTHORIZED' }); } const records = await listDeviceTokensForUser(req.params.userId); res.json({ tokens: records.map((record) => ({ userId: record.userId, platform: record.platform, token: record.token, updatedAt: record.updatedAt })) }); }); router.post('/:userId/dispatch', async (req, res) => { if (req.params.userId !== req.authUserId) { return res.status(403).json({ error: 'Not authorized', errorCode: 'NOT_AUTHORIZED' }); } const { title, body, data } = req.body as { title?: string; body?: string; data?: Record; }; if (!title || !body) { return res.status(400).json({ error: 'Missing title/body' }); } await dispatchPushToUser(req.params.userId, { title, body, data }); res.json({ ok: true }); }); export default router;