Files
triqura-ecd/app/epd/patients/[id]/intakes/[intakeId]/actions.ts
2025-11-23 10:13:00 +01:00

416 lines
13 KiB
TypeScript

'use server';
import { revalidatePath } from 'next/cache';
import { createClient } from '@/lib/auth/server';
import type { Database } from '@/lib/supabase/database.types';
export type Encounter = Database['public']['Tables']['encounters']['Row'];
export type RiskAssessment = Database['public']['Tables']['risk_assessments']['Row'];
export type Anamnese = Database['public']['Tables']['anamneses']['Row'];
export type Examination = Database['public']['Tables']['examinations']['Row'];
export type Condition = Database['public']['Tables']['conditions']['Row'];
export type KindcheckData = {
hasChildren?: boolean;
childCount?: number;
ages?: string;
concerns?: boolean;
concernsNotes?: string;
actionTaken?: boolean;
actionNotes?: string;
notes?: string;
};
function buildPath(patientId: string, intakeId: string, tab?: string) {
const base = `/epd/patients/${patientId}/intakes/${intakeId}`;
return tab ? `${base}/${tab}` : base;
}
async function getSupabase() {
return createClient();
}
// ---------------- Contacts ----------------
export async function getContactMoments(intakeId: string) {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('encounters')
.select('*')
.eq('intake_id', intakeId)
.order('period_start', { ascending: false });
if (error) {
console.error('getContactMoments error', error);
throw new Error('Kon contactmomenten niet ophalen');
}
return data || [];
}
export interface ContactPayload {
patientId: string;
intakeId: string;
date: string;
startTime: string;
endTime?: string;
type: string;
location?: string;
notes?: string;
}
export async function createContactMoment(input: ContactPayload) {
const supabase = await getSupabase();
const startIso = new Date(`${input.date}T${input.startTime}:00`).toISOString();
const endIso = input.endTime ? new Date(`${input.date}T${input.endTime}:00`).toISOString() : null;
const { error } = await supabase.from('encounters').insert({
patient_id: input.patientId,
intake_id: input.intakeId,
class_code: input.location || 'AMB',
class_display: input.location || 'Onbekend',
status: 'finished',
type_code: input.type,
type_display: input.type,
period_start: startIso,
period_end: endIso,
notes: input.notes,
});
if (error) {
console.error('createContactMoment error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(input.patientId, input.intakeId, 'contacts'));
revalidatePath(buildPath(input.patientId, input.intakeId));
}
export async function deleteContactMoment(patientId: string, intakeId: string, encounterId: string) {
const supabase = await getSupabase();
const { error } = await supabase.from('encounters').delete().eq('id', encounterId);
if (error) {
console.error('deleteContactMoment error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(patientId, intakeId, 'contacts'));
revalidatePath(buildPath(patientId, intakeId));
}
// ---------------- Kindcheck ----------------
export async function getKindcheck(intakeId: string): Promise<KindcheckData> {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('intakes')
.select('kindcheck_data')
.eq('id', intakeId)
.maybeSingle();
if (error) {
console.error('getKindcheck error', error);
throw new Error('Kon kindcheck niet ophalen');
}
return (data?.kindcheck_data as KindcheckData) || {};
}
export async function saveKindcheck(
patientId: string,
intakeId: string,
payload: KindcheckData
) {
const supabase = await getSupabase();
const { error } = await supabase
.from('intakes')
.update({ kindcheck_data: payload })
.eq('id', intakeId);
if (error) {
console.error('saveKindcheck error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(patientId, intakeId, 'kindcheck'));
revalidatePath(buildPath(patientId, intakeId));
}
// ---------------- Risks ----------------
export async function getRiskAssessments(intakeId: string) {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('risk_assessments')
.select('*')
.eq('intake_id', intakeId)
.order('assessment_date', { ascending: false });
if (error) {
console.error('getRiskAssessments error', error);
throw new Error('Kon risicotaxaties niet ophalen');
}
return data || [];
}
export interface RiskPayload {
patientId: string;
intakeId: string;
date: string;
type: string;
level: string;
rationale: string;
measures?: string;
evaluationDate?: string;
notes?: string;
}
export async function createRiskAssessment(payload: RiskPayload) {
const supabase = await getSupabase();
const { error } = await supabase.from('risk_assessments').insert({
intake_id: payload.intakeId,
assessment_date: payload.date,
risk_type: payload.type,
risk_level: payload.level,
rationale: payload.rationale,
measures: payload.measures,
evaluation_date: payload.evaluationDate || null,
notes: payload.notes,
});
if (error) {
console.error('createRiskAssessment error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(payload.patientId, payload.intakeId, 'risk'));
revalidatePath(buildPath(payload.patientId, payload.intakeId));
}
export async function deleteRiskAssessment(patientId: string, intakeId: string, riskId: string) {
const supabase = await getSupabase();
const { error } = await supabase.from('risk_assessments').delete().eq('id', riskId);
if (error) {
console.error('deleteRiskAssessment error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(patientId, intakeId, 'risk'));
revalidatePath(buildPath(patientId, intakeId));
}
// ---------------- Anamneses ----------------
export async function getAnamneses(intakeId: string) {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('anamneses')
.select('*')
.eq('intake_id', intakeId)
.order('anamnese_date', { ascending: false });
if (error) {
console.error('getAnamneses error', error);
throw new Error('Kon anamneses niet ophalen');
}
return data || [];
}
export interface AnamnesePayload {
patientId: string;
intakeId: string;
date: string;
type: string;
content: string;
notes?: string;
}
export async function createAnamnese(payload: AnamnesePayload) {
const supabase = await getSupabase();
const { error } = await supabase.from('anamneses').insert({
intake_id: payload.intakeId,
anamnese_date: payload.date,
anamnese_type: payload.type,
content: payload.content,
notes: payload.notes,
});
if (error) {
console.error('createAnamnese error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(payload.patientId, payload.intakeId, 'anamnese'));
revalidatePath(buildPath(payload.patientId, payload.intakeId));
}
export async function deleteAnamnese(patientId: string, intakeId: string, anamneseId: string) {
const supabase = await getSupabase();
const { error } = await supabase.from('anamneses').delete().eq('id', anamneseId);
if (error) {
console.error('deleteAnamnese error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(patientId, intakeId, 'anamnese'));
revalidatePath(buildPath(patientId, intakeId));
}
// ---------------- Examinations (including ROM) ----------------
export async function getExaminations(intakeId: string) {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('examinations')
.select('*')
.eq('intake_id', intakeId)
.order('examination_date', { ascending: false });
if (error) {
console.error('getExaminations error', error);
throw new Error('Kon onderzoeken niet ophalen');
}
return data || [];
}
export interface ExaminationPayload {
patientId: string;
intakeId: string;
date: string;
type: string;
findings: string;
performer?: string;
reason?: string;
notes?: string;
isRom?: boolean;
}
export async function createExamination(payload: ExaminationPayload) {
const supabase = await getSupabase();
const { error } = await supabase.from('examinations').insert({
intake_id: payload.intakeId,
examination_date: payload.date,
examination_type: payload.isRom ? 'ROM' : payload.type,
findings: payload.findings,
performed_by: payload.performer,
reason: payload.reason,
notes: payload.notes,
});
if (error) {
console.error('createExamination error', error);
throw new Error(error.message);
}
const tab = payload.isRom ? 'rom' : 'examination';
revalidatePath(buildPath(payload.patientId, payload.intakeId, tab));
revalidatePath(buildPath(payload.patientId, payload.intakeId));
}
export async function deleteExamination(patientId: string, intakeId: string, examinationId: string) {
const supabase = await getSupabase();
const { error } = await supabase.from('examinations').delete().eq('id', examinationId);
if (error) {
console.error('deleteExamination error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(patientId, intakeId, 'examination'));
revalidatePath(buildPath(patientId, intakeId, 'rom'));
revalidatePath(buildPath(patientId, intakeId));
}
// ---------------- Diagnoses ----------------
export async function getDiagnoses(intakeId: string) {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('conditions')
.select('*')
.eq('encounter_id', intakeId)
.order('recorded_date', { ascending: false });
if (error) {
console.error('getDiagnoses error', error);
throw new Error('Kon diagnoses niet ophalen');
}
return data || [];
}
export interface DiagnosisPayload {
patientId: string;
intakeId: string;
code: string;
description: string;
severity?: string;
status?: string;
notes?: string;
}
export async function createDiagnosis(payload: DiagnosisPayload) {
const supabase = await getSupabase();
const { error } = await supabase.from('conditions').insert({
patient_id: payload.patientId,
encounter_id: payload.intakeId,
code_code: payload.code,
code_display: payload.description,
code_system: 'DSM-5',
clinical_status: payload.status || 'active',
severity_display: payload.severity || null,
note: payload.notes,
recorded_date: new Date().toISOString(),
});
if (error) {
console.error('createDiagnosis error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(payload.patientId, payload.intakeId, 'diagnosis'));
revalidatePath(buildPath(payload.patientId, payload.intakeId));
}
export async function deleteDiagnosis(patientId: string, intakeId: string, diagnosisId: string) {
const supabase = await getSupabase();
const { error } = await supabase.from('conditions').delete().eq('id', diagnosisId);
if (error) {
console.error('deleteDiagnosis error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(patientId, intakeId, 'diagnosis'));
revalidatePath(buildPath(patientId, intakeId));
}
// ---------------- Treatment Advice ----------------
export async function getTreatmentAdvice(intakeId: string) {
const supabase = await getSupabase();
const { data, error } = await supabase
.from('intakes')
.select('treatment_advice')
.eq('id', intakeId)
.maybeSingle();
if (error) {
console.error('getTreatmentAdvice error', error);
throw new Error('Kon behandeladvies niet ophalen');
}
return data?.treatment_advice || {};
}
export interface TreatmentAdvicePayload {
patientId: string;
intakeId: string;
advice: string;
department?: string;
program?: string;
notes?: string;
psychologist?: string;
finalize?: boolean;
outcome?: 'in_zorg' | 'doorverwijzing' | 'extra_diagnostiek';
outcomeNotes?: string;
}
export async function saveTreatmentAdvice(payload: TreatmentAdvicePayload) {
const supabase = await getSupabase();
const updates: Record<string, unknown> = {
treatment_advice: {
advice: payload.advice,
department: payload.department,
program: payload.program,
notes: payload.notes,
psychologist: payload.psychologist,
outcome: payload.outcome,
outcomeNotes: payload.outcomeNotes,
updatedAt: new Date().toISOString(),
},
};
if (payload.finalize) {
updates.status = 'afgerond';
updates.end_date = new Date().toISOString().split('T')[0];
}
const { error } = await supabase
.from('intakes')
.update(updates)
.eq('id', payload.intakeId);
if (error) {
console.error('saveTreatmentAdvice error', error);
throw new Error(error.message);
}
revalidatePath(buildPath(payload.patientId, payload.intakeId, 'behandeladvies'));
revalidatePath(buildPath(payload.patientId, payload.intakeId));
}