Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-17 02:21:25 +00:00
co-authored by renee-png
parent 91a5b8377a
commit 46f2d14c5d
2 changed files with 225 additions and 0 deletions
@@ -0,0 +1,84 @@
-- Contacts directory
CREATE TABLE public.contacts (
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
company TEXT,
title TEXT,
email TEXT,
phone TEXT,
address_line1 TEXT,
address_line2 TEXT,
city TEXT,
state TEXT,
postal_code TEXT,
notes TEXT,
contact_type TEXT NOT NULL DEFAULT 'other',
created_by UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
ALTER TABLE public.contacts ENABLE ROW LEVEL SECURITY;
CREATE POLICY contacts_select_auth ON public.contacts
FOR SELECT TO authenticated USING (true);
CREATE POLICY contacts_insert_auth ON public.contacts
FOR INSERT TO authenticated WITH CHECK (auth.uid() IS NOT NULL);
CREATE POLICY contacts_update_owner ON public.contacts
FOR UPDATE TO authenticated USING (public.is_admin(auth.uid()) OR created_by = auth.uid());
CREATE POLICY contacts_delete_owner ON public.contacts
FOR DELETE TO authenticated USING (public.is_admin(auth.uid()) OR created_by = auth.uid());
CREATE TRIGGER tg_contacts_updated_at
BEFORE UPDATE ON public.contacts
FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
CREATE INDEX idx_contacts_name ON public.contacts (lower(name));
CREATE INDEX idx_contacts_type ON public.contacts (contact_type);
-- Case <-> Contact join
CREATE TABLE public.case_contacts (
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
case_id UUID NOT NULL REFERENCES public.cases(id) ON DELETE CASCADE,
contact_id UUID NOT NULL REFERENCES public.contacts(id) ON DELETE CASCADE,
role TEXT,
created_by UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (case_id, contact_id)
);
ALTER TABLE public.case_contacts ENABLE ROW LEVEL SECURITY;
CREATE POLICY case_contacts_select ON public.case_contacts
FOR SELECT TO authenticated USING (public.can_access_case(case_id, auth.uid()));
CREATE POLICY case_contacts_insert ON public.case_contacts
FOR INSERT TO authenticated WITH CHECK (public.can_access_case(case_id, auth.uid()));
CREATE POLICY case_contacts_delete ON public.case_contacts
FOR DELETE TO authenticated USING (public.can_access_case(case_id, auth.uid()));
CREATE INDEX idx_case_contacts_case ON public.case_contacts (case_id);
CREATE INDEX idx_case_contacts_contact ON public.case_contacts (contact_id);
-- Client <-> Contact join
CREATE TABLE public.client_contacts (
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
client_id UUID NOT NULL REFERENCES public.clients(id) ON DELETE CASCADE,
contact_id UUID NOT NULL REFERENCES public.contacts(id) ON DELETE CASCADE,
role TEXT,
created_by UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (client_id, contact_id)
);
ALTER TABLE public.client_contacts ENABLE ROW LEVEL SECURITY;
CREATE POLICY client_contacts_select ON public.client_contacts
FOR SELECT TO authenticated USING (true);
CREATE POLICY client_contacts_insert ON public.client_contacts
FOR INSERT TO authenticated WITH CHECK (auth.uid() IS NOT NULL);
CREATE POLICY client_contacts_delete ON public.client_contacts
FOR DELETE TO authenticated USING (public.is_admin(auth.uid()) OR created_by = auth.uid());
CREATE INDEX idx_client_contacts_client ON public.client_contacts (client_id);
CREATE INDEX idx_client_contacts_contact ON public.client_contacts (contact_id);