feat: migrate clients module to patients + add docs
This commit is contained in:
69
docs/api/intakes-api.md
Normal file
69
docs/api/intakes-api.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Intakes API
|
||||
|
||||
Deze custom REST API ondersteunt de intake-flow na consolidatie van `/clients/` → `/patients/`. Alle endpoints verwachten een geldige Supabase sessie (cookies) en geven JSON terug.
|
||||
|
||||
## Endpoints
|
||||
|
||||
### GET `/api/intakes?patientId={uuid}`
|
||||
Haalt alle intakes voor één patiënt op (nieuwste eerst).
|
||||
|
||||
**Query parameters**
|
||||
- `patientId` _(verplicht)_ — UUID van de patiënt.
|
||||
|
||||
**Response**
|
||||
```json
|
||||
{
|
||||
"intakes": [
|
||||
{
|
||||
"id": "uuid",
|
||||
"patient_id": "uuid",
|
||||
"title": "Intake - Aanvang zorg",
|
||||
"department": "Volwassenen",
|
||||
"status": "bezig",
|
||||
"start_date": "2025-11-22",
|
||||
"end_date": null,
|
||||
"psychologist_id": null,
|
||||
"notes": null
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
### POST `/api/intakes`
|
||||
Maakt een nieuwe intake.
|
||||
|
||||
**Body**
|
||||
```json
|
||||
{
|
||||
"patient_id": "uuid",
|
||||
"title": "Intake - Aanvang zorg",
|
||||
"department": "Volwassenen",
|
||||
"start_date": "2025-11-22",
|
||||
"psychologist_id": "uuid?",
|
||||
"notes": "optional"
|
||||
}
|
||||
```
|
||||
|
||||
**Responses**
|
||||
- `201` + intake object bij succes
|
||||
- `400` met `details[]` bij validatiefout
|
||||
|
||||
### GET `/api/intakes/{intakeId}`
|
||||
Levert één intake. Retourneert `404` als het ID niet bestaat.
|
||||
|
||||
### PUT `/api/intakes/{intakeId}`
|
||||
Partiële update. Ondersteunt `title`, `department`, `status` (`Open`/`Afgerond`), `start_date`, `end_date`, `psychologist_id`, `notes`.
|
||||
|
||||
### DELETE `/api/intakes/{intakeId}`
|
||||
Verwijdert een intake. `204 No Content` bij succes.
|
||||
|
||||
## Fouten
|
||||
- `401`/`403`: geen sessie of onvoldoende rechten.
|
||||
- `400`: ongeldige payload (zie `details`).
|
||||
- `500`: onverwachte fout; check server logs.
|
||||
|
||||
## Implementatieverwijzing
|
||||
- Type definities: `lib/types/intake.ts`
|
||||
- Server actions: `app/epd/patients/[id]/intakes/actions.ts`
|
||||
- API broncode: `app/api/intakes/` en `app/api/intakes/[intakeId]/`
|
||||
180
docs/archive/migrations/20241115000003_test_rls_policies.sql
Normal file
180
docs/archive/migrations/20241115000003_test_rls_policies.sql
Normal file
@@ -0,0 +1,180 @@
|
||||
-- ================================================
|
||||
-- RLS Policy Tests
|
||||
-- Created: 2024-11-15
|
||||
-- Epic: E2 - Database & Auth
|
||||
-- Story: E2.S2 - RLS policies implementeren
|
||||
-- ================================================
|
||||
-- This file contains test queries to verify RLS policies
|
||||
-- Run these queries manually to verify RLS is working correctly
|
||||
-- ================================================
|
||||
|
||||
-- ================================================
|
||||
-- TEST 1: Verify RLS is enabled on all tables
|
||||
-- ================================================
|
||||
-- Expected: All tables should have rowsecurity = true
|
||||
|
||||
SELECT
|
||||
tablename,
|
||||
rowsecurity as rls_enabled
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public'
|
||||
ORDER BY tablename;
|
||||
|
||||
-- Expected output:
|
||||
-- ai_events | true
|
||||
-- clients | true
|
||||
-- intake_notes | true
|
||||
-- problem_profiles | true
|
||||
-- treatment_plans | true
|
||||
|
||||
-- ================================================
|
||||
-- TEST 2: Check all RLS policies exist
|
||||
-- ================================================
|
||||
-- Expected: Each table should have 4 policies (SELECT, INSERT, UPDATE, DELETE)
|
||||
-- except ai_events which has only 2 (SELECT, INSERT)
|
||||
|
||||
SELECT
|
||||
tablename,
|
||||
COUNT(*) as policy_count,
|
||||
STRING_AGG(cmd, ', ' ORDER BY cmd) as commands
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
GROUP BY tablename
|
||||
ORDER BY tablename;
|
||||
|
||||
-- Expected output:
|
||||
-- ai_events | 2 | INSERT, SELECT
|
||||
-- clients | 4 | DELETE, INSERT, SELECT, UPDATE
|
||||
-- intake_notes | 4 | DELETE, INSERT, SELECT, UPDATE
|
||||
-- problem_profiles | 4 | DELETE, INSERT, SELECT, UPDATE
|
||||
-- treatment_plans | 4 | DELETE, INSERT, SELECT, UPDATE
|
||||
|
||||
-- ================================================
|
||||
-- TEST 3: Verify policy predicates use auth.uid()
|
||||
-- ================================================
|
||||
-- Expected: All policies should check auth.uid() IS NOT NULL
|
||||
|
||||
SELECT
|
||||
tablename,
|
||||
policyname,
|
||||
cmd,
|
||||
qual as using_clause,
|
||||
with_check
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
AND qual NOT LIKE '%auth.uid()%'
|
||||
ORDER BY tablename, policyname;
|
||||
|
||||
-- Expected output: Empty (no policies without auth.uid() check)
|
||||
|
||||
-- ================================================
|
||||
-- TEST 4: Simulate authenticated user query
|
||||
-- ================================================
|
||||
-- This test simulates what happens when an authenticated user
|
||||
-- tries to access data. In production, auth.uid() would return
|
||||
-- the user's actual UUID.
|
||||
|
||||
-- Note: These queries will work in the SQL editor when logged in,
|
||||
-- but will fail when run as unauthenticated
|
||||
|
||||
-- Test SELECT permission (should succeed when authenticated)
|
||||
-- SELECT * FROM clients LIMIT 1;
|
||||
|
||||
-- Test INSERT permission (should succeed when authenticated)
|
||||
-- INSERT INTO clients (first_name, last_name, birth_date)
|
||||
-- VALUES ('Test', 'User', '1990-01-01');
|
||||
|
||||
-- Test UPDATE permission (should succeed when authenticated)
|
||||
-- UPDATE clients SET first_name = 'Updated' WHERE id = 'some-uuid';
|
||||
|
||||
-- Test DELETE permission (should succeed when authenticated)
|
||||
-- DELETE FROM clients WHERE id = 'some-uuid';
|
||||
|
||||
-- ================================================
|
||||
-- TEST 5: Verify ai_events immutability
|
||||
-- ================================================
|
||||
-- Expected: ai_events should NOT have UPDATE or DELETE policies
|
||||
-- (except for service role via RLS bypass)
|
||||
|
||||
SELECT
|
||||
tablename,
|
||||
policyname,
|
||||
cmd
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
AND tablename = 'ai_events'
|
||||
AND cmd IN ('UPDATE', 'DELETE')
|
||||
ORDER BY cmd;
|
||||
|
||||
-- Expected output: Empty (no UPDATE or DELETE policies for regular users)
|
||||
|
||||
-- ================================================
|
||||
-- TEST 6: Check foreign key relationships
|
||||
-- ================================================
|
||||
-- Expected: All foreign keys should be properly set up
|
||||
|
||||
SELECT
|
||||
tc.table_name,
|
||||
kcu.column_name,
|
||||
ccu.table_name AS foreign_table_name,
|
||||
ccu.column_name AS foreign_column_name,
|
||||
rc.delete_rule
|
||||
FROM information_schema.table_constraints AS tc
|
||||
JOIN information_schema.key_column_usage AS kcu
|
||||
ON tc.constraint_name = kcu.constraint_name
|
||||
AND tc.table_schema = kcu.table_schema
|
||||
JOIN information_schema.constraint_column_usage AS ccu
|
||||
ON ccu.constraint_name = tc.constraint_name
|
||||
AND ccu.table_schema = tc.table_schema
|
||||
JOIN information_schema.referential_constraints AS rc
|
||||
ON tc.constraint_name = rc.constraint_name
|
||||
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||
AND tc.table_schema = 'public'
|
||||
ORDER BY tc.table_name, kcu.column_name;
|
||||
|
||||
-- Expected output:
|
||||
-- intake_notes | client_id | clients | id | CASCADE
|
||||
-- problem_profiles | client_id | clients | id | CASCADE
|
||||
-- problem_profiles | source_note_id | intake_notes | id | SET NULL
|
||||
-- treatment_plans | client_id | clients | id | CASCADE
|
||||
-- ai_events | client_id | clients | id | SET NULL
|
||||
-- ai_events | note_id | intake_notes | id | SET NULL
|
||||
|
||||
-- ================================================
|
||||
-- PRODUCTION MIGRATION PATH
|
||||
-- ================================================
|
||||
-- When moving to production, enhance policies with org_id filtering:
|
||||
--
|
||||
-- 1. Add org_id column to all tables:
|
||||
-- ALTER TABLE clients ADD COLUMN org_id UUID REFERENCES organizations(id);
|
||||
--
|
||||
-- 2. Update policies to filter by organization:
|
||||
-- CREATE POLICY "Users can view own org clients"
|
||||
-- ON clients
|
||||
-- FOR SELECT
|
||||
-- USING (
|
||||
-- auth.uid() IS NOT NULL AND
|
||||
-- org_id = (SELECT org_id FROM users WHERE id = auth.uid())
|
||||
-- );
|
||||
--
|
||||
-- 3. Add role-based access:
|
||||
-- CREATE POLICY "Admins can view all"
|
||||
-- ON clients
|
||||
-- FOR SELECT
|
||||
-- USING (
|
||||
-- auth.uid() IS NOT NULL AND
|
||||
-- EXISTS (
|
||||
-- SELECT 1 FROM users
|
||||
-- WHERE id = auth.uid() AND role = 'admin'
|
||||
-- )
|
||||
-- );
|
||||
|
||||
-- ================================================
|
||||
-- SECURITY NOTES
|
||||
-- ================================================
|
||||
-- 1. Current policies are MVP-level: all authenticated users can access all data
|
||||
-- 2. In production, add org_id filtering for multi-tenancy
|
||||
-- 3. ai_events table is append-only for regular users (audit trail)
|
||||
-- 4. Service role can bypass RLS for admin operations
|
||||
-- 5. All policies use auth.uid() for security
|
||||
-- 6. Foreign key CASCADE ensures orphaned records are cleaned up
|
||||
266
docs/archive/migrations/20251122-current-db-scheme.sql
Normal file
266
docs/archive/migrations/20251122-current-db-scheme.sql
Normal file
@@ -0,0 +1,266 @@
|
||||
-- WARNING: This schema is for context only and is not meant to be run.
|
||||
-- Table order and constraints may not be valid for execution.
|
||||
|
||||
CREATE TABLE public.ai_events (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
kind text NOT NULL CHECK (kind = ANY (ARRAY['summarize'::text, 'readability'::text, 'extract'::text, 'plan'::text])),
|
||||
client_id uuid,
|
||||
note_id uuid,
|
||||
request jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
response jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
duration_ms integer NOT NULL DEFAULT 0 CHECK (duration_ms >= 0),
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT ai_events_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT ai_events_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id),
|
||||
CONSTRAINT ai_events_note_id_fkey FOREIGN KEY (note_id) REFERENCES public.intake_notes(id)
|
||||
);
|
||||
CREATE TABLE public.care_plans (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
status USER-DEFINED NOT NULL DEFAULT 'draft'::careplan_status,
|
||||
intent text NOT NULL DEFAULT 'plan'::text,
|
||||
category_code text DEFAULT 'ggz-behandelplan'::text,
|
||||
category_display text DEFAULT 'GGZ Behandelplan'::text,
|
||||
title text NOT NULL,
|
||||
description text,
|
||||
patient_id uuid NOT NULL,
|
||||
encounter_id uuid,
|
||||
period_start date,
|
||||
period_end date,
|
||||
created_date timestamp with time zone DEFAULT now(),
|
||||
author_id uuid,
|
||||
contributor_ids ARRAY,
|
||||
care_team_ids ARRAY,
|
||||
addresses_condition_ids ARRAY,
|
||||
goals jsonb DEFAULT '[]'::jsonb,
|
||||
activities jsonb DEFAULT '[]'::jsonb,
|
||||
note text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT care_plans_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT care_plans_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT care_plans_encounter_id_fkey FOREIGN KEY (encounter_id) REFERENCES public.encounters(id),
|
||||
CONSTRAINT care_plans_author_id_fkey FOREIGN KEY (author_id) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.clients (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
first_name text NOT NULL,
|
||||
last_name text NOT NULL,
|
||||
birth_date date NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT clients_pkey PRIMARY KEY (id)
|
||||
);
|
||||
CREATE TABLE public.conditions (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
clinical_status USER-DEFINED NOT NULL DEFAULT 'active'::condition_clinical_status,
|
||||
verification_status USER-DEFINED NOT NULL DEFAULT 'provisional'::condition_verification_status,
|
||||
category text NOT NULL DEFAULT 'encounter-diagnosis'::text,
|
||||
severity_code text,
|
||||
severity_display text,
|
||||
code_system text NOT NULL DEFAULT 'http://hl7.org/fhir/sid/icd-10'::text,
|
||||
code_code text NOT NULL,
|
||||
code_display text NOT NULL,
|
||||
body_site_code text,
|
||||
body_site_display text,
|
||||
patient_id uuid NOT NULL,
|
||||
encounter_id uuid,
|
||||
onset_datetime timestamp with time zone,
|
||||
onset_age integer,
|
||||
abatement_datetime timestamp with time zone,
|
||||
abatement_age integer,
|
||||
recorded_date timestamp with time zone NOT NULL DEFAULT now(),
|
||||
recorder_id uuid,
|
||||
asserter_id uuid,
|
||||
note text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT conditions_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT conditions_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT conditions_encounter_id_fkey FOREIGN KEY (encounter_id) REFERENCES public.encounters(id),
|
||||
CONSTRAINT conditions_recorder_id_fkey FOREIGN KEY (recorder_id) REFERENCES public.practitioners(id),
|
||||
CONSTRAINT conditions_asserter_id_fkey FOREIGN KEY (asserter_id) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.demo_users (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
user_id uuid UNIQUE,
|
||||
access_level text NOT NULL DEFAULT 'read_only'::text CHECK (access_level = ANY (ARRAY['read_only'::text, 'interactive'::text, 'presenter'::text])),
|
||||
expires_at timestamp with time zone DEFAULT (now() + '90 days'::interval),
|
||||
usage_count integer DEFAULT 0,
|
||||
last_login_at timestamp with time zone,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
notes text,
|
||||
CONSTRAINT demo_users_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT demo_users_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id)
|
||||
);
|
||||
CREATE TABLE public.encounters (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
status USER-DEFINED NOT NULL DEFAULT 'planned'::encounter_status,
|
||||
class_code text NOT NULL,
|
||||
class_display text NOT NULL,
|
||||
type_code text NOT NULL,
|
||||
type_display text NOT NULL,
|
||||
priority_code text,
|
||||
priority_display text,
|
||||
patient_id uuid NOT NULL,
|
||||
practitioner_id uuid,
|
||||
organization_id uuid,
|
||||
period_start timestamp with time zone NOT NULL,
|
||||
period_end timestamp with time zone,
|
||||
reason_code ARRAY,
|
||||
reason_display ARRAY,
|
||||
admission_source text,
|
||||
discharge_disposition text,
|
||||
notes text,
|
||||
intake_note_id uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT encounters_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT encounters_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT encounters_practitioner_id_fkey FOREIGN KEY (practitioner_id) REFERENCES public.practitioners(id),
|
||||
CONSTRAINT encounters_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id),
|
||||
CONSTRAINT encounters_intake_note_id_fkey FOREIGN KEY (intake_note_id) REFERENCES public.intake_notes(id)
|
||||
);
|
||||
CREATE TABLE public.intake_notes (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL,
|
||||
title text,
|
||||
tag text CHECK (tag = ANY (ARRAY['Intake'::text, 'Evaluatie'::text, 'Plan'::text])),
|
||||
content_json jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (content_json IS NOT NULL),
|
||||
content_text text,
|
||||
author uuid,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT intake_notes_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT intake_notes_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id)
|
||||
);
|
||||
CREATE TABLE public.observations (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
status USER-DEFINED NOT NULL DEFAULT 'final'::observation_status,
|
||||
category text NOT NULL,
|
||||
code_system text NOT NULL,
|
||||
code_code text NOT NULL,
|
||||
code_display text NOT NULL,
|
||||
patient_id uuid NOT NULL,
|
||||
encounter_id uuid,
|
||||
effective_datetime timestamp with time zone NOT NULL,
|
||||
issued timestamp with time zone DEFAULT now(),
|
||||
performer_id uuid,
|
||||
value_type text NOT NULL,
|
||||
value_quantity_value numeric,
|
||||
value_quantity_unit text,
|
||||
value_quantity_comparator text,
|
||||
value_string text,
|
||||
value_boolean boolean,
|
||||
value_codeable_concept jsonb,
|
||||
interpretation_code text,
|
||||
interpretation_display text,
|
||||
note text,
|
||||
body_site text,
|
||||
method_code text,
|
||||
method_display text,
|
||||
reference_range_low numeric,
|
||||
reference_range_high numeric,
|
||||
reference_range_text text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT observations_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT observations_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT observations_encounter_id_fkey FOREIGN KEY (encounter_id) REFERENCES public.encounters(id),
|
||||
CONSTRAINT observations_performer_id_fkey FOREIGN KEY (performer_id) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.organizations (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier_agb text UNIQUE,
|
||||
identifier_kvk text,
|
||||
name text NOT NULL,
|
||||
alias ARRAY,
|
||||
type_code text DEFAULT 'prov'::text,
|
||||
type_display text DEFAULT 'Healthcare Provider'::text,
|
||||
telecom_phone text,
|
||||
telecom_email text,
|
||||
telecom_website text,
|
||||
address_line ARRAY,
|
||||
address_city text,
|
||||
address_postal_code text,
|
||||
address_country text DEFAULT 'NL'::text,
|
||||
active boolean DEFAULT true,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT organizations_pkey PRIMARY KEY (id)
|
||||
);
|
||||
CREATE TABLE public.patients (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier_bsn text DEFAULT '999999990'::text,
|
||||
identifier_client_number text,
|
||||
name_family text NOT NULL,
|
||||
name_given ARRAY NOT NULL,
|
||||
name_prefix text,
|
||||
name_use text DEFAULT 'official'::text,
|
||||
birth_date date NOT NULL,
|
||||
gender USER-DEFINED NOT NULL,
|
||||
telecom_phone text,
|
||||
telecom_email text,
|
||||
address_line ARRAY,
|
||||
address_city text,
|
||||
address_postal_code text,
|
||||
address_country text DEFAULT 'NL'::text,
|
||||
insurance_company text,
|
||||
insurance_number text,
|
||||
emergency_contact_name text,
|
||||
emergency_contact_relationship text,
|
||||
emergency_contact_phone text,
|
||||
active boolean DEFAULT true,
|
||||
general_practitioner_name text,
|
||||
general_practitioner_agb text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT patients_pkey PRIMARY KEY (id)
|
||||
);
|
||||
CREATE TABLE public.practitioners (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier_big text UNIQUE,
|
||||
identifier_agb text,
|
||||
name_prefix text,
|
||||
name_given ARRAY NOT NULL,
|
||||
name_family text NOT NULL,
|
||||
name_suffix text,
|
||||
qualification ARRAY,
|
||||
telecom_phone text,
|
||||
telecom_email text,
|
||||
active boolean DEFAULT true,
|
||||
user_id uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT practitioners_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT practitioners_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id)
|
||||
);
|
||||
CREATE TABLE public.problem_profiles (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL,
|
||||
category text NOT NULL CHECK (category = ANY (ARRAY['stemming_depressie'::text, 'angst'::text, 'gedrag_impuls'::text, 'middelen_gebruik'::text, 'cognitief'::text, 'context_psychosociaal'::text])),
|
||||
severity text NOT NULL CHECK (severity = ANY (ARRAY['laag'::text, 'middel'::text, 'hoog'::text])),
|
||||
remarks text,
|
||||
source_note_id uuid,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT problem_profiles_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT problem_profiles_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id),
|
||||
CONSTRAINT problem_profiles_source_note_id_fkey FOREIGN KEY (source_note_id) REFERENCES public.intake_notes(id)
|
||||
);
|
||||
CREATE TABLE public.treatment_plans (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL,
|
||||
version integer NOT NULL DEFAULT 1 CHECK (version > 0),
|
||||
status text NOT NULL DEFAULT 'concept'::text CHECK (status = ANY (ARRAY['concept'::text, 'gepubliceerd'::text])),
|
||||
plan jsonb NOT NULL DEFAULT '{"doelen": [], "frequentie": "", "interventies": [], "meetmomenten": []}'::jsonb CHECK (plan ? 'doelen'::text AND plan ? 'interventies'::text AND plan ? 'frequentie'::text AND plan ? 'meetmomenten'::text),
|
||||
created_by uuid,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
published_at timestamp with time zone,
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT treatment_plans_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT treatment_plans_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id)
|
||||
);
|
||||
382
docs/archive/migrations/20251122-supabase-scheme.sql
Normal file
382
docs/archive/migrations/20251122-supabase-scheme.sql
Normal file
@@ -0,0 +1,382 @@
|
||||
-- WARNING: This schema is for context only and is not meant to be run.
|
||||
-- Table order and constraints may not be valid for execution.
|
||||
|
||||
CREATE TABLE public.ai_events (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
kind text NOT NULL CHECK (kind = ANY (ARRAY['summarize'::text, 'readability'::text, 'extract'::text, 'plan'::text])),
|
||||
client_id uuid,
|
||||
note_id uuid,
|
||||
request jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
response jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
duration_ms integer NOT NULL DEFAULT 0 CHECK (duration_ms >= 0),
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT ai_events_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT ai_events_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id),
|
||||
CONSTRAINT ai_events_note_id_fkey FOREIGN KEY (note_id) REFERENCES public.intake_notes(id)
|
||||
);
|
||||
CREATE TABLE public.anamneses (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
intake_id uuid NOT NULL,
|
||||
anamnese_date date NOT NULL DEFAULT CURRENT_DATE,
|
||||
anamnese_type text NOT NULL CHECK (anamnese_type = ANY (ARRAY['psychiatrisch'::text, 'sociaal'::text, 'medisch'::text, 'familie'::text, 'ontwikkeling'::text, 'overig'::text])),
|
||||
content text NOT NULL,
|
||||
notes text,
|
||||
created_by uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT anamneses_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT anamneses_intake_id_fkey FOREIGN KEY (intake_id) REFERENCES public.intakes(id),
|
||||
CONSTRAINT anamneses_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.care_plans (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
status USER-DEFINED NOT NULL DEFAULT 'draft'::careplan_status,
|
||||
intent text NOT NULL DEFAULT 'plan'::text,
|
||||
category_code text DEFAULT 'ggz-behandelplan'::text,
|
||||
category_display text DEFAULT 'GGZ Behandelplan'::text,
|
||||
title text NOT NULL,
|
||||
description text,
|
||||
patient_id uuid NOT NULL,
|
||||
encounter_id uuid,
|
||||
period_start date,
|
||||
period_end date,
|
||||
created_date timestamp with time zone DEFAULT now(),
|
||||
author_id uuid,
|
||||
contributor_ids ARRAY,
|
||||
care_team_ids ARRAY,
|
||||
addresses_condition_ids ARRAY,
|
||||
goals jsonb DEFAULT '[]'::jsonb,
|
||||
activities jsonb DEFAULT '[]'::jsonb,
|
||||
note text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
based_on_intake_id uuid,
|
||||
based_on_anamneses ARRAY,
|
||||
based_on_examinations ARRAY,
|
||||
based_on_risk_assessments ARRAY,
|
||||
CONSTRAINT care_plans_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT care_plans_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT care_plans_encounter_id_fkey FOREIGN KEY (encounter_id) REFERENCES public.encounters(id),
|
||||
CONSTRAINT care_plans_author_id_fkey FOREIGN KEY (author_id) REFERENCES public.practitioners(id),
|
||||
CONSTRAINT care_plans_based_on_intake_id_fkey FOREIGN KEY (based_on_intake_id) REFERENCES public.intakes(id)
|
||||
);
|
||||
CREATE TABLE public.clients (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
first_name text NOT NULL,
|
||||
last_name text NOT NULL,
|
||||
birth_date date NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT clients_pkey PRIMARY KEY (id)
|
||||
);
|
||||
CREATE TABLE public.conditions (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
clinical_status USER-DEFINED NOT NULL DEFAULT 'active'::condition_clinical_status,
|
||||
verification_status USER-DEFINED NOT NULL DEFAULT 'provisional'::condition_verification_status,
|
||||
category text NOT NULL DEFAULT 'encounter-diagnosis'::text,
|
||||
severity_code text,
|
||||
severity_display text,
|
||||
code_system text NOT NULL DEFAULT 'http://hl7.org/fhir/sid/icd-10'::text,
|
||||
code_code text NOT NULL,
|
||||
code_display text NOT NULL,
|
||||
body_site_code text,
|
||||
body_site_display text,
|
||||
patient_id uuid NOT NULL,
|
||||
encounter_id uuid,
|
||||
onset_datetime timestamp with time zone,
|
||||
onset_age integer,
|
||||
abatement_datetime timestamp with time zone,
|
||||
abatement_age integer,
|
||||
recorded_date timestamp with time zone NOT NULL DEFAULT now(),
|
||||
recorder_id uuid,
|
||||
asserter_id uuid,
|
||||
note text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT conditions_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT conditions_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT conditions_encounter_id_fkey FOREIGN KEY (encounter_id) REFERENCES public.encounters(id),
|
||||
CONSTRAINT conditions_recorder_id_fkey FOREIGN KEY (recorder_id) REFERENCES public.practitioners(id),
|
||||
CONSTRAINT conditions_asserter_id_fkey FOREIGN KEY (asserter_id) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.demo_users (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
user_id uuid UNIQUE,
|
||||
access_level text NOT NULL DEFAULT 'read_only'::text CHECK (access_level = ANY (ARRAY['read_only'::text, 'interactive'::text, 'presenter'::text])),
|
||||
expires_at timestamp with time zone DEFAULT (now() + '90 days'::interval),
|
||||
usage_count integer DEFAULT 0,
|
||||
last_login_at timestamp with time zone,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
notes text,
|
||||
CONSTRAINT demo_users_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT demo_users_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id)
|
||||
);
|
||||
CREATE TABLE public.encounters (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
status USER-DEFINED NOT NULL DEFAULT 'planned'::encounter_status,
|
||||
class_code text NOT NULL,
|
||||
class_display text NOT NULL,
|
||||
type_code text NOT NULL,
|
||||
type_display text NOT NULL,
|
||||
priority_code text,
|
||||
priority_display text,
|
||||
patient_id uuid NOT NULL,
|
||||
practitioner_id uuid,
|
||||
organization_id uuid,
|
||||
period_start timestamp with time zone NOT NULL,
|
||||
period_end timestamp with time zone,
|
||||
reason_code ARRAY,
|
||||
reason_display ARRAY,
|
||||
admission_source text,
|
||||
discharge_disposition text,
|
||||
notes text,
|
||||
intake_note_id uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
intake_id uuid,
|
||||
CONSTRAINT encounters_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT encounters_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT encounters_practitioner_id_fkey FOREIGN KEY (practitioner_id) REFERENCES public.practitioners(id),
|
||||
CONSTRAINT encounters_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id),
|
||||
CONSTRAINT encounters_intake_note_id_fkey FOREIGN KEY (intake_note_id) REFERENCES public.intake_notes(id),
|
||||
CONSTRAINT encounters_intake_id_fkey FOREIGN KEY (intake_id) REFERENCES public.intakes(id)
|
||||
);
|
||||
CREATE TABLE public.examinations (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
intake_id uuid NOT NULL,
|
||||
examination_date date NOT NULL DEFAULT CURRENT_DATE,
|
||||
examination_type text NOT NULL CHECK (examination_type = ANY (ARRAY['bloedonderzoek'::text, 'neuropsychologisch'::text, 'psychodiagnostiek'::text, 'iq_test'::text, 'persoonlijkheid'::text, 'medisch'::text, 'overig'::text])),
|
||||
performed_by text,
|
||||
reason text,
|
||||
findings text NOT NULL,
|
||||
document_url text,
|
||||
notes text,
|
||||
created_by uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT examinations_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT examinations_intake_id_fkey FOREIGN KEY (intake_id) REFERENCES public.intakes(id),
|
||||
CONSTRAINT examinations_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.intake_notes (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL,
|
||||
title text,
|
||||
tag text CHECK (tag = ANY (ARRAY['Intake'::text, 'Evaluatie'::text, 'Plan'::text])),
|
||||
content_json jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (content_json IS NOT NULL),
|
||||
content_text text,
|
||||
author uuid,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT intake_notes_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT intake_notes_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id)
|
||||
);
|
||||
CREATE TABLE public.intakes (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
patient_id uuid NOT NULL,
|
||||
title text NOT NULL,
|
||||
department text NOT NULL,
|
||||
psychologist_id uuid,
|
||||
status text NOT NULL DEFAULT 'bezig'::text CHECK (status = ANY (ARRAY['bezig'::text, 'afgerond'::text])),
|
||||
start_date date NOT NULL DEFAULT CURRENT_DATE,
|
||||
end_date date,
|
||||
notes text,
|
||||
kindcheck_data jsonb DEFAULT '{}'::jsonb,
|
||||
treatment_advice jsonb DEFAULT '{}'::jsonb,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT intakes_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT intakes_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT intakes_psychologist_id_fkey FOREIGN KEY (psychologist_id) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.observations (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier text DEFAULT (gen_random_uuid())::text UNIQUE,
|
||||
status USER-DEFINED NOT NULL DEFAULT 'final'::observation_status,
|
||||
category text NOT NULL,
|
||||
code_system text NOT NULL,
|
||||
code_code text NOT NULL,
|
||||
code_display text NOT NULL,
|
||||
patient_id uuid NOT NULL,
|
||||
encounter_id uuid,
|
||||
effective_datetime timestamp with time zone NOT NULL,
|
||||
issued timestamp with time zone DEFAULT now(),
|
||||
performer_id uuid,
|
||||
value_type text NOT NULL,
|
||||
value_quantity_value numeric,
|
||||
value_quantity_unit text,
|
||||
value_quantity_comparator text,
|
||||
value_string text,
|
||||
value_boolean boolean,
|
||||
value_codeable_concept jsonb,
|
||||
interpretation_code text,
|
||||
interpretation_display text,
|
||||
note text,
|
||||
body_site text,
|
||||
method_code text,
|
||||
method_display text,
|
||||
reference_range_low numeric,
|
||||
reference_range_high numeric,
|
||||
reference_range_text text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT observations_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT observations_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT observations_encounter_id_fkey FOREIGN KEY (encounter_id) REFERENCES public.encounters(id),
|
||||
CONSTRAINT observations_performer_id_fkey FOREIGN KEY (performer_id) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.organizations (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier_agb text UNIQUE,
|
||||
identifier_kvk text,
|
||||
name text NOT NULL,
|
||||
alias ARRAY,
|
||||
type_code text DEFAULT 'prov'::text,
|
||||
type_display text DEFAULT 'Healthcare Provider'::text,
|
||||
telecom_phone text,
|
||||
telecom_email text,
|
||||
telecom_website text,
|
||||
address_line ARRAY,
|
||||
address_city text,
|
||||
address_postal_code text,
|
||||
address_country text DEFAULT 'NL'::text,
|
||||
active boolean DEFAULT true,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT organizations_pkey PRIMARY KEY (id)
|
||||
);
|
||||
CREATE TABLE public.patients (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier_bsn text DEFAULT '999999990'::text,
|
||||
identifier_client_number text,
|
||||
name_family text NOT NULL,
|
||||
name_given ARRAY NOT NULL,
|
||||
name_prefix text,
|
||||
name_use text DEFAULT 'official'::text,
|
||||
birth_date date NOT NULL,
|
||||
gender USER-DEFINED NOT NULL,
|
||||
telecom_phone text,
|
||||
telecom_email text,
|
||||
address_line ARRAY,
|
||||
address_city text,
|
||||
address_postal_code text,
|
||||
address_country text DEFAULT 'NL'::text,
|
||||
insurance_company text,
|
||||
insurance_number text,
|
||||
emergency_contact_name text,
|
||||
emergency_contact_relationship text,
|
||||
emergency_contact_phone text,
|
||||
active boolean DEFAULT true,
|
||||
general_practitioner_name text,
|
||||
general_practitioner_agb text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
status USER-DEFINED DEFAULT 'planned'::episode_status,
|
||||
is_john_doe boolean DEFAULT false,
|
||||
CONSTRAINT patients_pkey PRIMARY KEY (id)
|
||||
);
|
||||
CREATE TABLE public.practitioners (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
identifier_big text UNIQUE,
|
||||
identifier_agb text,
|
||||
name_prefix text,
|
||||
name_given ARRAY NOT NULL,
|
||||
name_family text NOT NULL,
|
||||
name_suffix text,
|
||||
qualification ARRAY,
|
||||
telecom_phone text,
|
||||
telecom_email text,
|
||||
active boolean DEFAULT true,
|
||||
user_id uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT practitioners_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT practitioners_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id)
|
||||
);
|
||||
CREATE TABLE public.problem_profiles (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL,
|
||||
category text NOT NULL CHECK (category = ANY (ARRAY['stemming_depressie'::text, 'angst'::text, 'gedrag_impuls'::text, 'middelen_gebruik'::text, 'cognitief'::text, 'context_psychosociaal'::text])),
|
||||
severity text NOT NULL CHECK (severity = ANY (ARRAY['laag'::text, 'middel'::text, 'hoog'::text])),
|
||||
remarks text,
|
||||
source_note_id uuid,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT problem_profiles_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT problem_profiles_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id),
|
||||
CONSTRAINT problem_profiles_source_note_id_fkey FOREIGN KEY (source_note_id) REFERENCES public.intake_notes(id)
|
||||
);
|
||||
CREATE TABLE public.risk_assessments (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
intake_id uuid NOT NULL,
|
||||
assessment_date date NOT NULL DEFAULT CURRENT_DATE,
|
||||
risk_type text NOT NULL CHECK (risk_type = ANY (ARRAY['suicidaliteit'::text, 'agressie'::text, 'zelfverwaarlozing'::text, 'middelenmisbruik'::text, 'verward_gedrag'::text, 'overig'::text])),
|
||||
risk_level text NOT NULL CHECK (risk_level = ANY (ARRAY['laag'::text, 'gemiddeld'::text, 'hoog'::text, 'zeer_hoog'::text])),
|
||||
rationale text NOT NULL,
|
||||
measures text,
|
||||
evaluation_date date,
|
||||
notes text,
|
||||
created_by uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT risk_assessments_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT risk_assessments_intake_id_fkey FOREIGN KEY (intake_id) REFERENCES public.intakes(id),
|
||||
CONSTRAINT risk_assessments_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.screening_activities (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
screening_id uuid NOT NULL,
|
||||
activity_text text NOT NULL,
|
||||
created_by uuid,
|
||||
created_by_name text,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT screening_activities_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT screening_activities_screening_id_fkey FOREIGN KEY (screening_id) REFERENCES public.screenings(id),
|
||||
CONSTRAINT screening_activities_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.screening_documents (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
screening_id uuid NOT NULL,
|
||||
file_name text NOT NULL,
|
||||
file_type text,
|
||||
file_size integer,
|
||||
file_path text,
|
||||
document_type text CHECK (document_type = ANY (ARRAY['verwijsbrief'::text, 'verhuisbericht'::text, 'indicatie'::text, 'overig'::text])),
|
||||
uploaded_by uuid,
|
||||
uploaded_by_name text,
|
||||
uploaded_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT screening_documents_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT screening_documents_screening_id_fkey FOREIGN KEY (screening_id) REFERENCES public.screenings(id),
|
||||
CONSTRAINT screening_documents_uploaded_by_fkey FOREIGN KEY (uploaded_by) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.screenings (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
patient_id uuid NOT NULL,
|
||||
request_for_help text,
|
||||
decision text CHECK (decision = ANY (ARRAY['geschikt'::text, 'niet_geschikt'::text])),
|
||||
decision_department text,
|
||||
decision_notes text,
|
||||
decision_date timestamp with time zone,
|
||||
decision_by uuid,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT screenings_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT screenings_patient_id_fkey FOREIGN KEY (patient_id) REFERENCES public.patients(id),
|
||||
CONSTRAINT screenings_decision_by_fkey FOREIGN KEY (decision_by) REFERENCES public.practitioners(id)
|
||||
);
|
||||
CREATE TABLE public.treatment_plans (
|
||||
id uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL,
|
||||
version integer NOT NULL DEFAULT 1 CHECK (version > 0),
|
||||
status text NOT NULL DEFAULT 'concept'::text CHECK (status = ANY (ARRAY['concept'::text, 'gepubliceerd'::text])),
|
||||
plan jsonb NOT NULL DEFAULT '{"doelen": [], "frequentie": "", "interventies": [], "meetmomenten": []}'::jsonb CHECK (plan ? 'doelen'::text AND plan ? 'interventies'::text AND plan ? 'frequentie'::text AND plan ? 'meetmomenten'::text),
|
||||
created_by uuid,
|
||||
created_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
published_at timestamp with time zone,
|
||||
updated_at timestamp with time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT treatment_plans_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT treatment_plans_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id)
|
||||
);
|
||||
29
docs/archive/migrations/README.md
Normal file
29
docs/archive/migrations/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Archived Migrations & Schema Snapshots
|
||||
|
||||
Deze directory bevat migrations en schema snapshots die niet meer actief gebruikt worden als migrations, maar behouden blijven voor referentie.
|
||||
|
||||
## Schema Snapshots
|
||||
|
||||
Deze bestanden zijn **niet bedoeld om uit te voeren** als migrations, maar dienen als documentatie van het huidige database schema:
|
||||
|
||||
- **`20251122-current-db-scheme.sql`** - Snapshot van database schema (2025-11-22)
|
||||
- **`20251122-supabase-scheme.sql`** - Actueel database schema snapshot (2025-11-22)
|
||||
|
||||
⚠️ **Waarschuwing:** Deze bestanden bevatten een WARNING dat ze niet uitgevoerd moeten worden. Ze zijn alleen voor documentatie/referentie doeleinden.
|
||||
|
||||
## Test Files
|
||||
|
||||
- **`20241115000003_test_rls_policies.sql`** - Test queries voor RLS policies verificatie (niet een echte migration)
|
||||
|
||||
## Waarom gearchiveerd?
|
||||
|
||||
Deze bestanden zijn gearchiveerd omdat:
|
||||
1. Ze geen echte migrations zijn (snapshots/test files)
|
||||
2. Ze niet uitgevoerd moeten worden door Supabase CLI
|
||||
3. Ze alleen voor documentatie/referentie dienen
|
||||
4. Ze de migrations directory vervuilen
|
||||
|
||||
## Actieve Migrations
|
||||
|
||||
Actieve migrations staan in `/supabase/migrations/` en worden uitgevoerd door Supabase CLI.
|
||||
|
||||
1058
docs/archive/schemas/20241121_fhir_ggz_schema.sql
Normal file
1058
docs/archive/schemas/20241121_fhir_ggz_schema.sql
Normal file
File diff suppressed because it is too large
Load Diff
704
docs/archive/schemas/20241121_pragmatic_fhir_schema.sql
Normal file
704
docs/archive/schemas/20241121_pragmatic_fhir_schema.sql
Normal file
@@ -0,0 +1,704 @@
|
||||
-- ============================================================================
|
||||
-- PRAGMATIC FHIR GGZ EPD SCHEMA
|
||||
-- ============================================================================
|
||||
-- Created: 2024-11-21
|
||||
-- Version: Pragmatic v2.0
|
||||
-- Description: Simplified FHIR schema for prototype focused on data interoperability
|
||||
--
|
||||
-- Differences from full schema (20241121_fhir_ggz_schema.sql):
|
||||
-- - Only 7 tables (6 FHIR resources + organizations)
|
||||
-- - Goals embedded in care_plans.goals JSONB (not separate table)
|
||||
-- - Activities embedded in care_plans.activities JSONB (not separate table)
|
||||
-- - No medications, consents, flags, documents tables
|
||||
-- - BSN placeholders (no encryption for demo)
|
||||
-- - Keeps existing tables: clients, intake_notes, treatment_plans, ai_events
|
||||
-- ============================================================================
|
||||
|
||||
-- ============================================================================
|
||||
-- ENABLE EXTENSIONS
|
||||
-- ============================================================================
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- Note: pgcrypto not needed for pragmatic version (no BSN encryption)
|
||||
|
||||
-- ============================================================================
|
||||
-- ENUM TYPES (for type safety)
|
||||
-- ============================================================================
|
||||
|
||||
-- FHIR Gender
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE gender_type AS ENUM ('male', 'female', 'other', 'unknown');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- FHIR Encounter Status
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE encounter_status AS ENUM (
|
||||
'planned', 'in-progress', 'on-hold', 'completed',
|
||||
'cancelled', 'entered-in-error', 'unknown'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- FHIR Condition Clinical Status
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE condition_clinical_status AS ENUM (
|
||||
'active', 'recurrence', 'relapse', 'inactive',
|
||||
'remission', 'resolved', 'unknown'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- FHIR Condition Verification Status
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE condition_verification_status AS ENUM (
|
||||
'unconfirmed', 'provisional', 'differential',
|
||||
'confirmed', 'refuted', 'entered-in-error'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- FHIR Observation Status
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE observation_status AS ENUM (
|
||||
'registered', 'preliminary', 'final', 'amended',
|
||||
'corrected', 'cancelled', 'entered-in-error', 'unknown'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- FHIR CarePlan Status
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE careplan_status AS ENUM (
|
||||
'draft', 'active', 'on-hold', 'revoked',
|
||||
'completed', 'entered-in-error', 'unknown'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: practitioners (FHIR: Practitioner)
|
||||
-- Behandelaren/professionals
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS practitioners (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR Practitioner fields
|
||||
identifier_big TEXT UNIQUE, -- BIG-nummer (optioneel)
|
||||
identifier_agb TEXT, -- AGB-code
|
||||
|
||||
-- Name (HumanName)
|
||||
name_prefix TEXT, -- "Drs.", "Dr."
|
||||
name_given TEXT[] NOT NULL, -- Voornamen
|
||||
name_family TEXT NOT NULL, -- Achternaam
|
||||
name_suffix TEXT, -- "PhD", "MSc"
|
||||
|
||||
-- Qualification
|
||||
qualification TEXT[], -- ["GZ-psycholoog", "Psychotherapeut"]
|
||||
|
||||
-- Contact
|
||||
telecom_phone TEXT,
|
||||
telecom_email TEXT,
|
||||
|
||||
-- Active
|
||||
active BOOLEAN DEFAULT true,
|
||||
|
||||
-- Link to auth user
|
||||
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE practitioners IS 'FHIR: Practitioner - Behandelaren en zorgprofessionals';
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: organizations (FHIR: Organization)
|
||||
-- GGZ-instellingen
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS organizations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR Organization fields
|
||||
identifier_agb TEXT UNIQUE, -- AGB-code instelling
|
||||
identifier_kvk TEXT, -- KVK-nummer
|
||||
|
||||
-- Name
|
||||
name TEXT NOT NULL,
|
||||
alias TEXT[], -- Alternative names
|
||||
|
||||
-- Type
|
||||
type_code TEXT DEFAULT 'prov', -- healthcare provider
|
||||
type_display TEXT DEFAULT 'Healthcare Provider',
|
||||
|
||||
-- Contact
|
||||
telecom_phone TEXT,
|
||||
telecom_email TEXT,
|
||||
telecom_website TEXT,
|
||||
|
||||
-- Address
|
||||
address_line TEXT[],
|
||||
address_city TEXT,
|
||||
address_postal_code TEXT,
|
||||
address_country TEXT DEFAULT 'NL',
|
||||
|
||||
-- Active
|
||||
active BOOLEAN DEFAULT true,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE organizations IS 'FHIR: Organization - GGZ-instellingen';
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: patients (FHIR: Patient / ZIB: Patient)
|
||||
-- Cliënten/patiënten
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS patients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR Patient.identifier
|
||||
-- PRAGMATIC: No encryption, use placeholder BSN for demo
|
||||
identifier_bsn TEXT DEFAULT '999999990', -- Placeholder BSN
|
||||
identifier_client_number TEXT, -- Interne cliëntnummer
|
||||
|
||||
-- FHIR Patient.name (HumanName)
|
||||
name_family TEXT NOT NULL, -- Achternaam
|
||||
name_given TEXT[] NOT NULL, -- Voornamen array
|
||||
name_prefix TEXT, -- Voorvoegsel (van, de, etc)
|
||||
name_use TEXT DEFAULT 'official', -- official, maiden, nickname
|
||||
|
||||
-- FHIR Patient.birthDate
|
||||
birth_date DATE NOT NULL,
|
||||
|
||||
-- FHIR Patient.gender
|
||||
gender gender_type NOT NULL,
|
||||
|
||||
-- FHIR Patient.telecom (ContactPoint)
|
||||
telecom_phone TEXT,
|
||||
telecom_email TEXT,
|
||||
|
||||
-- FHIR Patient.address (Address)
|
||||
address_line TEXT[], -- Straat + huisnummer
|
||||
address_city TEXT,
|
||||
address_postal_code TEXT,
|
||||
address_country TEXT DEFAULT 'NL',
|
||||
|
||||
-- Insurance (ZIB: Payer)
|
||||
insurance_company TEXT, -- Zorgverzekeraar
|
||||
insurance_number TEXT, -- Polisnummer
|
||||
|
||||
-- FHIR Patient.contact (naasten)
|
||||
emergency_contact_name TEXT,
|
||||
emergency_contact_relationship TEXT,
|
||||
emergency_contact_phone TEXT,
|
||||
|
||||
-- FHIR Patient.active
|
||||
active BOOLEAN DEFAULT true,
|
||||
|
||||
-- FHIR Patient.generalPractitioner (huisarts)
|
||||
general_practitioner_name TEXT,
|
||||
general_practitioner_agb TEXT,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE patients IS 'FHIR: Patient / ZIB: Patient - Cliënten/patiënten (pragmatic version with placeholder BSN)';
|
||||
COMMENT ON COLUMN patients.identifier_bsn IS 'Placeholder BSN for demo (not encrypted in pragmatic version)';
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: encounters (FHIR: Encounter / ZIB: Contact)
|
||||
-- Contactmomenten (intake, behandelsessie, etc)
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS encounters (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR Encounter.identifier
|
||||
identifier TEXT UNIQUE DEFAULT gen_random_uuid()::TEXT,
|
||||
|
||||
-- FHIR Encounter.status
|
||||
status encounter_status NOT NULL DEFAULT 'planned',
|
||||
|
||||
-- FHIR Encounter.class
|
||||
class_code TEXT NOT NULL, -- AMB (ambulatory), IMP (inpatient), EMER (emergency), VR (virtual)
|
||||
class_display TEXT NOT NULL,
|
||||
|
||||
-- FHIR Encounter.type
|
||||
type_code TEXT NOT NULL, -- intake, diagnostiek, behandeling, follow-up, crisis
|
||||
type_display TEXT NOT NULL,
|
||||
|
||||
-- FHIR Encounter.priority
|
||||
priority_code TEXT, -- routine, urgent, emergency
|
||||
priority_display TEXT,
|
||||
|
||||
-- FHIR Encounter.subject (patient)
|
||||
patient_id UUID REFERENCES patients(id) ON DELETE CASCADE NOT NULL,
|
||||
|
||||
-- FHIR Encounter.participant (behandelaar)
|
||||
practitioner_id UUID REFERENCES practitioners(id),
|
||||
|
||||
-- FHIR Encounter.serviceProvider (instelling)
|
||||
organization_id UUID REFERENCES organizations(id),
|
||||
|
||||
-- FHIR Encounter.period
|
||||
period_start TIMESTAMPTZ NOT NULL,
|
||||
period_end TIMESTAMPTZ,
|
||||
|
||||
-- FHIR Encounter.reasonCode
|
||||
reason_code TEXT[], -- DSM-5 codes, SNOMED codes
|
||||
reason_display TEXT[], -- Human-readable reason
|
||||
|
||||
-- FHIR Encounter.hospitalization (indien opname)
|
||||
admission_source TEXT,
|
||||
discharge_disposition TEXT,
|
||||
|
||||
-- Free text notes
|
||||
notes TEXT,
|
||||
|
||||
-- Link to intake_notes (existing table)
|
||||
intake_note_id UUID REFERENCES intake_notes(id),
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE encounters IS 'FHIR: Encounter / ZIB: Contact - Contactmomenten (intake, behandeling, etc)';
|
||||
COMMENT ON COLUMN encounters.intake_note_id IS 'Link to existing intake_notes table for backwards compatibility';
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: conditions (FHIR: Condition / ZIB: Problem)
|
||||
-- DSM-5 diagnoses en problemlijst
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS conditions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR Condition.identifier
|
||||
identifier TEXT UNIQUE DEFAULT gen_random_uuid()::TEXT,
|
||||
|
||||
-- FHIR Condition.clinicalStatus
|
||||
clinical_status condition_clinical_status NOT NULL DEFAULT 'active',
|
||||
|
||||
-- FHIR Condition.verificationStatus
|
||||
verification_status condition_verification_status NOT NULL DEFAULT 'provisional',
|
||||
|
||||
-- FHIR Condition.category
|
||||
category TEXT NOT NULL DEFAULT 'encounter-diagnosis', -- of 'problem-list-item'
|
||||
|
||||
-- FHIR Condition.severity
|
||||
severity_code TEXT, -- mild, moderate, severe
|
||||
severity_display TEXT,
|
||||
|
||||
-- FHIR Condition.code (DSM-5 / ICD-10)
|
||||
code_system TEXT NOT NULL DEFAULT 'http://hl7.org/fhir/sid/icd-10',
|
||||
code_code TEXT NOT NULL, -- "F32.2", "F41.1"
|
||||
code_display TEXT NOT NULL, -- "Depressieve episode, ernstig"
|
||||
|
||||
-- FHIR Condition.bodySite (indien relevant)
|
||||
body_site_code TEXT,
|
||||
body_site_display TEXT,
|
||||
|
||||
-- FHIR Condition.subject (patient)
|
||||
patient_id UUID REFERENCES patients(id) ON DELETE CASCADE NOT NULL,
|
||||
|
||||
-- FHIR Condition.encounter (wanneer gesteld)
|
||||
encounter_id UUID REFERENCES encounters(id),
|
||||
|
||||
-- FHIR Condition.onsetDateTime / abatementDateTime
|
||||
onset_datetime TIMESTAMPTZ,
|
||||
onset_age INTEGER, -- Leeftijd bij ontstaan (optioneel)
|
||||
abatement_datetime TIMESTAMPTZ,
|
||||
abatement_age INTEGER,
|
||||
|
||||
-- FHIR Condition.recordedDate
|
||||
recorded_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
|
||||
-- FHIR Condition.recorder (wie legde vast)
|
||||
recorder_id UUID REFERENCES practitioners(id),
|
||||
|
||||
-- FHIR Condition.asserter (wie stelde diagnose)
|
||||
asserter_id UUID REFERENCES practitioners(id),
|
||||
|
||||
-- FHIR Condition.note
|
||||
note TEXT,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE conditions IS 'FHIR: Condition / ZIB: Problem - DSM-5 diagnoses en problemlijst';
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: observations (FHIR: Observation)
|
||||
-- ROM-scores, risico's, klachten, metingen
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS observations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR Observation.identifier
|
||||
identifier TEXT UNIQUE DEFAULT gen_random_uuid()::TEXT,
|
||||
|
||||
-- FHIR Observation.status
|
||||
status observation_status NOT NULL DEFAULT 'final',
|
||||
|
||||
-- FHIR Observation.category
|
||||
category TEXT NOT NULL, -- vital-signs, social-history, exam, survey, therapy
|
||||
|
||||
-- FHIR Observation.code (wat werd geobserveerd)
|
||||
code_system TEXT NOT NULL, -- SNOMED, LOINC, custom
|
||||
code_code TEXT NOT NULL,
|
||||
code_display TEXT NOT NULL,
|
||||
|
||||
-- FHIR Observation.subject (patient)
|
||||
patient_id UUID REFERENCES patients(id) ON DELETE CASCADE NOT NULL,
|
||||
|
||||
-- FHIR Observation.encounter
|
||||
encounter_id UUID REFERENCES encounters(id),
|
||||
|
||||
-- FHIR Observation.effectiveDateTime
|
||||
effective_datetime TIMESTAMPTZ NOT NULL,
|
||||
|
||||
-- FHIR Observation.issued
|
||||
issued TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
-- FHIR Observation.performer (wie deed observatie)
|
||||
performer_id UUID REFERENCES practitioners(id),
|
||||
|
||||
-- FHIR Observation.value[x] (polymorf!)
|
||||
value_type TEXT NOT NULL, -- quantity, string, boolean, codeableConcept
|
||||
value_quantity_value NUMERIC,
|
||||
value_quantity_unit TEXT,
|
||||
value_quantity_comparator TEXT, -- <, <=, >=, >
|
||||
value_string TEXT,
|
||||
value_boolean BOOLEAN,
|
||||
value_codeable_concept JSONB, -- {system, code, display}
|
||||
|
||||
-- FHIR Observation.interpretation
|
||||
interpretation_code TEXT, -- H (high), L (low), N (normal)
|
||||
interpretation_display TEXT,
|
||||
|
||||
-- FHIR Observation.note
|
||||
note TEXT,
|
||||
|
||||
-- FHIR Observation.bodySite
|
||||
body_site TEXT,
|
||||
|
||||
-- FHIR Observation.method
|
||||
method_code TEXT,
|
||||
method_display TEXT,
|
||||
|
||||
-- Reference range (normaalwaarden)
|
||||
reference_range_low NUMERIC,
|
||||
reference_range_high NUMERIC,
|
||||
reference_range_text TEXT,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE observations IS 'FHIR: Observation - ROM-scores, risico-inschattingen, metingen';
|
||||
|
||||
-- ============================================================================
|
||||
-- TABLE: care_plans (FHIR: CarePlan)
|
||||
-- Behandelplannen met embedded goals en activities
|
||||
-- ============================================================================
|
||||
CREATE TABLE IF NOT EXISTS care_plans (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- FHIR CarePlan.identifier
|
||||
identifier TEXT UNIQUE DEFAULT gen_random_uuid()::TEXT,
|
||||
|
||||
-- FHIR CarePlan.status
|
||||
status careplan_status NOT NULL DEFAULT 'draft',
|
||||
|
||||
-- FHIR CarePlan.intent
|
||||
intent TEXT NOT NULL DEFAULT 'plan', -- proposal, plan, order, option
|
||||
|
||||
-- FHIR CarePlan.category
|
||||
category_code TEXT DEFAULT 'ggz-behandelplan',
|
||||
category_display TEXT DEFAULT 'GGZ Behandelplan',
|
||||
|
||||
-- FHIR CarePlan.title
|
||||
title TEXT NOT NULL,
|
||||
|
||||
-- FHIR CarePlan.description
|
||||
description TEXT,
|
||||
|
||||
-- FHIR CarePlan.subject (patient)
|
||||
patient_id UUID REFERENCES patients(id) ON DELETE CASCADE NOT NULL,
|
||||
|
||||
-- FHIR CarePlan.encounter (intake waar uit voortkomt)
|
||||
encounter_id UUID REFERENCES encounters(id),
|
||||
|
||||
-- FHIR CarePlan.period
|
||||
period_start DATE,
|
||||
period_end DATE,
|
||||
|
||||
-- FHIR CarePlan.created
|
||||
created_date TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
-- FHIR CarePlan.author (regiebehandelaar)
|
||||
author_id UUID REFERENCES practitioners(id),
|
||||
|
||||
-- FHIR CarePlan.contributor
|
||||
contributor_ids UUID[], -- Array van practitioner IDs
|
||||
|
||||
-- FHIR CarePlan.careTeam
|
||||
care_team_ids UUID[], -- Array van practitioner IDs
|
||||
|
||||
-- FHIR CarePlan.addresses (welke diagnoses)
|
||||
addresses_condition_ids UUID[], -- Array van condition IDs
|
||||
|
||||
-- ========================================================================
|
||||
-- PRAGMATIC APPROACH: EMBEDDED GOALS AND ACTIVITIES
|
||||
-- ========================================================================
|
||||
-- FHIR CarePlan.goal (behandeldoelen als JSONB array)
|
||||
goals JSONB DEFAULT '[]'::jsonb,
|
||||
-- Structure: [
|
||||
-- {
|
||||
-- "description": {"text": "PHQ-9 score < 10"},
|
||||
-- "target": [{
|
||||
-- "measure": {"coding": [{"system": "...", "code": "44249-1"}]},
|
||||
-- "detailQuantity": {"value": 10, "comparator": "<"},
|
||||
-- "dueDate": "2024-06-30"
|
||||
-- }]
|
||||
-- }
|
||||
-- ]
|
||||
|
||||
-- FHIR CarePlan.activity (behandelactiviteiten als JSONB array)
|
||||
activities JSONB DEFAULT '[]'::jsonb,
|
||||
-- Structure: [
|
||||
-- {
|
||||
-- "detail": {
|
||||
-- "code": {"text": "Cognitieve gedragstherapie"},
|
||||
-- "status": "in-progress",
|
||||
-- "scheduledTiming": {"repeat": {"frequency": 1, "period": 1, "periodUnit": "wk"}},
|
||||
-- "performer": ["practitioner-id"],
|
||||
-- "description": "Individuele CGT sessies, 12 weken",
|
||||
-- "location": "Polikliniek"
|
||||
-- }
|
||||
-- }
|
||||
-- ]
|
||||
-- ========================================================================
|
||||
|
||||
-- FHIR CarePlan.note
|
||||
note TEXT,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
COMMENT ON TABLE care_plans IS 'FHIR: CarePlan - Behandelplannen met embedded goals en activities (pragmatic approach)';
|
||||
COMMENT ON COLUMN care_plans.goals IS 'FHIR Goal structures embedded as JSONB array (pragmatic: no separate table)';
|
||||
COMMENT ON COLUMN care_plans.activities IS 'FHIR CarePlan.activity structures embedded as JSONB array (pragmatic: no separate table)';
|
||||
|
||||
-- ============================================================================
|
||||
-- INDEXES (voor performance)
|
||||
-- ============================================================================
|
||||
|
||||
-- Practitioners
|
||||
CREATE INDEX IF NOT EXISTS idx_practitioners_user_id ON practitioners(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_practitioners_active ON practitioners(active);
|
||||
|
||||
-- Patients
|
||||
CREATE INDEX IF NOT EXISTS idx_patients_bsn ON patients(identifier_bsn);
|
||||
CREATE INDEX IF NOT EXISTS idx_patients_active ON patients(active);
|
||||
CREATE INDEX IF NOT EXISTS idx_patients_client_number ON patients(identifier_client_number);
|
||||
|
||||
-- Encounters
|
||||
CREATE INDEX IF NOT EXISTS idx_encounters_patient_id ON encounters(patient_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_encounters_practitioner_id ON encounters(practitioner_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_encounters_status ON encounters(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_encounters_period_start ON encounters(period_start DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_encounters_intake_note_id ON encounters(intake_note_id);
|
||||
|
||||
-- Conditions
|
||||
CREATE INDEX IF NOT EXISTS idx_conditions_patient_id ON conditions(patient_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_conditions_encounter_id ON conditions(encounter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_conditions_clinical_status ON conditions(clinical_status);
|
||||
CREATE INDEX IF NOT EXISTS idx_conditions_code ON conditions(code_code);
|
||||
|
||||
-- Observations
|
||||
CREATE INDEX IF NOT EXISTS idx_observations_patient_id ON observations(patient_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_observations_encounter_id ON observations(encounter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_observations_category ON observations(category);
|
||||
CREATE INDEX IF NOT EXISTS idx_observations_effective_datetime ON observations(effective_datetime DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_observations_code ON observations(code_code);
|
||||
|
||||
-- Care Plans
|
||||
CREATE INDEX IF NOT EXISTS idx_care_plans_patient_id ON care_plans(patient_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_care_plans_status ON care_plans(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_care_plans_author_id ON care_plans(author_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_care_plans_encounter_id ON care_plans(encounter_id);
|
||||
|
||||
-- GIN indexes for JSONB columns (for efficient querying)
|
||||
CREATE INDEX IF NOT EXISTS idx_care_plans_goals_gin ON care_plans USING GIN (goals);
|
||||
CREATE INDEX IF NOT EXISTS idx_care_plans_activities_gin ON care_plans USING GIN (activities);
|
||||
|
||||
-- ============================================================================
|
||||
-- ROW LEVEL SECURITY (RLS) - basis setup
|
||||
-- ============================================================================
|
||||
|
||||
-- Enable RLS on all tables
|
||||
ALTER TABLE practitioners ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE organizations ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE patients ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE encounters ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE conditions ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE observations ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE care_plans ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Voor MVP: authenticated users kunnen alles zien (later verfijnen)
|
||||
|
||||
-- Practitioners: can read/update their own record
|
||||
DROP POLICY IF EXISTS "Practitioners can view own record" ON practitioners;
|
||||
CREATE POLICY "Practitioners can view own record" ON practitioners
|
||||
FOR SELECT USING (user_id = auth.uid());
|
||||
|
||||
DROP POLICY IF EXISTS "Practitioners can update own record" ON practitioners;
|
||||
CREATE POLICY "Practitioners can update own record" ON practitioners
|
||||
FOR UPDATE USING (user_id = auth.uid());
|
||||
|
||||
-- Patients: authenticated users can view/create/update
|
||||
DROP POLICY IF EXISTS "Authenticated users can view patients" ON patients;
|
||||
CREATE POLICY "Authenticated users can view patients" ON patients
|
||||
FOR SELECT USING (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can insert patients" ON patients;
|
||||
CREATE POLICY "Authenticated users can insert patients" ON patients
|
||||
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can update patients" ON patients;
|
||||
CREATE POLICY "Authenticated users can update patients" ON patients
|
||||
FOR UPDATE USING (auth.role() = 'authenticated');
|
||||
|
||||
-- Encounters: authenticated users can view/create/update
|
||||
DROP POLICY IF EXISTS "Authenticated users can view encounters" ON encounters;
|
||||
CREATE POLICY "Authenticated users can view encounters" ON encounters
|
||||
FOR SELECT USING (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can insert encounters" ON encounters;
|
||||
CREATE POLICY "Authenticated users can insert encounters" ON encounters
|
||||
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can update encounters" ON encounters;
|
||||
CREATE POLICY "Authenticated users can update encounters" ON encounters
|
||||
FOR UPDATE USING (auth.role() = 'authenticated');
|
||||
|
||||
-- Conditions: authenticated users can view/create/update
|
||||
DROP POLICY IF EXISTS "Authenticated users can view conditions" ON conditions;
|
||||
CREATE POLICY "Authenticated users can view conditions" ON conditions
|
||||
FOR SELECT USING (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can insert conditions" ON conditions;
|
||||
CREATE POLICY "Authenticated users can insert conditions" ON conditions
|
||||
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can update conditions" ON conditions;
|
||||
CREATE POLICY "Authenticated users can update conditions" ON conditions
|
||||
FOR UPDATE USING (auth.role() = 'authenticated');
|
||||
|
||||
-- Observations: authenticated users can view/create
|
||||
DROP POLICY IF EXISTS "Authenticated users can view observations" ON observations;
|
||||
CREATE POLICY "Authenticated users can view observations" ON observations
|
||||
FOR SELECT USING (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can insert observations" ON observations;
|
||||
CREATE POLICY "Authenticated users can insert observations" ON observations
|
||||
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
|
||||
|
||||
-- Care Plans: authenticated users can view/create/update
|
||||
DROP POLICY IF EXISTS "Authenticated users can view care plans" ON care_plans;
|
||||
CREATE POLICY "Authenticated users can view care plans" ON care_plans
|
||||
FOR SELECT USING (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can insert care plans" ON care_plans;
|
||||
CREATE POLICY "Authenticated users can insert care plans" ON care_plans
|
||||
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
|
||||
|
||||
DROP POLICY IF EXISTS "Authenticated users can update care plans" ON care_plans;
|
||||
CREATE POLICY "Authenticated users can update care plans" ON care_plans
|
||||
FOR UPDATE USING (auth.role() = 'authenticated');
|
||||
|
||||
-- ============================================================================
|
||||
-- FUNCTIONS - updated_at trigger
|
||||
-- ============================================================================
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Apply trigger to all tables with updated_at
|
||||
DROP TRIGGER IF EXISTS set_updated_at ON practitioners;
|
||||
CREATE TRIGGER set_updated_at BEFORE UPDATE ON practitioners
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
DROP TRIGGER IF EXISTS set_updated_at ON organizations;
|
||||
CREATE TRIGGER set_updated_at BEFORE UPDATE ON organizations
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
DROP TRIGGER IF EXISTS set_updated_at ON patients;
|
||||
CREATE TRIGGER set_updated_at BEFORE UPDATE ON patients
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
DROP TRIGGER IF EXISTS set_updated_at ON encounters;
|
||||
CREATE TRIGGER set_updated_at BEFORE UPDATE ON encounters
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
DROP TRIGGER IF EXISTS set_updated_at ON conditions;
|
||||
CREATE TRIGGER set_updated_at BEFORE UPDATE ON conditions
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
DROP TRIGGER IF EXISTS set_updated_at ON care_plans;
|
||||
CREATE TRIGGER set_updated_at BEFORE UPDATE ON care_plans
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- ============================================================================
|
||||
-- SEED DATA (demo/development)
|
||||
-- ============================================================================
|
||||
|
||||
-- Default organization
|
||||
INSERT INTO organizations (id, name, identifier_agb, active)
|
||||
VALUES (
|
||||
'00000000-0000-0000-0000-000000000001'::uuid,
|
||||
'Demo GGZ Instelling',
|
||||
'AGB-DEMO-001',
|
||||
true
|
||||
)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- SUMMARY
|
||||
-- ============================================================================
|
||||
-- ✅ Created 7 tables: practitioners, organizations, patients, encounters, conditions, observations, care_plans
|
||||
-- ✅ Goals and activities embedded in care_plans JSONB (pragmatic approach)
|
||||
-- ✅ No medications, consents, flags, documents tables (out of scope)
|
||||
-- ✅ Simplified BSN (placeholder for demo)
|
||||
-- ✅ RLS enabled on all tables
|
||||
-- ✅ Indexes for performance
|
||||
-- ✅ Triggers for updated_at
|
||||
-- ✅ 1 default organization seeded
|
||||
--
|
||||
-- NEXT STEPS:
|
||||
-- 1. Run this migration in Supabase
|
||||
-- 2. Generate TypeScript types: supabase gen types
|
||||
-- 3. Create data migration script: clients → patients, treatment_plans → care_plans
|
||||
-- 4. Seed demo data: practitioners, patients, encounters
|
||||
-- ============================================================================
|
||||
BIN
docs/fonts/Lora-Bold.woff
Normal file
BIN
docs/fonts/Lora-Bold.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Bold.woff2
Normal file
BIN
docs/fonts/Lora-Bold.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Bold.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Bold.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Bold.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Bold.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-BoldItalic.woff
Normal file
BIN
docs/fonts/Lora-BoldItalic.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-BoldItalic.woff2
Normal file
BIN
docs/fonts/Lora-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-BoldItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-BoldItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-BoldItalic.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-BoldItalic.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Italic.woff
Normal file
BIN
docs/fonts/Lora-Italic.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Italic.woff2
Normal file
BIN
docs/fonts/Lora-Italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Italic.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Italic.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Medium.woff
Normal file
BIN
docs/fonts/Lora-Medium.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Medium.woff2
Normal file
BIN
docs/fonts/Lora-Medium.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Medium.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Medium.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Medium.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Medium.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-MediumItalic.woff
Normal file
BIN
docs/fonts/Lora-MediumItalic.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-MediumItalic.woff2
Normal file
BIN
docs/fonts/Lora-MediumItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-MediumItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-MediumItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-MediumItalic.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-MediumItalic.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Regular.woff
Normal file
BIN
docs/fonts/Lora-Regular.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Regular.woff2
Normal file
BIN
docs/fonts/Lora-Regular.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Regular.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Regular.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-Regular.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-Regular.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBold.woff
Normal file
BIN
docs/fonts/Lora-SemiBold.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBold.woff2
Normal file
BIN
docs/fonts/Lora-SemiBold.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBold.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-SemiBold.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBold.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-SemiBold.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBoldItalic.woff
Normal file
BIN
docs/fonts/Lora-SemiBoldItalic.woff
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBoldItalic.woff2
Normal file
BIN
docs/fonts/Lora-SemiBoldItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBoldItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-SemiBoldItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Lora-SemiBoldItalic.woff:Zone.Identifier
Normal file
BIN
docs/fonts/Lora-SemiBoldItalic.woff:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Black.woff2
Normal file
BIN
docs/fonts/Poppins-Black.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Black.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Black.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-BlackItalic.woff2
Normal file
BIN
docs/fonts/Poppins-BlackItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-BlackItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-BlackItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Bold.woff2
Normal file
BIN
docs/fonts/Poppins-Bold.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Bold.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Bold.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-BoldItalic.woff2
Normal file
BIN
docs/fonts/Poppins-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-BoldItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-BoldItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraBold.woff2
Normal file
BIN
docs/fonts/Poppins-ExtraBold.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraBold.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-ExtraBold.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraBoldItalic.woff2
Normal file
BIN
docs/fonts/Poppins-ExtraBoldItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraBoldItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-ExtraBoldItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraLight.woff2
Normal file
BIN
docs/fonts/Poppins-ExtraLight.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraLight.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-ExtraLight.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraLightItalic.woff2
Normal file
BIN
docs/fonts/Poppins-ExtraLightItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ExtraLightItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-ExtraLightItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Italic.woff2
Normal file
BIN
docs/fonts/Poppins-Italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Light.woff2
Normal file
BIN
docs/fonts/Poppins-Light.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Light.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Light.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-LightItalic.woff2
Normal file
BIN
docs/fonts/Poppins-LightItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-LightItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-LightItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Medium.woff2
Normal file
BIN
docs/fonts/Poppins-Medium.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Medium.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Medium.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Regular.woff2
Normal file
BIN
docs/fonts/Poppins-Regular.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Regular.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Regular.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-SemiBold.woff2
Normal file
BIN
docs/fonts/Poppins-SemiBold.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-SemiBold.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-SemiBold.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-SemiBoldItalic.woff2
Normal file
BIN
docs/fonts/Poppins-SemiBoldItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-SemiBoldItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-SemiBoldItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Thin.woff2
Normal file
BIN
docs/fonts/Poppins-Thin.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-Thin.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-Thin.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ThinItalic.woff2
Normal file
BIN
docs/fonts/Poppins-ThinItalic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/Poppins-ThinItalic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/Poppins-ThinItalic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-200.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-200.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-200.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-200.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-200italic.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-200italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-200italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-200italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-300.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-300.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-300.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-300.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-300italic.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-300italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-300italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-300italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-500.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-500.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-500.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-500.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-500italic.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-500italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-500italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-500italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-600.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-600.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-600.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-600.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-600italic.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-600italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-600italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-600italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-italic.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-italic.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-italic.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-italic.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-regular.woff2
Normal file
BIN
docs/fonts/roboto-v47-latin-regular.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/roboto-v47-latin-regular.woff2:Zone.Identifier
Normal file
BIN
docs/fonts/roboto-v47-latin-regular.woff2:Zone.Identifier
Normal file
Binary file not shown.
BIN
docs/fonts/source-code-pro-v30-latin-200.woff2
Normal file
BIN
docs/fonts/source-code-pro-v30-latin-200.woff2
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user