Files
adminandClaude Sonnet 4.6 98f5c4e421 feat(db): phase 4 group 3 — incident routes to Drizzle
Convert all 11 incident API routes from Supabase PostgREST to Drizzle
ORM with withUser/asAdmin/writeAuditLog patterns and RLS enforcement.
Only uploadEvidenceFile retains supabase client (Phase 5 storage work).

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

60 lines
2.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 } from '@/lib/db/schema'
import { eq } from 'drizzle-orm'
interface TriageBody {
severity: number
is_fatality: boolean
is_serious_bodily_injury: boolean
is_dangerous_occurrence: boolean
is_occupational_disease: boolean
triage_notes: string | null
}
export async function PATCH(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params
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: TriageBody = await request.json()
if (body.severity < 1 || body.severity > 5)
return NextResponse.json({ error: 'severity must be 15' }, { status: 422 })
const [incident] = await withUser(session.sub, async tx =>
tx.select({ status: incidents.status }).from(incidents).where(eq(incidents.id, id)).limit(1)
)
if (!incident) return NextResponse.json({ error: 'Not found' }, { status: 404 })
if (incident.status !== 'reported')
return NextResponse.json({ error: 'Incident is not in reported status' }, { status: 409 })
await withUser(session.sub, async tx => {
await tx.update(incidents).set({
severity: body.severity,
isFatality: body.is_fatality,
isSeriousBodilyInjury: body.is_serious_bodily_injury,
isDangerousOccurrence: body.is_dangerous_occurrence,
isOccupationalDisease: body.is_occupational_disease,
triageNotes: body.triage_notes ?? null,
triagedBy: session.sub,
triagedAt: new Date(),
status: 'triaged',
}).where(eq(incidents.id, id))
await writeAuditLog(tx, 'incidents', id, 'triage', {
severity: body.severity, status: 'triaged', triaged_by: session.sub,
})
})
return NextResponse.json({ ok: true })
}