From 168c6b2302e5813ae97478ab76a68cedc9f8838f Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Wed, 28 Jan 2026 15:41:40 -0500 Subject: [PATCH] feat: add media_notes and media_highlights tables - Add media_notes table for user annotations with position tracking - Add media_highlights table for text highlighting with color customization - Add optional note_id foreign key for highlight-note associations - Add backward compatibility views (ebook_notes, ebook_highlights) - Add proper indexes for performance optimization - Update schema comments to document new annotation features --- database/schema/schema.sql | 58 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/database/schema/schema.sql b/database/schema/schema.sql index 4f67324..b557790 100644 --- a/database/schema/schema.sql +++ b/database/schema/schema.sql @@ -127,6 +127,31 @@ CREATE TABLE media_ratings ( UNIQUE(media_item_id, user_id) ); +-- Create media_notes table for user notes on media items +CREATE TABLE media_notes ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + media_item_id UUID NOT NULL REFERENCES media_items(id) ON DELETE CASCADE, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + content TEXT NOT NULL, + position VARCHAR(100), -- optional position (page:offset or CFI) for standalone notes + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +-- Create media_highlights table for user highlights on media items +CREATE TABLE media_highlights ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + media_item_id UUID NOT NULL REFERENCES media_items(id) ON DELETE CASCADE, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + selection_text TEXT NOT NULL, + start_position VARCHAR(100), -- position (page:offset or CFI) where highlight starts + end_position VARCHAR(100), -- position (page:offset or CFI) where highlight ends + color VARCHAR(7) DEFAULT '#ffff00', -- hex color code for highlight + note_id UUID REFERENCES media_notes(id) ON DELETE SET NULL, -- optional associated note + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + -- Create ebook_ratings view for backward compatibility CREATE VIEW ebook_ratings AS SELECT mr.*, @@ -137,6 +162,26 @@ JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id WHERE lt.name = 'ebooks'; +-- Create ebook_notes view for backward compatibility +CREATE VIEW ebook_notes AS +SELECT mn.*, + mi.id as ebook_id -- Map media_item_id to ebook_id for compatibility +FROM media_notes mn +JOIN media_items mi ON mn.media_item_id = mi.id +JOIN libraries l ON mi.library_id = l.id +JOIN library_types lt ON l.library_type_id = lt.id +WHERE lt.name = 'ebooks'; + +-- Create ebook_highlights view for backward compatibility +CREATE VIEW ebook_highlights AS +SELECT mh.*, + mi.id as ebook_id -- Map media_item_id to ebook_id for compatibility +FROM media_highlights mh +JOIN media_items mi ON mh.media_item_id = mi.id +JOIN libraries l ON mi.library_id = l.id +JOIN library_types lt ON l.library_type_id = lt.id +WHERE lt.name = 'ebooks'; + -- Note: user_ebook_folders table is replaced by library_folders table -- Libraries now handle folder management instead of individual users @@ -165,6 +210,13 @@ CREATE INDEX idx_reading_progress_user_id ON reading_progress(user_id); CREATE INDEX idx_media_ratings_media_item_id ON media_ratings(media_item_id); CREATE INDEX idx_media_ratings_user_id ON media_ratings(user_id); +-- Notes and highlights indexes +CREATE INDEX idx_media_notes_media_item_id ON media_notes(media_item_id); +CREATE INDEX idx_media_notes_user_id ON media_notes(user_id); +CREATE INDEX idx_media_highlights_media_item_id ON media_highlights(media_item_id); +CREATE INDEX idx_media_highlights_user_id ON media_highlights(user_id); +CREATE INDEX idx_media_highlights_note_id ON media_highlights(note_id); + -- Add comment explaining the rating system COMMENT ON COLUMN media_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)'; @@ -176,7 +228,9 @@ COMMENT ON COLUMN media_ratings.rating IS 'Rating scale 1-10 (odd numbers = half -- Role System Notes: -- - All users default to 'user' role -- - Admin users can: create/manage libraries and folders, scan media, modify media metadata, delete media, control library visibility --- - Regular users can: view visible libraries, rate media, track reading progress, manage their profile +-- - Regular users can: view visible libraries, rate media, track reading progress, create notes and highlights, manage their profile -- - To create first admin: UPDATE users SET role = 'admin' WHERE email = 'your-admin-email'; -- - Library visibility is controlled through library_visibility table - admins can hide/show libraries per user --- - Backward compatibility views (ebooks, ebook_ratings, ebook_reading_progress) maintain existing API contracts \ No newline at end of file +-- - Notes and highlights support position data (page:offset or CFI format) for precise location tracking +-- - Highlights can have associated notes for detailed annotations +-- - Backward compatibility views (ebooks, ebook_ratings, ebook_reading_progress, ebook_notes, ebook_highlights) maintain existing API contracts \ No newline at end of file