export const dynamic = 'force-dynamic' import { NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth/get-session' import { withUser } from '@/lib/db/with-user' import { writeAuditLog } from '@/lib/db/audit' import { incidents, sites, zones } from '@/lib/db/schema' import { eq, desc } from 'drizzle-orm' import { rowsToCsv } from '@/lib/csv' export async function GET(request: NextRequest) { const session = await getSession() if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) const role = request.nextUrl.searchParams.get('role') ?? 'hse' const allowedRoles: Record = { hse: ['hse', 'admin'], management: ['management', 'admin'], } if (!allowedRoles[role] || !allowedRoles[role].includes(session.role)) { return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) } const rows = await withUser(session.sub, async tx => tx.select({ referenceNo: incidents.referenceNo, incidentType: incidents.incidentType, status: incidents.status, severity: incidents.severity, reportedAt: incidents.reportedAt, closedAt: incidents.closedAt, injuryInvolved: incidents.injuryInvolved, medicalStatus: incidents.medicalStatus, lostDays: incidents.lostDays, siteName: sites.name, zoneName: zones.name, }) .from(incidents) .leftJoin(sites, eq(incidents.siteId, sites.id)) .leftJoin(zones, eq(incidents.zoneId, zones.id)) .orderBy(desc(incidents.reportedAt)) .limit(10000) ) const headers = [ 'Reference', 'Type', 'Status', 'Severity', 'Site', 'Zone', 'Reported At', 'Closed At', 'Injury Involved', 'Medical Status', 'Lost Days', ] const csvRows = rows.map(inc => [ inc.referenceNo ?? '', inc.incidentType, inc.status, String(inc.severity ?? ''), inc.siteName ?? '', inc.zoneName ?? '', inc.reportedAt ? new Date(inc.reportedAt).toISOString().split('T')[0] : '', inc.closedAt ? new Date(inc.closedAt).toISOString().split('T')[0] : '', inc.injuryInvolved ? 'Yes' : 'No', inc.medicalStatus ?? '', String(inc.lostDays ?? ''), ]) const csv = rowsToCsv(headers, csvRows) const safeRole = role.replace(/[^a-z0-9]/gi, '') const filename = `incidents-${safeRole}-${new Date().toISOString().split('T')[0]}.csv` await withUser(session.sub, async tx => writeAuditLog(tx, 'incidents', session.sub, 'export_csv', { role, row_count: rows.length }) ) return new NextResponse(csv, { status: 200, headers: { 'Content-Type': 'text/csv; charset=utf-8', 'Content-Disposition': `attachment; filename="${filename}"`, }, }) }