Files
minstrel/internal/db/queries/admin_summary.sql
T
bvandeusenandClaude Opus 5.5 ace7e22e6a
release / govulncheck (push) Successful in 15s
release / web (push) Successful in 1m21s
release / go (push) Successful in 1m37s
release / integration (push) Successful in 5m10s
release / android (push) Successful in 5m16s
release / Build signed APK (releases and dev) (push) Successful in 5m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 24s
release / Verify release artifacts (tag releases only) (push) Skipped
feat: Admin is a left rail with how many wait on you in each queue, and the Overview opens with a verdict, the queues that need you and since when, then the clear ones on one line (M503 #5605)
- GET /api/admin/summary: every admin queue (requests, reported tracks,
  playback errors, duplicates, suspect sources, missing files) with its
  count and the age of its oldest item, in one query.
- The admin layout drops the 11-tab strip for SectionRail, as Settings and
  the Collection have, with each queue's count as its badge; the counts
  refresh on each admin navigation and every 30s.
- The Overview leads with "Nothing needs you." or "N things need you.",
  lists each waiting queue with "oldest 3d ago" and a link to it, counts a
  failed library scan as a problem, and names the empty queues on one line.
  The request and quarantine previews and the stat tiles are gone; those
  queues are worked on their own pages. A failed summary says so with Try
  again instead of reading as all-clear.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 09:58:13 -04:00

24 lines
1.9 KiB
SQL

-- name: AdminSummary :one
-- What the admin rail and the Overview's verdict read (#5605): each queue
-- that waits on a person, with how many and since when. One round trip, so
-- the rail costs one cheap read on every admin page. The "since" is the
-- oldest item still waiting: how long the queue has been left, which is what
-- tells the operator a count of 2 is fine today and wrong after a month.
SELECT
(SELECT count(*) FROM requests WHERE status = 'pending')::bigint AS requests,
(SELECT min(requested_at) FROM requests WHERE status = 'pending')::timestamptz AS requests_since,
(SELECT count(DISTINCT track_id) FROM lidarr_quarantine)::bigint AS quarantined,
(SELECT min(created_at) FROM lidarr_quarantine)::timestamptz AS quarantined_since,
(SELECT count(*) FROM playback_errors WHERE resolved_at IS NULL)::bigint AS playback_errors,
(SELECT min(occurred_at) FROM playback_errors WHERE resolved_at IS NULL)::timestamptz AS playback_errors_since,
(SELECT count(*) FROM duplicate_groups g
WHERE g.status = 'pending'
AND (SELECT count(*) FROM duplicate_group_members m WHERE m.group_id = g.id) >= 2)::bigint AS duplicates,
(SELECT min(g.detected_at) FROM duplicate_groups g
WHERE g.status = 'pending'
AND (SELECT count(*) FROM duplicate_group_members m WHERE m.group_id = g.id) >= 2)::timestamptz AS duplicates_since,
(SELECT count(*) FROM tracks WHERE source_verdict = 'suspect' AND missing_since IS NULL)::bigint AS suspect,
(SELECT min(source_verdict_at) FROM tracks WHERE source_verdict = 'suspect' AND missing_since IS NULL)::timestamptz AS suspect_since,
(SELECT count(*) FROM tracks WHERE missing_since IS NOT NULL)::bigint AS missing,
(SELECT min(missing_since) FROM tracks WHERE missing_since IS NOT NULL)::timestamptz AS missing_since;