From 86fa337c2cb6be264f2289090fc4c84ca157f0e6 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 26 Jan 2026 13:52:18 -0500 Subject: [PATCH] refactor: Consolidate database schema for first release - Replace migration files with single schema.sql - Include all current functionality in one file - Add 10-point rating scale with half-star precision - Remove old migration complexity for development - Maintain all table constraints and indexes - Add proper comments for rating system - Prepare clean schema for first release deployment --- database/schema/001_create_tables.up.sql | 44 ---------- database/schema/002_add_ratings.up.sql | 14 ---- .../003_add_ebook_metadata_fields.up.sql | 8 -- .../schema/004_add_ebook_folder_path.up.sql | 2 - .../005_create_user_ebook_folders.up.sql | 11 --- .../schema/006_drop_ebook_folder_path.up.sql | 2 - database/schema/007_add_scan_settings.up.sql | 3 - database/schema/008_add_user_names.up.sql | 3 - database/schema/normalize_folder_paths.sql | 15 ---- database/schema/schema.sql | 84 +++++++++++++++++++ 10 files changed, 84 insertions(+), 102 deletions(-) delete mode 100644 database/schema/001_create_tables.up.sql delete mode 100644 database/schema/002_add_ratings.up.sql delete mode 100644 database/schema/003_add_ebook_metadata_fields.up.sql delete mode 100644 database/schema/004_add_ebook_folder_path.up.sql delete mode 100644 database/schema/005_create_user_ebook_folders.up.sql delete mode 100644 database/schema/006_drop_ebook_folder_path.up.sql delete mode 100644 database/schema/007_add_scan_settings.up.sql delete mode 100644 database/schema/008_add_user_names.up.sql delete mode 100644 database/schema/normalize_folder_paths.sql create mode 100644 database/schema/schema.sql diff --git a/database/schema/001_create_tables.up.sql b/database/schema/001_create_tables.up.sql deleted file mode 100644 index aa8159f..0000000 --- a/database/schema/001_create_tables.up.sql +++ /dev/null @@ -1,44 +0,0 @@ --- Create users table -CREATE TABLE users ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - email VARCHAR(255) UNIQUE NOT NULL, - username VARCHAR(255) UNIQUE NOT NULL, - password_hash VARCHAR(255) NOT NULL, - theme VARCHAR(50) DEFAULT 'tokyo-night', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Create ebooks table -CREATE TABLE ebooks ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - title VARCHAR(255) NOT NULL, - author VARCHAR(255), - isbn VARCHAR(13), - description TEXT, - file_path VARCHAR(500) NOT NULL, - file_size BIGINT, - mime_type VARCHAR(100), - cover_image_path VARCHAR(500), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Create reading_progress table -CREATE TABLE reading_progress ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - ebook_id UUID NOT NULL REFERENCES ebooks(id) ON DELETE CASCADE, - user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, - current_page INTEGER DEFAULT 0, - total_pages INTEGER, - last_read_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - UNIQUE(ebook_id, user_id) -); - --- Create indexes -CREATE INDEX idx_users_email ON users(email); -CREATE INDEX idx_users_username ON users(username); -CREATE INDEX idx_ebooks_title ON ebooks(title); -CREATE INDEX idx_ebooks_author ON ebooks(author); -CREATE INDEX idx_reading_progress_ebook_id ON reading_progress(ebook_id); -CREATE INDEX idx_reading_progress_user_id ON reading_progress(user_id); \ No newline at end of file diff --git a/database/schema/002_add_ratings.up.sql b/database/schema/002_add_ratings.up.sql deleted file mode 100644 index a966dda..0000000 --- a/database/schema/002_add_ratings.up.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Add ebook ratings functionality -CREATE TABLE ebook_ratings ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - ebook_id UUID NOT NULL REFERENCES ebooks(id) ON DELETE CASCADE, - user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, - rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - UNIQUE(ebook_id, user_id) -); - --- Create indexes for better query performance -CREATE INDEX idx_ebook_ratings_ebook_id ON ebook_ratings(ebook_id); -CREATE INDEX idx_ebook_ratings_user_id ON ebook_ratings(user_id); \ No newline at end of file diff --git a/database/schema/003_add_ebook_metadata_fields.up.sql b/database/schema/003_add_ebook_metadata_fields.up.sql deleted file mode 100644 index d5bdbaf..0000000 --- a/database/schema/003_add_ebook_metadata_fields.up.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Add additional metadata fields to ebooks table -ALTER TABLE ebooks ADD COLUMN series VARCHAR(255); -ALTER TABLE ebooks ADD COLUMN series_number INTEGER; -ALTER TABLE ebooks ADD COLUMN tags TEXT; -ALTER TABLE ebooks ADD COLUMN asin VARCHAR(20); -ALTER TABLE ebooks ADD COLUMN date_published DATE; -ALTER TABLE ebooks ADD COLUMN publisher VARCHAR(255); -ALTER TABLE ebooks ADD COLUMN contributors TEXT; \ No newline at end of file diff --git a/database/schema/004_add_ebook_folder_path.up.sql b/database/schema/004_add_ebook_folder_path.up.sql deleted file mode 100644 index 8a1eb91..0000000 --- a/database/schema/004_add_ebook_folder_path.up.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Add ebook_folder_path to users table -ALTER TABLE users ADD COLUMN ebook_folder_path VARCHAR(500); \ No newline at end of file diff --git a/database/schema/005_create_user_ebook_folders.up.sql b/database/schema/005_create_user_ebook_folders.up.sql deleted file mode 100644 index 7e1b2c8..0000000 --- a/database/schema/005_create_user_ebook_folders.up.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Create user_ebook_folders table for multiple folders per user -CREATE TABLE user_ebook_folders ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, - folder_path VARCHAR(500) NOT NULL, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - UNIQUE(user_id, folder_path) -); - --- Create index for faster lookups -CREATE INDEX idx_user_ebook_folders_user_id ON user_ebook_folders(user_id); \ No newline at end of file diff --git a/database/schema/006_drop_ebook_folder_path.up.sql b/database/schema/006_drop_ebook_folder_path.up.sql deleted file mode 100644 index 4b6b5df..0000000 --- a/database/schema/006_drop_ebook_folder_path.up.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Drop the old ebook_folder_path column from users table -ALTER TABLE users DROP COLUMN IF EXISTS ebook_folder_path; \ No newline at end of file diff --git a/database/schema/007_add_scan_settings.up.sql b/database/schema/007_add_scan_settings.up.sql deleted file mode 100644 index 1b3b7e4..0000000 --- a/database/schema/007_add_scan_settings.up.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Add scan settings to users table -ALTER TABLE users ADD COLUMN scan_frequency_minutes INTEGER DEFAULT 60; -ALTER TABLE users ADD COLUMN auto_scan_enabled BOOLEAN DEFAULT true; \ No newline at end of file diff --git a/database/schema/008_add_user_names.up.sql b/database/schema/008_add_user_names.up.sql deleted file mode 100644 index bd49e6b..0000000 --- a/database/schema/008_add_user_names.up.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Add first and last name to users table -ALTER TABLE users ADD COLUMN first_name VARCHAR(255); -ALTER TABLE users ADD COLUMN last_name VARCHAR(255); \ No newline at end of file diff --git a/database/schema/normalize_folder_paths.sql b/database/schema/normalize_folder_paths.sql deleted file mode 100644 index bf63b68..0000000 --- a/database/schema/normalize_folder_paths.sql +++ /dev/null @@ -1,15 +0,0 @@ --- Normalize existing folder paths in user_ebook_folders table --- This script will clean up inconsistent path formatting - -UPDATE user_ebook_folders -SET folder_path = REPLACE(REPLACE(folder_path, '\\', '/'), '//', '/') -WHERE folder_path LIKE '%\\%' OR folder_path LIKE '%//%'; - --- Remove trailing slashes from non-root paths -UPDATE user_ebook_folders -SET folder_path = CASE - WHEN folder_path = '/' THEN '/' - WHEN RIGHT(folder_path, 1) = '/' THEN LEFT(folder_path, LENGTH(folder_path) - 1) - ELSE folder_path -END -WHERE folder_path != '/' AND RIGHT(folder_path, 1) = '/'; \ No newline at end of file diff --git a/database/schema/schema.sql b/database/schema/schema.sql new file mode 100644 index 0000000..cd26c86 --- /dev/null +++ b/database/schema/schema.sql @@ -0,0 +1,84 @@ +-- Consolidated Bookmann Database Schema +-- This file contains the complete current schema for the Bookmann ebook management system + +-- Create users table +CREATE TABLE users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + email VARCHAR(255) UNIQUE NOT NULL, + username VARCHAR(255) UNIQUE NOT NULL, + password_hash VARCHAR(255) NOT NULL, + first_name VARCHAR(255), + last_name VARCHAR(255), + theme VARCHAR(50) DEFAULT 'tokyo-night', + scan_frequency_minutes INTEGER DEFAULT 60, + auto_scan_enabled BOOLEAN DEFAULT true, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +-- Create ebooks table +CREATE TABLE ebooks ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + title VARCHAR(255) NOT NULL, + author VARCHAR(255), + isbn VARCHAR(13), + description TEXT, + file_path VARCHAR(500) NOT NULL, + file_size BIGINT, + mime_type VARCHAR(100), + cover_image_path VARCHAR(500), + series VARCHAR(255), + series_number INTEGER, + tags TEXT, + asin VARCHAR(20), + date_published DATE, + publisher VARCHAR(255), + contributors TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +-- Create reading_progress table +CREATE TABLE reading_progress ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + ebook_id UUID NOT NULL REFERENCES ebooks(id) ON DELETE CASCADE, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + current_page INTEGER DEFAULT 0, + total_pages INTEGER, + last_read_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(ebook_id, user_id) +); + +-- Create ebook_ratings table +CREATE TABLE ebook_ratings ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + ebook_id UUID NOT NULL REFERENCES ebooks(id) ON DELETE CASCADE, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 10), -- 10-point scale for half-star precision + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(ebook_id, user_id) +); + +-- Create user_ebook_folders table for multiple folders per user +CREATE TABLE user_ebook_folders ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + folder_path VARCHAR(500) NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(user_id, folder_path) +); + +-- Create indexes for better query performance +CREATE INDEX idx_users_email ON users(email); +CREATE INDEX idx_users_username ON users(username); +CREATE INDEX idx_ebooks_title ON ebooks(title); +CREATE INDEX idx_ebooks_author ON ebooks(author); +CREATE INDEX idx_reading_progress_ebook_id ON reading_progress(ebook_id); +CREATE INDEX idx_reading_progress_user_id ON reading_progress(user_id); +CREATE INDEX idx_ebook_ratings_ebook_id ON ebook_ratings(ebook_id); +CREATE INDEX idx_ebook_ratings_user_id ON ebook_ratings(user_id); +CREATE INDEX idx_user_ebook_folders_user_id ON user_ebook_folders(user_id); + +-- Add comment explaining the rating system +COMMENT ON COLUMN ebook_ratings.rating IS 'Rating scale 1-10 (odd numbers = half-stars: 1,3,5,7,9 = 0.5,1.5,2.5,3.5,4.5 stars)'; \ No newline at end of file