-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsupabase_schema.sql
More file actions
151 lines (128 loc) · 5.73 KB
/
Copy pathsupabase_schema.sql
File metadata and controls
151 lines (128 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
-- =============================================================
-- EditFlow — Supabase Schema
-- =============================================================
-- Run this in Supabase SQL Editor or via Management API.
-- Tables, indexes, RLS, triggers, and realtime are already set.
-- This file is a reference / migration record.
-- =============================================================
-- Extensions
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- 1. Clients
CREATE TABLE IF NOT EXISTS clients (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
name TEXT NOT NULL,
phone TEXT,
email TEXT,
company TEXT,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_clients_user_id ON clients(user_id);
ALTER TABLE clients ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own clients"
ON clients FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can create own clients"
ON clients FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own clients"
ON clients FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete own clients"
ON clients FOR DELETE USING (auth.uid() = user_id);
-- 2. Projects
CREATE TABLE IF NOT EXISTS projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
client_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
price NUMERIC NOT NULL DEFAULT 0,
received_amount NUMERIC NOT NULL DEFAULT 0,
deadline TIMESTAMPTZ,
status TEXT NOT NULL DEFAULT 'yet_to_start' CHECK (status = ANY (ARRAY['yet_to_start', 'in_progress', 'revision_pending', 'completed', 'paid'])),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_projects_user_id ON projects(user_id);
CREATE INDEX IF NOT EXISTS idx_projects_client_id ON projects(client_id);
CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own projects"
ON projects FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can create own projects"
ON projects FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own projects"
ON projects FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete own projects"
ON projects FOR DELETE USING (auth.uid() = user_id);
-- 3. Activities
CREATE TABLE IF NOT EXISTS activities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
type TEXT NOT NULL,
description TEXT NOT NULL,
reference_id UUID,
reference_type TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_activities_user_id ON activities(user_id);
CREATE INDEX IF NOT EXISTS idx_activities_created_at ON activities(created_at DESC);
ALTER TABLE activities ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own activities"
ON activities FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can create own activities"
ON activities FOR INSERT WITH CHECK (auth.uid() = user_id);
-- 4. Auto-update triggers for updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS update_clients_updated_at ON clients;
CREATE TRIGGER update_clients_updated_at
BEFORE UPDATE ON clients
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_projects_updated_at ON projects;
CREATE TRIGGER update_projects_updated_at
BEFORE UPDATE ON projects
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- 5. Realtime (for live subscriptions in Flutter)
ALTER PUBLICATION supabase_realtime ADD TABLE clients;
ALTER PUBLICATION supabase_realtime ADD TABLE projects;
ALTER PUBLICATION supabase_realtime ADD TABLE comments;
ALTER PUBLICATION supabase_realtime ADD TABLE reviews;
ALTER PUBLICATION supabase_realtime ADD TABLE review_videos;
ALTER PUBLICATION supabase_realtime ADD TABLE review_comments;
-- 6. Comments
CREATE TABLE IF NOT EXISTS public.comments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES public.projects(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
user_name TEXT NOT NULL DEFAULT 'User',
content TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
voice_url TEXT,
voice_duration INT
);
CREATE INDEX IF NOT EXISTS idx_comments_project_id ON public.comments(project_id);
CREATE INDEX IF NOT EXISTS idx_comments_created_at ON public.comments(created_at ASC);
ALTER TABLE public.comments ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view comments on accessible projects"
ON public.comments FOR SELECT TO authenticated USING (
project_id IN (SELECT id FROM public.projects)
);
CREATE POLICY "Users can create comments on accessible projects"
ON public.comments FOR INSERT TO authenticated WITH CHECK (
project_id IN (SELECT id FROM public.projects)
);
-- =============================================================
-- Migration: Old status → new status (run once)
-- =============================================================
-- ALTER TABLE projects DROP CONSTRAINT IF EXISTS projects_status_check;
-- ALTER TABLE projects ADD CONSTRAINT projects_status_check
-- CHECK (status = ANY (ARRAY['yet_to_start', 'in_progress', 'revision_pending', 'completed', 'paid']));
-- UPDATE projects SET status = 'in_progress' WHERE status = 'in_process';
-- UPDATE projects SET status = 'completed' WHERE status = 'yet_to_be_paid';
-- UPDATE projects SET status = 'paid' WHERE status = 'completed';