schema(dashboard): implement Phase 1 unified collections architecture
Add support for Carousel-style dashboard with unified collections architecture: Database Schema Changes: - Add user_dashboard_preferences table: - hidden_collections: TEXT[] for managing section visibility - collection_order: TEXT[] for custom ordering - items_per_section: INT for limiting items per section - Update collections table: - user_id: Make nullable to support system-owned collections (NULL = system) - show_on_dashboard: BOOLEAN for controlling visibility - query_type: TEXT for different query types (continue-reading, recently-added, etc.) - priority: INT for display order (lower = higher priority) - is_system_collection: BOOLEAN for flagging system defaults - Update collection_items table: - Add excluded BOOLEAN for user overrides of auto-assigned items Indexes: - idx_collections_dashboard: (user_id, show_on_dashboard, priority) WHERE show_on_dashboard = true - idx_dashboard_prefs_user_library: (user_id, library_id) - idx_collection_items_excluded: (collection_id, excluded) WHERE excluded = true System Collections (pre-seeded defaults): - continue-reading: Books with 0 < progress < 1 - recently-added: Newly added items to library - recently-read: Books with progress >= 1 - not-started: Books with progress = 0 or no record This implements Phase 1 of the Carousel-style dashboard redesign plan.
This commit is contained in:
@@ -847,19 +847,43 @@ CREATE INDEX IF NOT EXISTS idx_device_file_aliases_sha256 ON device_file_aliases
|
||||
-- Create collections table (device-neutral collections)
|
||||
CREATE TABLE IF NOT EXISTS collections (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description TEXT,
|
||||
color VARCHAR(7),
|
||||
icon VARCHAR(50),
|
||||
auto_assign_rules JSONB,
|
||||
view_settings JSONB,
|
||||
show_on_dashboard BOOLEAN DEFAULT false,
|
||||
query_type TEXT DEFAULT 'filter',
|
||||
priority INT DEFAULT 100,
|
||||
is_system_collection BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(user_id, name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_collections_user_id ON collections(user_id);
|
||||
|
||||
-- Index for dashboard queries
|
||||
CREATE INDEX IF NOT EXISTS idx_collections_dashboard ON collections(user_id, show_on_dashboard, priority)
|
||||
WHERE show_on_dashboard = true;
|
||||
|
||||
-- Create user_dashboard_preferences table
|
||||
CREATE TABLE IF NOT EXISTS user_dashboard_preferences (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
library_id UUID REFERENCES libraries(id) ON DELETE CASCADE,
|
||||
hidden_collections TEXT[] DEFAULT '{}',
|
||||
collection_order TEXT[] DEFAULT '{}',
|
||||
items_per_section INT DEFAULT 20,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(user_id, library_id)
|
||||
);
|
||||
|
||||
-- Index for fast lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_dashboard_prefs_user_library ON user_dashboard_preferences(user_id, library_id);
|
||||
|
||||
-- Create collection_items table (which books belong to each collection)
|
||||
CREATE TABLE IF NOT EXISTS collection_items (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
@@ -867,12 +891,26 @@ CREATE TABLE IF NOT EXISTS collection_items (
|
||||
media_item_id UUID NOT NULL REFERENCES media_items(id) ON DELETE CASCADE,
|
||||
added_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
added_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
excluded BOOLEAN DEFAULT false,
|
||||
UNIQUE(collection_id, media_item_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_collection_items_collection ON collection_items(collection_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_collection_items_media ON collection_items(media_item_id);
|
||||
|
||||
-- Index for excluding auto-assigned items
|
||||
CREATE INDEX IF NOT EXISTS idx_collection_items_excluded ON collection_items(collection_id, excluded)
|
||||
WHERE excluded = true;
|
||||
|
||||
-- Insert 4 system collections (pre-seeded defaults)
|
||||
-- These are user_id NULL to indicate system ownership
|
||||
INSERT INTO collections (user_id, name, description, icon, color, show_on_dashboard, query_type, priority, is_system_collection, auto_assign_rules) VALUES
|
||||
(NULL, 'continue-reading', 'Books you''re currently reading (0 < progress < 1)', '📖', '#7aa2f7', true, 'continue-reading', 1, true, 'null'),
|
||||
(NULL, 'recently-added', 'Newly added items to this library', '🆕', '#9ece6a', true, 'recently-added', 2, true, 'null'),
|
||||
(NULL, 'recently-read', 'Books you''ve finished (progress >= 1)', '✅', '#e0af68', true, 'recently-read', 3, true, 'null'),
|
||||
(NULL, 'not-started', 'Books you haven''t read yet (progress = 0 or no record)', '📕', '#f7768e', true, 'not-started', 4, true, 'null')
|
||||
ON CONFLICT (user_id, name) DO NOTHING;
|
||||
|
||||
-- Create device_shelf_mappings table (map Bookhoard collections to device-specific shelf names)
|
||||
CREATE TABLE IF NOT EXISTS device_shelf_mappings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
Reference in New Issue
Block a user