-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSETUP_DB.sql
More file actions
168 lines (141 loc) · 5.4 KB
/
SETUP_DB.sql
File metadata and controls
168 lines (141 loc) · 5.4 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
-- Create a table for public profiles
create table profiles (
id uuid references auth.users on delete cascade not null primary key,
updated_at timestamp with time zone default timezone('utc'::text, now()),
username text unique,
full_name text,
avatar_url text,
bio text, -- Renamed from biography (About Me)
profession text,
is_available boolean default true, -- Current Status
status_message text,
github_username text, -- For Contribution Graph
github_graph_title text default '', -- Added custom title for GitHub Graph
status_icon text default null, -- Status Emoji
social_links jsonb default '[]'::jsonb, -- Store links: [{ name, icon, href }]
tech_stack jsonb default '[]'::jsonb, -- Store list of tech: [{ name, icon }]
about_me text, -- Separate field for the About Me card
cta_title text,
cta_description text,
cta_text text,
cta_link text,
theme text default 'dark',
beams_enabled boolean default true,
is_donor boolean default false,
cv_url text,
constraint username_length check (char_length(username) >= 3)
);
-- Create a table for Projects
create table projects (
id uuid default gen_random_uuid() primary key,
user_id uuid references profiles(id) on delete cascade not null,
created_at timestamp with time zone default timezone('utc'::text, now()) not null,
title text not null,
description text,
url text,
image_url text, -- Project Logo URL
tech_tags jsonb default '[]'::jsonb, -- Array of tech strings e.g. ["Next.js", "React"]
sort_order integer default 0 -- For rearranging projects
);
-- Table for tracking profile views
create table profile_views (
id uuid default gen_random_uuid() primary key,
profile_id uuid references profiles(id) on delete cascade not null,
viewed_at timestamp with time zone default timezone('utc'::text, now()) not null,
viewer_country text,
viewer_country_code text
);
-- Table for tracking link clicks
create table link_clicks (
id uuid default gen_random_uuid() primary key,
profile_id uuid references profiles(id) on delete cascade not null,
link_type text not null, -- 'social', 'project', 'cta'
link_url text not null,
clicked_at timestamp with time zone default timezone('utc'::text, now()) not null,
viewer_country text,
viewer_country_code text
);
-- Set up Row Level Security (RLS) for Profiles
alter table profiles enable row level security;
create policy "Public profiles are viewable by everyone."
on profiles for select
using ( true );
create policy "Users can insert their own profile."
on profiles for insert
with check ( auth.uid() = id );
create policy "Users can update own profile."
on profiles for update
using ( auth.uid() = id );
-- Set up RLS for Projects
alter table projects enable row level security;
create policy "Public projects are viewable by everyone."
on projects for select
using ( true );
create policy "Users can insert their 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 );
-- RLS for Analytics
alter table profile_views enable row level security;
alter table link_clicks enable row level security;
create policy "Public can record views."
on profile_views for insert
with check ( true );
create policy "Users can view own profile analytics."
on profile_views for select
using ( auth.uid() = profile_id );
create policy "Public can record clicks."
on link_clicks for insert
with check ( true );
create policy "Users can view own click analytics."
on link_clicks for select
using ( auth.uid() = profile_id );
-- Ensure username is unique
create unique index if not exists profiles_username_idx on profiles (username);
-- Function to handle new user signup automatically
create or replace function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, full_name, avatar_url, username)
values (
new.id,
new.raw_user_meta_data->>'full_name',
new.raw_user_meta_data->>'avatar_url',
new.raw_user_meta_data->>'username'
);
return new;
end;
$$ language plpgsql security definer;
-- Trigger the function every time a user is created
create or replace trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
-- Create Storage bucket for Avatars and Project Images
insert into storage.buckets (id, name, public)
values ('images', 'images', true)
on conflict (id) do nothing;
-- Policy to allow public access to images
create policy "Images are publicly accessible."
on storage.objects for select
using ( bucket_id = 'images' );
-- Policy to allow authenticated users to upload images
create policy "Authenticated users can upload images."
on storage.objects for insert
with check ( bucket_id = 'images' and auth.role() = 'authenticated' );
-- Create Storage bucket for CVs
insert into storage.buckets (id, name, public)
values ('cvs', 'cvs', true)
on conflict (id) do nothing;
-- Policy to allow public access to CVs
create policy "CVs are publicly accessible."
on storage.objects for select
using ( bucket_id = 'cvs' );
-- Policy to allow authenticated users to upload CVs
create policy "Authenticated users can upload CVs."
on storage.objects for insert
with check ( bucket_id = 'cvs' and auth.role() = 'authenticated' );