From 5520ba109e76641c889c3a2b91c20800a7bee72c Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:08:11 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/integrations/supabase/types.ts | 32 ++++++- ...7_f78237d1-c516-45e1-a8bc-9460a7c9912c.sql | 88 +++++++++++++++++++ 2 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 supabase/migrations/20260426080807_f78237d1-c516-45e1-a8bc-9460a7c9912c.sql diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index c52fcac..ecb0ec9 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -2538,7 +2538,10 @@ export type Database = { notes: string | null paid: boolean paid_amount: number | null + paid_method: string | null paid_on: string | null + paid_reference: string | null + payment_request_id: string | null plan_id: string sort_order: number updated_at: string @@ -2552,7 +2555,10 @@ export type Database = { notes?: string | null paid?: boolean paid_amount?: number | null + paid_method?: string | null paid_on?: string | null + paid_reference?: string | null + payment_request_id?: string | null plan_id: string sort_order?: number updated_at?: string @@ -2566,7 +2572,10 @@ export type Database = { notes?: string | null paid?: boolean paid_amount?: number | null + paid_method?: string | null paid_on?: string | null + paid_reference?: string | null + payment_request_id?: string | null plan_id?: string sort_order?: number updated_at?: string @@ -2579,6 +2588,13 @@ export type Database = { referencedRelation: "collection_ledger_entries" referencedColumns: ["id"] }, + { + foreignKeyName: "payment_plan_installments_payment_request_id_fkey" + columns: ["payment_request_id"] + isOneToOne: false + referencedRelation: "payment_requests" + referencedColumns: ["id"] + }, { foreignKeyName: "payment_plan_installments_plan_id_fkey" columns: ["plan_id"] @@ -2590,7 +2606,8 @@ export type Database = { } payment_plans: { Row: { - collection_id: string + case_id: string | null + collection_id: string | null created_at: string created_by: string | null down_payment: number @@ -2606,7 +2623,8 @@ export type Database = { updated_at: string } Insert: { - collection_id: string + case_id?: string | null + collection_id?: string | null created_at?: string created_by?: string | null down_payment?: number @@ -2622,7 +2640,8 @@ export type Database = { updated_at?: string } Update: { - collection_id?: string + case_id?: string | null + collection_id?: string | null created_at?: string created_by?: string | null down_payment?: number @@ -2638,6 +2657,13 @@ export type Database = { updated_at?: string } Relationships: [ + { + foreignKeyName: "payment_plans_case_id_fkey" + columns: ["case_id"] + isOneToOne: false + referencedRelation: "cases" + referencedColumns: ["id"] + }, { foreignKeyName: "payment_plans_collection_id_fkey" columns: ["collection_id"] diff --git a/supabase/migrations/20260426080807_f78237d1-c516-45e1-a8bc-9460a7c9912c.sql b/supabase/migrations/20260426080807_f78237d1-c516-45e1-a8bc-9460a7c9912c.sql new file mode 100644 index 0000000..62743b4 --- /dev/null +++ b/supabase/migrations/20260426080807_f78237d1-c516-45e1-a8bc-9460a7c9912c.sql @@ -0,0 +1,88 @@ +-- Allow payment_plans to be attached to a case directly +ALTER TABLE public.payment_plans + ADD COLUMN IF NOT EXISTS case_id UUID REFERENCES public.cases(id) ON DELETE CASCADE; + +ALTER TABLE public.payment_plans + ALTER COLUMN collection_id DROP NOT NULL; + +ALTER TABLE public.payment_plans + DROP CONSTRAINT IF EXISTS pp_case_or_collection; +ALTER TABLE public.payment_plans + ADD CONSTRAINT pp_case_or_collection CHECK (case_id IS NOT NULL OR collection_id IS NOT NULL); + +CREATE INDEX IF NOT EXISTS idx_payment_plans_case ON public.payment_plans(case_id); + +-- Installment fields for online + manual payments +ALTER TABLE public.payment_plan_installments + ADD COLUMN IF NOT EXISTS payment_request_id UUID REFERENCES public.payment_requests(id) ON DELETE SET NULL, + ADD COLUMN IF NOT EXISTS paid_method TEXT, + ADD COLUMN IF NOT EXISTS paid_reference TEXT; + +-- Update RLS to also allow case-based access +DROP POLICY IF EXISTS pp_select ON public.payment_plans; +DROP POLICY IF EXISTS pp_insert ON public.payment_plans; +DROP POLICY IF EXISTS pp_update ON public.payment_plans; +DROP POLICY IF EXISTS pp_delete ON public.payment_plans; + +CREATE POLICY pp_select ON public.payment_plans FOR SELECT TO authenticated USING ( + (case_id IS NOT NULL AND public.can_access_case(case_id, auth.uid())) + OR (collection_id IS NOT NULL AND EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND public.can_access_case(c.case_id, auth.uid()))) +); +CREATE POLICY pp_insert ON public.payment_plans FOR INSERT TO authenticated WITH CHECK ( + (case_id IS NOT NULL AND public.can_access_case(case_id, auth.uid())) + OR (collection_id IS NOT NULL AND EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND public.can_access_case(c.case_id, auth.uid()))) +); +CREATE POLICY pp_update ON public.payment_plans FOR UPDATE TO authenticated USING ( + (case_id IS NOT NULL AND public.can_access_case(case_id, auth.uid())) + OR (collection_id IS NOT NULL AND EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND public.can_access_case(c.case_id, auth.uid()))) +); +CREATE POLICY pp_delete ON public.payment_plans FOR DELETE TO authenticated USING ( + (case_id IS NOT NULL AND public.can_access_case(case_id, auth.uid())) + OR (collection_id IS NOT NULL AND EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND public.can_access_case(c.case_id, auth.uid()))) +); + +DROP POLICY IF EXISTS ppi_select ON public.payment_plan_installments; +DROP POLICY IF EXISTS ppi_insert ON public.payment_plan_installments; +DROP POLICY IF EXISTS ppi_update ON public.payment_plan_installments; +DROP POLICY IF EXISTS ppi_delete ON public.payment_plan_installments; + +CREATE POLICY ppi_select ON public.payment_plan_installments FOR SELECT TO authenticated USING ( + EXISTS ( + SELECT 1 FROM public.payment_plans p + LEFT JOIN public.collections c ON c.id = p.collection_id + WHERE p.id = plan_id AND ( + (p.case_id IS NOT NULL AND public.can_access_case(p.case_id, auth.uid())) + OR (c.id IS NOT NULL AND public.can_access_case(c.case_id, auth.uid())) + ) + ) +); +CREATE POLICY ppi_insert ON public.payment_plan_installments FOR INSERT TO authenticated WITH CHECK ( + EXISTS ( + SELECT 1 FROM public.payment_plans p + LEFT JOIN public.collections c ON c.id = p.collection_id + WHERE p.id = plan_id AND ( + (p.case_id IS NOT NULL AND public.can_access_case(p.case_id, auth.uid())) + OR (c.id IS NOT NULL AND public.can_access_case(c.case_id, auth.uid())) + ) + ) +); +CREATE POLICY ppi_update ON public.payment_plan_installments FOR UPDATE TO authenticated USING ( + EXISTS ( + SELECT 1 FROM public.payment_plans p + LEFT JOIN public.collections c ON c.id = p.collection_id + WHERE p.id = plan_id AND ( + (p.case_id IS NOT NULL AND public.can_access_case(p.case_id, auth.uid())) + OR (c.id IS NOT NULL AND public.can_access_case(c.case_id, auth.uid())) + ) + ) +); +CREATE POLICY ppi_delete ON public.payment_plan_installments FOR DELETE TO authenticated USING ( + EXISTS ( + SELECT 1 FROM public.payment_plans p + LEFT JOIN public.collections c ON c.id = p.collection_id + WHERE p.id = plan_id AND ( + (p.case_id IS NOT NULL AND public.can_access_case(p.case_id, auth.uid())) + OR (c.id IS NOT NULL AND public.can_access_case(c.case_id, auth.uid())) + ) + ) +); \ No newline at end of file