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:
2026-03-21 00:16:05 -04:00
parent a63394f429
commit e17a96123f
5 changed files with 222 additions and 0 deletions
+5
View File
@@ -72,6 +72,7 @@ type Querier interface {
CreateReadingHistory(ctx context.Context, arg CreateReadingHistoryParams) (ReadingHistory, error)
// Refresh Tokens queries
CreateRefreshToken(ctx context.Context, arg CreateRefreshTokenParams) (RefreshTokens, error)
CreateSavedFilter(ctx context.Context, arg CreateSavedFilterParams) (SavedFilters, error)
// Conflict Resolution
CreateSyncConflict(ctx context.Context, arg CreateSyncConflictParams) (SyncConflicts, error)
CreateSyncHistoryEntry(ctx context.Context, arg CreateSyncHistoryEntryParams) (SyncQueue, error)
@@ -104,6 +105,7 @@ type Querier interface {
DeleteMediaNote(ctx context.Context, id pgtype.UUID) error
DeleteMediaRating(ctx context.Context, arg DeleteMediaRatingParams) error
DeleteReadingProgress(ctx context.Context, arg DeleteReadingProgressParams) error
DeleteSavedFilter(ctx context.Context, arg DeleteSavedFilterParams) error
DeleteSyncConflict(ctx context.Context, id pgtype.UUID) error
DeleteSyncQueueItem(ctx context.Context, id pgtype.UUID) error
// Delete system config
@@ -212,6 +214,8 @@ type Querier interface {
GetRecentlyAddedItems(ctx context.Context, arg GetRecentlyAddedItemsParams) ([]MediaItems, error)
GetRecentlyReadItems(ctx context.Context, arg GetRecentlyReadItemsParams) ([]MediaItems, error)
GetRefreshToken(ctx context.Context, token pgtype.UUID) (GetRefreshTokenRow, error)
GetSavedFilterByID(ctx context.Context, arg GetSavedFilterByIDParams) (SavedFilters, error)
GetSavedFilters(ctx context.Context, arg GetSavedFiltersParams) ([]SavedFilters, error)
GetStuckSyncQueueItems(ctx context.Context) ([]SyncQueue, error)
GetSyncConflict(ctx context.Context, id pgtype.UUID) (SyncConflicts, error)
GetSyncQueueItem(ctx context.Context, id pgtype.UUID) (SyncQueue, error)
@@ -328,6 +332,7 @@ type Querier interface {
UpdateMediaRating(ctx context.Context, arg UpdateMediaRatingParams) (MediaRatings, error)
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
UpdateReadingProgress(ctx context.Context, arg UpdateReadingProgressParams) (ReadingProgress, error)
UpdateSavedFilter(ctx context.Context, arg UpdateSavedFilterParams) (SavedFilters, error)
UpdateSyncQueueItemStatus(ctx context.Context, arg UpdateSyncQueueItemStatusParams) (SyncQueue, error)
UpdateSystemSetting(ctx context.Context, arg UpdateSystemSettingParams) error
// Update universal progress