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 { capaActions, incidents, users } from '@/lib/db/schema' import { aliasedTable, eq, asc } from 'drizzle-orm' import { createInAppNotifications } from '@/lib/notifications/in-app' export async function GET() { const session = await getSession() if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) const ownerAlias = aliasedTable(users, 'owner') const rows = await withUser(session.sub, async tx => { let q = tx .select({ id: capaActions.id, incidentId: capaActions.incidentId, rootCauseRef: capaActions.rootCauseRef, description: capaActions.description, ownerUserId: capaActions.ownerUserId, department: capaActions.department, dueDate: capaActions.dueDate, priority: capaActions.priority, status: capaActions.status, completedAt: capaActions.completedAt, verifiedBy: capaActions.verifiedBy, verifiedAt: capaActions.verifiedAt, createdAt: capaActions.createdAt, incidentReferenceNo: incidents.referenceNo, incidentType: incidents.incidentType, ownerName: ownerAlias.name, ownerEmail: ownerAlias.email, }) .from(capaActions) .leftJoin(ownerAlias, eq(capaActions.ownerUserId, ownerAlias.id)) .leftJoin(incidents, eq(capaActions.incidentId, incidents.id)) .orderBy(asc(capaActions.dueDate)) if (session.role === 'supervisor' || session.role === 'worker') { q = q.where(eq(capaActions.ownerUserId, session.sub)) as typeof q } return q }) const data = rows.map(r => ({ id: r.id, incident_id: r.incidentId, root_cause_ref: r.rootCauseRef, description: r.description, owner_user_id: r.ownerUserId, department: r.department, due_date: r.dueDate, priority: r.priority, status: r.status, completed_at: r.completedAt, verified_by: r.verifiedBy, verified_at: r.verifiedAt, created_at: r.createdAt, incidents: { reference_no: r.incidentReferenceNo, incident_type: r.incidentType }, owner: { name: r.ownerName, email: r.ownerEmail }, })) return NextResponse.json(data) } export async function POST(request: NextRequest) { const session = await getSession() if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) if (!['hse', 'admin'].includes(session.role)) return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) const body = await request.json() const { incident_id, description, owner_user_id, department, due_date, priority, root_cause_ref } = body if (!incident_id || !description || !owner_user_id || !due_date) return NextResponse.json({ error: 'Missing required fields' }, { status: 422 }) let capaId!: string await withUser(session.sub, async tx => { const [capa] = await tx .insert(capaActions) .values({ incidentId: incident_id, description, ownerUserId: owner_user_id, department: department || '', dueDate: due_date, priority: priority ?? 'med', rootCauseRef: root_cause_ref ?? null, }) .returning({ id: capaActions.id }) if (!capa) throw new Error('Insert failed') capaId = capa.id await writeAuditLog(tx, 'capa_actions', capa.id, 'created', { incident_id, description, owner_user_id, department, due_date, }) }) await createInAppNotifications([{ userId: owner_user_id, title: `CAPA assigned to you, due ${due_date}`, link: `/hse/capa/${capaId}`, incidentId: incident_id, capaId, }]) return NextResponse.json({ id: capaId }, { status: 201 }) }