feat: track download progress on Job (migration + worker poller + API)

Add Job.downloadProgress (0.0-1.0), derived from a worker background
poller that counts audio files landing in staging / expected track
count, since streamrip only reports 0/1. No UI yet (slice B).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-13 23:23:15 +02:00
parent 52e74f7709
commit 9d5e1ff58a
7 changed files with 120 additions and 22 deletions
+11 -1
View File
@@ -62,7 +62,15 @@ describe("requests API", () => {
data: {
artist: "Chosen Artist",
album: "Chosen Album",
job: { create: { state: "downloading", currentStage: "download", attempts: 2, error: "boom" } },
job: {
create: {
state: "downloading",
currentStage: "download",
attempts: 2,
error: "boom",
downloadProgress: 0.42,
},
},
},
include: { job: true },
});
@@ -99,6 +107,7 @@ describe("requests API", () => {
expect(found.job.chosen).toEqual({ source: "qobuz", format: "flac", trackCount: 12 });
expect(found.job.error).toBe("boom");
expect(found.job.attempts).toBe(2);
expect(found.job.downloadProgress).toBe(0.42);
});
it("reports no chosen candidate and zero count when a job has none", async () => {
@@ -109,5 +118,6 @@ describe("requests API", () => {
const found = body.requests.find((r: { id: string }) => r.id === created.id);
expect(found.job.candidateCount).toBe(0);
expect(found.job.chosen).toBeNull();
expect(found.job.downloadProgress).toBe(0);
});
});
+1
View File
@@ -63,6 +63,7 @@ export async function GET() {
error: r.job.error,
claimedAt: r.job.claimedAt,
updatedAt: r.job.updatedAt,
downloadProgress: r.job.downloadProgress,
candidateCount: cands.length,
chosen: chosen ? { source: chosen.source, format: chosen.format, trackCount: chosen.trackCount } : null,
};