-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.sql
More file actions
239 lines (221 loc) · 9.67 KB
/
Copy pathdatabase.sql
File metadata and controls
239 lines (221 loc) · 9.67 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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
-- Enable necessary extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Profiles
CREATE TABLE IF NOT EXISTS profiles (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL UNIQUE REFERENCES auth.users(id) ON DELETE CASCADE,
email TEXT NOT NULL,
full_name TEXT,
avatar_url TEXT,
is_admin BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_profiles_user_id ON profiles(user_id);
CREATE INDEX idx_profiles_is_admin ON profiles(is_admin);
-- Style Presets
CREATE TABLE IF NOT EXISTS style_presets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
description TEXT,
best_for TEXT,
sample_before_url TEXT,
sample_after_url TEXT,
prompt_template TEXT NOT NULL,
negative_prompt TEXT,
is_active BOOLEAN DEFAULT TRUE,
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_style_presets_slug ON style_presets(slug);
CREATE INDEX idx_style_presets_active ON style_presets(is_active);
-- User Uploads
CREATE TABLE IF NOT EXISTS user_uploads (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
original_file_name TEXT NOT NULL,
original_url TEXT NOT NULL,
file_size INTEGER,
image_width INTEGER,
image_height INTEGER,
has_face BOOLEAN DEFAULT FALSE,
quality_score FLOAT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_user_uploads_user_id ON user_uploads(user_id);
CREATE INDEX idx_user_uploads_created_at ON user_uploads(created_at DESC);
-- Generated Designs
CREATE TABLE IF NOT EXISTS generated_designs (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
upload_id UUID NOT NULL REFERENCES user_uploads(id) ON DELETE CASCADE,
style_preset_id UUID NOT NULL REFERENCES style_presets(id),
original_image_url TEXT NOT NULL,
generated_image_url TEXT,
thumbnail_url TEXT,
status TEXT DEFAULT 'pending', -- pending, generating, completed, failed
error_message TEXT,
ai_provider TEXT DEFAULT 'mock',
ai_request_id TEXT,
prompt_used TEXT,
is_approved BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_generated_designs_user_id ON generated_designs(user_id);
CREATE INDEX idx_generated_designs_status ON generated_designs(status);
CREATE INDEX idx_generated_designs_created_at ON generated_designs(created_at DESC);
-- Products
CREATE TABLE IF NOT EXISTS products (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
description TEXT,
category TEXT NOT NULL, -- canvas, poster, mug, tshirt, hoodie, tote, phone-case, sticker, digital, etc.
base_price DECIMAL(10, 2) NOT NULL,
retail_price DECIMAL(10, 2) NOT NULL,
mockup_template_url TEXT,
print_area_config JSONB, -- {x, y, width, height, scale_min, scale_max, ...}
printify_blueprint_id TEXT, -- TODO: Set in Printify integration
printify_provider_id TEXT, -- TODO: Set in Printify integration
is_active BOOLEAN DEFAULT TRUE,
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_products_slug ON products(slug);
CREATE INDEX idx_products_category ON products(category);
CREATE INDEX idx_products_active ON products(is_active);
-- Product Variants
CREATE TABLE IF NOT EXISTS product_variants (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- e.g., "11x14 Canvas", "Large Mug"
color TEXT,
size TEXT,
price_modifier DECIMAL(10, 2) DEFAULT 0,
printify_variant_id TEXT, -- TODO: Set in Printify integration
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_product_variants_product_id ON product_variants(product_id);
-- Carts
CREATE TABLE IF NOT EXISTS carts (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
status TEXT DEFAULT 'active', -- active, abandoned, converted
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_carts_user_id ON carts(user_id);
CREATE INDEX idx_carts_status ON carts(status);
-- Cart Items
CREATE TABLE IF NOT EXISTS cart_items (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
cart_id UUID NOT NULL REFERENCES carts(id) ON DELETE CASCADE,
design_id UUID NOT NULL REFERENCES generated_designs(id) ON DELETE CASCADE,
product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE,
product_variant_id UUID NOT NULL REFERENCES product_variants(id) ON DELETE CASCADE,
quantity INTEGER NOT NULL DEFAULT 1,
unit_price DECIMAL(10, 2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_cart_items_cart_id ON cart_items(cart_id);
-- Orders
CREATE TABLE IF NOT EXISTS orders (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
cart_id UUID REFERENCES carts(id),
status TEXT DEFAULT 'pending', -- pending, paid, processing, shipped, delivered, cancelled, failed
stripe_payment_intent_id TEXT,
stripe_checkout_session_id TEXT,
printify_order_id TEXT,
subtotal DECIMAL(10, 2) NOT NULL,
shipping DECIMAL(10, 2) DEFAULT 0,
tax DECIMAL(10, 2) DEFAULT 0,
total DECIMAL(10, 2) NOT NULL,
customer_email TEXT,
shipping_address JSONB,
notes TEXT,
error_message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_stripe_payment_intent_id ON orders(stripe_payment_intent_id);
CREATE INDEX idx_orders_printify_order_id ON orders(printify_order_id);
CREATE INDEX idx_orders_created_at ON orders(created_at DESC);
-- Order Items
CREATE TABLE IF NOT EXISTS order_items (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
order_id UUID NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
design_id UUID NOT NULL REFERENCES generated_designs(id),
product_id UUID NOT NULL REFERENCES products(id),
product_variant_id UUID NOT NULL REFERENCES product_variants(id),
quantity INTEGER NOT NULL,
unit_price DECIMAL(10, 2) NOT NULL,
printify_line_item_id TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
-- Webhook Events (audit trail)
CREATE TABLE IF NOT EXISTS webhook_events (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
event_type TEXT NOT NULL, -- stripe.payment_intent.succeeded, printify.order.created, etc.
event_source TEXT NOT NULL, -- stripe, printify
event_id TEXT NOT NULL,
order_id UUID REFERENCES orders(id),
payload JSONB NOT NULL,
processed BOOLEAN DEFAULT FALSE,
error_message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_webhook_events_event_type ON webhook_events(event_type);
CREATE INDEX idx_webhook_events_order_id ON webhook_events(order_id);
CREATE INDEX idx_webhook_events_processed ON webhook_events(processed);
-- Row Level Security (RLS) Policies
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_uploads ENABLE ROW LEVEL SECURITY;
ALTER TABLE generated_designs ENABLE ROW LEVEL SECURITY;
ALTER TABLE carts ENABLE ROW LEVEL SECURITY;
ALTER TABLE cart_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
ALTER TABLE order_items ENABLE ROW LEVEL SECURITY;
-- RLS Policies for profiles (users can only see their own)
CREATE POLICY "Users can view own profile" ON profiles
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can update own profile" ON profiles
FOR UPDATE USING (auth.uid() = user_id);
-- RLS Policies for user_uploads (users can only see their own)
CREATE POLICY "Users can view own uploads" ON user_uploads
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can create uploads" ON user_uploads
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- RLS Policies for generated_designs (users can only see their own)
CREATE POLICY "Users can view own designs" ON generated_designs
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can create designs" ON generated_designs
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- RLS Policies for carts (users can only see their own)
CREATE POLICY "Users can view own cart" ON carts
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can create cart" ON carts
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- RLS Policies for orders (users can only see their own)
CREATE POLICY "Users can view own orders" ON orders
FOR SELECT USING (auth.uid() = user_id);
-- Comments on tables
COMMENT ON TABLE profiles IS 'User profile information extended from auth.users';
COMMENT ON TABLE user_uploads IS 'Original images uploaded by users before AI processing';
COMMENT ON TABLE generated_designs IS 'AI-generated/edited designs from user uploads';
COMMENT ON TABLE products IS 'Print-on-demand products available for printing designs';
COMMENT ON TABLE product_variants IS 'Variants of products (size, color, etc)';
COMMENT ON TABLE carts IS 'Shopping carts for users';
COMMENT ON TABLE orders IS 'Orders that have been placed by users';
COMMENT ON TABLE webhook_events IS 'Incoming webhooks from Stripe and Printify for audit/debugging';