gaurv007 commited on
Commit
a393ff3
Β·
verified Β·
1 Parent(s): 07b6c91

security: remove hardcoded admin email from public schema

Browse files
Files changed (1) hide show
  1. web/lib/supabase/schema.sql +1 -203
web/lib/supabase/schema.sql CHANGED
@@ -1,203 +1 @@
1
- -- ClauseGuard β€” Full Database Schema v3.0
2
- -- Tables ordered by dependency (no forward references)
3
-
4
- -- ─── 1. Teams (no dependencies) ───
5
- CREATE TABLE IF NOT EXISTS public.teams (
6
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
7
- name TEXT NOT NULL,
8
- owner_id UUID REFERENCES auth.users NOT NULL,
9
- plan TEXT DEFAULT 'team',
10
- max_seats INT DEFAULT 5,
11
- razorpay_subscription_id TEXT,
12
- created_at TIMESTAMPTZ DEFAULT NOW()
13
- );
14
-
15
- -- ─── 2. Profiles (depends on teams) ───
16
- CREATE TABLE IF NOT EXISTS public.profiles (
17
- id UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY,
18
- email TEXT,
19
- full_name TEXT,
20
- avatar_url TEXT,
21
- razorpay_subscription_id TEXT,
22
- plan TEXT DEFAULT 'free' CHECK (plan IN ('free', 'pro', 'team')),
23
- role TEXT DEFAULT 'user' CHECK (role IN ('user', 'admin')),
24
- is_banned BOOLEAN DEFAULT false,
25
- team_id UUID REFERENCES public.teams(id) ON DELETE SET NULL,
26
- analyses_this_month INT DEFAULT 0,
27
- monthly_reset_at TIMESTAMPTZ DEFAULT date_trunc('month', NOW()),
28
- created_at TIMESTAMPTZ DEFAULT NOW(),
29
- updated_at TIMESTAMPTZ DEFAULT NOW()
30
- );
31
-
32
- -- ─── 3. Team Invites (depends on teams) ───
33
- CREATE TABLE IF NOT EXISTS public.team_invites (
34
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
35
- team_id UUID REFERENCES public.teams ON DELETE CASCADE NOT NULL,
36
- email TEXT NOT NULL,
37
- role TEXT DEFAULT 'member' CHECK (role IN ('admin', 'member')),
38
- status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'accepted', 'expired')),
39
- invited_by UUID REFERENCES auth.users NOT NULL,
40
- created_at TIMESTAMPTZ DEFAULT NOW(),
41
- expires_at TIMESTAMPTZ DEFAULT NOW() + INTERVAL '7 days',
42
- UNIQUE(team_id, email)
43
- );
44
-
45
- -- ─── 4. Analyses (depends on profiles, teams) ───
46
- CREATE TABLE IF NOT EXISTS public.analyses (
47
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
48
- user_id UUID REFERENCES public.profiles ON DELETE CASCADE NOT NULL,
49
- team_id UUID REFERENCES public.teams ON DELETE SET NULL,
50
- source_url TEXT,
51
- source_type TEXT DEFAULT 'tos' CHECK (source_type IN ('tos', 'contract', 'rental', 'other')),
52
- total_clauses INT NOT NULL,
53
- flagged_count INT NOT NULL,
54
- risk_score INT NOT NULL CHECK (risk_score >= 0 AND risk_score <= 100),
55
- grade CHAR(1) NOT NULL CHECK (grade IN ('A', 'B', 'C', 'D', 'F')),
56
- clauses JSONB NOT NULL DEFAULT '[]',
57
- entities JSONB DEFAULT '[]',
58
- contradictions JSONB DEFAULT '[]',
59
- obligations JSONB DEFAULT '[]',
60
- compliance JSONB DEFAULT '{}',
61
- raw_text TEXT,
62
- model TEXT DEFAULT 'regex',
63
- latency_ms INT DEFAULT 0,
64
- created_at TIMESTAMPTZ DEFAULT NOW()
65
- );
66
-
67
- -- ─── 5. API Keys (depends on profiles, teams) ───
68
- CREATE TABLE IF NOT EXISTS public.api_keys (
69
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
70
- user_id UUID REFERENCES public.profiles ON DELETE CASCADE NOT NULL,
71
- team_id UUID REFERENCES public.teams ON DELETE CASCADE,
72
- name TEXT NOT NULL,
73
- key_hash TEXT NOT NULL UNIQUE,
74
- key_prefix TEXT NOT NULL,
75
- calls_this_month INT DEFAULT 0,
76
- calls_limit INT DEFAULT 1000,
77
- last_used_at TIMESTAMPTZ,
78
- is_active BOOLEAN DEFAULT true,
79
- created_at TIMESTAMPTZ DEFAULT NOW()
80
- );
81
-
82
- -- ─── 6. Custom Clause Rules (depends on profiles, teams) ───
83
- CREATE TABLE IF NOT EXISTS public.custom_rules (
84
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
85
- user_id UUID REFERENCES public.profiles ON DELETE CASCADE,
86
- team_id UUID REFERENCES public.teams ON DELETE CASCADE,
87
- name TEXT NOT NULL,
88
- description TEXT,
89
- pattern TEXT NOT NULL,
90
- severity TEXT DEFAULT 'MEDIUM' CHECK (severity IN ('HIGH', 'MEDIUM', 'LOW')),
91
- category TEXT NOT NULL,
92
- is_active BOOLEAN DEFAULT true,
93
- created_at TIMESTAMPTZ DEFAULT NOW(),
94
- updated_at TIMESTAMPTZ DEFAULT NOW()
95
- );
96
-
97
- -- ─── 7. Admin Logs ───
98
- CREATE TABLE IF NOT EXISTS public.admin_logs (
99
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
100
- admin_id UUID REFERENCES auth.users NOT NULL,
101
- action TEXT NOT NULL,
102
- target_type TEXT,
103
- target_id TEXT,
104
- details JSONB,
105
- created_at TIMESTAMPTZ DEFAULT NOW()
106
- );
107
-
108
- -- ─── Indexes ───
109
- CREATE INDEX IF NOT EXISTS idx_analyses_user_id ON public.analyses(user_id);
110
- CREATE INDEX IF NOT EXISTS idx_analyses_team_id ON public.analyses(team_id);
111
- CREATE INDEX IF NOT EXISTS idx_analyses_created_at ON public.analyses(created_at DESC);
112
- CREATE INDEX IF NOT EXISTS idx_api_keys_key_hash ON public.api_keys(key_hash);
113
- CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON public.api_keys(user_id);
114
- CREATE INDEX IF NOT EXISTS idx_team_invites_email ON public.team_invites(email);
115
- CREATE INDEX IF NOT EXISTS idx_custom_rules_user_id ON public.custom_rules(user_id);
116
- CREATE INDEX IF NOT EXISTS idx_custom_rules_team_id ON public.custom_rules(team_id);
117
- CREATE INDEX IF NOT EXISTS idx_admin_logs_created ON public.admin_logs(created_at DESC);
118
- CREATE INDEX IF NOT EXISTS idx_profiles_role ON public.profiles(role);
119
- CREATE INDEX IF NOT EXISTS idx_profiles_email ON public.profiles(email);
120
-
121
- -- ─── Row Level Security ───
122
- ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
123
- ALTER TABLE public.analyses ENABLE ROW LEVEL SECURITY;
124
- ALTER TABLE public.teams ENABLE ROW LEVEL SECURITY;
125
- ALTER TABLE public.team_invites ENABLE ROW LEVEL SECURITY;
126
- ALTER TABLE public.api_keys ENABLE ROW LEVEL SECURITY;
127
- ALTER TABLE public.custom_rules ENABLE ROW LEVEL SECURITY;
128
- ALTER TABLE public.admin_logs ENABLE ROW LEVEL SECURITY;
129
-
130
- -- Profiles
131
- CREATE POLICY "Users see own profile" ON public.profiles FOR SELECT USING (auth.uid() = id);
132
- CREATE POLICY "Users update own profile" ON public.profiles FOR UPDATE USING (auth.uid() = id);
133
- CREATE POLICY "Admins read all profiles" ON public.profiles FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
134
- CREATE POLICY "Admins update all profiles" ON public.profiles FOR UPDATE USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
135
-
136
- -- Analyses
137
- CREATE POLICY "Users see own analyses" ON public.analyses FOR SELECT
138
- USING (auth.uid() = user_id OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
139
- CREATE POLICY "Users insert analyses" ON public.analyses FOR INSERT WITH CHECK (auth.uid() = user_id);
140
- CREATE POLICY "Users delete own analyses" ON public.analyses FOR DELETE USING (auth.uid() = user_id);
141
- CREATE POLICY "Admins read all analyses" ON public.analyses FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
142
-
143
- -- Teams
144
- CREATE POLICY "Team members can view" ON public.teams FOR SELECT
145
- USING (id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()) OR owner_id = auth.uid());
146
- CREATE POLICY "Owner can update team" ON public.teams FOR UPDATE USING (owner_id = auth.uid());
147
- CREATE POLICY "Admins read all teams" ON public.teams FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
148
-
149
- -- Team invites
150
- CREATE POLICY "Members see team invites" ON public.team_invites FOR SELECT
151
- USING (team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
152
- CREATE POLICY "Users can invite" ON public.team_invites FOR INSERT WITH CHECK (invited_by = auth.uid());
153
-
154
- -- API Keys
155
- CREATE POLICY "Users see own API keys" ON public.api_keys FOR SELECT
156
- USING (user_id = auth.uid() OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
157
- CREATE POLICY "Users manage own API keys" ON public.api_keys FOR ALL USING (user_id = auth.uid());
158
- CREATE POLICY "Admins read all api_keys" ON public.api_keys FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
159
-
160
- -- Custom Rules
161
- CREATE POLICY "Users see own rules" ON public.custom_rules FOR SELECT
162
- USING (user_id = auth.uid() OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
163
- CREATE POLICY "Users manage own rules" ON public.custom_rules FOR ALL USING (user_id = auth.uid());
164
- CREATE POLICY "Admins read all rules" ON public.custom_rules FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
165
-
166
- -- Admin Logs
167
- CREATE POLICY "Admins manage logs" ON public.admin_logs FOR ALL
168
- USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
169
-
170
- -- ─── Auto-create profile on signup ───
171
- CREATE OR REPLACE FUNCTION public.handle_new_user()
172
- RETURNS TRIGGER AS $$
173
- BEGIN
174
- INSERT INTO public.profiles (id, email, full_name, avatar_url)
175
- VALUES (
176
- NEW.id, NEW.email,
177
- COALESCE(NEW.raw_user_meta_data ->> 'full_name', NEW.raw_user_meta_data ->> 'name', ''),
178
- COALESCE(NEW.raw_user_meta_data ->> 'avatar_url', NEW.raw_user_meta_data ->> 'picture', '')
179
- );
180
- RETURN NEW;
181
- END;
182
- $$ LANGUAGE plpgsql SECURITY DEFINER;
183
-
184
- DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;
185
- CREATE TRIGGER on_auth_user_created
186
- AFTER INSERT ON auth.users
187
- FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
188
-
189
- -- ─── Set owner as admin with full access ───
190
- -- Run this AFTER your first signup with your email:
191
- UPDATE public.profiles
192
- SET role = 'admin', plan = 'pro'
193
- WHERE email = 'ankygaur9972@gmail.com';
194
-
195
- -- ─── Monthly reset function ───
196
- CREATE OR REPLACE FUNCTION public.reset_monthly_usage()
197
- RETURNS void AS $$
198
- BEGIN
199
- UPDATE public.profiles SET analyses_this_month = 0, monthly_reset_at = date_trunc('month', NOW())
200
- WHERE monthly_reset_at < date_trunc('month', NOW());
201
- UPDATE public.api_keys SET calls_this_month = 0;
202
- END;
203
- $$ LANGUAGE plpgsql SECURITY DEFINER;
 
1
+ file:/app/web_schema.sql