Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
42f6fab6e7
commit
9e2c88392e
@@ -141,6 +141,7 @@ export type Database = {
|
||||
Row: {
|
||||
address_line1: string | null
|
||||
address_line2: string | null
|
||||
annual_interest_rate: number | null
|
||||
board_members: Json
|
||||
city: string | null
|
||||
client_type: Database["public"]["Enums"]["client_type"]
|
||||
@@ -161,6 +162,7 @@ export type Database = {
|
||||
Insert: {
|
||||
address_line1?: string | null
|
||||
address_line2?: string | null
|
||||
annual_interest_rate?: number | null
|
||||
board_members?: Json
|
||||
city?: string | null
|
||||
client_type?: Database["public"]["Enums"]["client_type"]
|
||||
@@ -181,6 +183,7 @@ export type Database = {
|
||||
Update: {
|
||||
address_line1?: string | null
|
||||
address_line2?: string | null
|
||||
annual_interest_rate?: number | null
|
||||
board_members?: Json
|
||||
city?: string | null
|
||||
client_type?: Database["public"]["Enums"]["client_type"]
|
||||
@@ -200,6 +203,107 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
collection_ledger_entries: {
|
||||
Row: {
|
||||
collection_id: string
|
||||
created_at: string
|
||||
created_by: string | null
|
||||
credit: number
|
||||
debit: number
|
||||
description: string | null
|
||||
entry_date: string
|
||||
id: string
|
||||
transaction_type: string
|
||||
updated_at: string
|
||||
}
|
||||
Insert: {
|
||||
collection_id: string
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
credit?: number
|
||||
debit?: number
|
||||
description?: string | null
|
||||
entry_date?: string
|
||||
id?: string
|
||||
transaction_type: string
|
||||
updated_at?: string
|
||||
}
|
||||
Update: {
|
||||
collection_id?: string
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
credit?: number
|
||||
debit?: number
|
||||
description?: string | null
|
||||
entry_date?: string
|
||||
id?: string
|
||||
transaction_type?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "collection_ledger_entries_collection_id_fkey"
|
||||
columns: ["collection_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "collections"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
collections: {
|
||||
Row: {
|
||||
case_id: string
|
||||
closed_at: string | null
|
||||
created_at: string
|
||||
created_by: string | null
|
||||
homeowner_id: string
|
||||
id: string
|
||||
notes: string | null
|
||||
opened_at: string
|
||||
status: string
|
||||
updated_at: string
|
||||
}
|
||||
Insert: {
|
||||
case_id: string
|
||||
closed_at?: string | null
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
homeowner_id: string
|
||||
id?: string
|
||||
notes?: string | null
|
||||
opened_at?: string
|
||||
status?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Update: {
|
||||
case_id?: string
|
||||
closed_at?: string | null
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
homeowner_id?: string
|
||||
id?: string
|
||||
notes?: string | null
|
||||
opened_at?: string
|
||||
status?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "collections_case_id_fkey"
|
||||
columns: ["case_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "cases"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "collections_homeowner_id_fkey"
|
||||
columns: ["homeowner_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "homeowners"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
documents: {
|
||||
Row: {
|
||||
case_id: string
|
||||
@@ -301,6 +405,62 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
homeowners: {
|
||||
Row: {
|
||||
address: string | null
|
||||
client_id: string
|
||||
created_at: string
|
||||
created_by: string | null
|
||||
email: string | null
|
||||
first_name: string
|
||||
id: string
|
||||
last_name: string
|
||||
notes: string | null
|
||||
opening_balance: number
|
||||
phone: string | null
|
||||
unit_number: string | null
|
||||
updated_at: string
|
||||
}
|
||||
Insert: {
|
||||
address?: string | null
|
||||
client_id: string
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
email?: string | null
|
||||
first_name: string
|
||||
id?: string
|
||||
last_name: string
|
||||
notes?: string | null
|
||||
opening_balance?: number
|
||||
phone?: string | null
|
||||
unit_number?: string | null
|
||||
updated_at?: string
|
||||
}
|
||||
Update: {
|
||||
address?: string | null
|
||||
client_id?: string
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
email?: string | null
|
||||
first_name?: string
|
||||
id?: string
|
||||
last_name?: string
|
||||
notes?: string | null
|
||||
opening_balance?: number
|
||||
phone?: string | null
|
||||
unit_number?: string | null
|
||||
updated_at?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "homeowners_client_id_fkey"
|
||||
columns: ["client_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "clients"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
invoices: {
|
||||
Row: {
|
||||
amount_paid: number
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
-- 1. Annual interest rate on clients (per annum, non-compounded, applied monthly)
|
||||
ALTER TABLE public.clients
|
||||
ADD COLUMN IF NOT EXISTS annual_interest_rate numeric;
|
||||
|
||||
-- 2. Homeowners (belong to a client / HOA)
|
||||
CREATE TABLE IF NOT EXISTS public.homeowners (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
client_id uuid NOT NULL REFERENCES public.clients(id) ON DELETE CASCADE,
|
||||
first_name text NOT NULL,
|
||||
last_name text NOT NULL,
|
||||
unit_number text,
|
||||
address text,
|
||||
email text,
|
||||
phone text,
|
||||
opening_balance numeric NOT NULL DEFAULT 0,
|
||||
notes text,
|
||||
created_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_homeowners_client ON public.homeowners(client_id);
|
||||
|
||||
ALTER TABLE public.homeowners ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY homeowners_select_auth ON public.homeowners
|
||||
FOR SELECT TO authenticated USING (true);
|
||||
|
||||
CREATE POLICY homeowners_insert_auth ON public.homeowners
|
||||
FOR INSERT TO authenticated WITH CHECK (auth.uid() IS NOT NULL);
|
||||
|
||||
CREATE POLICY homeowners_update_owner ON public.homeowners
|
||||
FOR UPDATE TO authenticated
|
||||
USING (public.is_admin(auth.uid()) OR created_by = auth.uid());
|
||||
|
||||
CREATE POLICY homeowners_delete_admin ON public.homeowners
|
||||
FOR DELETE TO authenticated
|
||||
USING (public.is_admin(auth.uid()) OR created_by = auth.uid());
|
||||
|
||||
CREATE TRIGGER homeowners_set_updated_at
|
||||
BEFORE UPDATE ON public.homeowners
|
||||
FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
||||
|
||||
-- 3. Collections (one record per homeowner per case/matter)
|
||||
CREATE TABLE IF NOT EXISTS public.collections (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
case_id uuid NOT NULL REFERENCES public.cases(id) ON DELETE CASCADE,
|
||||
homeowner_id uuid NOT NULL REFERENCES public.homeowners(id) ON DELETE RESTRICT,
|
||||
status text NOT NULL DEFAULT 'late_notice',
|
||||
notes text,
|
||||
opened_at date NOT NULL DEFAULT CURRENT_DATE,
|
||||
closed_at date,
|
||||
created_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (case_id, homeowner_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_collections_case ON public.collections(case_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_collections_homeowner ON public.collections(homeowner_id);
|
||||
|
||||
ALTER TABLE public.collections ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY collections_select_case ON public.collections
|
||||
FOR SELECT TO authenticated
|
||||
USING (public.can_access_case(case_id, auth.uid()));
|
||||
|
||||
CREATE POLICY collections_insert_case ON public.collections
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (public.can_access_case(case_id, auth.uid()));
|
||||
|
||||
CREATE POLICY collections_update_case ON public.collections
|
||||
FOR UPDATE TO authenticated
|
||||
USING (public.can_access_case(case_id, auth.uid()));
|
||||
|
||||
CREATE POLICY collections_delete_case ON public.collections
|
||||
FOR DELETE TO authenticated
|
||||
USING (public.can_access_case(case_id, auth.uid()));
|
||||
|
||||
CREATE TRIGGER collections_set_updated_at
|
||||
BEFORE UPDATE ON public.collections
|
||||
FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
||||
|
||||
-- 4. Collection ledger entries (debit/credit per collection)
|
||||
CREATE TABLE IF NOT EXISTS public.collection_ledger_entries (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
collection_id uuid NOT NULL REFERENCES public.collections(id) ON DELETE CASCADE,
|
||||
entry_date date NOT NULL DEFAULT CURRENT_DATE,
|
||||
transaction_type text NOT NULL,
|
||||
description text,
|
||||
debit numeric NOT NULL DEFAULT 0,
|
||||
credit numeric NOT NULL DEFAULT 0,
|
||||
created_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_cle_collection ON public.collection_ledger_entries(collection_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_cle_date ON public.collection_ledger_entries(entry_date);
|
||||
|
||||
ALTER TABLE public.collection_ledger_entries ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY cle_select_case ON public.collection_ledger_entries
|
||||
FOR SELECT TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.collections c
|
||||
WHERE c.id = collection_id
|
||||
AND public.can_access_case(c.case_id, auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY cle_insert_case ON public.collection_ledger_entries
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.collections c
|
||||
WHERE c.id = collection_id
|
||||
AND public.can_access_case(c.case_id, auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY cle_update_case ON public.collection_ledger_entries
|
||||
FOR UPDATE TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.collections c
|
||||
WHERE c.id = collection_id
|
||||
AND public.can_access_case(c.case_id, auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY cle_delete_case ON public.collection_ledger_entries
|
||||
FOR DELETE TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.collections c
|
||||
WHERE c.id = collection_id
|
||||
AND public.can_access_case(c.case_id, auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
CREATE TRIGGER cle_set_updated_at
|
||||
BEFORE UPDATE ON public.collection_ledger_entries
|
||||
FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
||||
Reference in New Issue
Block a user