Files
sendewerk/migrations/0001_editorial_core.sql
2026-10-21 14:50:31 +02:00

97 lines
3.2 KiB
SQL

CREATE TABLE section_categories (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
color TEXT NOT NULL,
sort_order INTEGER NOT NULL CHECK (sort_order >= 0)
);
CREATE TABLE formats (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
CREATE TABLE topics (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
CREATE TABLE pieces (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
summary TEXT NOT NULL DEFAULT '',
format_id TEXT REFERENCES formats(id) ON DELETE SET NULL,
status TEXT NOT NULL CHECK (status IN ('inbox', 'preparing', 'ready', 'archived')),
duration_seconds INTEGER NOT NULL DEFAULT 0 CHECK (duration_seconds >= 0),
intro TEXT NOT NULL DEFAULT '',
moderation_notes TEXT NOT NULL DEFAULT '',
transition_text TEXT NOT NULL DEFAULT '',
presentation_text TEXT NOT NULL DEFAULT '',
created_at_utc TEXT NOT NULL,
updated_at_utc TEXT NOT NULL
);
CREATE TABLE piece_topics (
piece_id TEXT NOT NULL REFERENCES pieces(id) ON DELETE CASCADE,
topic_id TEXT NOT NULL REFERENCES topics(id) ON DELETE CASCADE,
PRIMARY KEY (piece_id, topic_id)
);
CREATE TABLE piece_category_suggestions (
piece_id TEXT NOT NULL REFERENCES pieces(id) ON DELETE CASCADE,
category_id TEXT NOT NULL REFERENCES section_categories(id) ON DELETE CASCADE,
PRIMARY KEY (piece_id, category_id)
);
CREATE TABLE piece_sources (
id TEXT PRIMARY KEY,
piece_id TEXT NOT NULL REFERENCES pieces(id) ON DELETE CASCADE,
label TEXT NOT NULL,
url TEXT NOT NULL,
timecode_seconds INTEGER CHECK (timecode_seconds IS NULL OR timecode_seconds >= 0),
position INTEGER NOT NULL CHECK (position >= 0)
);
CREATE TABLE shows (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
starts_at_utc TEXT NOT NULL,
twitch_title TEXT NOT NULL DEFAULT '',
announcement_text TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL CHECK (status IN ('draft', 'ready', 'live', 'completed')),
created_at_utc TEXT NOT NULL,
updated_at_utc TEXT NOT NULL
);
CREATE TABLE show_sections (
id TEXT PRIMARY KEY,
show_id TEXT NOT NULL REFERENCES shows(id) ON DELETE CASCADE,
name TEXT NOT NULL,
category_id TEXT REFERENCES section_categories(id) ON DELETE SET NULL,
position INTEGER NOT NULL CHECK (position >= 0),
explicit_duration_seconds INTEGER CHECK (
explicit_duration_seconds IS NULL OR explicit_duration_seconds >= 0
),
UNIQUE (show_id, position)
);
CREATE TABLE piece_usages (
id TEXT PRIMARY KEY,
show_section_id TEXT NOT NULL REFERENCES show_sections(id) ON DELETE CASCADE,
original_piece_id TEXT REFERENCES pieces(id) ON DELETE SET NULL,
position INTEGER NOT NULL CHECK (position >= 0),
status TEXT NOT NULL CHECK (status IN ('open', 'current', 'done', 'skipped')),
duration_seconds INTEGER NOT NULL CHECK (duration_seconds >= 0),
title_snapshot TEXT NOT NULL,
intro_snapshot TEXT NOT NULL DEFAULT '',
moderation_snapshot TEXT NOT NULL DEFAULT '',
transition_snapshot TEXT NOT NULL DEFAULT '',
presentation_snapshot TEXT NOT NULL DEFAULT '',
is_reserve INTEGER NOT NULL DEFAULT 0 CHECK (is_reserve IN (0, 1)),
UNIQUE (show_section_id, position)
);
CREATE INDEX idx_pieces_status ON pieces(status);
CREATE INDEX idx_shows_status_start ON shows(status, starts_at_utc);
CREATE INDEX idx_sections_show ON show_sections(show_id, position);
CREATE INDEX idx_usages_section ON piece_usages(show_section_id, position);