Files
triqura-ecd/app/api/cortex/context/route.ts
colinislit cf26022583 feat(cortex): Epic 0 - Foundation & Context voor V2 architectuur
Implementeert de basis voor de Cortex V2 three-layer architecture.

E0.S1 - CortexContext Types (lib/cortex/types.ts):
- EscalationReason type voor Reflex → Orchestrator
- LocalClassificationResult met ambiguity detection
- CortexContext voor AI classificatie context
- IntentChain en IntentAction voor multi-intent flows
- NudgeSuggestion voor proactieve suggesties
- CONFIDENCE_THRESHOLD (0.7) en AMBIGUITY_THRESHOLD (0.1)
- getCurrentShift() utility (DRY - herbruikbaar)

E0.S2 - Context API (app/api/cortex/context/route.ts):
- GET endpoint voor huidige context
- Haalt agenda vandaag op uit database
- Retourneert CortexContext object

E0.S3 - Feature Flags (lib/config/feature-flags.ts):
- CORTEX_V2_ENABLED, CORTEX_MULTI_INTENT
- CORTEX_NUDGE, CORTEX_LOGGING
- isFeatureEnabled() helper
- Dev mode: default true

E0.S4 - CortexStore V2 (stores/cortex-store.ts):
- Types geïmporteerd uit lib/cortex (DRY)
- ChatEntities type voor AI responses (string-based)
- V2 state: context, activeChain, chainHistory, suggestions
- V2 actions: chain management, nudge management, clarification

E0.S5 - Classification Logging (lib/cortex/logger.ts):
- PII sanitization (BSN, tel, namen, email)
- logClassification(), logEscalation(), logNudge()
- logPerformance() met threshold checks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:46:35 +01:00

112 lines
3.1 KiB
TypeScript

import { NextResponse } from 'next/server';
import { createClient } from '@/lib/auth/server';
import { getCurrentShift } from '@/lib/cortex/types';
import type { CortexContext } from '@/lib/cortex/types';
/**
* Cortex Context API
*
* GET /api/cortex/context
*
* Returns the current context for AI classification.
* Includes: shift, agenda today, recent intents.
* Note: activePatient is set client-side via store.
*/
export async function GET() {
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 }
);
}
// Get practitioner info
const { data: practitioner } = await supabase
.from('practitioners')
.select('id')
.eq('user_id', user.id)
.single();
// Get today's date range
const today = new Date();
today.setHours(0, 0, 0, 0);
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
// Fetch today's appointments
const { data: appointments } = await supabase
.from('encounters')
.select(
`
id,
period_start,
type_display,
patient:patients(id, name_given, name_prefix, name_family)
`
)
.eq('practitioner_id', practitioner?.id ?? '')
.gte('period_start', today.toISOString())
.lt('period_start', tomorrow.toISOString())
.order('period_start');
// Build context object
const context: CortexContext = {
activePatient: null, // Set by client via store
currentView: 'dashboard', // Default, overridden by client
shift: getCurrentShift(),
currentTime: new Date(),
agendaToday: (appointments || []).map((apt) => {
// Handle the nested patient relation
const patient = apt.patient as {
id: string;
name_given: string[];
name_prefix: string | null;
name_family: string;
} | null;
// Construct full name: "Voornaam [tussenvoegsel] Achternaam"
const fullName = patient
? [
patient.name_given?.[0],
patient.name_prefix,
patient.name_family,
]
.filter(Boolean)
.join(' ')
: 'Onbekend';
return {
time: new Date(apt.period_start).toLocaleTimeString('nl-NL', {
hour: '2-digit',
minute: '2-digit',
}),
patientName: fullName,
patientId: patient?.id || '',
type: apt.type_display || 'afspraak',
};
}),
recentIntents: [], // Populated by client from store history
};
return NextResponse.json({ context }, { status: 200 });
} catch (error) {
console.error('[Cortex Context API] Error:', error);
return NextResponse.json(
{
error:
'Er ging iets mis bij het ophalen van context. Probeer het opnieuw.',
},
{ status: 500 }
);
}
}