Files
MyClub/database/migrations/20251102000003_create_sweepstakes_system.up.sql
T
Tomas Dvorak 087f30e82c dev day #80
2025-11-02 21:31:00 +01:00

86 lines
3.4 KiB
SQL

-- Sweepstakes/Lottery system
-- Tables: sweepstakes, sweepstake_prizes, sweepstake_entries, sweepstake_winners
-- Main sweepstakes table
CREATE TABLE IF NOT EXISTS sweepstakes (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
title VARCHAR(255) NOT NULL,
description TEXT,
image_url VARCHAR(500),
rules_url VARCHAR(500),
start_at TIMESTAMPTZ NOT NULL,
end_at TIMESTAMPTZ NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'draft', -- draft|scheduled|active|locked|finalized|archived
picker_style VARCHAR(16) NOT NULL DEFAULT 'wheel', -- wheel|cycler
total_prizes INTEGER NOT NULL DEFAULT 1,
prize_summary TEXT,
winners_selected_at TIMESTAMPTZ,
visibility_until TIMESTAMPTZ, -- set to end_at + 3 days at finalize
draw_seed VARCHAR(64),
max_entries_per_user INTEGER NOT NULL DEFAULT 1
);
CREATE INDEX IF NOT EXISTS idx_sweepstakes_status ON sweepstakes(status);
CREATE INDEX IF NOT EXISTS idx_sweepstakes_start ON sweepstakes(start_at);
CREATE INDEX IF NOT EXISTS idx_sweepstakes_end ON sweepstakes(end_at);
-- Prizes (per sweepstake)
CREATE TABLE IF NOT EXISTS sweepstake_prizes (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
sweepstake_id BIGINT NOT NULL REFERENCES sweepstakes(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
description TEXT,
image_url VARCHAR(500),
value VARCHAR(255),
quantity INTEGER NOT NULL DEFAULT 1,
display_order INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_prizes_sweepstake ON sweepstake_prizes(sweepstake_id);
-- Entries (unique per user per sweepstake)
CREATE TABLE IF NOT EXISTS sweepstake_entries (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
sweepstake_id BIGINT NOT NULL REFERENCES sweepstakes(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status VARCHAR(16) NOT NULL DEFAULT 'valid', -- valid|invalid|withdrawn
ip_hash VARCHAR(64),
visual_played_at TIMESTAMPTZ,
view_count INTEGER NOT NULL DEFAULT 0,
UNIQUE (sweepstake_id, user_id)
);
CREATE INDEX IF NOT EXISTS idx_entries_sweepstake ON sweepstake_entries(sweepstake_id);
CREATE INDEX IF NOT EXISTS idx_entries_user ON sweepstake_entries(user_id);
-- Winners (one per prize unit, unique winner per sweepstake)
CREATE TABLE IF NOT EXISTS sweepstake_winners (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
sweepstake_id BIGINT NOT NULL REFERENCES sweepstakes(id) ON DELETE CASCADE,
entry_id BIGINT NOT NULL REFERENCES sweepstake_entries(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
prize_id BIGINT REFERENCES sweepstake_prizes(id) ON DELETE SET NULL,
prize_name VARCHAR(255), -- denormalized for safety
announced_at TIMESTAMPTZ,
notified_user_at TIMESTAMPTZ,
notified_admin_at TIMESTAMPTZ,
claim_status VARCHAR(16) NOT NULL DEFAULT 'pending', -- pending|claimed|delivered
claim_note TEXT,
UNIQUE (sweepstake_id, user_id)
);
CREATE INDEX IF NOT EXISTS idx_winners_sweepstake ON sweepstake_winners(sweepstake_id);
CREATE INDEX IF NOT EXISTS idx_winners_user ON sweepstake_winners(user_id);