feat(cortex): no-show casus — intent flow, brief-rescript en document artifact
Cortex handelt een no-show af vanuit één chatcommando: afspraak annuleren (declarabiliteits-nudge), en de openstaande concept- huisartsbrief wordt via LLM herschreven en ter review aangeboden in een document artifact (human-in-the-loop, PATCH dispatch zet status op verzendklaar). - API-routes: context, rescript, cancel, dispatch - NoShowDocumentBlock: review/edit UI met origineel-vergelijk - Mock-data voor concept huisartsbrief - PRD, FO, bouwplan en epics in docs/intent/noshow-case/ Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
54
app/api/cortex/noshow/dispatch/route.ts
Normal file
54
app/api/cortex/noshow/dispatch/route.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
import { createClient } from '@/lib/auth/server';
|
||||
import { isMockDocument } from '@/lib/cortex/mock-data/noshow';
|
||||
|
||||
const DispatchSchema = z.object({
|
||||
documentId: z.string().min(1),
|
||||
finalContent: z.string().min(1, 'Definitieve inhoud is verplicht'),
|
||||
});
|
||||
|
||||
export async function PATCH(request: NextRequest) {
|
||||
const supabase = await createClient();
|
||||
const { data: { user }, error: authError } = await supabase.auth.getUser();
|
||||
if (authError || !user) {
|
||||
return NextResponse.json({ error: 'Niet geautoriseerd' }, { status: 401 });
|
||||
}
|
||||
|
||||
let body: z.infer<typeof DispatchSchema>;
|
||||
try {
|
||||
body = DispatchSchema.parse(await request.json());
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'Ongeldige invoer' }, { status: 400 });
|
||||
}
|
||||
|
||||
const { documentId, finalContent } = body;
|
||||
|
||||
// Mock path — demo flow
|
||||
if (isMockDocument(documentId)) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
documentId,
|
||||
newStatus: 'ready_for_dispatch',
|
||||
message: 'Brief verzendklaar gemaakt (demo)',
|
||||
});
|
||||
}
|
||||
|
||||
// Productie path
|
||||
const { error } = await supabase
|
||||
.from('reports')
|
||||
.update({
|
||||
status: 'ready_for_dispatch',
|
||||
structured_data: { content: finalContent },
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.eq('id', documentId)
|
||||
.eq('user_id', user.id);
|
||||
|
||||
if (error) {
|
||||
console.error('[noshow/dispatch] DB error:', error);
|
||||
return NextResponse.json({ error: 'Opslaan mislukt' }, { status: 500 });
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true, documentId, newStatus: 'ready_for_dispatch' });
|
||||
}
|
||||
Reference in New Issue
Block a user