Add existing scripts

This commit is contained in:
chris committed 2026-09-29 15:24:09 -04:00
1 parent 2ab5a42c2b
commit 3c05d74104
31 files changed
+1138

No files matched your search

+193
View File
@@ -0,0 +1,193 @@
CREATE EXTENSION IF NOT EXISTS ltree;
DO $$ BEGIN
CREATE TYPE "ProgressType" AS ENUM (
'PAGES',
'PERCENTAGE',
'SECONDS'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
CREATE TYPE "BookFormat" AS ENUM (
'HARDCOVER',
'TRADE_PAPERBACK',
'MASS_MARKET_PAPERBACK',
'EBOOK',
'AUDIOBOOK'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
CREATE TYPE "ReadingStatus" AS ENUM (
'WANT_TO_READ',
'CURRENTLY_READING',
'READ',
'DNF',
'PAUSED'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
CREATE TYPE "TierType" AS ENUM (
'FREE',
'NOADS',
'ANALYTICS_PLUS',
'PREMIUM'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
CREATE TYPE "UserRole" AS ENUM (
'USER',
'AGENT',
'AUTHOR',
'MODERATOR',
'EDITOR',
'PUBLISHER',
'ADMIN'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
username TEXT UNIQUE NOT NULL,
display_name TEXT,
role "UserRole" DEFAULT 'USER'::"UserRole",
tier "TierType" DEFAULT 'FREE'::"TierType",
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
is_enabled BOOLEAN DEFAULT TRUE
);
CREATE TABLE IF NOT EXISTS publishers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
website TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS books (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
description TEXT,
isbn_13 VARCHAR(13) UNIQUE,
format "BookFormat" NOT NULL,
published_year INT,
cover_image_url TEXT,
total_pages INT,
total_audio_seconds INT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS authors (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID,
name TEXT NOT NULL,
bio TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS author_agents (
agent_id UUID NOT NULL,
author_id UUID NOT NULL,
PRIMARY KEY (agent_id, author_id)
);
CREATE TABLE IF NOT EXISTS book_authors (
book_id UUID REFERENCES books(id) ON DELETE CASCADE,
author_id UUID REFERENCES authors(id) ON DELETE CASCADE,
author_order INT NOT NULL DEFAULT 0,
PRIMARY KEY (book_id, author_id)
);
CREATE TABLE IF NOT EXISTS book_publishers (
book_id UUID REFERENCES books(id) ON DELETE CASCADE,
publisher_id UUID REFERENCES publishers(id) ON DELETE CASCADE,
PRIMARY KEY (book_id, publisher_id)
);
CREATE TABLE IF NOT EXISTS author_publishers (
publisher_id UUID NOT NULL,
author_id UUID NOT NULL,
PRIMARY KEY (publisher_id, author_id)
);
CREATE TABLE IF NOT EXISTS user_publishers (
publisher_id UUID NOT NULL,
user_id UUID NOT NULL,
PRIMARY KEY (publisher_id, user_id)
);
CREATE TABLE IF NOT EXISTS user_books (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
book_id UUID REFERENCES books(id) ON DELETE CASCADE NOT NULL,
status "ReadingStatus" NOT NULL,
is_favorite BOOLEAN DEFAULT FALSE,
dnf_reason TEXT, -- Nullable, used only if status is 'DNF'
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, book_id)
);
CREATE TABLE IF NOT EXISTS reading_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_book_id UUID REFERENCES user_books(id) ON DELETE CASCADE NOT NULL,
progress_type "ProgressType" NOT NULL, -- 'PAGES', 'PERCENTAGE', 'SECONDS'
session_start INT NOT NULL DEFAULT 0,
session_end INT NOT NULL,
total_progress INT NOT NULL,
notes TEXT,
logged_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
book_id UUID REFERENCES books(id) ON DELETE CASCADE NOT NULL,
overall_rating NUMERIC(3,2) CHECK (overall_rating >= 0 AND overall_rating <= 5.00), -- Allows 4.25, 4.5
pacing_rating NUMERIC(3,2) CHECK (pacing_rating >= 0 AND pacing_rating <= 5.00), -- Multi-dimensional
prose_rating NUMERIC(3,2) CHECK (prose_rating >= 0 AND prose_rating <= 5.00),
character_rating NUMERIC(3,2) CHECK (character_rating >= 0 AND character_rating <= 5.00),
review_text TEXT,
is_spoiler BOOLEAN DEFAULT FALSE,
spoiler_cutoff_progress INT, -- Hides review if reader hasn't reached this page/percentage
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, book_id)
);
CREATE TABLE IF NOT EXISTS shelves (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
name TEXT NOT NULL,
path ltree NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS book_shelves (
book_id UUID REFERENCES user_books(id),
shelf_id UUID NOT NULL REFERENCES shelves(id) ON DELETE CASCADE,
PRIMARY KEY (book_id, shelf_id)
);
-- Database Performance Indexes
CREATE INDEX idx_user_books_user_status ON user_books(user_id, status);
CREATE INDEX idx_books_isbn ON books(isbn_13);
CREATE INDEX idx_reviews_book_rating ON reviews(book_id, overall_rating);
CREATE INDEX idx_shelves_path_gist ON shelves USING gist (path);
CREATE UNIQUE INDEX idx_user_shelf_path ON shelves (user_id, path);
GRANT usage ON SCHEMA public TO tomes_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO tomes_user;