Förslag-sidan: typ-knappar i vänsterspalten, alla fynd nyast först
All checks were successful
build-and-push / build (push) Successful in 12s

Tre knappar (Artister & album / Låtar / Genrer) ersätter batch-listan;
huvudspalten visar alla cachade fynd av vald typ i tidsordning med
nyast först, grupperade per körning med datum-avdelare. Nytt API
GET /api/suggest/items?type=X (plattar batcher med batch-metadata).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
This commit is contained in:
2026-08-01 03:07:54 +02:00
parent dca6d3ab24
commit 4e89bd1986
4 changed files with 85 additions and 39 deletions

View File

@@ -235,6 +235,11 @@ export function buildApp(config, deps = {}) {
}
})
app.get('/api/suggest/items', async (req) => {
const type = SUGGEST_TYPES.includes(req.query.type) ? req.query.type : 'mix'
return suggest.allItems(type)
})
app.get('/api/suggest/batches', async () => {
return suggest.loadBatches().map((b) => ({
id: b.id,

View File

@@ -355,6 +355,16 @@ export function suggestEngine({ config, store, lidarr, fetchImpl = fetch }) {
return items.slice(0, limit)
},
// alla fynd av en typ, nyast först, med batch-metadata för gruppering
allItems(type = 'mix', limit = 500) {
return loadBatches()
.filter((b) => (b.type ?? 'mix') === type)
.flatMap((b) =>
b.items.map((it) => ({ ...it, batchId: b.id, batchCreatedAt: b.createdAt, trigger: b.trigger })),
)
.slice(0, limit)
},
lastRun(type = 'mix') {
return loadBatches().find((b) => (b.type ?? 'mix') === type)?.createdAt ?? null
},

View File

@@ -103,6 +103,18 @@ test('run: batch-id räknas upp och latest tar nyaste först', async () => {
assert.equal(engine.loadBatches()[0].id, b2.id)
})
test('allItems: plattar batcher nyast först med batch-metadata', async () => {
const { engine } = setup()
const b1 = await engine.run()
const b2 = await engine.run()
const all = engine.allItems('mix')
assert.equal(all.length, 2)
assert.equal(all[0].batchId, b2.id, 'nyaste batchens fynd först')
assert.equal(all[1].batchId, b1.id)
assert.equal(all[0].batchCreatedAt, b2.createdAt)
assert.equal(engine.allItems('tracks').length, 0)
})
test('run: markdown-staket runt JSON hanteras', async () => {
const { engine } = setup({
geminiResponse: '```json\n[{"type":"artist","name":"Ghost","motivation":"x"}]\n```',