feat(db): add saved_filters table and CRUD operations
Add database schema and SQL queries for generic saved filters system that allows users to save custom filter presets for any resource type. Database Schema: - Add saved_filters table with user_id, name, resource_type, filters (JSONB) - Create composite index on (user_id, resource_type) for efficient lookups - Create index on (user_id, name) for future name search feature - Add update_updated_at_column() trigger to auto-update timestamps - Make trigger creation idempotent with DROP TRIGGER IF EXISTS SQL Queries (5 new queries): - GetSavedFilters: List all filters for user + resource type - GetSavedFilterByID: Retrieve single filter by ID - CreateSavedFilter: Create new saved filter - UpdateSavedFilter: Update filter name/criteria - DeleteSavedFilter: Remove saved filter Design Decisions: - Generic resource_type field supports any resource (media-items, collections, devices) - JSONB filters field allows flexible schema without migrations - User-scoped via JWT (user_id foreign key with CASCADE delete) - Automatic updated_at timestamp via database trigger Generated Code: - database.SavedFilters model (10 fields including JSONB filters) - All 5 CRUD query functions with proper parameter types - pgtype.UUID wrappers for UUID parameters Part of: Saved Filters Implementation (Phase 1: Database) Related: #saved-filters-feature
This commit is contained in:
@@ -992,3 +992,36 @@ CREATE TABLE IF NOT EXISTS unlinked_books (
|
||||
CREATE INDEX IF NOT EXISTS idx_unlinked_books_device ON unlinked_books(device_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_unlinked_books_content_id ON unlinked_books(content_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_unlinked_books_resolved ON unlinked_books(resolved);
|
||||
|
||||
-- Create saved_filters for users to be able to filter different parts of the application
|
||||
CREATE TABLE IF NOT EXISTS saved_filters (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
resource_type TEXT NOT NULL, -- 'media-items', 'collections', 'devices', etc.
|
||||
filters JSONB NOT NULL, -- {search: "", author_filter: "", genre: "", ...}
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Index for efficient user+resource lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_saved_filters_user_resource ON saved_filters(user_id, resource_type);
|
||||
|
||||
-- Index for name searches (future feature)
|
||||
CREATE INDEX IF NOT EXISTS idx_saved_filters_name ON saved_filters(user_id, name);
|
||||
|
||||
-- Trigger to auto-update updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
DROP TRIGGER IF EXISTS update_saved_filters_updated_at ON saved_filters;
|
||||
|
||||
CREATE TRIGGER update_saved_filters_updated_at
|
||||
BEFORE UPDATE ON saved_filters
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
Reference in New Issue
Block a user