Files
ims/lib/notifications/email.ts
T
adminandClaude Sonnet 4.6 25f923f530 feat(db): phase 4 group 1 — lib/ settings + notifications to Drizzle
Convert lib/settings.ts, lib/notifications/{in-app,email,capa-escalation,
effectiveness-recheck}.ts from Supabase PostgREST to Drizzle asAdmin queries.
Drop supabase arg from all call sites in app/api/ and cron routes. Rewrite
notification unit tests to mock @/lib/db/with-user instead of SupabaseClient.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 16:37:51 +08:00

64 lines
2.0 KiB
TypeScript

import 'server-only'
import { Resend } from 'resend'
import { asAdmin } from '@/lib/db/with-user'
import { users, incidents, sites } from '@/lib/db/schema'
import { and, eq, inArray } from 'drizzle-orm'
import { newIncidentTemplate } from '@/lib/notifications/templates/new-incident'
export async function sendNewIncidentEmail(
incidentId: string,
siteId: string,
reference_no: string,
incidentType: string,
): Promise<void> {
const recipients = await asAdmin(db =>
db.select({ email: users.email })
.from(users)
.where(and(
inArray(users.role, ['supervisor', 'hse']),
eq(users.siteId, siteId),
))
)
if (!recipients || recipients.length === 0) return
const to = recipients.map(r => r.email).filter(Boolean) as string[]
if (to.length === 0) return
const incidentRows = await asAdmin(db =>
db.select({
reportedAt: incidents.reportedAt,
siteName: sites.name,
reporterName: users.name,
})
.from(incidents)
.leftJoin(sites, eq(incidents.siteId, sites.id))
.leftJoin(users, eq(incidents.reportedBy, users.id))
.where(eq(incidents.id, incidentId))
.limit(1)
)
const incident = incidentRows[0]
const siteName = incident?.siteName ?? 'Unknown Site'
const reporterName = incident?.reporterName ?? 'Unknown'
const reportedAt = incident?.reportedAt
? new Date(incident.reportedAt).toLocaleString('en-MY', { timeZone: 'Asia/Kuala_Lumpur' })
: '-'
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'http://localhost:3000'
const { subject, html, text } = newIncidentTemplate({
reference_no,
incident_type: incidentType,
site_name: siteName,
reporter_name: reporterName,
reported_at: reportedAt,
site_url: siteUrl,
incident_id: incidentId,
})
const resend = new Resend(process.env.RESEND_API_KEY)
const from = process.env.RESEND_FROM_EMAIL ?? 'onboarding@resend.dev'
const { error } = await resend.emails.send({ from, to, subject, html, text })
if (error) console.error('Resend error:', error)
}