import { Resend } from 'resend' import type { SupabaseClient } from '@supabase/supabase-js' import { sendWhatsAppMessage } from '@/lib/notifications/whatsapp' import { getApiKey } from '@/lib/settings' const ROUND_LABELS = ['30-day', '60-day', '90-day'] as const const NEXT_INTERVAL_DAYS: (number | null)[] = [60, 90, null] export function getRoundLabel(round: number): string { return ROUND_LABELS[round] ?? '90-day' } export function getNextRecheckDate(verifiedAt: string, currentRound: number): string | null { const days = NEXT_INTERVAL_DAYS[currentRound] if (days === null || days === undefined) return null const base = new Date(verifiedAt) base.setDate(base.getDate() + days) return base.toISOString().split('T')[0] } export function shouldSendRecheck( recheckDate: string | null, round: number, today: string = new Date().toISOString().split('T')[0], ): boolean { if (!recheckDate || round >= 3) return false return recheckDate <= today } export async function sendEffectivenessRecheckNotifications( supabase: SupabaseClient, ): Promise<{ notified: number }> { const today = new Date().toISOString().split('T')[0] const { data: capas } = await supabase .from('capa_actions') .select(` id, description, effectiveness_recheck_date, effectiveness_recheck_round, verified_at, incident_id, incidents (reference_no), verifier:users!verified_by (email, name, phone) `) .in('status', ['verified', 'closed']) .not('effectiveness_recheck_date', 'is', null) .lt('effectiveness_recheck_round', 3) if (!capas || capas.length === 0) return { notified: 0 } const resend = new Resend(process.env.RESEND_API_KEY) const from = process.env.RESEND_FROM_EMAIL ?? 'onboarding@resend.dev' const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'http://localhost:3000' let whatsappPhoneId: string | null = null let whatsappToken: string | null = null try { whatsappPhoneId = await getApiKey(supabase, 'META_WHATSAPP_PHONE_NUMBER_ID') whatsappToken = await getApiKey(supabase, 'META_WHATSAPP_ACCESS_TOKEN') } catch { // WhatsApp not configured — email only } let notified = 0 for (const capa of capas) { const recheckDate = (capa as { effectiveness_recheck_date: string | null }).effectiveness_recheck_date const round = (capa as { effectiveness_recheck_round: number }).effectiveness_recheck_round if (!shouldSendRecheck(recheckDate, round, today)) continue const verifierEmail = (capa.verifier as unknown as { email: string } | null)?.email const verifierName = (capa.verifier as unknown as { name: string } | null)?.name ?? 'HSE Officer' const verifierPhone = (capa.verifier as unknown as { phone: string | null } | null)?.phone ?? '' if (!verifierEmail) continue const incidentRef = (capa.incidents as unknown as { reference_no: string | null } | null)?.reference_no ?? (capa as { incident_id: string }).incident_id const roundLabel = getRoundLabel(round) const capaDesc = (capa as { description: string }).description const capaUrl = `${siteUrl}/ims/hse/capa/${(capa as { id: string }).id}` const subject = `[IMS] ${roundLabel} effectiveness check — ${incidentRef}` const html = `
Hi ${verifierName},
This is the ${roundLabel} effectiveness check for a corrective action you verified on incident ${incidentRef}.
Action: ${capaDesc}
Please confirm the corrective action is still in place and effective.
` const text = `${roundLabel} effectiveness check for ${incidentRef}\nAction: ${capaDesc}\n${capaUrl}` const { error } = await resend.emails.send({ from, to: [verifierEmail], subject, html, text }) if (error) { console.error('Effectiveness recheck email error:', error) continue } // WhatsApp (non-blocking, best-effort) if (whatsappPhoneId && whatsappToken && verifierPhone) { sendWhatsAppMessage( verifierPhone, 'ims_effectiveness_recheck', [roundLabel, incidentRef, capaDesc], whatsappPhoneId, whatsappToken, ).catch(err => console.error('WhatsApp recheck error:', err)) } // Advance round const verifiedAt = (capa as { verified_at: string }).verified_at const nextDate = getNextRecheckDate(verifiedAt, round) await supabase .from('capa_actions') .update({ effectiveness_recheck_round: round + 1, effectiveness_recheck_date: nextDate ?? null, }) .eq('id', (capa as { id: string }).id) notified++ } return { notified } }