diff --git a/database/schema/schema.sql b/database/schema/schema.sql
index 1e96b3d..b7defda 100644
--- a/database/schema/schema.sql
+++ b/database/schema/schema.sql
@@ -16,8 +16,8 @@ CREATE TABLE IF NOT EXISTS library_types (
-- Insert default library types
INSERT INTO library_types (name, description, allowed_extensions) VALUES
('ebooks', 'Ebook files including EPUB, PDF, MOBI, etc.', ARRAY['.epub', '.pdf', '.mobi', '.azw', '.azw3', '.txt', '.rtf', '.doc', '.docx', '.lit', '.fb2', '.pdb']),
-('comics', 'Comic book archives and image formats', ARRAY['.cbz', '.cbr', '.cb7', '.cbt', '.pdf']),
-('manga', 'Manga files including archives and image folders', ARRAY['.cbz', '.cbr', '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'])
+('comics', 'Comic book archives and image formats', ARRAY['.cbz', '.cbr', '.cb7', '.cbt', '.epub', '.pdf']),
+('manga', 'Manga files including archives and image folders', ARRAY['.cbz', '.cbr', '.epub', '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'])
ON CONFLICT (name) DO NOTHING;
-- Create users table
@@ -387,6 +387,30 @@ CREATE INDEX IF NOT EXISTS idx_kobo_shelves_device_id ON kobo_shelves(device_id)
CREATE INDEX IF NOT EXISTS idx_kobo_shelves_media_item_id ON kobo_shelves(media_item_id);
CREATE INDEX IF NOT EXISTS idx_kobo_shelves_shelf_name ON kobo_shelves(shelf_name);
+-- Table to track items that can't be processed in their library
+CREATE TABLE IF NOT EXISTS processing_issues (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ media_item_id UUID NOT NULL REFERENCES media_items(id) ON DELETE CASCADE,
+ library_id UUID NOT NULL REFERENCES libraries(id) ON DELETE CASCADE,
+ issue_type VARCHAR(50) NOT NULL,
+ issue_description TEXT NOT NULL,
+ severity VARCHAR(20) NOT NULL DEFAULT 'warning',
+ resolved BOOLEAN DEFAULT FALSE,
+ resolved_at TIMESTAMP WITH TIME ZONE,
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
+ UNIQUE(media_item_id, issue_type)
+);
+
+-- Indexes for querying problem items
+CREATE INDEX IF NOT EXISTS idx_processing_issues_library
+ ON processing_issues(library_id, resolved);
+CREATE INDEX IF NOT EXISTS idx_processing_issues_severity
+ ON processing_issues(severity, resolved);
+
+-- Add comment for documentation
+COMMENT ON TABLE processing_issues IS 'Tracks media items that cannot be properly processed in their assigned library due to format mismatches or other issues';
+
+
-- ============================================
-- KOBO ENTITLEMENTS TRACKING
-- ============================================
@@ -711,6 +735,35 @@ BEGIN
END;
$$ LANGUAGE plpgsql;
+-- Function to detect fixed-layout EPUBs from OPF content
+CREATE OR REPLACE FUNCTION detect_fixed_layout_epub(opf_content TEXT)
+RETURNS BOOLEAN AS $$
+BEGIN
+ -- Check for pre-paginated metadata
+ IF opf_content LIKE '%rendition:layout">pre-paginated<%' THEN
+ RETURN TRUE;
+ END IF;
+
+ IF opf_content LIKE '%rendition:layout="pre-paginated"%' THEN
+ RETURN TRUE;
+ END IF;
+
+ -- Check for RTL page progression (manga indicator)
+ IF opf_content LIKE '%page-progression-direction="rtl"%' THEN
+ RETURN TRUE;
+ END IF;
+
+ -- Check for image-heavy content (count
tags)
+ -- Threshold of 50 images suggests manga/comic vs novel
+ IF array_length(string_to_array(opf_content, '
50 THEN
+ RETURN TRUE;
+ END IF;
+
+ RETURN FALSE;
+END;
+$$ LANGUAGE plpgsql;
+
+
-- Convert progress between format groups
CREATE OR REPLACE FUNCTION convert_progress(
source_format VARCHAR,