Skip to content

Commit 34bc711

Browse files
authored
Merge pull request #36 from brylie/supabase-migrations
Add TypeScript definitions and SQL migrations for Supabase tables
2 parents 16b4ba6 + 833fec3 commit 34bc711

File tree

4 files changed

+271
-0
lines changed

4 files changed

+271
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/**
2+
* TypeScript definitions for Supabase database tables
3+
*/
4+
5+
export type Json =
6+
| string
7+
| number
8+
| boolean
9+
| null
10+
| { [key: string]: Json | undefined }
11+
| Json[];
12+
13+
export interface Database {
14+
public: {
15+
Tables: {
16+
completed_exercises: {
17+
Row: {
18+
id: number;
19+
exercise_id: string;
20+
completed_at: string;
21+
user_id: string;
22+
metrics: {
23+
sets?: number;
24+
reps?: number;
25+
weight?: number;
26+
time?: number;
27+
distance?: number;
28+
resistance?: number;
29+
speed?: number;
30+
incline?: number;
31+
resistance_type?: string;
32+
calories?: number;
33+
heart_rate?: number;
34+
rpe?: number;
35+
};
36+
};
37+
Insert: {
38+
id?: number;
39+
exercise_id: string;
40+
completed_at: string;
41+
user_id: string;
42+
metrics: {
43+
sets?: number;
44+
reps?: number;
45+
weight?: number;
46+
time?: number;
47+
distance?: number;
48+
resistance?: number;
49+
speed?: number;
50+
incline?: number;
51+
resistance_type?: string;
52+
calories?: number;
53+
heart_rate?: number;
54+
rpe?: number;
55+
};
56+
};
57+
Update: {
58+
id?: number;
59+
exercise_id?: string;
60+
completed_at?: string;
61+
user_id?: string;
62+
metrics?: {
63+
sets?: number;
64+
reps?: number;
65+
weight?: number;
66+
time?: number;
67+
distance?: number;
68+
resistance?: number;
69+
speed?: number;
70+
incline?: number;
71+
resistance_type?: string;
72+
calories?: number;
73+
heart_rate?: number;
74+
rpe?: number;
75+
};
76+
};
77+
};
78+
stripe_customers: {
79+
Row: {
80+
user_id: string;
81+
stripe_customer_id: string;
82+
created_at: string;
83+
updated_at: string;
84+
};
85+
Insert: {
86+
user_id: string;
87+
stripe_customer_id: string;
88+
created_at?: string;
89+
updated_at?: string;
90+
};
91+
Update: {
92+
user_id?: string;
93+
stripe_customer_id?: string;
94+
created_at?: string;
95+
updated_at?: string;
96+
};
97+
};
98+
subscriptions: {
99+
Row: {
100+
id: string;
101+
user_id: string;
102+
stripe_subscription_id: string | null;
103+
stripe_price_id: string | null;
104+
stripe_product_id: string | null;
105+
status: string;
106+
cancel_at_period_end: boolean;
107+
current_period_start: string | null;
108+
current_period_end: string | null;
109+
created_at: string;
110+
updated_at: string;
111+
ended_at: string | null;
112+
};
113+
Insert: {
114+
id?: string;
115+
user_id: string;
116+
stripe_subscription_id?: string | null;
117+
stripe_price_id?: string | null;
118+
stripe_product_id?: string | null;
119+
status: string;
120+
cancel_at_period_end?: boolean;
121+
current_period_start?: string | null;
122+
current_period_end?: string | null;
123+
created_at?: string;
124+
updated_at?: string;
125+
ended_at?: string | null;
126+
};
127+
Update: {
128+
id?: string;
129+
user_id?: string;
130+
stripe_subscription_id?: string | null;
131+
stripe_price_id?: string | null;
132+
stripe_product_id?: string | null;
133+
status?: string;
134+
cancel_at_period_end?: boolean;
135+
current_period_start?: string | null;
136+
current_period_end?: string | null;
137+
created_at?: string;
138+
updated_at?: string;
139+
ended_at?: string | null;
140+
};
141+
};
142+
pricing_plans: {
143+
Row: {
144+
id: string;
145+
name: string;
146+
description: string | null;
147+
features: Json | null;
148+
stripe_price_id: string | null;
149+
stripe_product_id: string | null;
150+
amount: number;
151+
currency: string;
152+
interval: string;
153+
active: boolean;
154+
created_at: string;
155+
updated_at: string;
156+
};
157+
Insert: {
158+
id?: string;
159+
name: string;
160+
description?: string | null;
161+
features?: Json | null;
162+
stripe_price_id?: string | null;
163+
stripe_product_id?: string | null;
164+
amount: number;
165+
currency?: string;
166+
interval: string;
167+
active?: boolean;
168+
created_at?: string;
169+
updated_at?: string;
170+
};
171+
Update: {
172+
id?: string;
173+
name?: string;
174+
description?: string | null;
175+
features?: Json | null;
176+
stripe_price_id?: string | null;
177+
stripe_product_id?: string | null;
178+
amount?: number;
179+
currency?: string;
180+
interval?: string;
181+
active?: boolean;
182+
created_at?: string;
183+
updated_at?: string;
184+
};
185+
};
186+
};
187+
Views: {
188+
[_ in never]: never;
189+
};
190+
Functions: {
191+
[_ in never]: never;
192+
};
193+
Enums: {
194+
[_ in never]: never;
195+
};
196+
CompositeTypes: {
197+
[_ in never]: never;
198+
};
199+
};
200+
}

