Files
colinislit a789bebe96 feat: rapportage API, speech recorder refactor, docs reorganisatie
Multiple features and improvements:

Reports/Rapportage API:
- Created REST API endpoints: /api/reports (GET/POST), /api/reports/[id] (GET/PATCH/DELETE)
- Added /api/reports/classify endpoint for AI classification
- Supabase migrations: reports table + RLS policies
- Server utilities: api-client.ts for DRY fetch logic
- Type definitions: lib/types/report.ts with Zod schemas
- Removed old rapportage-modal component (replaced by split-view)

Speech Recorder Refactor:
- Moved speech-recorder from intake-specific to shared components/
- Updated treatment-advice-form to use new location
- Updated intake actions for speech functionality

UI Components (shadcn):
- Added dialog, dropdown-menu, toast, toaster components
- Added use-toast hook for toast notifications

Documentation:
- Reorganized docs/release/ → docs/reports/ for better structure
- Archived old specs to docs/specs/archive/
- Added screening-system.mdx documentation
- Added rapportage-split-view-design.md
- Added UI screenshots for troubleshooting

Dependencies:
- Updated package.json and pnpm-lock.yaml
- Regenerated database.types.ts from Supabase

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 14:14:06 +01:00

139 lines
3.6 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { createClient } from '@/lib/auth/server';
const uuidSchema = z.string().uuid('reportId moet een geldige UUID zijn');
export async function GET(
_request: NextRequest,
{ params }: { params: Promise<{ reportId: string }> }
) {
try {
const { reportId } = await params;
if (!uuidSchema.safeParse(reportId).success) {
return NextResponse.json(
{ error: 'reportId moet een geldige UUID zijn' },
{ status: 400 }
);
}
const supabase = await createClient();
const { data, error } = await supabase
.from('reports')
.select('*')
.eq('id', reportId)
.is('deleted_at', null)
.single();
if (error) {
if (error.code === 'PGRST116') {
return NextResponse.json({ error: 'Rapport niet gevonden' }, { status: 404 });
}
console.error('Error fetching report:', error);
return NextResponse.json(
{ error: 'Fout bij ophalen rapport', details: error.message },
{ status: 500 }
);
}
return NextResponse.json(data);
} catch (error) {
console.error('Unexpected error in GET /api/reports/[reportId]:', error);
return NextResponse.json(
{ error: 'Onverwachte serverfout' },
{ status: 500 }
);
}
}
export async function PATCH(
request: NextRequest,
{ params }: { params: Promise<{ reportId: string }> }
) {
try {
const { reportId } = await params;
const body = await request.json();
if (!uuidSchema.safeParse(reportId).success) {
return NextResponse.json(
{ error: 'reportId moet een geldige UUID zijn' },
{ status: 400 }
);
}
const supabase = await createClient();
const { data, error } = await supabase
.from('reports')
.update({ ...body, updated_at: new Date().toISOString() })
.eq('id', reportId)
.select('*')
.single();
if (error) {
if (error.code === 'PGRST116') {
return NextResponse.json({ error: 'Rapport niet gevonden' }, { status: 404 });
}
console.error('Error updating report:', error);
return NextResponse.json(
{ error: 'Fout bij updaten rapport', details: error.message },
{ status: 500 }
);
}
return NextResponse.json(data);
} catch (error) {
console.error('Unexpected error in PATCH /api/reports/[reportId]:', error);
if (error instanceof SyntaxError) {
return NextResponse.json(
{ error: 'Ongeldige JSON in request body' },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Onverwachte serverfout' },
{ status: 500 }
);
}
}
export async function DELETE(
_request: NextRequest,
{ params }: { params: Promise<{ reportId: string }> }
) {
try {
const { reportId } = await params;
if (!uuidSchema.safeParse(reportId).success) {
return NextResponse.json(
{ error: 'reportId moet een geldige UUID zijn' },
{ status: 400 }
);
}
const supabase = await createClient();
const { error } = await supabase
.from('reports')
.update({ deleted_at: new Date().toISOString() })
.eq('id', reportId);
if (error) {
console.error('Error deleting report:', error);
return NextResponse.json(
{ error: 'Verwijderen mislukt', details: error.message },
{ status: 500 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
console.error('Unexpected error in DELETE /api/reports/[reportId]:', error);
return NextResponse.json(
{ error: 'Onverwachte serverfout' },
{ status: 500 }
);
}
}