feat(overdracht): E0 + E1 - Database setup en API nursing logs
Epic 0 - Database Setup: - nursing_logs tabel met indexes en constraints - RLS policies (SELECT/INSERT/UPDATE/DELETE) - TypeScript types gegenereerd Epic 1 - API Nursing Logs: - GET/POST /api/nursing-logs (lijst + aanmaken) - PATCH/DELETE /api/nursing-logs/[id] (bewerken + verwijderen) - Zod validatie schemas - Automatische shift_date berekening Documentatie: - PRD, FO, TO en Bouwplan voor Overdracht Dashboard 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -129,6 +129,7 @@ export type Database = {
|
||||
based_on_examinations: string[] | null
|
||||
based_on_intake_id: string | null
|
||||
based_on_risk_assessments: string[] | null
|
||||
behandelstructuur: Json | null
|
||||
care_team_ids: string[] | null
|
||||
category_code: string | null
|
||||
category_display: string | null
|
||||
@@ -137,6 +138,7 @@ export type Database = {
|
||||
created_date: string | null
|
||||
description: string | null
|
||||
encounter_id: string | null
|
||||
evaluatiemomenten: Json | null
|
||||
goals: Json | null
|
||||
id: string
|
||||
identifier: string | null
|
||||
@@ -145,9 +147,13 @@ export type Database = {
|
||||
patient_id: string
|
||||
period_end: string | null
|
||||
period_start: string | null
|
||||
published_at: string | null
|
||||
sessie_planning: Json | null
|
||||
status: Database["public"]["Enums"]["careplan_status"]
|
||||
title: string
|
||||
updated_at: string | null
|
||||
veiligheidsplan: Json | null
|
||||
version: number | null
|
||||
}
|
||||
Insert: {
|
||||
activities?: Json | null
|
||||
@@ -157,6 +163,7 @@ export type Database = {
|
||||
based_on_examinations?: string[] | null
|
||||
based_on_intake_id?: string | null
|
||||
based_on_risk_assessments?: string[] | null
|
||||
behandelstructuur?: Json | null
|
||||
care_team_ids?: string[] | null
|
||||
category_code?: string | null
|
||||
category_display?: string | null
|
||||
@@ -165,6 +172,7 @@ export type Database = {
|
||||
created_date?: string | null
|
||||
description?: string | null
|
||||
encounter_id?: string | null
|
||||
evaluatiemomenten?: Json | null
|
||||
goals?: Json | null
|
||||
id?: string
|
||||
identifier?: string | null
|
||||
@@ -173,9 +181,13 @@ export type Database = {
|
||||
patient_id: string
|
||||
period_end?: string | null
|
||||
period_start?: string | null
|
||||
published_at?: string | null
|
||||
sessie_planning?: Json | null
|
||||
status?: Database["public"]["Enums"]["careplan_status"]
|
||||
title: string
|
||||
updated_at?: string | null
|
||||
veiligheidsplan?: Json | null
|
||||
version?: number | null
|
||||
}
|
||||
Update: {
|
||||
activities?: Json | null
|
||||
@@ -185,6 +197,7 @@ export type Database = {
|
||||
based_on_examinations?: string[] | null
|
||||
based_on_intake_id?: string | null
|
||||
based_on_risk_assessments?: string[] | null
|
||||
behandelstructuur?: Json | null
|
||||
care_team_ids?: string[] | null
|
||||
category_code?: string | null
|
||||
category_display?: string | null
|
||||
@@ -193,6 +206,7 @@ export type Database = {
|
||||
created_date?: string | null
|
||||
description?: string | null
|
||||
encounter_id?: string | null
|
||||
evaluatiemomenten?: Json | null
|
||||
goals?: Json | null
|
||||
id?: string
|
||||
identifier?: string | null
|
||||
@@ -201,9 +215,13 @@ export type Database = {
|
||||
patient_id?: string
|
||||
period_end?: string | null
|
||||
period_start?: string | null
|
||||
published_at?: string | null
|
||||
sessie_planning?: Json | null
|
||||
status?: Database["public"]["Enums"]["careplan_status"]
|
||||
title?: string
|
||||
updated_at?: string | null
|
||||
veiligheidsplan?: Json | null
|
||||
version?: number | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
@@ -765,6 +783,53 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
nursing_logs: {
|
||||
Row: {
|
||||
category: string
|
||||
content: string
|
||||
created_at: string
|
||||
created_by: string
|
||||
id: string
|
||||
include_in_handover: boolean
|
||||
patient_id: string
|
||||
shift_date: string
|
||||
timestamp: string
|
||||
updated_at: string
|
||||
}
|
||||
Insert: {
|
||||
category: string
|
||||
content: string
|
||||
created_at?: string
|
||||
created_by: string
|
||||
id?: string
|
||||
include_in_handover?: boolean
|
||||
patient_id: string
|
||||
shift_date: string
|
||||
timestamp?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Update: {
|
||||
category?: string
|
||||
content?: string
|
||||
created_at?: string
|
||||
created_by?: string
|
||||
id?: string
|
||||
include_in_handover?: boolean
|
||||
patient_id?: string
|
||||
shift_date?: string
|
||||
timestamp?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "nursing_logs_patient_id_fkey"
|
||||
columns: ["patient_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "patients"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
observations: {
|
||||
Row: {
|
||||
body_site: string | null
|
||||
|
||||
114
lib/types/nursing-log.ts
Normal file
114
lib/types/nursing-log.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import { z } from 'zod';
|
||||
import type { Database } from '@/lib/supabase/database.types';
|
||||
|
||||
// Database types
|
||||
export type NursingLog = Database['public']['Tables']['nursing_logs']['Row'];
|
||||
export type NursingLogInsert = Database['public']['Tables']['nursing_logs']['Insert'];
|
||||
export type NursingLogUpdate = Database['public']['Tables']['nursing_logs']['Update'];
|
||||
|
||||
// Category enum
|
||||
export const NURSING_LOG_CATEGORIES = [
|
||||
'medicatie',
|
||||
'adl',
|
||||
'gedrag',
|
||||
'incident',
|
||||
'observatie',
|
||||
] as const;
|
||||
|
||||
export type NursingLogCategory = (typeof NURSING_LOG_CATEGORIES)[number];
|
||||
|
||||
// Zod schemas for validation
|
||||
export const NursingLogCategorySchema = z.enum(NURSING_LOG_CATEGORIES);
|
||||
|
||||
export const CreateNursingLogSchema = z.object({
|
||||
patient_id: z.string().uuid('Patient ID moet een geldige UUID zijn'),
|
||||
category: NursingLogCategorySchema,
|
||||
content: z
|
||||
.string()
|
||||
.min(1, 'Notitie mag niet leeg zijn')
|
||||
.max(500, 'Notitie mag maximaal 500 karakters bevatten'),
|
||||
timestamp: z.string().datetime().optional(),
|
||||
include_in_handover: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type CreateNursingLogInput = z.infer<typeof CreateNursingLogSchema>;
|
||||
|
||||
export const UpdateNursingLogSchema = z.object({
|
||||
category: NursingLogCategorySchema.optional(),
|
||||
content: z
|
||||
.string()
|
||||
.min(1, 'Notitie mag niet leeg zijn')
|
||||
.max(500, 'Notitie mag maximaal 500 karakters bevatten')
|
||||
.optional(),
|
||||
timestamp: z.string().datetime().optional(),
|
||||
include_in_handover: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type UpdateNursingLogInput = z.infer<typeof UpdateNursingLogSchema>;
|
||||
|
||||
// Response types
|
||||
export interface NursingLogListResponse {
|
||||
logs: NursingLog[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
// Category display configuration
|
||||
export const CATEGORY_CONFIG: Record<
|
||||
NursingLogCategory,
|
||||
{
|
||||
label: string;
|
||||
icon: string;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
textColor: string;
|
||||
}
|
||||
> = {
|
||||
medicatie: {
|
||||
label: 'Medicatie',
|
||||
icon: 'Pill',
|
||||
color: 'blue',
|
||||
bgColor: 'bg-blue-100',
|
||||
textColor: 'text-blue-700',
|
||||
},
|
||||
adl: {
|
||||
label: 'ADL/verzorging',
|
||||
icon: 'Utensils',
|
||||
color: 'green',
|
||||
bgColor: 'bg-green-100',
|
||||
textColor: 'text-green-700',
|
||||
},
|
||||
gedrag: {
|
||||
label: 'Gedragsobservatie',
|
||||
icon: 'User',
|
||||
color: 'purple',
|
||||
bgColor: 'bg-purple-100',
|
||||
textColor: 'text-purple-700',
|
||||
},
|
||||
incident: {
|
||||
label: 'Incident',
|
||||
icon: 'AlertTriangle',
|
||||
color: 'red',
|
||||
bgColor: 'bg-red-100',
|
||||
textColor: 'text-red-700',
|
||||
},
|
||||
observatie: {
|
||||
label: 'Algemene observatie',
|
||||
icon: 'FileText',
|
||||
color: 'gray',
|
||||
bgColor: 'bg-gray-100',
|
||||
textColor: 'text-gray-700',
|
||||
},
|
||||
};
|
||||
|
||||
// Helper function to calculate shift_date from timestamp
|
||||
export function calculateShiftDate(timestamp: Date | string): string {
|
||||
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
|
||||
const hours = date.getHours();
|
||||
|
||||
// Night shift (before 7:00) belongs to previous day
|
||||
if (hours < 7) {
|
||||
date.setDate(date.getDate() - 1);
|
||||
}
|
||||
|
||||
return date.toISOString().split('T')[0];
|
||||
}
|
||||
Reference in New Issue
Block a user