shop.tonybtw.com

shop.tonybtw.com

https://git.tonybtw.com/shop.tonybtw.com.git git://git.tonybtw.com/shop.tonybtw.com.git
2,903 bytes raw
1
-- Shared schema for both PHP and Go versions
2
3
CREATE TABLE IF NOT EXISTS products (
4
    id SERIAL PRIMARY KEY,
5
    slug VARCHAR(255) UNIQUE NOT NULL,
6
    name VARCHAR(255) NOT NULL,
7
    description TEXT,
8
    price INTEGER NOT NULL,  -- cents
9
    image_url VARCHAR(500),
10
    active BOOLEAN DEFAULT true,
11
    printful_product_id VARCHAR(100),
12
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
13
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
14
);
15
16
CREATE TABLE IF NOT EXISTS variants (
17
    id SERIAL PRIMARY KEY,
18
    product_id INTEGER REFERENCES products(id) ON DELETE CASCADE,
19
    size VARCHAR(50) NOT NULL,
20
    printful_variant_id VARCHAR(100),
21
    stock INTEGER DEFAULT 0,
22
    sort_order INTEGER DEFAULT 0
23
);
24
25
CREATE TABLE IF NOT EXISTS orders (
26
    id SERIAL PRIMARY KEY,
27
    stripe_session_id VARCHAR(255) UNIQUE,
28
    stripe_payment_intent VARCHAR(255),
29
    email VARCHAR(255),
30
    status VARCHAR(50) DEFAULT 'pending',  -- pending, paid, fulfilled, shipped
31
    total INTEGER NOT NULL,  -- cents
32
    shipping_name VARCHAR(255),
33
    shipping_address TEXT,
34
    printful_order_id VARCHAR(100),
35
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
36
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
37
);
38
39
CREATE TABLE IF NOT EXISTS order_items (
40
    id SERIAL PRIMARY KEY,
41
    order_id INTEGER REFERENCES orders(id) ON DELETE CASCADE,
42
    product_id INTEGER REFERENCES products(id),
43
    variant_id INTEGER REFERENCES variants(id),
44
    quantity INTEGER NOT NULL,
45
    price INTEGER NOT NULL  -- cents at time of purchase
46
);
47
48
CREATE TABLE IF NOT EXISTS product_images (
49
    id SERIAL PRIMARY KEY,
50
    product_id INTEGER REFERENCES products(id) ON DELETE CASCADE,
51
    image_url VARCHAR(500) NOT NULL,
52
    sort_order INTEGER DEFAULT 0
53
);
54
55
-- Sample data for testing
56
INSERT INTO products (slug, name, description, price, image_url) VALUES
57
    ('linux-tux-tee', 'Linux Tux Tee', 'Classic penguin on a comfy tee. 100% cotton.', 2500, 'https://placehold.co/600x600/1a1a1a/3b82f6?text=Linux+Tux+Tee'),
58
    ('btw-i-use-arch-hoodie', 'BTW I Use Arch Hoodie', 'Let everyone know. Heavyweight fleece.', 4500, 'https://placehold.co/600x600/1a1a1a/3b82f6?text=Arch+Hoodie'),
59
    ('foss-freedom-cap', 'FOSS Freedom Cap', 'Embroidered dad hat for free software enjoyers.', 2000, 'https://placehold.co/600x600/1a1a1a/3b82f6?text=FOSS+Cap')
60
ON CONFLICT (slug) DO UPDATE SET image_url = EXCLUDED.image_url;
61
62
INSERT INTO variants (product_id, size, sort_order) VALUES
63
    (1, 'S', 1), (1, 'M', 2), (1, 'L', 3), (1, 'XL', 4),
64
    (2, 'S', 1), (2, 'M', 2), (2, 'L', 3), (2, 'XL', 4), (2, 'XXL', 5),
65
    (3, 'One Size', 1)
66
ON CONFLICT DO NOTHING;
67
68
CREATE INDEX IF NOT EXISTS idx_products_slug ON products(slug);
69
CREATE INDEX IF NOT EXISTS idx_products_active ON products(active);
70
CREATE INDEX IF NOT EXISTS idx_variants_product ON variants(product_id);
71
CREATE INDEX IF NOT EXISTS idx_orders_stripe ON orders(stripe_session_id);