/** * Intake Diagnosis API * * GET /api/cortex/intake/diagnose?patientId=xxx&intakeId=xxx * * Returns diagnoses for an intake. * Used by DiagnoseBlock in Cortex Command Center. */ import { NextRequest, NextResponse } from 'next/server'; import { createClient } from '@/lib/auth/server'; import { z } from 'zod'; // Query parameter schema const QuerySchema = z.object({ patientId: z.string().uuid({ message: 'patientId moet een geldige UUID zijn' }), intakeId: z.string().uuid({ message: 'intakeId moet een geldige UUID zijn' }).optional(), }); // Clinical status type type ClinicalStatus = 'active' | 'recurrence' | 'relapse' | 'inactive' | 'remission' | 'resolved'; export interface DiagnosisItem { id: string; code: string; description: string; codeSystem: string; clinicalStatus: ClinicalStatus; severity: string | null; isPrimary: boolean; notes: string | null; recordedDate: string; } export interface IntakeDiagnoseResponse { intakeId: string; patientId: string; diagnoses: DiagnosisItem[]; summary: { total: number; primaryDiagnosis: DiagnosisItem | null; secondaryCount: number; hasActiveConditions: boolean; }; lastUpdated: string | null; } // Dutch labels for clinical status (not exported - Route files can only export route handlers) const CLINICAL_STATUS_LABELS: Record = { active: 'Actief', recurrence: 'Recidief', relapse: 'Terugval', inactive: 'Inactief', remission: 'Remissie', resolved: 'Hersteld', }; export async function GET(request: NextRequest) { try { // Auth check const supabase = await createClient(); const { data: { user }, error: authError, } = await supabase.auth.getUser(); if (authError || !user) { return NextResponse.json( { error: 'Niet geautoriseerd. Log opnieuw in.' }, { status: 401 } ); } // Parse and validate query parameters const searchParams = request.nextUrl.searchParams; const patientId = searchParams.get('patientId'); const intakeId = searchParams.get('intakeId'); if (!patientId) { return NextResponse.json( { error: 'Query parameter "patientId" is verplicht' }, { status: 400 } ); } const validation = QuerySchema.safeParse({ patientId, intakeId }); if (!validation.success) { const errorMessage = validation.error.issues .map((e) => e.message) .join(', '); return NextResponse.json({ error: errorMessage }, { status: 400 }); } // If no intakeId provided, get the most recent active intake for this patient let targetIntakeId = validation.data.intakeId; if (!targetIntakeId) { const { data: latestIntake, error: intakeError } = await supabase .from('intakes') .select('id') .eq('patient_id', patientId) .eq('status', 'bezig') .order('start_date', { ascending: false }) .limit(1) .maybeSingle(); if (intakeError) { console.error('Error fetching latest intake:', intakeError); return NextResponse.json( { error: 'Fout bij ophalen intake' }, { status: 500 } ); } if (!latestIntake) { return NextResponse.json( { error: 'Geen actieve intake gevonden voor deze patiƫnt' }, { status: 404 } ); } targetIntakeId = latestIntake.id; } // Fetch diagnoses (conditions linked to intake via encounter_id) const { data: conditionsData, error: conditionsError } = await supabase .from('conditions') .select('*') .eq('encounter_id', targetIntakeId) .order('recorded_date', { ascending: false }); if (conditionsError) { console.error('Error fetching diagnoses:', conditionsError); return NextResponse.json( { error: 'Fout bij ophalen diagnoses' }, { status: 500 } ); } const diagnoses: DiagnosisItem[] = (conditionsData || []).map((condition) => ({ id: condition.id, code: condition.code_code || '', description: condition.code_display || 'Onbekende diagnose', codeSystem: condition.code_system || 'ICD-10', clinicalStatus: (condition.clinical_status as ClinicalStatus) || 'active', severity: condition.severity_display, isPrimary: condition.category === 'primary-diagnosis', notes: condition.note, recordedDate: condition.recorded_date || '', })); // Build summary const primaryDiagnosis = diagnoses.find((d) => d.isPrimary) || null; const secondaryCount = diagnoses.filter((d) => !d.isPrimary).length; const hasActiveConditions = diagnoses.some( (d) => d.clinicalStatus === 'active' || d.clinicalStatus === 'recurrence' || d.clinicalStatus === 'relapse' ); // Get last updated timestamp const lastUpdated = diagnoses.length > 0 ? diagnoses[0].recordedDate : null; const response: IntakeDiagnoseResponse = { intakeId: targetIntakeId, patientId, diagnoses, summary: { total: diagnoses.length, primaryDiagnosis, secondaryCount, hasActiveConditions, }, lastUpdated, }; return NextResponse.json(response, { status: 200 }); } catch (error) { console.error('Error in intake diagnosis API:', error); return NextResponse.json( { error: 'Er ging iets mis bij het ophalen van de diagnoses.' }, { status: 500 } ); } }