Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
ff3afeef11
commit
f524dc8fd1
@@ -690,6 +690,47 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
comments: {
|
||||
Row: {
|
||||
author_id: string
|
||||
body: string
|
||||
case_id: string | null
|
||||
created_at: string
|
||||
edited_at: string | null
|
||||
entity_id: string
|
||||
entity_type: Database["public"]["Enums"]["comment_entity"]
|
||||
id: string
|
||||
}
|
||||
Insert: {
|
||||
author_id: string
|
||||
body?: string
|
||||
case_id?: string | null
|
||||
created_at?: string
|
||||
edited_at?: string | null
|
||||
entity_id: string
|
||||
entity_type: Database["public"]["Enums"]["comment_entity"]
|
||||
id?: string
|
||||
}
|
||||
Update: {
|
||||
author_id?: string
|
||||
body?: string
|
||||
case_id?: string | null
|
||||
created_at?: string
|
||||
edited_at?: string | null
|
||||
entity_id?: string
|
||||
entity_type?: Database["public"]["Enums"]["comment_entity"]
|
||||
id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "comments_case_id_fkey"
|
||||
columns: ["case_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "cases"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
contacts: {
|
||||
Row: {
|
||||
address_line1: string | null
|
||||
@@ -1517,6 +1558,73 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
notifications: {
|
||||
Row: {
|
||||
body: string | null
|
||||
case_id: string | null
|
||||
conversation_id: string | null
|
||||
created_at: string
|
||||
created_by: string | null
|
||||
id: string
|
||||
kind: Database["public"]["Enums"]["notification_kind"]
|
||||
link: string | null
|
||||
read_at: string | null
|
||||
task_id: string | null
|
||||
title: string
|
||||
user_id: string
|
||||
}
|
||||
Insert: {
|
||||
body?: string | null
|
||||
case_id?: string | null
|
||||
conversation_id?: string | null
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
id?: string
|
||||
kind: Database["public"]["Enums"]["notification_kind"]
|
||||
link?: string | null
|
||||
read_at?: string | null
|
||||
task_id?: string | null
|
||||
title: string
|
||||
user_id: string
|
||||
}
|
||||
Update: {
|
||||
body?: string | null
|
||||
case_id?: string | null
|
||||
conversation_id?: string | null
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
id?: string
|
||||
kind?: Database["public"]["Enums"]["notification_kind"]
|
||||
link?: string | null
|
||||
read_at?: string | null
|
||||
task_id?: string | null
|
||||
title?: string
|
||||
user_id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "notifications_case_id_fkey"
|
||||
columns: ["case_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "cases"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "notifications_conversation_id_fkey"
|
||||
columns: ["conversation_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "conversations"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "notifications_task_id_fkey"
|
||||
columns: ["task_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "tasks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
payment_plan_installments: {
|
||||
Row: {
|
||||
amount: number
|
||||
@@ -1701,6 +1809,184 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
task_assignees: {
|
||||
Row: {
|
||||
assigned_by: string | null
|
||||
created_at: string
|
||||
id: string
|
||||
task_id: string
|
||||
user_id: string
|
||||
}
|
||||
Insert: {
|
||||
assigned_by?: string | null
|
||||
created_at?: string
|
||||
id?: string
|
||||
task_id: string
|
||||
user_id: string
|
||||
}
|
||||
Update: {
|
||||
assigned_by?: string | null
|
||||
created_at?: string
|
||||
id?: string
|
||||
task_id?: string
|
||||
user_id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "task_assignees_task_id_fkey"
|
||||
columns: ["task_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "tasks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
task_comments: {
|
||||
Row: {
|
||||
author_id: string
|
||||
body: string
|
||||
created_at: string
|
||||
edited_at: string | null
|
||||
id: string
|
||||
task_id: string
|
||||
}
|
||||
Insert: {
|
||||
author_id: string
|
||||
body?: string
|
||||
created_at?: string
|
||||
edited_at?: string | null
|
||||
id?: string
|
||||
task_id: string
|
||||
}
|
||||
Update: {
|
||||
author_id?: string
|
||||
body?: string
|
||||
created_at?: string
|
||||
edited_at?: string | null
|
||||
id?: string
|
||||
task_id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "task_comments_task_id_fkey"
|
||||
columns: ["task_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "tasks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
task_history: {
|
||||
Row: {
|
||||
actor_id: string | null
|
||||
created_at: string
|
||||
detail: Json
|
||||
event: string
|
||||
id: string
|
||||
task_id: string
|
||||
}
|
||||
Insert: {
|
||||
actor_id?: string | null
|
||||
created_at?: string
|
||||
detail?: Json
|
||||
event: string
|
||||
id?: string
|
||||
task_id: string
|
||||
}
|
||||
Update: {
|
||||
actor_id?: string | null
|
||||
created_at?: string
|
||||
detail?: Json
|
||||
event?: string
|
||||
id?: string
|
||||
task_id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "task_history_task_id_fkey"
|
||||
columns: ["task_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "tasks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
tasks: {
|
||||
Row: {
|
||||
case_id: string | null
|
||||
completed_at: string | null
|
||||
completed_by: string | null
|
||||
created_at: string
|
||||
created_by: string | null
|
||||
description: string | null
|
||||
due_date: string | null
|
||||
id: string
|
||||
parent_task_id: string | null
|
||||
priority: Database["public"]["Enums"]["task_priority"]
|
||||
sort_order: number
|
||||
status: Database["public"]["Enums"]["task_status"]
|
||||
title: string
|
||||
updated_at: string
|
||||
workflow_template_id: string | null
|
||||
}
|
||||
Insert: {
|
||||
case_id?: string | null
|
||||
completed_at?: string | null
|
||||
completed_by?: string | null
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
description?: string | null
|
||||
due_date?: string | null
|
||||
id?: string
|
||||
parent_task_id?: string | null
|
||||
priority?: Database["public"]["Enums"]["task_priority"]
|
||||
sort_order?: number
|
||||
status?: Database["public"]["Enums"]["task_status"]
|
||||
title: string
|
||||
updated_at?: string
|
||||
workflow_template_id?: string | null
|
||||
}
|
||||
Update: {
|
||||
case_id?: string | null
|
||||
completed_at?: string | null
|
||||
completed_by?: string | null
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
description?: string | null
|
||||
due_date?: string | null
|
||||
id?: string
|
||||
parent_task_id?: string | null
|
||||
priority?: Database["public"]["Enums"]["task_priority"]
|
||||
sort_order?: number
|
||||
status?: Database["public"]["Enums"]["task_status"]
|
||||
title?: string
|
||||
updated_at?: string
|
||||
workflow_template_id?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "tasks_case_id_fkey"
|
||||
columns: ["case_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "cases"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "tasks_parent_task_id_fkey"
|
||||
columns: ["parent_task_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "tasks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "tasks_workflow_template_id_fkey"
|
||||
columns: ["workflow_template_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "workflow_templates"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
time_entries: {
|
||||
Row: {
|
||||
billable: boolean
|
||||
@@ -1779,6 +2065,80 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
workflow_template_tasks: {
|
||||
Row: {
|
||||
created_at: string
|
||||
days_from_start: number
|
||||
default_assignee_id: string | null
|
||||
description: string | null
|
||||
id: string
|
||||
priority: Database["public"]["Enums"]["task_priority"]
|
||||
sort_order: number
|
||||
template_id: string
|
||||
title: string
|
||||
updated_at: string
|
||||
}
|
||||
Insert: {
|
||||
created_at?: string
|
||||
days_from_start?: number
|
||||
default_assignee_id?: string | null
|
||||
description?: string | null
|
||||
id?: string
|
||||
priority?: Database["public"]["Enums"]["task_priority"]
|
||||
sort_order?: number
|
||||
template_id: string
|
||||
title: string
|
||||
updated_at?: string
|
||||
}
|
||||
Update: {
|
||||
created_at?: string
|
||||
days_from_start?: number
|
||||
default_assignee_id?: string | null
|
||||
description?: string | null
|
||||
id?: string
|
||||
priority?: Database["public"]["Enums"]["task_priority"]
|
||||
sort_order?: number
|
||||
template_id?: string
|
||||
title?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "workflow_template_tasks_template_id_fkey"
|
||||
columns: ["template_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "workflow_templates"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
workflow_templates: {
|
||||
Row: {
|
||||
created_at: string
|
||||
created_by: string | null
|
||||
description: string | null
|
||||
id: string
|
||||
name: string
|
||||
updated_at: string
|
||||
}
|
||||
Insert: {
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
description?: string | null
|
||||
id?: string
|
||||
name: string
|
||||
updated_at?: string
|
||||
}
|
||||
Update: {
|
||||
created_at?: string
|
||||
created_by?: string | null
|
||||
description?: string | null
|
||||
id?: string
|
||||
name?: string
|
||||
updated_at?: string
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
}
|
||||
Views: {
|
||||
[_ in never]: never
|
||||
@@ -1788,6 +2148,10 @@ export type Database = {
|
||||
Args: { _case_id: string; _user_id: string }
|
||||
Returns: boolean
|
||||
}
|
||||
can_access_task: {
|
||||
Args: { _task_id: string; _user_id: string }
|
||||
Returns: boolean
|
||||
}
|
||||
has_role: {
|
||||
Args: {
|
||||
_role: Database["public"]["Enums"]["app_role"]
|
||||
@@ -1811,7 +2175,20 @@ export type Database = {
|
||||
| "closed_lost"
|
||||
| "closed"
|
||||
client_type: "hoa" | "individual" | "business" | "condo"
|
||||
comment_entity: "case" | "document"
|
||||
invoice_status: "draft" | "sent" | "paid" | "overdue" | "void"
|
||||
notification_kind:
|
||||
| "task_assigned"
|
||||
| "task_mention"
|
||||
| "task_comment"
|
||||
| "task_due"
|
||||
| "task_completed"
|
||||
| "case_mention"
|
||||
| "document_mention"
|
||||
| "message_mention"
|
||||
| "message"
|
||||
task_priority: "low" | "normal" | "high" | "urgent"
|
||||
task_status: "incomplete" | "complete"
|
||||
}
|
||||
CompositeTypes: {
|
||||
[_ in never]: never
|
||||
@@ -1949,7 +2326,21 @@ export const Constants = {
|
||||
"closed",
|
||||
],
|
||||
client_type: ["hoa", "individual", "business", "condo"],
|
||||
comment_entity: ["case", "document"],
|
||||
invoice_status: ["draft", "sent", "paid", "overdue", "void"],
|
||||
notification_kind: [
|
||||
"task_assigned",
|
||||
"task_mention",
|
||||
"task_comment",
|
||||
"task_due",
|
||||
"task_completed",
|
||||
"case_mention",
|
||||
"document_mention",
|
||||
"message_mention",
|
||||
"message",
|
||||
],
|
||||
task_priority: ["low", "normal", "high", "urgent"],
|
||||
task_status: ["incomplete", "complete"],
|
||||
},
|
||||
},
|
||||
} as const
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
-- Enums
|
||||
CREATE TYPE public.task_priority AS ENUM ('low', 'normal', 'high', 'urgent');
|
||||
CREATE TYPE public.task_status AS ENUM ('incomplete', 'complete');
|
||||
CREATE TYPE public.comment_entity AS ENUM ('case', 'document');
|
||||
CREATE TYPE public.notification_kind AS ENUM ('task_assigned', 'task_mention', 'task_comment', 'task_due', 'task_completed', 'case_mention', 'document_mention', 'message_mention', 'message');
|
||||
|
||||
-- Workflow templates
|
||||
CREATE TABLE public.workflow_templates (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name text NOT NULL,
|
||||
description text,
|
||||
created_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE public.workflow_template_tasks (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
template_id uuid NOT NULL REFERENCES public.workflow_templates(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
description text,
|
||||
priority public.task_priority NOT NULL DEFAULT 'normal',
|
||||
days_from_start integer NOT NULL DEFAULT 7,
|
||||
default_assignee_id uuid,
|
||||
sort_order integer NOT NULL DEFAULT 0,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Tasks
|
||||
CREATE TABLE public.tasks (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title text NOT NULL,
|
||||
description text,
|
||||
status public.task_status NOT NULL DEFAULT 'incomplete',
|
||||
priority public.task_priority NOT NULL DEFAULT 'normal',
|
||||
due_date date,
|
||||
case_id uuid REFERENCES public.cases(id) ON DELETE CASCADE,
|
||||
parent_task_id uuid REFERENCES public.tasks(id) ON DELETE CASCADE,
|
||||
workflow_template_id uuid REFERENCES public.workflow_templates(id) ON DELETE SET NULL,
|
||||
created_by uuid,
|
||||
completed_by uuid,
|
||||
completed_at timestamptz,
|
||||
sort_order integer NOT NULL DEFAULT 0,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_tasks_case_id ON public.tasks(case_id);
|
||||
CREATE INDEX idx_tasks_parent ON public.tasks(parent_task_id);
|
||||
CREATE INDEX idx_tasks_due_date ON public.tasks(due_date);
|
||||
CREATE INDEX idx_tasks_status ON public.tasks(status);
|
||||
|
||||
-- Task assignees
|
||||
CREATE TABLE public.task_assignees (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
task_id uuid NOT NULL REFERENCES public.tasks(id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL,
|
||||
assigned_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (task_id, user_id)
|
||||
);
|
||||
CREATE INDEX idx_task_assignees_user ON public.task_assignees(user_id);
|
||||
|
||||
-- Task comments
|
||||
CREATE TABLE public.task_comments (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
task_id uuid NOT NULL REFERENCES public.tasks(id) ON DELETE CASCADE,
|
||||
author_id uuid NOT NULL,
|
||||
body text NOT NULL DEFAULT '',
|
||||
edited_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX idx_task_comments_task ON public.task_comments(task_id);
|
||||
|
||||
-- Task history (activity log)
|
||||
CREATE TABLE public.task_history (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
task_id uuid NOT NULL REFERENCES public.tasks(id) ON DELETE CASCADE,
|
||||
actor_id uuid,
|
||||
event text NOT NULL,
|
||||
detail jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX idx_task_history_task ON public.task_history(task_id);
|
||||
|
||||
-- Generic comments (cases / documents)
|
||||
CREATE TABLE public.comments (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
entity_type public.comment_entity NOT NULL,
|
||||
entity_id uuid NOT NULL,
|
||||
case_id uuid REFERENCES public.cases(id) ON DELETE CASCADE,
|
||||
author_id uuid NOT NULL,
|
||||
body text NOT NULL DEFAULT '',
|
||||
edited_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX idx_comments_entity ON public.comments(entity_type, entity_id);
|
||||
CREATE INDEX idx_comments_case ON public.comments(case_id);
|
||||
|
||||
-- Notifications (global inbox)
|
||||
CREATE TABLE public.notifications (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL,
|
||||
kind public.notification_kind NOT NULL,
|
||||
title text NOT NULL,
|
||||
body text,
|
||||
link text,
|
||||
task_id uuid REFERENCES public.tasks(id) ON DELETE CASCADE,
|
||||
case_id uuid REFERENCES public.cases(id) ON DELETE CASCADE,
|
||||
conversation_id uuid REFERENCES public.conversations(id) ON DELETE CASCADE,
|
||||
read_at timestamptz,
|
||||
created_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX idx_notifications_user_unread ON public.notifications(user_id, read_at);
|
||||
|
||||
-- Triggers for updated_at
|
||||
CREATE TRIGGER trg_tasks_updated_at BEFORE UPDATE ON public.tasks FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
||||
CREATE TRIGGER trg_workflow_templates_updated_at BEFORE UPDATE ON public.workflow_templates FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
||||
CREATE TRIGGER trg_workflow_template_tasks_updated_at BEFORE UPDATE ON public.workflow_template_tasks FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at();
|
||||
|
||||
-- Helper: can_access_task
|
||||
CREATE OR REPLACE FUNCTION public.can_access_task(_task_id uuid, _user_id uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE sql
|
||||
STABLE SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
SELECT
|
||||
public.is_admin(_user_id)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.tasks t
|
||||
WHERE t.id = _task_id
|
||||
AND (
|
||||
t.created_by = _user_id
|
||||
OR (t.case_id IS NOT NULL AND public.can_access_case(t.case_id, _user_id))
|
||||
OR EXISTS (SELECT 1 FROM public.task_assignees ta WHERE ta.task_id = t.id AND ta.user_id = _user_id)
|
||||
)
|
||||
)
|
||||
$$;
|
||||
|
||||
-- Enable RLS
|
||||
ALTER TABLE public.tasks ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.task_assignees ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.task_comments ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.task_history ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.comments ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.notifications ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.workflow_templates ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.workflow_template_tasks ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Tasks policies
|
||||
CREATE POLICY tasks_select ON public.tasks FOR SELECT TO authenticated
|
||||
USING (public.can_access_task(id, auth.uid()));
|
||||
CREATE POLICY tasks_insert ON public.tasks FOR INSERT TO authenticated
|
||||
WITH CHECK (
|
||||
auth.uid() IS NOT NULL
|
||||
AND (case_id IS NULL OR public.can_access_case(case_id, auth.uid()))
|
||||
);
|
||||
CREATE POLICY tasks_update ON public.tasks FOR UPDATE TO authenticated
|
||||
USING (public.can_access_task(id, auth.uid()));
|
||||
CREATE POLICY tasks_delete ON public.tasks FOR DELETE TO authenticated
|
||||
USING (public.is_admin(auth.uid()) OR created_by = auth.uid());
|
||||
|
||||
-- Task assignees policies
|
||||
CREATE POLICY task_assignees_select ON public.task_assignees FOR SELECT TO authenticated
|
||||
USING (public.can_access_task(task_id, auth.uid()));
|
||||
CREATE POLICY task_assignees_insert ON public.task_assignees FOR INSERT TO authenticated
|
||||
WITH CHECK (public.can_access_task(task_id, auth.uid()));
|
||||
CREATE POLICY task_assignees_delete ON public.task_assignees FOR DELETE TO authenticated
|
||||
USING (public.can_access_task(task_id, auth.uid()));
|
||||
|
||||
-- Task comments policies
|
||||
CREATE POLICY task_comments_select ON public.task_comments FOR SELECT TO authenticated
|
||||
USING (public.can_access_task(task_id, auth.uid()));
|
||||
CREATE POLICY task_comments_insert ON public.task_comments FOR INSERT TO authenticated
|
||||
WITH CHECK (author_id = auth.uid() AND public.can_access_task(task_id, auth.uid()));
|
||||
CREATE POLICY task_comments_update ON public.task_comments FOR UPDATE TO authenticated
|
||||
USING (author_id = auth.uid());
|
||||
CREATE POLICY task_comments_delete ON public.task_comments FOR DELETE TO authenticated
|
||||
USING (author_id = auth.uid() OR public.is_admin(auth.uid()));
|
||||
|
||||
-- Task history policies
|
||||
CREATE POLICY task_history_select ON public.task_history FOR SELECT TO authenticated
|
||||
USING (public.can_access_task(task_id, auth.uid()));
|
||||
CREATE POLICY task_history_insert ON public.task_history FOR INSERT TO authenticated
|
||||
WITH CHECK (public.can_access_task(task_id, auth.uid()));
|
||||
|
||||
-- Generic comments policies
|
||||
CREATE POLICY comments_select ON public.comments FOR SELECT TO authenticated
|
||||
USING (
|
||||
public.is_admin(auth.uid())
|
||||
OR (case_id IS NOT NULL AND public.can_access_case(case_id, auth.uid()))
|
||||
OR author_id = auth.uid()
|
||||
);
|
||||
CREATE POLICY comments_insert ON public.comments FOR INSERT TO authenticated
|
||||
WITH CHECK (
|
||||
author_id = auth.uid()
|
||||
AND (case_id IS NULL OR public.can_access_case(case_id, auth.uid()))
|
||||
);
|
||||
CREATE POLICY comments_update ON public.comments FOR UPDATE TO authenticated
|
||||
USING (author_id = auth.uid());
|
||||
CREATE POLICY comments_delete ON public.comments FOR DELETE TO authenticated
|
||||
USING (author_id = auth.uid() OR public.is_admin(auth.uid()));
|
||||
|
||||
-- Notifications policies (private to user)
|
||||
CREATE POLICY notifications_select ON public.notifications FOR SELECT TO authenticated
|
||||
USING (user_id = auth.uid());
|
||||
CREATE POLICY notifications_insert ON public.notifications FOR INSERT TO authenticated
|
||||
WITH CHECK (auth.uid() IS NOT NULL);
|
||||
CREATE POLICY notifications_update ON public.notifications FOR UPDATE TO authenticated
|
||||
USING (user_id = auth.uid());
|
||||
CREATE POLICY notifications_delete ON public.notifications FOR DELETE TO authenticated
|
||||
USING (user_id = auth.uid());
|
||||
|
||||
-- Workflow templates policies
|
||||
CREATE POLICY wft_select ON public.workflow_templates FOR SELECT TO authenticated USING (true);
|
||||
CREATE POLICY wft_insert ON public.workflow_templates FOR INSERT TO authenticated WITH CHECK (auth.uid() IS NOT NULL);
|
||||
CREATE POLICY wft_update ON public.workflow_templates FOR UPDATE TO authenticated
|
||||
USING (created_by = auth.uid() OR public.is_admin(auth.uid()));
|
||||
CREATE POLICY wft_delete ON public.workflow_templates FOR DELETE TO authenticated
|
||||
USING (created_by = auth.uid() OR public.is_admin(auth.uid()));
|
||||
|
||||
CREATE POLICY wftt_select ON public.workflow_template_tasks FOR SELECT TO authenticated USING (true);
|
||||
CREATE POLICY wftt_insert ON public.workflow_template_tasks FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (SELECT 1 FROM public.workflow_templates wt WHERE wt.id = template_id AND (wt.created_by = auth.uid() OR public.is_admin(auth.uid()))));
|
||||
CREATE POLICY wftt_update ON public.workflow_template_tasks FOR UPDATE TO authenticated
|
||||
USING (EXISTS (SELECT 1 FROM public.workflow_templates wt WHERE wt.id = template_id AND (wt.created_by = auth.uid() OR public.is_admin(auth.uid()))));
|
||||
CREATE POLICY wftt_delete ON public.workflow_template_tasks FOR DELETE TO authenticated
|
||||
USING (EXISTS (SELECT 1 FROM public.workflow_templates wt WHERE wt.id = template_id AND (wt.created_by = auth.uid() OR public.is_admin(auth.uid()))));
|
||||
|
||||
-- Realtime
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.tasks;
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.task_comments;
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.task_assignees;
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.task_history;
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.comments;
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.notifications;
|
||||
Reference in New Issue
Block a user