Files
homelab/apps/harness/src/app/api/models/curated/route.ts
Julia McGhee 3fe75a8e04
Some checks failed
CI / lint-and-test (push) Successful in 22s
Deploy Production / deploy (push) Failing after 21s
CI / build (push) Failing after 1m51s
Migrate harness from in-memory stores to CloudNativePG
Replace all in-memory Map-backed stores (credentials, models, agents,
tasks, iterations, usage) with Drizzle ORM queries against the
homelab-pg PostgreSQL cluster. All store functions are now async.

- Add 6 harness_* tables to @homelab/db schema
- Generate and apply initial Drizzle migration
- Add lazy DB connection proxy to avoid build-time errors
- Wire DATABASE_URL from sealed secret into harness deployment
- Update all API routes, orchestrator, executor, and boot to await
  async store operations
2026-03-21 20:17:08 +00:00

55 lines
1.8 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import {
getCuratedModels,
getEnabledModels,
upsertCuratedModel,
removeCuratedModel,
toggleModelEnabled,
updateModelCost,
CuratedModel,
} from "@/lib/model-store";
export async function GET(request: NextRequest) {
const enabledOnly = request.nextUrl.searchParams.get("enabled") === "true";
return NextResponse.json(enabledOnly ? await getEnabledModels() : await getCuratedModels());
}
export async function POST(request: NextRequest) {
const body = await request.json();
if (body.action === "toggle" && body.id) {
const result = await toggleModelEnabled(body.id);
if (!result) return NextResponse.json({ error: "not found" }, { status: 404 });
return NextResponse.json(result);
}
if (body.action === "update-cost" && body.id) {
const result = await updateModelCost(body.id, body.costPer1kInput, body.costPer1kOutput);
if (!result) return NextResponse.json({ error: "not found" }, { status: 404 });
return NextResponse.json(result);
}
if (!body.id || !body.provider) {
return NextResponse.json({ error: "id and provider are required" }, { status: 400 });
}
const model: CuratedModel = {
id: body.id,
name: body.name || body.id,
provider: body.provider,
enabled: body.enabled ?? true,
contextWindow: body.contextWindow,
costPer1kInput: body.costPer1kInput,
costPer1kOutput: body.costPer1kOutput,
};
return NextResponse.json(await upsertCuratedModel(model), { status: 201 });
}
export async function DELETE(request: NextRequest) {
const id = request.nextUrl.searchParams.get("id");
if (!id) return NextResponse.json({ error: "id required" }, { status: 400 });
await removeCuratedModel(id);
return NextResponse.json({ ok: true });
}