-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsupabase_schema.sql
More file actions
187 lines (165 loc) · 6.85 KB
/
supabase_schema.sql
File metadata and controls
187 lines (165 loc) · 6.85 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
-- =============================================================================
-- WARNING: HISTORICAL REFERENCE ONLY — DO NOT USE AS A MIGRATION SOURCE
--
-- This file is the original baseline schema snapshot (pre-migration era).
-- It does NOT reflect the current database state. It is missing columns and
-- tables added by migrations 002–022 (status, override_pin, high_school,
-- organizations, audit_log, rate limiting, HLC fields, and more).
--
-- Authoritative sequence: migrations/001_initial_schema.sql through 022+
-- Run those files in numeric order against a fresh database.
-- =============================================================================
-- Core Elite Combine 2026 Database Schema (original seed — see warning above)
-- 1. Events
CREATE TABLE events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
slug TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
date DATE NOT NULL,
location TEXT NOT NULL,
required_drills JSONB NOT NULL DEFAULT '[]'::jsonb,
created_at TIMESTAMPTZ DEFAULT now()
);
-- 2. Athletes
CREATE TABLE athletes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_id UUID NOT NULL REFERENCES events(id),
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
date_of_birth DATE,
age INT,
grade TEXT,
grad_year INT,
position TEXT,
height_in INT,
weight_lb INT,
parent_name TEXT NOT NULL,
parent_email TEXT NOT NULL,
parent_phone TEXT NOT NULL,
band_id TEXT UNIQUE, -- Linked later
created_at TIMESTAMPTZ DEFAULT now()
);
-- 3. Bands
CREATE TABLE bands (
band_id TEXT PRIMARY KEY, -- Non-guessable ID from QR
event_id UUID NOT NULL REFERENCES events(id),
display_number INT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('available', 'assigned', 'void')) DEFAULT 'available',
athlete_id UUID REFERENCES athletes(id),
assigned_at TIMESTAMPTZ,
assigned_by UUID REFERENCES auth.users(id),
UNIQUE(event_id, display_number)
);
-- Add foreign key back to athletes for band_id
ALTER TABLE athletes ADD CONSTRAINT fk_athlete_band FOREIGN KEY (band_id) REFERENCES bands(band_id);
-- 4. Waivers
CREATE TABLE waivers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
athlete_id UUID NOT NULL REFERENCES athletes(id),
event_id UUID NOT NULL REFERENCES events(id),
guardian_name TEXT NOT NULL,
guardian_relationship TEXT,
emergency_contact_name TEXT NOT NULL,
emergency_contact_phone TEXT NOT NULL,
signature_data_url TEXT NOT NULL,
agreed BOOLEAN NOT NULL DEFAULT true,
agreed_at TIMESTAMPTZ DEFAULT now(),
ip_address TEXT,
user_agent TEXT
);
-- 5. Stations
CREATE TABLE stations (
id TEXT PRIMARY KEY, -- e.g., 'SPEED-1'
event_id UUID NOT NULL REFERENCES events(id),
name TEXT NOT NULL,
drill_type TEXT NOT NULL,
requires_auth BOOLEAN DEFAULT true
);
-- 6. Results
CREATE TABLE results (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
client_result_id UUID UNIQUE NOT NULL, -- For idempotency
event_id UUID NOT NULL REFERENCES events(id),
athlete_id UUID NOT NULL REFERENCES athletes(id),
band_id TEXT NOT NULL REFERENCES bands(band_id),
station_id TEXT NOT NULL REFERENCES stations(id),
drill_type TEXT NOT NULL,
value_num NUMERIC,
value_text TEXT,
meta JSONB,
recorded_by UUID REFERENCES auth.users(id),
recorded_at TIMESTAMPTZ DEFAULT now()
);
-- 7. Token Claims (for band claim flow)
CREATE TABLE token_claims (
token_hash TEXT PRIMARY KEY,
event_id UUID NOT NULL REFERENCES events(id),
athlete_id UUID NOT NULL REFERENCES athletes(id),
expires_at TIMESTAMPTZ NOT NULL,
used_at TIMESTAMPTZ
);
-- 8. Device Status
CREATE TABLE device_status (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_id UUID NOT NULL REFERENCES events(id),
station_id TEXT NOT NULL,
device_label TEXT,
last_seen_at TIMESTAMPTZ DEFAULT now(),
is_online BOOLEAN DEFAULT true,
pending_queue_count INT DEFAULT 0,
last_sync_at TIMESTAMPTZ
);
-- 9. Report Jobs
CREATE TABLE report_jobs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_id UUID NOT NULL REFERENCES events(id),
athlete_id UUID NOT NULL REFERENCES athletes(id),
status TEXT NOT NULL CHECK (status IN ('pending', 'ready', 'failed')) DEFAULT 'pending',
completed_drills JSONB DEFAULT '[]'::jsonb,
generated_at TIMESTAMPTZ,
report_url TEXT,
summary JSONB
);
-- RLS POLICIES
-- Enable RLS
ALTER TABLE events ENABLE ROW LEVEL SECURITY;
ALTER TABLE athletes ENABLE ROW LEVEL SECURITY;
ALTER TABLE bands ENABLE ROW LEVEL SECURITY;
ALTER TABLE waivers ENABLE ROW LEVEL SECURITY;
ALTER TABLE stations ENABLE ROW LEVEL SECURITY;
ALTER TABLE results ENABLE ROW LEVEL SECURITY;
ALTER TABLE token_claims ENABLE ROW LEVEL SECURITY;
ALTER TABLE device_status ENABLE ROW LEVEL SECURITY;
ALTER TABLE report_jobs ENABLE ROW LEVEL SECURITY;
-- Events: Public Read
CREATE POLICY "Public Read Events" ON events FOR SELECT USING (true);
-- Athletes: Public Insert (Registration)
CREATE POLICY "Public Insert Athletes" ON athletes FOR INSERT WITH CHECK (true);
-- Athletes: Update via Token (Internal logic usually handles this, but for RLS we might need a specific check if we do it client-side)
-- For simplicity in this demo, we'll allow public update if they know the ID, but in production we'd use a more secure check.
CREATE POLICY "Public Update Athlete via ID" ON athletes FOR UPDATE USING (true);
-- Athletes: Staff Read
CREATE POLICY "Staff Read Athletes" ON athletes FOR SELECT TO authenticated USING (true);
-- Bands: Staff Read/Update
CREATE POLICY "Staff Full Access Bands" ON bands FOR ALL TO authenticated USING (true);
-- Bands: Public Update (Claim) - Restricted to specific fields
CREATE POLICY "Public Update Band Claim" ON bands FOR UPDATE USING (true);
-- Bands: Public Read (Minimal)
CREATE POLICY "Public Read Band" ON bands FOR SELECT USING (true);
-- Waivers: Public Insert
CREATE POLICY "Public Insert Waivers" ON waivers FOR INSERT WITH CHECK (true);
-- Waivers: Staff Read
CREATE POLICY "Staff Read Waivers" ON waivers FOR SELECT TO authenticated USING (true);
-- Stations: Authenticated Read
CREATE POLICY "Staff Read Stations" ON stations FOR SELECT TO authenticated USING (true);
-- Results: Authenticated Insert/Read
CREATE POLICY "Staff Insert Results" ON results FOR INSERT TO authenticated WITH CHECK (true);
CREATE POLICY "Staff Read Results" ON results FOR SELECT TO authenticated USING (true);
-- Results: Admin Update
CREATE POLICY "Admin Update Results" ON results FOR UPDATE TO authenticated USING (true);
-- Token Claims: Public Insert/Read/Update
CREATE POLICY "Public Token Claims" ON token_claims FOR ALL USING (true);
-- Device Status: Authenticated All
CREATE POLICY "Staff Device Status" ON device_status FOR ALL TO authenticated USING (true);
-- Report Jobs: Staff Read
CREATE POLICY "Staff Read Report Jobs" ON report_jobs FOR SELECT TO authenticated USING (true);