feat(dashboard): add Phase 3 database queries for Carousel-style dashboard
Add SQL queries for dashboard functionality and system collections: Dashboard Preferences Queries: - GetDashboardPreferences: Fetch user preferences for a library - UpsertDashboardPreferences: Create or update user dashboard preferences - UpdateDashboardPreferences: Update existing preferences Dashboard Collections Queries: - GetSystemCollectionsForDashboard: Fetch system collections (user_id IS NULL) - GetUserCollectionsForDashboard: Fetch user collections marked for dashboard - DeleteUserSystemCollection: Delete user's copy of a system collection System Collection Smart Queries: - GetContinueReadingItems: Books with 0 < progress < 1 - GetRecentlyAddedItems: Newly added items to library - GetRecentlyReadItems: Books with progress >= 1 - GetNotStartedItems: Books with progress = 0 or no record Collection Management Queries: - GetCollectionItemsForDashboard: Fetch collection items with excluded flag - GetLibraryItems: Fetch all items in a library These queries support the unified collections architecture where system defaults and user-created sections are both collections with user_id NULL for system-owned and NOT NULL for user-created.
This commit is contained in:
@@ -1588,3 +1588,103 @@ JOIN devices d ON ub.device_id = d.id
|
||||
WHERE ub.resolved = false
|
||||
ORDER BY ub.last_seen_at DESC
|
||||
LIMIT $1 OFFSET $2;
|
||||
|
||||
-- ============================================
|
||||
-- CAROUSEL-STYLE DASHBOARD
|
||||
-- ============================================
|
||||
|
||||
-- Dashboard preferences queries
|
||||
-- name: GetDashboardPreferences :one
|
||||
SELECT * FROM user_dashboard_preferences
|
||||
WHERE user_id = $1 AND library_id = $2;
|
||||
|
||||
-- name: UpsertDashboardPreferences :one
|
||||
INSERT INTO user_dashboard_preferences (user_id, library_id, hidden_collections, collection_order, items_per_section)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
ON CONFLICT (user_id, library_id)
|
||||
DO UPDATE SET
|
||||
hidden_collections = EXCLUDED.hidden_collections,
|
||||
collection_order = EXCLUDED.collection_order,
|
||||
items_per_section = EXCLUDED.items_per_section,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpdateDashboardPreferences :one
|
||||
UPDATE user_dashboard_preferences
|
||||
SET hidden_collections = $2,
|
||||
collection_order = $3,
|
||||
items_per_section = $4,
|
||||
updated_at = NOW()
|
||||
WHERE user_id = $1 AND library_id = $5
|
||||
RETURNING *;
|
||||
|
||||
-- Dashboard collections queries
|
||||
-- name: GetSystemCollectionsForDashboard :many
|
||||
SELECT * FROM collections
|
||||
WHERE user_id IS NULL
|
||||
AND show_on_dashboard = true
|
||||
ORDER BY priority ASC;
|
||||
|
||||
-- name: GetUserCollectionsForDashboard :many
|
||||
SELECT c.* FROM collections c
|
||||
WHERE c.user_id = $1
|
||||
AND c.show_on_dashboard = true
|
||||
AND c.is_system_collection = false
|
||||
ORDER BY priority ASC;
|
||||
|
||||
-- name: DeleteUserSystemCollection :exec
|
||||
DELETE FROM collections
|
||||
WHERE user_id = $1
|
||||
AND name = $2
|
||||
AND is_system_collection = true;
|
||||
|
||||
-- Smart section queries (for system collections)
|
||||
-- name: GetContinueReadingItems :many
|
||||
SELECT DISTINCT mi.* FROM media_items mi
|
||||
INNER JOIN reading_progress rp ON rp.media_item_id = mi.id
|
||||
WHERE mi.library_id = $1
|
||||
AND rp.user_id = $2
|
||||
AND rp.percentage > 0
|
||||
AND rp.percentage < 1
|
||||
ORDER BY rp.last_read_at DESC
|
||||
LIMIT $3;
|
||||
|
||||
-- name: GetRecentlyAddedItems :many
|
||||
SELECT mi.* FROM media_items mi
|
||||
WHERE mi.library_id = $1
|
||||
ORDER BY mi.created_at DESC
|
||||
LIMIT $2;
|
||||
|
||||
-- name: GetRecentlyReadItems :many
|
||||
SELECT DISTINCT mi.* FROM media_items mi
|
||||
INNER JOIN reading_progress rp ON rp.media_item_id = mi.id
|
||||
WHERE mi.library_id = $1
|
||||
AND rp.user_id = $2
|
||||
AND rp.percentage >= 1
|
||||
ORDER BY rp.last_read_at DESC
|
||||
LIMIT $3;
|
||||
|
||||
-- name: GetNotStartedItems :many
|
||||
SELECT mi.* FROM media_items mi
|
||||
WHERE mi.library_id = $1
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM reading_progress rp
|
||||
WHERE rp.media_item_id = mi.id
|
||||
AND rp.user_id = $2
|
||||
AND rp.percentage > 0
|
||||
)
|
||||
ORDER BY mi.created_at DESC
|
||||
LIMIT $3;
|
||||
|
||||
-- name: GetCollectionItemsForDashboard :many
|
||||
SELECT mi.*, ci.excluded FROM media_items mi
|
||||
INNER JOIN collection_items ci ON ci.media_item_id = mi.id
|
||||
WHERE ci.collection_id = $1
|
||||
AND mi.library_id = $2
|
||||
ORDER BY ci.added_at DESC
|
||||
LIMIT $3;
|
||||
|
||||
-- name: GetLibraryItems :many
|
||||
SELECT mi.* FROM media_items mi
|
||||
WHERE mi.library_id = $1
|
||||
ORDER BY mi.created_at DESC;
|
||||
|
||||
Reference in New Issue
Block a user