app/supabase/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.branches
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- Create the completed_exercises table
2+
CREATE TABLE completed_exercises (
3+
id SERIAL PRIMARY KEY,
4+
exercise_id TEXT NOT NULL,
5+
completed_at TIMESTAMPTZ NOT NULL,
6+
user_id UUID NOT NULL REFERENCES auth.users(id),
7+
metrics JSONB NOT NULL DEFAULT '{}'
8+
);
9+
-- Set up row-level security
10+
ALTER TABLE completed_exercises ENABLE ROW LEVEL SECURITY;
11+
-- Create policy for users to only see and modify their own data
12+
CREATE POLICY "Users can only access their own data" ON completed_exercises USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
13+
-- Create indexes for better query performance
14+
CREATE INDEX completed_exercises_user_id_idx ON completed_exercises (user_id);
15+
CREATE INDEX completed_exercises_exercise_id_idx ON completed_exercises (exercise_id);
16+
CREATE INDEX completed_exercises_completed_at_idx ON completed_exercises (completed_at);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
-- Create stripe customers table to link Supabase users to Stripe customers
2+
CREATE TABLE IF NOT EXISTS stripe_customers (
3+
user_id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
4+
stripe_customer_id TEXT NOT NULL UNIQUE,
5+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
6+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
7+
);
8+
-- Create subscriptions table to track user subscription status
9+
CREATE TABLE IF NOT EXISTS subscriptions (
10+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
11+
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
12+
stripe_subscription_id TEXT UNIQUE,
13+
stripe_price_id TEXT,
14+
stripe_product_id TEXT,
15+
status TEXT NOT NULL,
16+
cancel_at_period_end BOOLEAN DEFAULT FALSE,
17+
current_period_start TIMESTAMP WITH TIME ZONE,
18+
current_period_end TIMESTAMP WITH TIME ZONE,
19+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
20+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
21+
ended_at TIMESTAMP WITH TIME ZONE
22+
);
23+
-- Create pricing plans table for subscription options
24+
CREATE TABLE IF NOT EXISTS pricing_plans (
25+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
26+
name TEXT NOT NULL,
27+
description TEXT,
28+
features JSONB,
29+
stripe_price_id TEXT UNIQUE,
30+
stripe_product_id TEXT,
31+
amount INTEGER NOT NULL,
32+
currency TEXT NOT NULL DEFAULT 'usd',
33+
interval TEXT NOT NULL,
34+
-- month, year, etc.
35+
active BOOLEAN DEFAULT TRUE,
36+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
37+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
38+
);
39+
-- Set up RLS (Row Level Security) policies
40+
ALTER TABLE stripe_customers ENABLE ROW LEVEL SECURITY;
41+
ALTER TABLE subscriptions ENABLE ROW LEVEL SECURITY;
42+
ALTER TABLE pricing_plans ENABLE ROW LEVEL SECURITY;
43+
-- Allow users to read their own customer and subscription data
44+
CREATE POLICY "Users can read their own Stripe customer data" ON stripe_customers FOR
45+
SELECT USING (auth.uid() = user_id);
46+
CREATE POLICY "Users can read their own subscription data" ON subscriptions FOR
47+
SELECT USING (auth.uid() = user_id);
48+
-- Allow everyone to read active pricing plans
49+
CREATE POLICY "Anyone can read active pricing plans" ON pricing_plans FOR
50+
SELECT USING (active = true);
51+
-- Allow service role to manage all tables (for webhooks and admin operations)
52+
CREATE POLICY "Service role can manage all Stripe customers" ON stripe_customers USING (auth.jwt()->>'role' = 'service_role');
53+
CREATE POLICY "Service role can manage all subscriptions" ON subscriptions USING (auth.jwt()->>'role' = 'service_role');
54+
CREATE POLICY "Service role can manage all pricing plans" ON pricing_plans USING (auth.jwt()->>'role' = 'service_role');

0 commit comments

Comments
 (0)