diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 9d6560c..1432806 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -205,6 +205,10 @@ export type Database = { } collection_ledger_entries: { Row: { + account: string | null + admin: number + assess: number + bank: number collection_id: string created_at: string created_by: string | null @@ -213,10 +217,19 @@ export type Database = { description: string | null entry_date: string id: string + interest: number + late: number + legal: number + payment: number transaction_type: string updated_at: string + viol: number } Insert: { + account?: string | null + admin?: number + assess?: number + bank?: number collection_id: string created_at?: string created_by?: string | null @@ -225,10 +238,19 @@ export type Database = { description?: string | null entry_date?: string id?: string + interest?: number + late?: number + legal?: number + payment?: number transaction_type: string updated_at?: string + viol?: number } Update: { + account?: string | null + admin?: number + assess?: number + bank?: number collection_id?: string created_at?: string created_by?: string | null @@ -237,8 +259,13 @@ export type Database = { description?: string | null entry_date?: string id?: string + interest?: number + late?: number + legal?: number + payment?: number transaction_type?: string updated_at?: string + viol?: number } Relationships: [ { @@ -250,6 +277,48 @@ export type Database = { }, ] } + collection_payment_allocations: { + Row: { + amount: number + bucket: string + collection_id: string + created_at: string + entry_id: string + id: string + } + Insert: { + amount?: number + bucket: string + collection_id: string + created_at?: string + entry_id: string + id?: string + } + Update: { + amount?: number + bucket?: string + collection_id?: string + created_at?: string + entry_id?: string + id?: string + } + Relationships: [ + { + foreignKeyName: "collection_payment_allocations_collection_id_fkey" + columns: ["collection_id"] + isOneToOne: false + referencedRelation: "collections" + referencedColumns: ["id"] + }, + { + foreignKeyName: "collection_payment_allocations_entry_id_fkey" + columns: ["entry_id"] + isOneToOne: false + referencedRelation: "collection_ledger_entries" + referencedColumns: ["id"] + }, + ] + } collection_tasks: { Row: { assignee_id: string | null @@ -391,6 +460,8 @@ export type Database = { current_stage: string | null homeowner_id: string id: string + interest_rate_override: number | null + name: string | null notes: string | null opened_at: string status: string @@ -404,6 +475,8 @@ export type Database = { current_stage?: string | null homeowner_id: string id?: string + interest_rate_override?: number | null + name?: string | null notes?: string | null opened_at?: string status?: string @@ -417,6 +490,8 @@ export type Database = { current_stage?: string | null homeowner_id?: string id?: string + interest_rate_override?: number | null + name?: string | null notes?: string | null opened_at?: string status?: string diff --git a/supabase/migrations/20260417014832_66f77211-1c95-4974-b591-7e7c674a5987.sql b/supabase/migrations/20260417014832_66f77211-1c95-4974-b591-7e7c674a5987.sql new file mode 100644 index 0000000..b75b068 --- /dev/null +++ b/supabase/migrations/20260417014832_66f77211-1c95-4974-b591-7e7c674a5987.sql @@ -0,0 +1,58 @@ +-- Add category columns to ledger entries +ALTER TABLE public.collection_ledger_entries + ADD COLUMN IF NOT EXISTS assess numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS late numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS admin numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS legal numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS viol numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS interest numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS bank numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS payment numeric NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS account text; + +-- Backfill: split existing debit/credit into the appropriate column based on transaction_type +UPDATE public.collection_ledger_entries +SET + assess = CASE WHEN transaction_type = 'assessment' THEN COALESCE(debit,0) ELSE 0 END, + late = CASE WHEN transaction_type = 'late_fee' THEN COALESCE(debit,0) ELSE 0 END, + admin = CASE WHEN transaction_type = 'admin_fee' THEN COALESCE(debit,0) ELSE 0 END, + legal = CASE WHEN transaction_type = 'legal_fee' THEN COALESCE(debit,0) ELSE 0 END, + viol = CASE WHEN transaction_type = 'violation' THEN COALESCE(debit,0) ELSE 0 END, + interest = CASE WHEN transaction_type = 'interest' THEN COALESCE(debit,0) ELSE 0 END, + bank = CASE WHEN transaction_type IN ('bank_fee') THEN COALESCE(debit,0) ELSE 0 END, + payment = CASE WHEN transaction_type IN ('payment','adjustment') THEN COALESCE(credit,0) ELSE 0 END, + account = transaction_type +WHERE assess = 0 AND late = 0 AND admin = 0 AND legal = 0 AND viol = 0 AND interest = 0 AND bank = 0 AND payment = 0; + +-- Add ledger metadata to collections +ALTER TABLE public.collections + ADD COLUMN IF NOT EXISTS name text, + ADD COLUMN IF NOT EXISTS interest_rate_override numeric; + +-- Payment allocations: how a payment row is applied across priority buckets +CREATE TABLE IF NOT EXISTS public.collection_payment_allocations ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + entry_id uuid NOT NULL REFERENCES public.collection_ledger_entries(id) ON DELETE CASCADE, + collection_id uuid NOT NULL REFERENCES public.collections(id) ON DELETE CASCADE, + bucket text NOT NULL, -- 'bank' | 'interest' | 'late' | 'legal' | 'admin' | 'viol' | 'assess' + amount numeric NOT NULL DEFAULT 0, + created_at timestamptz NOT NULL DEFAULT now() +); + +ALTER TABLE public.collection_payment_allocations ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "cpa_select_case" ON public.collection_payment_allocations + FOR SELECT TO authenticated USING ( + EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND can_access_case(c.case_id, auth.uid())) + ); +CREATE POLICY "cpa_insert_case" ON public.collection_payment_allocations + FOR INSERT TO authenticated WITH CHECK ( + EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND can_access_case(c.case_id, auth.uid())) + ); +CREATE POLICY "cpa_delete_case" ON public.collection_payment_allocations + FOR DELETE TO authenticated USING ( + EXISTS (SELECT 1 FROM public.collections c WHERE c.id = collection_id AND can_access_case(c.case_id, auth.uid())) + ); + +CREATE INDEX IF NOT EXISTS idx_cpa_entry ON public.collection_payment_allocations(entry_id); +CREATE INDEX IF NOT EXISTS idx_cpa_collection ON public.collection_payment_allocations(collection_id);