Spaces:
Sleeping
Sleeping
File size: 5,223 Bytes
d9a03db 513eb9c d9a03db 513eb9c d9a03db 513eb9c d9a03db 513eb9c d9a03db 513eb9c d9a03db 513eb9c d9a03db | 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 | -- SQL Script to initialize the Supabase PostgreSQL database
-- Copy and paste this into the Supabase SQL Editor (SQL Editor -> New Query)
-- 1. STREAMS TABLE
CREATE TABLE IF NOT EXISTS streams (
id SERIAL PRIMARY KEY,
start_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
end_time TIMESTAMP WITH TIME ZONE,
title TEXT,
twitch_stream_id TEXT UNIQUE,
category TEXT,
backfill_status TEXT DEFAULT 'pending',
twitch_vod_id TEXT
);
-- 2. MESSAGES TABLE
CREATE TABLE IF NOT EXISTS messages (
id TEXT PRIMARY KEY, -- Twitch Message ID (UUID-like from tags)
stream_id INTEGER REFERENCES streams(id) ON DELETE SET NULL,
username TEXT NOT NULL,
display_name TEXT,
message TEXT NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
is_streamer BOOLEAN DEFAULT FALSE,
is_mod BOOLEAN DEFAULT FALSE,
is_sub BOOLEAN DEFAULT FALSE
);
-- Create indexes for fast querying and statistics aggregation
CREATE INDEX IF NOT EXISTS idx_messages_stream_id ON messages(stream_id);
CREATE INDEX IF NOT EXISTS idx_messages_username ON messages(username);
CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(timestamp);
-- 2.5 STREAM VIEWERS TABLE
CREATE TABLE IF NOT EXISTS stream_viewers (
stream_id INTEGER REFERENCES streams(id) ON DELETE CASCADE,
username TEXT NOT NULL,
display_name TEXT,
has_chatted BOOLEAN DEFAULT FALSE,
is_mod BOOLEAN DEFAULT FALSE,
is_sub BOOLEAN DEFAULT FALSE,
first_seen TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (stream_id, username)
);
CREATE INDEX IF NOT EXISTS idx_stream_viewers_stream_id ON stream_viewers(stream_id);
-- 2.6 CHAT USERS TABLE
CREATE TABLE IF NOT EXISTS chat_users (
username TEXT PRIMARY KEY,
display_name TEXT,
is_mod BOOLEAN DEFAULT FALSE,
is_sub BOOLEAN DEFAULT FALSE,
is_vip BOOLEAN DEFAULT FALSE,
last_seen TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- 3. VOICE WORDS TABLE (transcribed spoken words from streamer)
CREATE TABLE IF NOT EXISTS voice_words (
id SERIAL PRIMARY KEY,
stream_id INTEGER REFERENCES streams(id) ON DELETE CASCADE,
word TEXT NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_voice_words_stream_id ON voice_words(stream_id);
CREATE INDEX IF NOT EXISTS idx_voice_words_word ON voice_words(word);
-- 4. MOD ACTIONS TABLE (from EventSub: bans, timeouts, message deletions)
CREATE TABLE IF NOT EXISTS mod_actions (
id SERIAL PRIMARY KEY,
stream_id INTEGER REFERENCES streams(id) ON DELETE SET NULL,
action_type TEXT NOT NULL, -- 'ban', 'timeout', 'unban', 'delete'
moderator TEXT NOT NULL, -- Moderator's username
target_user TEXT, -- Banned/timed out user's username
duration INTEGER, -- Timeout duration in seconds (NULL for bans/deletions)
reason TEXT, -- Reason provided
message_text TEXT, -- Text of deleted message (for 'delete' action)
timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
reaction_time REAL
);
CREATE INDEX IF NOT EXISTS idx_mod_actions_stream_id ON mod_actions(stream_id);
CREATE INDEX IF NOT EXISTS idx_mod_actions_timestamp ON mod_actions(timestamp);
-- 5. SETTINGS TABLE (for persistent oauth tokens, etc.)
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- A trigger to automatically update updated_at in settings table
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE OR REPLACE TRIGGER update_settings_modtime
BEFORE UPDATE ON settings
FOR EACH ROW
EXECUTE FUNCTION update_modified_column();
-- =========================================================================
-- HELPER VIEWS FOR STATISTICS
-- =========================================================================
-- View for chatter statistics per stream
DROP VIEW IF EXISTS stream_chatter_stats;
CREATE VIEW stream_chatter_stats AS
SELECT
v.stream_id,
v.username,
u.display_name,
u.is_mod,
u.is_sub,
u.is_vip,
v.has_chatted,
v.first_seen,
(SELECT COUNT(*) FROM messages m WHERE m.stream_id = v.stream_id AND m.username = v.username) as message_count
FROM stream_viewers v
LEFT JOIN chat_users u ON v.username = u.username;
-- View for chatter statistics overall (all-time)
DROP VIEW IF EXISTS global_chatter_stats;
CREATE VIEW global_chatter_stats AS
SELECT
m.username,
u.display_name,
u.is_mod,
u.is_sub,
u.is_vip,
count(*) as message_count
FROM messages m
LEFT JOIN chat_users u ON m.username = u.username
GROUP BY m.username, u.display_name, u.is_mod, u.is_sub, u.is_vip;
-- View for spoken word statistics per stream
CREATE OR REPLACE VIEW stream_voice_word_stats AS
SELECT
stream_id,
word,
count(*) as word_count
FROM voice_words
GROUP BY stream_id, word;
-- View for spoken word statistics overall (all-time)
CREATE OR REPLACE VIEW global_voice_word_stats AS
SELECT
word,
count(*) as word_count
FROM voice_words
GROUP BY word;
|