-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup.sql
139 lines (118 loc) · 4.15 KB
/
setup.sql
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
-- Enable UUID extension
create extension if not exists "uuid-ossp";
-- Create profiles table (extends Supabase auth.users)
create table public.profiles (
id uuid references auth.users on delete cascade primary key,
username text unique,
name text not null,
avatar_url text,
country text,
twitter_url text,
spotify_url text,
soundcloud_url text,
youtube_url text,
created_at timestamp with time zone default timezone('utc'::text, now()),
updated_at timestamp with time zone default timezone('utc'::text, now())
);
-- Create artists table
create table public.artists (
id text primary key, -- Spotify artist ID
name text not null,
image_url text,
spotify_url text not null,
genres text[],
followers integer,
created_at timestamp with time zone default timezone('utc'::text, now())
);
-- Create user_artist_experiences table
create table public.user_artist_experiences (
id uuid default uuid_generate_v4() primary key,
user_id uuid references public.profiles on delete cascade,
artist_id text references public.artists on delete cascade,
event_name text,
city text,
country text,
attended_with uuid[] default array[]::uuid[],
created_at timestamp with time zone default timezone('utc'::text, now()),
unique(user_id, artist_id)
);
-- Set up Row Level Security (RLS)
alter table public.profiles enable row level security;
alter table public.artists enable row level security;
alter table public.user_artist_experiences enable row level security;
-- Profiles policies
create policy "Public profiles are viewable by everyone"
on public.profiles for select
using (true);
create policy "Users can insert their own profile"
on public.profiles for insert
with check (auth.uid() = id);
create policy "Users can update own profile"
on public.profiles for update
using (auth.uid() = id);
-- Artists policies
create policy "Artists are viewable by everyone"
on public.artists for select
using (true);
create policy "Authenticated users can insert artists"
on public.artists for insert
with check (auth.role() = 'authenticated');
-- User Artist Experiences policies
create policy "Experiences are viewable by everyone"
on public.user_artist_experiences for select
using (true);
create policy "Users can insert own experiences"
on public.user_artist_experiences for insert
with check (auth.uid() = user_id);
create policy "Users can update own experiences"
on public.user_artist_experiences for update
using (auth.uid() = user_id);
create policy "Users can delete own experiences"
on public.user_artist_experiences for delete
using (auth.uid() = user_id);
-- Create profile on user signup
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, username, name, avatar_url)
values (
new.id,
new.raw_user_meta_data->>'username',
new.raw_user_meta_data->>'name',
new.raw_user_meta_data->>'avatar_url'
);
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
-- Create function to automatically update updated_at
CREATE OR REPLACE FUNCTION public.handle_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = timezone('utc'::text, now());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Create trigger for updated_at
DROP TRIGGER IF EXISTS set_updated_at ON public.profiles;
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON public.profiles
FOR EACH ROW
EXECUTE FUNCTION public.handle_updated_at();
-- Storage setup and policies
-- Create storage bucket for profile images
insert into storage.buckets (id, name, public)
values ('images', 'images', true)
on conflict (id) do nothing;
-- Enable RLS on storage.objects
alter table storage.objects enable row level security;
-- Simple policies for image storage
create policy "Give public access to images"
on storage.objects for select
using (bucket_id = 'images');
create policy "Allow authenticated uploads"
on storage.objects for insert
to authenticated
with check (bucket_id = 'images');