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:
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Job" ADD COLUMN "downloadProgress" DOUBLE PRECISION NOT NULL DEFAULT 0;
|
||||
+12
-11
@@ -43,17 +43,18 @@ model Request {
|
||||
}
|
||||
|
||||
model Job {
|
||||
id String @id @default(cuid())
|
||||
request Request @relation(fields: [requestId], references: [id], onDelete: Cascade)
|
||||
requestId String @unique
|
||||
state JobState @default(requested)
|
||||
currentStage String @default("intake")
|
||||
attempts Int @default(0)
|
||||
error String?
|
||||
claimedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
candidates Candidate[]
|
||||
id String @id @default(cuid())
|
||||
request Request @relation(fields: [requestId], references: [id], onDelete: Cascade)
|
||||
requestId String @unique
|
||||
state JobState @default(requested)
|
||||
currentStage String @default("intake")
|
||||
attempts Int @default(0)
|
||||
error String?
|
||||
claimedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
downloadProgress Float @default(0)
|
||||
candidates Candidate[]
|
||||
}
|
||||
|
||||
model Candidate {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user