Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 06:52:54 +00:00
co-authored by renee-png
parent 30ff4cb46b
commit 4eb7da6427
2 changed files with 145 additions and 0 deletions
+58
View File
@@ -183,10 +183,53 @@ export type Database = {
},
]
}
case_team_members: {
Row: {
billing_rate: number | null
case_id: string
created_at: string
created_by: string | null
id: string
user_id: string
}
Insert: {
billing_rate?: number | null
case_id: string
created_at?: string
created_by?: string | null
id?: string
user_id: string
}
Update: {
billing_rate?: number | null
case_id?: string
created_at?: string
created_by?: string | null
id?: string
user_id?: string
}
Relationships: [
{
foreignKeyName: "case_team_members_case_id_fkey"
columns: ["case_id"]
isOneToOne: false
referencedRelation: "cases"
referencedColumns: ["id"]
},
{
foreignKeyName: "case_team_members_user_id_fkey"
columns: ["user_id"]
isOneToOne: false
referencedRelation: "profiles"
referencedColumns: ["id"]
},
]
}
cases: {
Row: {
archived_at: string | null
assigned_attorney_id: string | null
billing_method: string | null
case_caption: string | null
case_number: string
case_summary: string | null
@@ -201,6 +244,7 @@ export type Database = {
description: string | null
external_id: string | null
filing_date: string | null
flat_fee_amount: number | null
id: string
judge: string | null
jurisdiction: string | null
@@ -214,6 +258,7 @@ export type Database = {
opposing_counsel_firm: string | null
opposing_counsel_phone: string | null
opposing_party: string | null
originating_attorney_id: string | null
practice_area: string | null
settlement_amount: number | null
status: Database["public"]["Enums"]["case_status"]
@@ -224,6 +269,7 @@ export type Database = {
Insert: {
archived_at?: string | null
assigned_attorney_id?: string | null
billing_method?: string | null
case_caption?: string | null
case_number: string
case_summary?: string | null
@@ -238,6 +284,7 @@ export type Database = {
description?: string | null
external_id?: string | null
filing_date?: string | null
flat_fee_amount?: number | null
id?: string
judge?: string | null
jurisdiction?: string | null
@@ -251,6 +298,7 @@ export type Database = {
opposing_counsel_firm?: string | null
opposing_counsel_phone?: string | null
opposing_party?: string | null
originating_attorney_id?: string | null
practice_area?: string | null
settlement_amount?: number | null
status?: Database["public"]["Enums"]["case_status"]
@@ -261,6 +309,7 @@ export type Database = {
Update: {
archived_at?: string | null
assigned_attorney_id?: string | null
billing_method?: string | null
case_caption?: string | null
case_number?: string
case_summary?: string | null
@@ -275,6 +324,7 @@ export type Database = {
description?: string | null
external_id?: string | null
filing_date?: string | null
flat_fee_amount?: number | null
id?: string
judge?: string | null
jurisdiction?: string | null
@@ -288,6 +338,7 @@ export type Database = {
opposing_counsel_firm?: string | null
opposing_counsel_phone?: string | null
opposing_party?: string | null
originating_attorney_id?: string | null
practice_area?: string | null
settlement_amount?: number | null
status?: Database["public"]["Enums"]["case_status"]
@@ -310,6 +361,13 @@ export type Database = {
referencedRelation: "clients"
referencedColumns: ["id"]
},
{
foreignKeyName: "cases_originating_attorney_id_fkey"
columns: ["originating_attorney_id"]
isOneToOne: false
referencedRelation: "profiles"
referencedColumns: ["id"]
},
]
}
client_contacts: {
@@ -0,0 +1,87 @@
-- 1. Add billing fields and originating attorney to cases
ALTER TABLE public.cases
ADD COLUMN IF NOT EXISTS billing_method text,
ADD COLUMN IF NOT EXISTS flat_fee_amount numeric,
ADD COLUMN IF NOT EXISTS originating_attorney_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL;
-- 2. Case team members table
CREATE TABLE IF NOT EXISTS public.case_team_members (
id uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
case_id uuid NOT NULL REFERENCES public.cases(id) ON DELETE CASCADE,
user_id uuid NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
billing_rate numeric,
created_at timestamptz NOT NULL DEFAULT now(),
created_by uuid,
UNIQUE (case_id, user_id)
);
CREATE INDEX IF NOT EXISTS idx_case_team_members_case ON public.case_team_members(case_id);
CREATE INDEX IF NOT EXISTS idx_case_team_members_user ON public.case_team_members(user_id);
ALTER TABLE public.case_team_members ENABLE ROW LEVEL SECURITY;
-- 3. Update can_access_case to also include team members
CREATE OR REPLACE FUNCTION public.can_access_case(_case_id uuid, _user_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE SECURITY DEFINER
SET search_path TO 'public'
AS $function$
SELECT
public.has_role(_user_id, 'admin')
OR EXISTS (
SELECT 1 FROM public.cases c
WHERE c.id = _case_id
AND (
c.assigned_attorney_id = _user_id
OR c.created_by = _user_id
OR c.originating_attorney_id = _user_id
)
)
OR EXISTS (
SELECT 1 FROM public.case_team_members tm
WHERE tm.case_id = _case_id AND tm.user_id = _user_id
)
$function$;
-- 4. RLS policies for case_team_members
DROP POLICY IF EXISTS ctm_select ON public.case_team_members;
CREATE POLICY ctm_select ON public.case_team_members
FOR SELECT TO authenticated
USING (public.can_access_case(case_id, auth.uid()));
DROP POLICY IF EXISTS ctm_insert ON public.case_team_members;
CREATE POLICY ctm_insert ON public.case_team_members
FOR INSERT TO authenticated
WITH CHECK (
public.is_admin(auth.uid())
OR EXISTS (
SELECT 1 FROM public.cases c
WHERE c.id = case_id
AND (c.assigned_attorney_id = auth.uid() OR c.created_by = auth.uid() OR c.originating_attorney_id = auth.uid())
)
);
DROP POLICY IF EXISTS ctm_delete ON public.case_team_members;
CREATE POLICY ctm_delete ON public.case_team_members
FOR DELETE TO authenticated
USING (
public.is_admin(auth.uid())
OR EXISTS (
SELECT 1 FROM public.cases c
WHERE c.id = case_id
AND (c.assigned_attorney_id = auth.uid() OR c.created_by = auth.uid() OR c.originating_attorney_id = auth.uid())
)
);
DROP POLICY IF EXISTS ctm_update ON public.case_team_members;
CREATE POLICY ctm_update ON public.case_team_members
FOR UPDATE TO authenticated
USING (
public.is_admin(auth.uid())
OR EXISTS (
SELECT 1 FROM public.cases c
WHERE c.id = case_id
AND (c.assigned_attorney_id = auth.uid() OR c.created_by = auth.uid() OR c.originating_attorney_id = auth.uid())
)
);