Initial commit: GM-Relay Telegram Bot
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
-- =============================================================
|
||||
-- Players: all known Telegram users who interact with the bot
|
||||
-- =============================================================
|
||||
CREATE TABLE players (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
telegram_id BIGINT NOT NULL UNIQUE,
|
||||
display_name VARCHAR(255) NOT NULL,
|
||||
telegram_username VARCHAR(255),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================
|
||||
-- Game groups: Telegram group chats where games are organized
|
||||
-- =============================================================
|
||||
CREATE TABLE game_groups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
telegram_chat_id BIGINT NOT NULL UNIQUE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
gm_telegram_id BIGINT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================
|
||||
-- Group membership: which players belong to which groups
|
||||
-- =============================================================
|
||||
CREATE TABLE game_group_members (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
group_id UUID NOT NULL REFERENCES game_groups(id) ON DELETE CASCADE,
|
||||
player_id UUID NOT NULL REFERENCES players(id) ON DELETE CASCADE,
|
||||
is_gm BOOLEAN NOT NULL DEFAULT false,
|
||||
joined_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (group_id, player_id)
|
||||
);
|
||||
|
||||
-- =============================================================
|
||||
-- Sessions: individual game sessions with scheduling
|
||||
-- =============================================================
|
||||
CREATE TABLE sessions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
group_id UUID NOT NULL REFERENCES game_groups(id) ON DELETE CASCADE,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
join_link TEXT NOT NULL,
|
||||
scheduled_at TIMESTAMPTZ NOT NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'Planned'
|
||||
CHECK (status IN ('Planned','ConfirmationSent','Confirmed','Cancelled')),
|
||||
confirmation_message_id INTEGER,
|
||||
link_message_id INTEGER,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Partial index: only scan sessions that still need processing
|
||||
CREATE INDEX ix_sessions_pending ON sessions (scheduled_at)
|
||||
WHERE status IN ('Planned', 'ConfirmationSent', 'Confirmed');
|
||||
|
||||
-- =============================================================
|
||||
-- Session participants: per-session RSVP tracking
|
||||
-- =============================================================
|
||||
CREATE TABLE session_participants (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
||||
player_id UUID NOT NULL REFERENCES players(id) ON DELETE CASCADE,
|
||||
is_gm BOOLEAN NOT NULL DEFAULT false,
|
||||
rsvp_status VARCHAR(50) NOT NULL DEFAULT 'Pending'
|
||||
CHECK (rsvp_status IN ('Pending','Confirmed','Declined')),
|
||||
responded_at TIMESTAMPTZ,
|
||||
UNIQUE (session_id, player_id)
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Add batch_id to sessions to support multiple sessions per message
|
||||
ALTER TABLE sessions ADD COLUMN batch_id UUID NOT NULL DEFAULT gen_random_uuid();
|
||||
CREATE INDEX ix_sessions_batch ON sessions (batch_id);
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Add thread_id to sessions to store the forum topic ID so we can delete it later
|
||||
ALTER TABLE sessions ADD COLUMN thread_id INTEGER;
|
||||
@@ -0,0 +1,27 @@
|
||||
-- Reschedule proposals: tracks GM-initiated time change requests
|
||||
-- Status flow: AwaitingTime → Voting → Approved/Rejected
|
||||
|
||||
CREATE TABLE reschedule_proposals (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
||||
proposed_at TIMESTAMPTZ, -- new proposed time (NULL while AwaitingTime)
|
||||
proposed_by BIGINT NOT NULL, -- GM's telegram_id
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'AwaitingTime'
|
||||
CHECK (status IN ('AwaitingTime', 'Voting', 'Approved', 'Rejected')),
|
||||
vote_message_id INTEGER, -- message ID of the voting message in chat
|
||||
vote_chat_id BIGINT, -- chat where voting takes place
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Only one active proposal per session at a time
|
||||
CREATE UNIQUE INDEX ix_reschedule_active ON reschedule_proposals (session_id)
|
||||
WHERE status IN ('AwaitingTime', 'Voting');
|
||||
|
||||
CREATE TABLE reschedule_votes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
proposal_id UUID NOT NULL REFERENCES reschedule_proposals(id) ON DELETE CASCADE,
|
||||
player_id UUID NOT NULL REFERENCES players(id) ON DELETE CASCADE,
|
||||
vote VARCHAR(10) NOT NULL CHECK (vote IN ('yes', 'no')),
|
||||
voted_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (proposal_id, player_id)
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Store the message ID of the batch schedule message so we can edit it later
|
||||
ALTER TABLE sessions ADD COLUMN batch_message_id INTEGER;
|
||||
Reference in New Issue
Block a user