diff --git a/database/schema/schema.sql b/database/schema/schema.sql index 663d375..1a961c0 100644 --- a/database/schema/schema.sql +++ b/database/schema/schema.sql @@ -133,7 +133,40 @@ CREATE TABLE IF NOT EXISTS media_items ( entitlement_id VARCHAR(255) UNIQUE, revision_number INTEGER DEFAULT 1, kobo_content_id VARCHAR(255), - kobo_metadata JSONB + kobo_metadata JSONB, + -- Manga and comic reading direction support + -- Stores raw Manga field from ComicInfo.xml + manga_type VARCHAR(30) DEFAULT 'unknown', + reading_direction VARCHAR(20) DEFAULT 'auto', + CHECK (manga_type IN ('unknown', 'no', 'yes', 'yes_and_right_to_left')), + CHECK (reading_direction IN ('auto', 'ltr', 'rtl', 'vertical')), + + -- Universal series information (applies to ALL formats: ebooks, audiobooks, comics) + series_count INTEGER, -- Total items in series (from ComicInfo Count field, or book series count) + volume INTEGER, -- Volume/omnibus number for collected editions + + -- Universal publisher and classification (applies to ALL formats) + imprint VARCHAR(255), -- Publisher imprint (e.g., Vertigo, HarperCollinsEpic) + age_rating VARCHAR(20), -- Age rating: Everyone, Teen, Mature, Adult (applies to all formats) + web_url VARCHAR(500), -- URL to info page (Goodreads, ComicVine, MangaUpdates, Audible, etc.) + + -- Comic-specific fields + story_arc VARCHAR(255), -- Story arc name (e.g., "The Dark Phoenix Saga", "Civil War") + is_black_and_white BOOLEAN, -- Black and white flag (mostly comics, some illustrated books) + + -- Additional metadata (applies to all formats) + metadata_notes TEXT, -- Notes from metadata files (ComicInfo.xml, EPUB, PDF) - distinct from user notes + community_rating DECIMAL(3,1), -- Pre-existing community rating from metadata (0.0-10.0) - distinct from user ratings + + -- Alternate series information (JSONB for flexible schema - comic-specific) + alternate_info JSONB, -- Stores AlternateSeries, AlternateNumber, AlternateCount + -- Example: {"alternate_series": "Ultimate X-Men", "alternate_number": 1, "alternate_count": 12} + + -- Scan and publication metadata (comic-specific) + scan_information TEXT, -- Scan information (scanner group, resolution, etc.) + + -- Summary (distinct from description - may merge with Calibre description) + summary TEXT -- Summary from ComicInfo.xml (may be merged with description from Calibre) ); -- Add GIN indexes for fast array searches @@ -387,6 +420,46 @@ CREATE INDEX IF NOT EXISTS idx_media_items_copyright_year ON media_items(copyrig CREATE INDEX IF NOT EXISTS idx_media_items_page_count ON media_items(page_count); CREATE INDEX IF NOT EXISTS idx_media_items_series ON media_items(series); +-- Index for filtering by reading direction (for manga/comic libraries) +CREATE INDEX IF NOT EXISTS idx_media_items_reading_direction +ON media_items(reading_direction) +WHERE reading_direction IS NOT NULL; + +-- Index for filtering by story arc (comic-specific) +CREATE INDEX IF NOT EXISTS idx_media_items_story_arc +ON media_items(story_arc) +WHERE story_arc IS NOT NULL; + +-- Index for filtering by imprint (universal - all formats) +CREATE INDEX IF NOT EXISTS idx_media_items_imprint +ON media_items(imprint) +WHERE imprint IS NOT NULL; + +-- Index for filtering by age rating (universal - all formats) +CREATE INDEX IF NOT EXISTS idx_media_items_age_rating +ON media_items(age_rating) +WHERE age_rating IS NOT NULL; + +-- Index for filtering by manga type (comic-specific) +CREATE INDEX IF NOT EXISTS idx_media_items_manga_type +ON media_items(manga_type) +WHERE manga_type IS NOT NULL; + +-- Index for filtering by series count (universal - all formats) +CREATE INDEX IF NOT EXISTS idx_media_items_series_count +ON media_items(series_count) +WHERE series_count IS NOT NULL; + +-- Index for filtering by volume (universal - all formats) +CREATE INDEX IF NOT EXISTS idx_media_items_volume +ON media_items(volume) +WHERE volume IS NOT NULL; + +-- GIN index for alternate_info JSONB queries (comic-specific) +CREATE INDEX IF NOT EXISTS idx_media_items_alternate_info_gin +ON media_items USING GIN (alternate_info) +WHERE alternate_info IS NOT NULL; + -- Progress and ratings indexes CREATE INDEX IF NOT EXISTS idx_reading_progress_media_item_id ON reading_progress(media_item_id); CREATE INDEX IF NOT EXISTS idx_reading_progress_user_id ON reading_progress(user_id); @@ -477,6 +550,26 @@ COMMENT ON COLUMN media_items.goodreads_id IS 'Goodreads book identifier for int COMMENT ON COLUMN media_items.openlibrary_id IS 'Open Library identifier for integration'; COMMENT ON COLUMN media_items.google_books_id IS 'Google Books identifier for integration'; +-- Comic-specific fields +COMMENT ON COLUMN media_items.manga_type IS 'Raw Manga field from ComicInfo.xml: unknown, no, yes, yes_and_right_to_left'; +COMMENT ON COLUMN media_items.reading_direction IS 'Computed reading direction: auto, ltr (left-to-right), rtl (right-to-left), vertical (webtoons/manhwa)'; +COMMENT ON COLUMN media_items.story_arc IS 'Story arc name for grouping related issues (e.g., "The Dark Phoenix Saga", "Civil War")'; +COMMENT ON COLUMN media_items.is_black_and_white IS 'Black and white comic flag from ComicInfo.xml'; +COMMENT ON COLUMN media_items.alternate_info IS 'Alternate series information as JSONB: {alternate_series, alternate_number, alternate_count}'; +COMMENT ON COLUMN media_items.scan_information IS 'Scan information from ComicInfo.xml (scanner group, resolution, etc.)'; + +-- Universal fields (apply to ebooks, audiobooks, comics) +COMMENT ON COLUMN media_items.series_count IS 'Total items in series (from ComicInfo.xml Count field, or book series count)'; +COMMENT ON COLUMN media_items.volume IS 'Volume/omnibus number for collected editions'; +COMMENT ON COLUMN media_items.imprint IS 'Publisher imprint/subdivision (e.g., Vertigo, HarperCollinsEpic, DC Black Label)'; +COMMENT ON COLUMN media_items.age_rating IS 'Age rating from metadata: Everyone, Teen, Mature, Adult (applies to all formats)'; +COMMENT ON COLUMN media_items.web_url IS 'URL to info page (Goodreads, ComicVine, MangaUpdates, Audible, etc.)'; + +-- Additional metadata (applies to all formats) +COMMENT ON COLUMN media_items.metadata_notes IS 'Notes from metadata files (ComicInfo.xml, EPUB, PDF) - distinct from user notes in media_notes table'; +COMMENT ON COLUMN media_items.community_rating IS 'Pre-existing community rating from metadata files (scale 0.0-10.0) - distinct from user ratings in media_ratings table'; +COMMENT ON COLUMN media_items.summary IS 'Summary from ComicInfo.xml (may be merged with description from Calibre)'; + -- Library Type File Extensions Notes: -- - Ebooks: .epub, .pdf, .mobi, .azw, .azw3, .txt, .rtf, .doc, .docx, .lit, .fb2, .pdb -- - Comics: .cbz, .cbr, .cb7, .cbt, .pdf