// src/services/push.service.js const webpush = require('web-push'); const config = require('../config'); const pushRepo = require('../repositories/push.repo'); const hasVapid = !!config.vapid.publicKey && !!config.vapid.privateKey; if (!hasVapid) { console.warn('[Push] VAPID keys não definidas. Push desativado.'); } else { webpush.setVapidDetails(config.vapid.subject, config.vapid.publicKey, config.vapid.privateKey); } async function sendWithRetry(subscription, message, tries = 2) { try { return await webpush.sendNotification(subscription, message); } catch (err) { const code = err?.statusCode; if ((code === 429 || code >= 500) && tries > 1) { await new Promise((r) => setTimeout(r, 1000)); return sendWithRetry(subscription, message, tries - 1); } throw err; } } async function sendPushToUser(userId, payload) { if (!hasVapid) return; const subs = await pushRepo.listByUser(userId); if (!subs.length) return; const message = JSON.stringify(payload); await Promise.allSettled( subs.map(async (s) => { const subscription = { endpoint: s.endpoint, keys: { p256dh: s.p256dh, auth: s.auth }, }; try { await sendWithRetry(subscription, message); } catch (err) { const code = err?.statusCode; if (code === 404 || code === 410) { await pushRepo.deleteById(s.id); } else { console.error('[Push] erro ao enviar:', err.message); } } }) ); } module.exports = { sendPushToUser };