From 46f2d14c5dc1adf7db2ab683daac0f3faf2c9f99 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 02:21:25 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/integrations/supabase/types.ts | 141 ++++++++++++++++++ ...2_8a0edd0a-97dc-4606-9958-f6c247997d3f.sql | 84 +++++++++++ 2 files changed, 225 insertions(+) create mode 100644 supabase/migrations/20260417022122_8a0edd0a-97dc-4606-9958-f6c247997d3f.sql diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 99ee050..77e48a7 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -14,6 +14,48 @@ export type Database = { } public: { Tables: { + case_contacts: { + Row: { + case_id: string + contact_id: string + created_at: string + created_by: string | null + id: string + role: string | null + } + Insert: { + case_id: string + contact_id: string + created_at?: string + created_by?: string | null + id?: string + role?: string | null + } + Update: { + case_id?: string + contact_id?: string + created_at?: string + created_by?: string | null + id?: string + role?: string | null + } + Relationships: [ + { + foreignKeyName: "case_contacts_case_id_fkey" + columns: ["case_id"] + isOneToOne: false + referencedRelation: "cases" + referencedColumns: ["id"] + }, + { + foreignKeyName: "case_contacts_contact_id_fkey" + columns: ["contact_id"] + isOneToOne: false + referencedRelation: "contacts" + referencedColumns: ["id"] + }, + ] + } cases: { Row: { assigned_attorney_id: string | null @@ -137,6 +179,48 @@ export type Database = { }, ] } + client_contacts: { + Row: { + client_id: string + contact_id: string + created_at: string + created_by: string | null + id: string + role: string | null + } + Insert: { + client_id: string + contact_id: string + created_at?: string + created_by?: string | null + id?: string + role?: string | null + } + Update: { + client_id?: string + contact_id?: string + created_at?: string + created_by?: string | null + id?: string + role?: string | null + } + Relationships: [ + { + foreignKeyName: "client_contacts_client_id_fkey" + columns: ["client_id"] + isOneToOne: false + referencedRelation: "clients" + referencedColumns: ["id"] + }, + { + foreignKeyName: "client_contacts_contact_id_fkey" + columns: ["contact_id"] + isOneToOne: false + referencedRelation: "contacts" + referencedColumns: ["id"] + }, + ] + } clients: { Row: { address_line1: string | null @@ -524,6 +608,63 @@ export type Database = { }, ] } + contacts: { + Row: { + address_line1: string | null + address_line2: string | null + city: string | null + company: string | null + contact_type: string + created_at: string + created_by: string | null + email: string | null + id: string + name: string + notes: string | null + phone: string | null + postal_code: string | null + state: string | null + title: string | null + updated_at: string + } + Insert: { + address_line1?: string | null + address_line2?: string | null + city?: string | null + company?: string | null + contact_type?: string + created_at?: string + created_by?: string | null + email?: string | null + id?: string + name: string + notes?: string | null + phone?: string | null + postal_code?: string | null + state?: string | null + title?: string | null + updated_at?: string + } + Update: { + address_line1?: string | null + address_line2?: string | null + city?: string | null + company?: string | null + contact_type?: string + created_at?: string + created_by?: string | null + email?: string | null + id?: string + name?: string + notes?: string | null + phone?: string | null + postal_code?: string | null + state?: string | null + title?: string | null + updated_at?: string + } + Relationships: [] + } document_folders: { Row: { case_id: string diff --git a/supabase/migrations/20260417022122_8a0edd0a-97dc-4606-9958-f6c247997d3f.sql b/supabase/migrations/20260417022122_8a0edd0a-97dc-4606-9958-f6c247997d3f.sql new file mode 100644 index 0000000..fe794fc --- /dev/null +++ b/supabase/migrations/20260417022122_8a0edd0a-97dc-4606-9958-f6c247997d3f.sql @@ -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);