feat(discovery): GET/PATCH /api/discover/config
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { prisma } from "@/lib/db";
|
||||||
|
import { GET, PATCH } from "./route";
|
||||||
|
|
||||||
|
function patch(body: unknown) {
|
||||||
|
return PATCH(new Request("http://localhost/api/discover/config", {
|
||||||
|
method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify(body),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("discover config API", () => {
|
||||||
|
it("GET returns defaults when nothing is stored", async () => {
|
||||||
|
const body = await (await GET()).json();
|
||||||
|
expect(body).toMatchObject({
|
||||||
|
"discover.enabled": "false", "discover.intervalHours": "168",
|
||||||
|
"discover.maxSeeds": "50", "discover.similarPerSeed": "20",
|
||||||
|
"discover.albumsPerArtist": "1", "discover.minScore": "0",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("PATCH upserts known keys and ignores unknown ones", async () => {
|
||||||
|
const res = await patch({ "discover.enabled": "true", "discover.maxSeeds": 25, "nope": "x" });
|
||||||
|
expect((await res.json()).updated).toBe(2);
|
||||||
|
const body = await (await GET()).json();
|
||||||
|
expect(body["discover.enabled"]).toBe("true");
|
||||||
|
expect(body["discover.maxSeeds"]).toBe("25");
|
||||||
|
expect(await prisma.config.findUnique({ where: { key: "nope" } })).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { prisma } from "@/lib/db";
|
||||||
|
|
||||||
|
const DEFAULTS: Record<string, string> = {
|
||||||
|
"discover.enabled": "false",
|
||||||
|
"discover.intervalHours": "168",
|
||||||
|
"discover.maxSeeds": "50",
|
||||||
|
"discover.similarPerSeed": "20",
|
||||||
|
"discover.albumsPerArtist": "1",
|
||||||
|
"discover.minScore": "0",
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
const rows = await prisma.config.findMany({ where: { key: { in: Object.keys(DEFAULTS) } } });
|
||||||
|
const stored = Object.fromEntries(rows.map((r) => [r.key, r.value]));
|
||||||
|
return Response.json(
|
||||||
|
Object.fromEntries(Object.entries(DEFAULTS).map(([k, d]) => [k, stored[k] ?? d])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function PATCH(request: Request) {
|
||||||
|
let body: unknown;
|
||||||
|
try {
|
||||||
|
body = await request.json();
|
||||||
|
} catch {
|
||||||
|
return Response.json({ error: "invalid JSON" }, { status: 400 });
|
||||||
|
}
|
||||||
|
const entries = Object.entries((body ?? {}) as Record<string, unknown>).filter(
|
||||||
|
([k]) => k in DEFAULTS,
|
||||||
|
);
|
||||||
|
for (const [key, value] of entries) {
|
||||||
|
await prisma.config.upsert({
|
||||||
|
where: { key },
|
||||||
|
create: { key, value: String(value), secret: false },
|
||||||
|
update: { value: String(value) },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Response.json({ updated: entries.length });
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user