-- NaughtyBulldogs Streamer Rating DB -- PostgreSQL schema CREATE TABLE IF NOT EXISTS streamers ( id SERIAL PRIMARY KEY, name TEXT NOT NULL UNIQUE, platform TEXT NOT NULL DEFAULT 'twitch', kick_name TEXT DEFAULT '', status TEXT NOT NULL DEFAULT 'offline', game TEXT DEFAULT '', title TEXT DEFAULT '', added_by TEXT NOT NULL DEFAULT 'admin', -- 'admin' or 'viewer' submitter TEXT DEFAULT '', -- viewer's nickname if added_by='viewer' evaluated BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS ratings ( id SERIAL PRIMARY KEY, streamer_id INT NOT NULL REFERENCES streamers(id) ON DELETE CASCADE, statistiky SMALLINT NOT NULL DEFAULT 0 CHECK (statistiky BETWEEN 0 AND 10), grafika SMALLINT NOT NULL DEFAULT 0 CHECK (grafika BETWEEN 0 AND 10), alerty SMALLINT NOT NULL DEFAULT 0 CHECK (alerty BETWEEN 0 AND 10), vychytavky SMALLINT NOT NULL DEFAULT 0 CHECK (vychytavky BETWEEN 0 AND 10), nahled SMALLINT NOT NULL DEFAULT 0 CHECK (nahled BETWEEN 0 AND 10), nastaveni SMALLINT NOT NULL DEFAULT 0 CHECK (nastaveni BETWEEN 0 AND 10), odlisnost SMALLINT NOT NULL DEFAULT 0 CHECK (odlisnost BETWEEN 0 AND 10), reward SMALLINT NOT NULL DEFAULT 0 CHECK (reward BETWEEN 0 AND 130), notes TEXT DEFAULT '', updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (streamer_id) ); CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, provider TEXT NOT NULL, -- 'twitch' provider_id TEXT NOT NULL, -- Twitch user ID login TEXT NOT NULL, -- username display_name TEXT NOT NULL, avatar TEXT DEFAULT '', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), last_seen TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (provider, provider_id) ); CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT NOT NULL DEFAULT '' ); -- Default settings INSERT INTO settings (key, value) VALUES ('auth_enabled', 'true'), ('auth_twitch_enabled', 'true'), ('auth_kick_enabled', 'true') ON CONFLICT (key) DO NOTHING; CREATE TABLE IF NOT EXISTS comments ( id SERIAL PRIMARY KEY, streamer_id INT NOT NULL REFERENCES streamers(id) ON DELETE CASCADE, user_id INT REFERENCES users(id) ON DELETE SET NULL, author TEXT NOT NULL DEFAULT 'Anonym', body TEXT NOT NULL, is_admin BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_comments_streamer ON comments(streamer_id); CREATE TABLE IF NOT EXISTS moderators ( id SERIAL PRIMARY KEY, user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE, granted_by TEXT NOT NULL DEFAULT 'admin', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (user_id) ); CREATE TABLE IF NOT EXISTS oauth_state ( state TEXT PRIMARY KEY, provider TEXT NOT NULL, verifier TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Auto-cleanup states older than 10 minutes CREATE INDEX IF NOT EXISTS idx_oauth_state_created ON oauth_state(created_at); CREATE OR REPLACE FUNCTION update_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE TRIGGER trg_streamers_updated BEFORE UPDATE ON streamers FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE OR REPLACE TRIGGER trg_ratings_updated BEFORE UPDATE ON ratings FOR EACH ROW EXECUTE FUNCTION update_updated_at(); -- Seed data from CSV INSERT INTO streamers (name, platform, status, game, title, evaluated) VALUES ('pigihonalejvarna', 'twitch', 'offline', '', '', false), ('mrcarwen', 'twitch', 'offline', '', '', false), ('bobsixkillercz', 'twitch', 'offline', '', '', false), ('evrondisek', 'twitch', 'offline', '', '', false), ('bigmajkycz', 'twitch', 'offline', '', '', false), ('jsemsadlo', 'twitch', 'offline', '', '', false), ('valkojr', 'twitch', 'offline', '', '', false), ('gathersk', 'twitch', 'offline', '', '', false), ('knefi_', 'twitch', 'offline', '', '', false), ('housepartycz14', 'twitch', 'offline', '', '', false), ('NaughtyBulldogsCZ','twitch','offline', '', '', false), ('mistr13', 'twitch', 'offline', '', '', false), ('annniecz', 'twitch', 'offline', '', '', false), ('Haruhi4chan', 'twitch', 'offline', '', '', false), ('bordaclands', 'twitch', 'offline', '', '', false), ('theskotos', 'twitch', 'offline', '', '', false), ('cicero_mt', 'twitch', 'offline', '', '', false), ('tessa_terry', 'twitch', 'offline', '', '', false), ('vtmod', 'twitch', 'offline', '', '', false), ('unholy666cz', 'twitch', 'offline', '', '', false), ('sh0rtyttv', 'twitch', 'offline', '', '', false), ('2002rebelka', 'twitch', 'offline', '', '', false), ('anetaamelie', 'twitch', 'offline', '', '', false), ('pajaaa18', 'twitch', 'offline', '', '', false), ('dedajede', 'twitch', 'offline', '', '', false), ('cliffboothcz', 'twitch', 'offline', '', '', false), ('aaleky', 'twitch', 'offline', '', '', false), ('jarvisgamingtv', 'twitch', 'offline', '', '', false), ('falazury', 'twitch', 'offline', '', '', false), ('tenfila', 'twitch', 'offline', '', '', false), ('mistrloutkar', 'twitch', 'offline', '', '', false), ('czechpatres', 'twitch', 'offline', '', '', false), ('barbee02', 'twitch', 'offline', '', '', false), ('nej_gamer', 'twitch', 'offline', '', '', false), ('d_o_n_alien', 'twitch', 'offline', '', '', false), ('entery99', 'twitch', 'offline', '', '', false), ('lukyss__', 'twitch', 'offline', '', '', false), ('mumu011', 'twitch', 'offline', '', '', false), ('jezisnazaretskyy','twitch', 'offline', '', '', false), ('crackfang', 'twitch', 'offline', '', '', false), ('julesteam', 'twitch', 'offline', '', '', false), ('tommyproductions', 'twitch','offline', '', '', false), ('vandalczz', 'twitch', 'offline', '', '', false), ('jirilaska', 'twitch', 'offline', '', '', false), ('xazzli', 'twitch', 'offline', '', '', false), ('kubape_', 'twitch', 'offline', '', '', false), ('fulopka', 'twitch', 'offline', '', '', false), ('mentiiix', 'twitch', 'offline', '', '', false), ('kristyyyyyyyyyyyy','twitch','offline', '', '', false), ('honzajcz', 'twitch', 'offline', '', '', false), ('vercrowcz', 'twitch', 'offline', '', '', false), ('akcelcz', 'twitch', 'offline', '', '', false), ('zeldok_', 'twitch', 'offline', '', '', false), ('drok_alar', 'twitch', 'offline', '', '', false), ('heimdallsvk', 'twitch', 'offline', '', '', false), ('darkvalkyra', 'twitch', 'offline', '', '', false), ('yakobcz', 'twitch', 'offline', '', '', false), ('satankattv', 'twitch', 'offline', '', '', false), ('paciinka', 'twitch', 'offline', '', '', false), ('nanami_blue_', 'twitch', 'offline', '', '', false), ('qwerydesign', 'twitch', 'offline', '', '', false), ('xxmonsterkaxx', 'twitch', 'offline', '', '', false), ('cleonatwitchi', 'twitch', 'offline', '', '', false), ('yukiidemon35', 'twitch', 'offline', '', '', false), ('denda_dennym', 'twitch', 'offline', '', '', false), ('korpo86', 'twitch', 'offline', '', '', false), ('m3rllin99', 'twitch', 'offline', '', '', false), ('hexor_fps', 'twitch', 'offline', '', '', false), ('polcarka1', 'twitch', 'offline', '', '', false), ('relic3dx', 'twitch', 'offline', '', '', false), ('poseidonpolabi', 'twitch', 'offline', '', '', false), ('podogor', 'twitch', 'offline', '', '', false), ('hermicze', 'twitch', 'offline', '', '', false), ('aifumi', 'twitch', 'offline', '', '', false), ('metl0sh', 'twitch', 'offline', '', '', false), ('kiycu', 'twitch', 'offline', '', '', false), ('johnydr4gon', 'twitch', 'offline', '', '', false), ('darkmortyr', 'twitch', 'offline', '', '', false), ('enbeast', 'twitch', 'offline', '', '', false), ('shery_len', 'twitch', 'offline', '', '', false), ('nejakyluke', 'twitch', 'offline', '', '', false), ('ulnear', 'twitch', 'offline', '', '', false), ('matyanes', 'twitch', 'offline', '', '', false), ('realelita15', 'twitch', 'offline', '', '', false), ('different_culture','twitch','offline', '', '', false), ('kapitan_vojta', 'twitch', 'offline', '', '', false), ('velkygouda', 'twitch', 'offline', '', '', false), ('17stanley_', 'twitch', 'offline', '', '', false), ('boudasek', 'twitch', 'offline', '', '', false), ('pajik_002', 'twitch', 'offline', '', '', false), ('gojirasaurr', 'twitch', 'offline', '', '', false), ('dattmark', 'twitch', 'offline', '', '', false), ('topkekstreaming', 'twitch','offline', '', '', false), ('vikita0_0', 'twitch', 'offline', '', '', false), ('tukan_cze', 'twitch', 'offline', '', '', false), ('seniseeq_', 'twitch', 'offline', '', '', false), ('mekaaja', 'twitch', 'offline', '', '', false), ('therasiaquinn', 'twitch', 'offline', '', '', false), ('moralnipodpora', 'twitch', 'offline', '', '', false), ('yanekcze', 'twitch', 'offline', '', '', false), ('ma_ty_x', 'twitch', 'offline', '', '', false), ('foxprague', 'twitch', 'offline', '', '', false), ('Aimonka', 'twitch', 'offline', '', '', false) ON CONFLICT (name) DO NOTHING;