-- Phase K: paliad.checklist_instances — per-user (and optionally per-Akte) -- instantiations of the static Checklisten templates defined in Go. -- -- Templates stay in handlers.checklists (static Go data). A row here is one -- user's personal checklist for one situation: a name, a link to an Akte -- (optional), and the current checkbox state as a jsonb map -- ({item_key: true}). State lives in the DB (not localStorage) so checkboxes -- survive browser changes, and office-mates can share them via an Akte link. -- -- Visibility mirrors paliad.termine (akte_id nullable): -- - akte_id NULL → creator-only (personal instance) -- - akte_id NOT NULL → parent Akte's office-scoped gate -- -- template_slug is a FK concept only — the slug's validity is enforced in -- the service layer against the static Go list. CREATE TABLE paliad.checklist_instances ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), template_slug text NOT NULL, name text NOT NULL, akte_id uuid REFERENCES paliad.akten(id) ON DELETE SET NULL, state jsonb NOT NULL DEFAULT '{}'::jsonb, created_by uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX checklist_instances_template_idx ON paliad.checklist_instances (template_slug); CREATE INDEX checklist_instances_akte_idx ON paliad.checklist_instances (akte_id) WHERE akte_id IS NOT NULL; CREATE INDEX checklist_instances_created_by_idx ON paliad.checklist_instances (created_by); ALTER TABLE paliad.checklist_instances ENABLE ROW LEVEL SECURITY; -- RLS — mirrors the termine policy so personal instances are creator-only -- while Akte-linked instances follow the office-scoped can_see_akte gate. CREATE POLICY checklist_instances_select ON paliad.checklist_instances FOR SELECT TO authenticated USING ( (akte_id IS NULL AND created_by = auth.uid()) OR (akte_id IS NOT NULL AND paliad.can_see_akte(akte_id)) ); CREATE POLICY checklist_instances_insert ON paliad.checklist_instances FOR INSERT TO authenticated WITH CHECK ( created_by = auth.uid() AND ( akte_id IS NULL OR paliad.can_see_akte(akte_id) ) ); CREATE POLICY checklist_instances_update ON paliad.checklist_instances FOR UPDATE TO authenticated USING ( (akte_id IS NULL AND created_by = auth.uid()) OR (akte_id IS NOT NULL AND paliad.can_see_akte(akte_id)) ) WITH CHECK ( (akte_id IS NULL AND created_by = auth.uid()) OR (akte_id IS NOT NULL AND paliad.can_see_akte(akte_id)) ); CREATE POLICY checklist_instances_delete ON paliad.checklist_instances FOR DELETE TO authenticated USING ( (akte_id IS NULL AND created_by = auth.uid()) OR (akte_id IS NOT NULL AND paliad.can_see_akte(akte_id)) );