const express = require('express'); const router = express.Router(); const jwt = require('jsonwebtoken'); const { supabase } = require('../config/supabase'); const { getNotificationHistory } = require('../services/notifications'); /** * Middleware to verify JWT token */ function authMiddleware(req, res, next) { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ error: 'No token provided' }); } try { const token = authHeader.split(' ')[1]; req.user = jwt.verify(token, process.env.JWT_SECRET); next(); } catch (err) { return res.status(401).json({ error: 'Invalid token' }); } } // Apply auth middleware to all routes router.use(authMiddleware); /** * GET /api/notification-settings * Returns notification settings for current user */ router.get('/', async (req, res) => { try { const userId = req.user.userId; // Get settings or return defaults const { data: settings, error } = await supabase .from('notification_settings') .select('*') .eq('user_id', userId) .single(); if (error && error.code !== 'PGRST116') { // PGRST116 = no rows returned console.error('Get notification settings error:', error); return res.status(500).json({ error: 'Failed to get notification settings' }); } // Return settings or defaults (using new field names for mobile app) res.json({ settings: settings ? { // Alert types emergencyAlerts: settings.emergency_alerts ?? true, activityAlerts: settings.activity_alerts ?? true, lowBattery: settings.low_battery ?? true, dailySummary: settings.daily_summary ?? false, weeklySummary: settings.weekly_summary ?? true, // Delivery methods pushEnabled: settings.push_enabled ?? true, emailEnabled: settings.email_enabled ?? false, smsEnabled: settings.sms_enabled ?? false, // Quiet hours quietHours: settings.quiet_hours_enabled ?? false, quietStart: settings.quiet_hours_start ?? '22:00', quietEnd: settings.quiet_hours_end ?? '07:00', } : { // Defaults emergencyAlerts: true, activityAlerts: true, lowBattery: true, dailySummary: false, weeklySummary: true, pushEnabled: true, emailEnabled: false, smsEnabled: false, quietHours: false, quietStart: '22:00', quietEnd: '07:00', } }); } catch (error) { console.error('Get notification settings error:', error); res.status(500).json({ error: error.message }); } }); /** * PATCH /api/notification-settings * Updates notification settings */ router.patch('/', async (req, res) => { try { const userId = req.user.userId; const { // New field names from mobile app emergencyAlerts, activityAlerts, lowBattery, dailySummary, weeklySummary, pushEnabled, emailEnabled, smsEnabled, quietHours, quietStart, quietEnd, } = req.body; // Build update data (map to DB column names) const updateData = { user_id: userId, updated_at: new Date().toISOString() }; // Alert types if (emergencyAlerts !== undefined) updateData.emergency_alerts = emergencyAlerts; if (activityAlerts !== undefined) updateData.activity_alerts = activityAlerts; if (lowBattery !== undefined) updateData.low_battery = lowBattery; if (dailySummary !== undefined) updateData.daily_summary = dailySummary; if (weeklySummary !== undefined) updateData.weekly_summary = weeklySummary; // Delivery methods if (pushEnabled !== undefined) updateData.push_enabled = pushEnabled; if (emailEnabled !== undefined) updateData.email_enabled = emailEnabled; if (smsEnabled !== undefined) updateData.sms_enabled = smsEnabled; // Quiet hours if (quietHours !== undefined) updateData.quiet_hours_enabled = quietHours; if (quietStart !== undefined) updateData.quiet_hours_start = quietStart; if (quietEnd !== undefined) updateData.quiet_hours_end = quietEnd; // Upsert (insert or update) const { data: settings, error } = await supabase .from('notification_settings') .upsert(updateData, { onConflict: 'user_id' }) .select() .single(); if (error) { console.error('Update notification settings error:', error); return res.status(500).json({ error: 'Failed to update notification settings' }); } res.json({ success: true, settings: { emergencyAlerts: settings.emergency_alerts, activityAlerts: settings.activity_alerts, lowBattery: settings.low_battery, dailySummary: settings.daily_summary, weeklySummary: settings.weekly_summary, pushEnabled: settings.push_enabled, emailEnabled: settings.email_enabled, smsEnabled: settings.sms_enabled, quietHours: settings.quiet_hours_enabled, quietStart: settings.quiet_hours_start, quietEnd: settings.quiet_hours_end, } }); } catch (error) { console.error('Update notification settings error:', error); res.status(500).json({ error: error.message }); } }); /** * GET /api/notification-settings/history * Returns notification history for current user * * Query params: * - limit: number (default 50, max 100) * - offset: number (default 0) * - type: string (filter by notification type) * - status: string (filter by status) */ router.get('/history', async (req, res) => { try { const userId = req.user.userId; const { limit = 50, offset = 0, type, status } = req.query; // Validate and cap limit const parsedLimit = Math.min(parseInt(limit) || 50, 100); const parsedOffset = parseInt(offset) || 0; const result = await getNotificationHistory(userId, { limit: parsedLimit, offset: parsedOffset, type, status }); if (result.error) { return res.status(500).json({ error: result.error }); } // Transform data for mobile app (camelCase) const history = result.data.map(item => ({ id: item.id, title: item.title, body: item.body, type: item.type, channel: item.channel, status: item.status, skipReason: item.skip_reason, data: item.data, beneficiaryId: item.beneficiary_id, createdAt: item.created_at, sentAt: item.sent_at, deliveredAt: item.delivered_at })); res.json({ history, total: result.total, limit: parsedLimit, offset: parsedOffset }); } catch (error) { console.error('Get notification history error:', error); res.status(500).json({ error: error.message }); } }); module.exports = router;