diff --git a/packages/gittensory-miner/lib/portfolio-queue.js b/packages/gittensory-miner/lib/portfolio-queue.js index 09181edfd3..b24fbce00d 100644 --- a/packages/gittensory-miner/lib/portfolio-queue.js +++ b/packages/gittensory-miner/lib/portfolio-queue.js @@ -109,6 +109,7 @@ export function initPortfolioQueueStore(dbPath = resolvePortfolioQueueDbPath()) ON CONFLICT(repo_full_name, identifier) DO UPDATE SET priority = excluded.priority, status = 'queued' + WHERE miner_portfolio_queue.status <> 'in_progress' `); const getStatement = db.prepare( "SELECT * FROM miner_portfolio_queue WHERE repo_full_name = ? AND identifier = ?", diff --git a/test/unit/miner-portfolio-queue.test.ts b/test/unit/miner-portfolio-queue.test.ts index 2470e88eca..c4ac989a8c 100644 --- a/test/unit/miner-portfolio-queue.test.ts +++ b/test/unit/miner-portfolio-queue.test.ts @@ -108,6 +108,17 @@ describe("gittensory-miner portfolio/queue store (#2292)", () => { expect(store.dequeueNext()?.identifier).toBe("1"); // re-queued → dequeuable again }); + it("re-enqueue does not demote an in-progress item back to queued", () => { + const store = tempStore(); + store.enqueue({ repoFullName: "o/a", identifier: "work", priority: 1 }); + expect(store.dequeueNext()).toMatchObject({ identifier: "work", status: "in_progress", priority: 1 }); + expect(store.enqueue({ repoFullName: "o/a", identifier: "work", priority: 99 })).toMatchObject({ + identifier: "work", + status: "in_progress", + priority: 1, + }); + }); + it("re-enqueue keeps an item's FIFO position (no queue-jumping) even when timestamps collide", () => { // Freeze the clock so A and B share an enqueued_at — the case where a restamp-vs-rowid inconsistency would show. vi.useFakeTimers();