feat(database): add analytics and book matching queries
Add analytics queries: - GetUserReadingHistory: detailed reading history with device info - GetUserDeviceUsage: device usage statistics (sync count, time spent) - GetPopularBooks: most read books with completion rates Add book matching queries: - GetUnlinkedBookByID: fetch single unlinked book - DeleteUnlinkedBook: remove resolved unlinked book - ListUnresolvedUnlinkedBooks: paginated list of unresolved books
This commit is contained in:
@@ -627,7 +627,66 @@ INSERT INTO reading_history (
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
RETURNING *;
|
||||
|
||||
-- ============================================
|
||||
-- Analytics queries
|
||||
|
||||
-- Get user reading history for analytics
|
||||
-- name: GetUserReadingHistory :many
|
||||
SELECT
|
||||
rh.id,
|
||||
rh.user_id,
|
||||
rh.media_item_id,
|
||||
rh.device_id,
|
||||
rh.progress_percentage,
|
||||
rh.reading_session_start,
|
||||
rh.reading_session_end,
|
||||
rh.pages_read,
|
||||
rh.time_spent_seconds,
|
||||
rh.device_metadata,
|
||||
rh.created_at,
|
||||
mi.title,
|
||||
mi.author,
|
||||
d.device_name,
|
||||
d.device_type
|
||||
FROM reading_history rh
|
||||
JOIN media_items mi ON rh.media_item_id = mi.id
|
||||
LEFT JOIN devices d ON rh.device_id = d.id
|
||||
WHERE rh.user_id = $1
|
||||
AND rh.created_at >= $2
|
||||
AND rh.created_at <= $3
|
||||
ORDER BY rh.created_at DESC;
|
||||
|
||||
-- Get user device usage statistics
|
||||
-- name: GetUserDeviceUsage :many
|
||||
SELECT
|
||||
d.id,
|
||||
d.device_name,
|
||||
d.device_type,
|
||||
COUNT(*) as sync_count,
|
||||
MAX(rh.created_at) as last_sync,
|
||||
SUM(rh.time_spent_seconds) as total_time_seconds
|
||||
FROM devices d
|
||||
JOIN reading_history rh ON rh.device_id = d.id
|
||||
WHERE d.user_id = $1
|
||||
GROUP BY d.id, d.device_name, d.device_type
|
||||
ORDER BY sync_count DESC;
|
||||
|
||||
-- Get most popular books for a user
|
||||
-- name: GetPopularBooks :many
|
||||
SELECT
|
||||
mi.id,
|
||||
mi.title,
|
||||
mi.author,
|
||||
COUNT(*) as read_count,
|
||||
AVG(rh.progress_percentage) as avg_completion,
|
||||
MAX(rh.created_at) as last_read
|
||||
FROM media_items mi
|
||||
JOIN reading_history rh ON rh.media_item_id = mi.id
|
||||
WHERE rh.user_id = $1
|
||||
GROUP BY mi.id, mi.title, mi.author
|
||||
ORDER BY read_count DESC
|
||||
LIMIT $2;
|
||||
|
||||
-- ============================================
|
||||
-- PHASE 2: DEVICE MANAGEMENT & AUTH (Weeks 5-6)
|
||||
-- ============================================
|
||||
|
||||
@@ -818,12 +877,19 @@ RETURNING *;
|
||||
-- name: DeleteSyncConflict :exec
|
||||
DELETE FROM sync_conflicts WHERE id = $1;
|
||||
|
||||
-- name: ListAllConflictsByUserAndStatus :many
|
||||
SELECT sc.*, mi.title, mi.author
|
||||
FROM sync_conflicts sc
|
||||
JOIN media_items mi ON sc.media_item_id = mi.id
|
||||
WHERE sc.user_id = $1 AND sc.resolution_status = $2
|
||||
ORDER BY sc.created_at DESC;
|
||||
-- name: ListAllConflictsByUserAndStatus :many
|
||||
SELECT sc.*, mi.title, mi.author
|
||||
FROM sync_conflicts sc
|
||||
JOIN media_items mi ON sc.media_item_id = mi.id
|
||||
WHERE sc.user_id = $1 AND sc.resolution_status = $2
|
||||
ORDER BY sc.created_at DESC;
|
||||
|
||||
-- name: ListConflictsByUser :many
|
||||
SELECT sc.*, mi.title, mi.author
|
||||
FROM sync_conflicts sc
|
||||
JOIN media_items mi ON sc.media_item_id = mi.id
|
||||
WHERE sc.user_id = $1
|
||||
ORDER BY sc.created_at DESC;
|
||||
|
||||
-- ============================================
|
||||
-- PHASE 3: KOREADER SYNC PROTOCOL (Weeks 7-9)
|
||||
@@ -1467,4 +1533,21 @@ SET
|
||||
resolved_at = NOW(),
|
||||
resolution_method = 'manual_link'
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
RETURNING *;
|
||||
|
||||
-- Get unlinked book by ID
|
||||
-- name: GetUnlinkedBookByID :one
|
||||
SELECT * FROM unlinked_books WHERE id = $1;
|
||||
|
||||
-- Delete unlinked book
|
||||
-- name: DeleteUnlinkedBook :exec
|
||||
DELETE FROM unlinked_books WHERE id = $1;
|
||||
|
||||
-- List unresolved unlinked books with pagination
|
||||
-- name: ListUnresolvedUnlinkedBooks :many
|
||||
SELECT ub.*, d.device_name, d.device_type
|
||||
FROM unlinked_books ub
|
||||
JOIN devices d ON ub.device_id = d.id
|
||||
WHERE ub.resolved = false
|
||||
ORDER BY ub.last_seen_at DESC
|
||||
LIMIT $1 OFFSET $2;
|
||||
Reference in New Issue
Block a user