export const dynamic = 'force-dynamic' import { NextRequest, NextResponse } from 'next/server' import { createClient } from '@/lib/supabase/server' import { anthropic } from '@/lib/claude/client' export async function POST( _request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { id } = await params const supabase = await createClient() const { data: { user }, error: authError } = await supabase.auth.getUser() if (authError || !user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) const { data: profile } = await supabase.from('users').select('role').eq('id', user.id).single() if (!profile || !['hse', 'admin'].includes(profile.role)) return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) const { data: incident } = await supabase .from('incidents') .select('id, incident_type, description, injury_involved, asset_involved, medical_status') .eq('id', id) .single() if (!incident) return NextResponse.json({ error: 'Not found' }, { status: 404 }) const inc = incident as { incident_type: string description: string injury_involved: boolean asset_involved: boolean medical_status: string | null } const message = await anthropic.messages.create({ model: 'claude-opus-4-8', thinking: { type: 'adaptive' }, max_tokens: 1024, tools: [{ name: 'suggest_triage', description: 'Suggest severity rating and NADOPOD 2004 DOSH classification for a warehouse incident', input_schema: { type: 'object' as const, properties: { severity: { type: 'number', description: '1=minor, 2=low, 3=moderate, 4=serious, 5=critical/fatality' }, is_fatality: { type: 'boolean' }, is_serious_bodily_injury: { type: 'boolean', description: 'Fracture, amputation, blindness, serious burn, or similar' }, is_dangerous_occurrence: { type: 'boolean', description: 'Structural collapse, explosion, fire, scaffold collapse, etc.' }, is_occupational_disease: { type: 'boolean', description: 'Disease arising from workplace exposure' }, rationale: { type: 'string', description: 'One-sentence rationale citing NADOPOD 2004 where applicable' }, }, required: [ 'severity', 'is_fatality', 'is_serious_bodily_injury', 'is_dangerous_occurrence', 'is_occupational_disease', 'rationale', ], }, }], tool_choice: { type: 'tool', name: 'suggest_triage' }, messages: [{ role: 'user', content: `You are an HSE triage specialist for a Malaysian 3PL warehouse. Assess this incident under NADOPOD 2004. Incident type: ${inc.incident_type} Description: ${inc.description} Injury involved: ${inc.injury_involved ? 'yes' : 'no'} Medical status: ${inc.medical_status ?? 'N/A'} Asset/equipment involved: ${inc.asset_involved ? 'yes' : 'no'} Suggest severity (1–5) and tick the appropriate NADOPOD 2004 flags. Give a one-sentence rationale.`, }], }) const toolBlock = message.content.find(b => b.type === 'tool_use') if (!toolBlock || toolBlock.type !== 'tool_use') return NextResponse.json({ error: 'AI suggestion failed' }, { status: 500 }) const input = toolBlock.input as { severity?: unknown is_fatality?: unknown is_serious_bodily_injury?: unknown is_dangerous_occurrence?: unknown is_occupational_disease?: unknown rationale?: unknown } if ( typeof input.severity !== 'number' || typeof input.is_fatality !== 'boolean' || typeof input.is_serious_bodily_injury !== 'boolean' || typeof input.is_dangerous_occurrence !== 'boolean' || typeof input.is_occupational_disease !== 'boolean' || typeof input.rationale !== 'string' ) { return NextResponse.json({ error: 'AI returned unexpected structure' }, { status: 500 }) } await supabase.rpc('write_audit_log', { p_table_name: 'incidents', p_record_id: id, p_action: 'ai_triage_suggest', p_new_value: { suggestion: toolBlock.input, model: 'claude-opus-4-8' } as never, }) return NextResponse.json(toolBlock.input) }