mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
ad1906589d
Drop the `chat_model_configs.provider -> chat_providers.provider` foreign key and soft-delete model configs when their provider is removed. The provider row is now hard-deleted inside a transaction that also tombstones its model configs and promotes a replacement default when needed. Historical chats and messages keep pointing at the soft-deleted model config rows, which are hidden from live/admin queries but still resolve for read. The runtime chat path already falls back to the default model config when a soft-deleted config is looked up. Replaces the lost FK validation in the create/update model-config handlers with an explicit provider lookup that returns the existing `Chat provider is not configured.` 400. ## UX **Admin deleting a chat provider that has historical usage** - Before: blocked with 400 `Provider models are still referenced by existing chats.` Admins had no in-product way to remove a provider that had ever been used. - After: delete succeeds (204). Any model configs under that provider are soft-deleted. If the removed provider owned the default model config, one of the remaining live configs is auto-promoted to the new default. The promotion is deterministic (`ensureDefaultChatModelConfig` picks the first live config by `provider ASC, model ASC, updated_at DESC, id DESC`); there is no picker, and no toast or response detail names which config became the new default. **End users with chats that used a deleted provider's model** - Old chats still open and their history still renders unchanged. - Sending a new turn in such a chat silently falls back to the current default model. No banner or warning tells the user the original model is gone. - The model picker no longer lists the deleted model. - If no default model config exists at all after the delete, sending a new turn fails with `no default chat model config is available`. **Admin creating or updating a model config against a provider that is not configured** - Same as before: 400 `Chat provider is not configured.` Only the detection mechanism changed (explicit `FOR UPDATE` lookup inside the transaction, which also serializes against a concurrent provider delete). **Admin updating a model config whose row disappears mid-transaction** - Now returns the standard 404 `Resource not found or you do not have access to this resource` instead of the previous 500 that leaked `sql: no rows in result set` in the detail. Unrelated internal races (for example a race on the promoted default candidate) are still reported as 500 so they are not misclassified as "your target is gone". Closes CODAGT-23
103 lines
1.9 KiB
SQL
103 lines
1.9 KiB
SQL
-- name: GetChatProviderByID :one
|
|
SELECT
|
|
*
|
|
FROM
|
|
chat_providers
|
|
WHERE
|
|
id = @id::uuid;
|
|
|
|
-- name: GetChatProviderByIDForUpdate :one
|
|
SELECT
|
|
*
|
|
FROM
|
|
chat_providers
|
|
WHERE
|
|
id = @id::uuid
|
|
FOR UPDATE;
|
|
|
|
-- name: GetChatProviderByProvider :one
|
|
SELECT
|
|
*
|
|
FROM
|
|
chat_providers
|
|
WHERE
|
|
provider = @provider::text;
|
|
|
|
-- name: GetChatProviderByProviderForUpdate :one
|
|
SELECT
|
|
*
|
|
FROM
|
|
chat_providers
|
|
WHERE
|
|
provider = @provider::text
|
|
FOR UPDATE;
|
|
|
|
-- name: GetChatProviders :many
|
|
SELECT
|
|
*
|
|
FROM
|
|
chat_providers
|
|
ORDER BY
|
|
provider ASC;
|
|
|
|
-- name: GetEnabledChatProviders :many
|
|
SELECT
|
|
*
|
|
FROM
|
|
chat_providers
|
|
WHERE
|
|
enabled = TRUE
|
|
ORDER BY
|
|
provider ASC;
|
|
|
|
-- name: InsertChatProvider :one
|
|
INSERT INTO chat_providers (
|
|
provider,
|
|
display_name,
|
|
api_key,
|
|
base_url,
|
|
api_key_key_id,
|
|
created_by,
|
|
enabled,
|
|
central_api_key_enabled,
|
|
allow_user_api_key,
|
|
allow_central_api_key_fallback
|
|
) VALUES (
|
|
@provider::text,
|
|
@display_name::text,
|
|
@api_key::text,
|
|
@base_url::text,
|
|
sqlc.narg('api_key_key_id')::text,
|
|
sqlc.narg('created_by')::uuid,
|
|
@enabled::boolean,
|
|
@central_api_key_enabled::boolean,
|
|
@allow_user_api_key::boolean,
|
|
@allow_central_api_key_fallback::boolean
|
|
)
|
|
RETURNING
|
|
*;
|
|
|
|
-- name: UpdateChatProvider :one
|
|
UPDATE
|
|
chat_providers
|
|
SET
|
|
display_name = @display_name::text,
|
|
api_key = @api_key::text,
|
|
base_url = @base_url::text,
|
|
api_key_key_id = sqlc.narg('api_key_key_id')::text,
|
|
enabled = @enabled::boolean,
|
|
central_api_key_enabled = @central_api_key_enabled::boolean,
|
|
allow_user_api_key = @allow_user_api_key::boolean,
|
|
allow_central_api_key_fallback = @allow_central_api_key_fallback::boolean,
|
|
updated_at = NOW()
|
|
WHERE
|
|
id = @id::uuid
|
|
RETURNING
|
|
*;
|
|
|
|
-- name: DeleteChatProviderByID :exec
|
|
DELETE FROM
|
|
chat_providers
|
|
WHERE
|
|
id = @id::uuid;
|