From b0d0202eb8bd96938cd3e2c60e26095fa723fc66 Mon Sep 17 00:00:00 2001 From: vegard Date: Mon, 16 Mar 2026 07:08:17 +0100 Subject: [PATCH] =?UTF-8?q?AI-admin:=20fiks=20provider-swap=20ved=20=C3=A5?= =?UTF-8?q?=20droppe=20UNIQUE-constraint=20p=C3=A5=20prioritet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fjernet UNIQUE(alias_id, priority) — prioritet er kun for sortering - Forenklet swap-endpoint til to rene UPDATE-statements - Renummerert kjapp-providers til sekvensielle prioriteter Co-Authored-By: Claude Opus 4.6 --- migrations/0013_drop_priority_unique.sql | 10 ++++++ .../api/admin/ai/providers/swap/+server.ts | 36 ++++++------------- 2 files changed, 21 insertions(+), 25 deletions(-) create mode 100644 migrations/0013_drop_priority_unique.sql diff --git a/migrations/0013_drop_priority_unique.sql b/migrations/0013_drop_priority_unique.sql new file mode 100644 index 0000000..3f5768d --- /dev/null +++ b/migrations/0013_drop_priority_unique.sql @@ -0,0 +1,10 @@ +-- 0013_drop_priority_unique.sql +-- Fjern UNIQUE-constraint på (alias_id, priority). +-- Prioritet brukes kun for sortering/fallback-rekkefølge, ikke som naturlig nøkkel. +-- Constrainten hindrer atomisk swap og krever unødvendig kompleksitet. + +BEGIN; + +ALTER TABLE ai_model_providers DROP CONSTRAINT IF EXISTS ai_model_providers_alias_id_priority_key; + +COMMIT; diff --git a/web/src/routes/api/admin/ai/providers/swap/+server.ts b/web/src/routes/api/admin/ai/providers/swap/+server.ts index d24451a..234516a 100644 --- a/web/src/routes/api/admin/ai/providers/swap/+server.ts +++ b/web/src/routes/api/admin/ai/providers/swap/+server.ts @@ -2,43 +2,29 @@ import { json, error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { sql } from '$lib/server/db'; -/** POST — bytt prioritet mellom to providers (atomisk) */ +/** POST — bytt prioritet mellom to providers */ export const POST: RequestHandler = async ({ request, locals }) => { if (!locals.workspace || !locals.user) error(401); const { id_a, id_b } = await request.json(); if (!id_a || !id_b) error(400, 'id_a og id_b kreves'); - // Atomisk swap via CTE — unngår UNIQUE-constraint-brudd - const rows = await sql` - WITH swap AS ( - SELECT - a.id AS id_a, a.priority AS pri_a, - b.id AS id_b, b.priority AS pri_b - FROM ai_model_providers a, ai_model_providers b - WHERE a.id = ${id_a}::uuid AND b.id = ${id_b}::uuid - AND a.alias_id = b.alias_id - ), - update_a AS ( - UPDATE ai_model_providers SET priority = -1, updated_at = now() - WHERE id = (SELECT id_a FROM swap) - ), - update_b AS ( - UPDATE ai_model_providers SET priority = (SELECT pri_a FROM swap), updated_at = now() - WHERE id = (SELECT id_b FROM swap) - ) - UPDATE ai_model_providers SET priority = (SELECT pri_b FROM swap), updated_at = now() - WHERE id = (SELECT id_a FROM swap) - RETURNING id - `; + // Hent begge providers + const [a] = await sql`SELECT id, alias_id, priority FROM ai_model_providers WHERE id = ${id_a}::uuid`; + const [b] = await sql`SELECT id, alias_id, priority FROM ai_model_providers WHERE id = ${id_b}::uuid`; - if (rows.length === 0) error(400, 'Kunne ikke bytte — sjekk at begge tilhører samme alias'); + if (!a || !b) error(404, 'Provider ikke funnet'); + if (a.alias_id !== b.alias_id) error(400, 'Providers tilhører ikke samme alias'); + + // Bytt prioriteter + await sql`UPDATE ai_model_providers SET priority = ${b.priority}, updated_at = now() WHERE id = ${a.id}`; + await sql`UPDATE ai_model_providers SET priority = ${a.priority}, updated_at = now() WHERE id = ${b.id}`; // Returner oppdaterte providers for aliaset const updated = await sql` SELECT id, alias_id, priority, litellm_model, api_key_env, is_active, extra_params FROM ai_model_providers - WHERE alias_id = (SELECT alias_id FROM ai_model_providers WHERE id = ${id_a}::uuid) + WHERE alias_id = ${a.alias_id} ORDER BY priority ASC `;