-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase_schema.sql
More file actions
136 lines (113 loc) · 4.51 KB
/
Copy pathdatabase_schema.sql
File metadata and controls
136 lines (113 loc) · 4.51 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
-- Database Schema for SevenArtList
-- Sprint 2 - Phase 1: Supabase Infrastructure
-- 1. Profiles (Extends auth.users)
CREATE TABLE profiles (
id UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY,
username TEXT UNIQUE,
avatar_url TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW()) NOT NULL
);
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- 2. Squads (Groups/Couples)
CREATE TABLE squads (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW()) NOT NULL
);
ALTER TABLE squads ENABLE ROW LEVEL SECURITY;
-- 3. Squad Members (Junction table)
CREATE TABLE squad_members (
squad_id UUID REFERENCES squads ON DELETE CASCADE,
user_id UUID REFERENCES profiles ON DELETE CASCADE,
role TEXT DEFAULT 'member',
PRIMARY KEY (squad_id, user_id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW()) NOT NULL
);
ALTER TABLE squad_members ENABLE ROW LEVEL SECURITY;
-- 4. Media Items (Cache for TMDB data)
CREATE TABLE media_items (
tmdb_id TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN ('movie', 'series', 'anime')),
title TEXT NOT NULL,
poster_path TEXT,
PRIMARY KEY (tmdb_id, type),
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW()) NOT NULL
);
ALTER TABLE media_items ENABLE ROW LEVEL SECURITY;
-- 5. Watchlists (The core tracking table)
CREATE TABLE watchlists (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES profiles ON DELETE CASCADE NOT NULL,
media_tmdb_id TEXT NOT NULL,
media_type TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('plan_to_watch', 'watching', 'completed', 'dropped')),
rating INTEGER CHECK (rating >= 0 AND rating <= 10),
comment TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW()) NOT NULL,
FOREIGN KEY (media_tmdb_id, media_type) REFERENCES media_items (tmdb_id, type)
);
ALTER TABLE watchlists ENABLE ROW LEVEL SECURITY;
-- RLS POLICIES
-- Profiles: Public read, self-update
CREATE POLICY "Profiles are viewable by everyone" ON profiles
FOR SELECT USING (TRUE);
CREATE POLICY "Users can update own profile" ON profiles
FOR UPDATE USING (auth.uid() = id);
-- Squads: Visible to members
CREATE POLICY "Squads are viewable by members" ON squads
FOR SELECT USING (
EXISTS (
SELECT 1 FROM squad_members
WHERE squad_members.squad_id = squads.id
AND squad_members.user_id = auth.uid()
)
);
-- Squad Members: Visible to fellow members
CREATE POLICY "Squad members are viewable by fellow members" ON squad_members
FOR SELECT USING (
EXISTS (
SELECT 1 FROM squad_members AS my_memberships
WHERE my_memberships.squad_id = squad_members.squad_id
AND my_memberships.user_id = auth.uid()
)
);
-- Media Items: Public read
CREATE POLICY "Media items are viewable by everyone" ON media_items
FOR SELECT USING (TRUE);
-- Watchlists: Own items OR squad member items
CREATE POLICY "Users can view own or squad members' watchlists" ON watchlists
FOR SELECT USING (
auth.uid() = user_id
OR
EXISTS (
SELECT 1 FROM squad_members AS me
JOIN squad_members AS others ON me.squad_id = others.squad_id
WHERE me.user_id = auth.uid()
AND others.user_id = watchlists.user_id
)
);
CREATE POLICY "Users can insert own watchlist items" ON watchlists
FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own watchlist items" ON watchlists
FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete own watchlist items" ON watchlists
FOR DELETE USING (auth.uid() = user_id);
-- PHASE 5: User Media (Watchlist)
CREATE TABLE public.user_media (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
tmdb_id INTEGER NOT NULL,
media_type TEXT CHECK (media_type IN ('movie', 'tv')) NOT NULL,
status TEXT CHECK (status IN ('to_watch', 'in_progress', 'completed', 'dropped')) DEFAULT 'to_watch',
rating INTEGER CHECK (rating >= 0 AND rating <= 100),
progress INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now()) NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now()) NOT NULL,
UNIQUE(user_id, tmdb_id, media_type)
);
ALTER TABLE public.user_media ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can manage their own media items"
ON public.user_media
FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);