feat(requests): show ingest progress while requests are in flight
After Lidarr accepts a request the local reconciler imports albums and
tracks as they arrive — but until the request hit 'completed' the
operator had no way to see "is anything happening?" The /requests and
/admin/requests rows now surface a live progress line whenever the
request's matched entity has children in our library.
Backend:
- New CountAlbumsByArtist + CountTracksByArtist sqlc queries.
- requestView gains imported_album_count and imported_track_count.
- New fillProgress helper computes them from the matched entity:
- kind=artist → counts albums + tracks under matched_artist_id
- kind=album → counts tracks under matched_album_id
- kind=track → 1 once matched_track_id is set
N+1 in the list endpoints; acceptable at admin scale.
- handleListRequests, handleGetRequest, and handleListAdminRequests
populate the new fields on every response.
Frontend:
- LidarrRequest TS type extended with the two counters.
- Both the operator's /requests page and the admin /admin/requests
page render an accent-colored line under the row meta when at
least one counter is non-zero, e.g.:
Artist: "5 albums · 47 tracks ingested"
Album: "12 tracks ingested"
Track: "Track ingested"
- Updated test fixtures to include the new required fields.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,19 @@ func (q *Queries) CountAlbums(ctx context.Context) (int64, error) {
|
||||
return count, err
|
||||
}
|
||||
|
||||
const countAlbumsByArtist = `-- name: CountAlbumsByArtist :one
|
||||
SELECT COUNT(*) FROM albums WHERE artist_id = $1
|
||||
`
|
||||
|
||||
// Used by request-progress reporting to count how many albums have been
|
||||
// ingested for a matched artist while a request is still in flight.
|
||||
func (q *Queries) CountAlbumsByArtist(ctx context.Context, artistID pgtype.UUID) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, countAlbumsByArtist, artistID)
|
||||
var count int64
|
||||
err := row.Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
const countAlbumsMatching = `-- name: CountAlbumsMatching :one
|
||||
SELECT COUNT(*) FROM albums WHERE title ILIKE '%' || $1::text || '%'
|
||||
`
|
||||
|
||||
@@ -22,6 +22,20 @@ func (q *Queries) CountTracksByAlbum(ctx context.Context, albumID pgtype.UUID) (
|
||||
return count, err
|
||||
}
|
||||
|
||||
const countTracksByArtist = `-- name: CountTracksByArtist :one
|
||||
SELECT COUNT(*) FROM tracks WHERE artist_id = $1
|
||||
`
|
||||
|
||||
// Used by request-progress reporting to count tracks ingested under a
|
||||
// matched artist (sum across all the artist's albums) while a request
|
||||
// is still in flight.
|
||||
func (q *Queries) CountTracksByArtist(ctx context.Context, artistID pgtype.UUID) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, countTracksByArtist, artistID)
|
||||
var count int64
|
||||
err := row.Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
const countTracksMatching = `-- name: CountTracksMatching :one
|
||||
SELECT COUNT(*) FROM tracks WHERE title ILIKE '%' || $1::text || '%'
|
||||
`
|
||||
|
||||
@@ -80,3 +80,8 @@ LIMIT $1 OFFSET $2;
|
||||
-- name: CountAlbums :one
|
||||
-- M6a: total album count for the /api/library/albums envelope.
|
||||
SELECT COUNT(*) FROM albums;
|
||||
|
||||
-- name: CountAlbumsByArtist :one
|
||||
-- Used by request-progress reporting to count how many albums have been
|
||||
-- ingested for a matched artist while a request is still in flight.
|
||||
SELECT COUNT(*) FROM albums WHERE artist_id = $1;
|
||||
|
||||
@@ -90,3 +90,9 @@ WHERE t.artist_id = $1
|
||||
)
|
||||
ORDER BY albums.release_date NULLS LAST, albums.sort_title,
|
||||
t.disc_number NULLS FIRST, t.track_number NULLS FIRST, t.id;
|
||||
|
||||
-- name: CountTracksByArtist :one
|
||||
-- Used by request-progress reporting to count tracks ingested under a
|
||||
-- matched artist (sum across all the artist's albums) while a request
|
||||
-- is still in flight.
|
||||
SELECT COUNT(*) FROM tracks WHERE artist_id = $1;
|
||||
|
||||
Reference in New Issue
Block a user