mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: remove legacy chat provider tables (#25416)
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
DROP TABLE IF EXISTS user_chat_provider_keys;
|
||||
|
||||
ALTER TABLE chat_providers DROP CONSTRAINT IF EXISTS valid_credential_policy;
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('chat_providers') IS NULL THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
ALTER TABLE chat_providers
|
||||
DROP COLUMN IF EXISTS central_api_key_enabled,
|
||||
DROP COLUMN IF EXISTS allow_user_api_key,
|
||||
DROP COLUMN IF EXISTS allow_central_api_key_fallback;
|
||||
ALTER TABLE chat_providers DROP CONSTRAINT IF EXISTS valid_credential_policy;
|
||||
|
||||
ALTER TABLE chat_providers
|
||||
DROP COLUMN IF EXISTS central_api_key_enabled,
|
||||
DROP COLUMN IF EXISTS allow_user_api_key,
|
||||
DROP COLUMN IF EXISTS allow_central_api_key_fallback;
|
||||
END $$;
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
-- Restore placeholder provider rows before re-adding the provider FK.
|
||||
--
|
||||
-- The companion up migration dropped chat_model_configs.provider's foreign
|
||||
-- key, so historical model-config rows can outlive a deleted provider row.
|
||||
-- These backfilled providers are deliberately disabled stubs with empty
|
||||
-- credential fields, which lets rollback restore referential integrity
|
||||
-- without re-enabling a provider. This insert depends on the current
|
||||
-- provider whitelist still admitting every historical
|
||||
-- chat_model_configs.provider value, and on the omitted columns keeping
|
||||
-- compatible defaults. Operators restoring a real provider should update the
|
||||
-- stub row, including credential-policy flags such as
|
||||
-- central_api_key_enabled, before enabling it, rather than insert a second
|
||||
-- row with the same provider name.
|
||||
INSERT INTO chat_providers (provider, enabled)
|
||||
SELECT DISTINCT
|
||||
cmc.provider,
|
||||
FALSE
|
||||
FROM
|
||||
chat_model_configs cmc
|
||||
LEFT JOIN
|
||||
chat_providers cp ON cp.provider = cmc.provider
|
||||
WHERE
|
||||
cp.provider IS NULL;
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('chat_providers') IS NULL THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
ALTER TABLE chat_model_configs
|
||||
ADD CONSTRAINT chat_model_configs_provider_fkey
|
||||
FOREIGN KEY (provider) REFERENCES chat_providers(provider) ON DELETE CASCADE;
|
||||
-- Restore placeholder provider rows before re-adding the provider FK.
|
||||
--
|
||||
-- The companion up migration dropped chat_model_configs.provider's foreign
|
||||
-- key, so historical model-config rows can outlive a deleted provider row.
|
||||
-- These backfilled providers are deliberately disabled stubs with empty
|
||||
-- credential fields, which lets rollback restore referential integrity
|
||||
-- without re-enabling a provider. This insert depends on the current
|
||||
-- provider whitelist still admitting every historical
|
||||
-- chat_model_configs.provider value, and on the omitted columns keeping
|
||||
-- compatible defaults. Operators restoring a real provider should update the
|
||||
-- stub row, including credential-policy flags such as
|
||||
-- central_api_key_enabled, before enabling it, rather than insert a second
|
||||
-- row with the same provider name.
|
||||
INSERT INTO chat_providers (provider, enabled)
|
||||
SELECT DISTINCT
|
||||
cmc.provider,
|
||||
FALSE
|
||||
FROM
|
||||
chat_model_configs cmc
|
||||
LEFT JOIN
|
||||
chat_providers cp ON cp.provider = cmc.provider
|
||||
WHERE
|
||||
cp.provider IS NULL;
|
||||
|
||||
ALTER TABLE chat_model_configs
|
||||
ADD CONSTRAINT chat_model_configs_provider_fkey
|
||||
FOREIGN KEY (provider) REFERENCES chat_providers(provider) ON DELETE CASCADE;
|
||||
END $$;
|
||||
|
||||
@@ -1,48 +1,55 @@
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
UPDATE chat_model_configs
|
||||
SET ai_provider_id = NULL
|
||||
WHERE ai_provider_id IN (SELECT id FROM migrated_provider_ids);
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('chat_providers') IS NULL THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
DELETE FROM user_ai_provider_keys
|
||||
WHERE ai_provider_id IN (SELECT id FROM migrated_provider_ids);
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
UPDATE chat_model_configs
|
||||
SET ai_provider_id = NULL
|
||||
WHERE ai_provider_id IN (SELECT id FROM migrated_provider_ids);
|
||||
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
DELETE FROM ai_provider_keys
|
||||
WHERE provider_id IN (SELECT id FROM migrated_provider_ids);
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
DELETE FROM user_ai_provider_keys
|
||||
WHERE ai_provider_id IN (SELECT id FROM migrated_provider_ids);
|
||||
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
DELETE FROM ai_providers
|
||||
WHERE id IN (SELECT id FROM migrated_provider_ids);
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
DELETE FROM ai_provider_keys
|
||||
WHERE provider_id IN (SELECT id FROM migrated_provider_ids);
|
||||
|
||||
WITH migrated_provider_ids AS (
|
||||
SELECT id
|
||||
FROM chat_providers
|
||||
UNION
|
||||
SELECT id
|
||||
FROM ai_providers
|
||||
WHERE name LIKE 'agents-%'
|
||||
AND deleted = TRUE
|
||||
)
|
||||
DELETE FROM ai_providers
|
||||
WHERE id IN (SELECT id FROM migrated_provider_ids);
|
||||
END $$;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- no-op. Legacy chat provider tables are intentionally not recreated from AI
|
||||
-- provider definitions. Rolling back past this migration is not reversible at
|
||||
-- the schema level.
|
||||
@@ -0,0 +1,140 @@
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM chat_providers cp
|
||||
JOIN ai_providers ap ON ap.name = 'agents-' || cp.provider
|
||||
WHERE ap.deleted = FALSE
|
||||
AND ap.id != cp.id
|
||||
) THEN
|
||||
RAISE EXCEPTION 'cannot finalize chat provider migration because a live agents-* AI provider name already exists';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
INSERT INTO ai_providers (
|
||||
id,
|
||||
type,
|
||||
name,
|
||||
display_name,
|
||||
enabled,
|
||||
base_url,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
cp.id,
|
||||
cp.provider::ai_provider_type,
|
||||
'agents-' || cp.provider,
|
||||
NULLIF(cp.display_name, ''),
|
||||
cp.enabled,
|
||||
cp.base_url,
|
||||
cp.created_at,
|
||||
cp.updated_at
|
||||
FROM chat_providers cp
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM ai_providers ap
|
||||
WHERE ap.id = cp.id
|
||||
);
|
||||
|
||||
UPDATE ai_providers ap
|
||||
SET
|
||||
type = cp.provider::ai_provider_type,
|
||||
name = 'agents-' || cp.provider,
|
||||
display_name = NULLIF(cp.display_name, ''),
|
||||
enabled = cp.enabled,
|
||||
deleted = FALSE,
|
||||
base_url = cp.base_url,
|
||||
updated_at = GREATEST(cp.updated_at, ap.updated_at)
|
||||
FROM chat_providers cp
|
||||
WHERE ap.id = cp.id
|
||||
AND (cp.updated_at > ap.updated_at OR ap.deleted);
|
||||
|
||||
DELETE FROM ai_provider_keys apk
|
||||
USING chat_providers cp
|
||||
WHERE cp.id = apk.provider_id
|
||||
AND cp.api_key = ''
|
||||
AND cp.updated_at > apk.updated_at;
|
||||
|
||||
WITH runtime_provider_keys AS (
|
||||
SELECT DISTINCT ON (apk.provider_id)
|
||||
apk.id,
|
||||
apk.provider_id
|
||||
FROM ai_provider_keys apk
|
||||
JOIN chat_providers cp ON cp.id = apk.provider_id
|
||||
WHERE cp.api_key != ''
|
||||
ORDER BY
|
||||
apk.provider_id ASC,
|
||||
apk.created_at ASC,
|
||||
apk.id ASC
|
||||
)
|
||||
UPDATE ai_provider_keys apk
|
||||
SET
|
||||
api_key = cp.api_key,
|
||||
api_key_key_id = cp.api_key_key_id,
|
||||
updated_at = cp.updated_at
|
||||
FROM runtime_provider_keys rpk
|
||||
JOIN chat_providers cp ON cp.id = rpk.provider_id
|
||||
WHERE apk.id = rpk.id
|
||||
AND cp.updated_at > apk.updated_at;
|
||||
|
||||
INSERT INTO ai_provider_keys (
|
||||
id,
|
||||
provider_id,
|
||||
api_key,
|
||||
api_key_key_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
gen_random_uuid(),
|
||||
cp.id,
|
||||
cp.api_key,
|
||||
cp.api_key_key_id,
|
||||
cp.updated_at,
|
||||
cp.updated_at
|
||||
FROM chat_providers cp
|
||||
WHERE cp.api_key != ''
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM ai_provider_keys apk
|
||||
WHERE apk.provider_id = cp.id
|
||||
);
|
||||
|
||||
INSERT INTO user_ai_provider_keys (
|
||||
id,
|
||||
user_id,
|
||||
ai_provider_id,
|
||||
api_key,
|
||||
api_key_key_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
ucpk.id,
|
||||
ucpk.user_id,
|
||||
ucpk.chat_provider_id,
|
||||
ucpk.api_key,
|
||||
ucpk.api_key_key_id,
|
||||
ucpk.created_at,
|
||||
ucpk.updated_at
|
||||
FROM user_chat_provider_keys ucpk
|
||||
ON CONFLICT (user_id, ai_provider_id) DO UPDATE
|
||||
SET
|
||||
api_key = EXCLUDED.api_key,
|
||||
api_key_key_id = EXCLUDED.api_key_key_id,
|
||||
updated_at = EXCLUDED.updated_at
|
||||
WHERE user_ai_provider_keys.updated_at < EXCLUDED.updated_at;
|
||||
|
||||
UPDATE chat_model_configs cmc
|
||||
SET ai_provider_id = cp.id
|
||||
FROM chat_providers cp
|
||||
WHERE cmc.provider = cp.provider
|
||||
AND cmc.ai_provider_id IS NULL;
|
||||
|
||||
ALTER TABLE chat_model_configs
|
||||
ADD CONSTRAINT chat_model_configs_ai_provider_required_when_active
|
||||
CHECK (deleted = TRUE OR ai_provider_id IS NOT NULL);
|
||||
|
||||
DROP TABLE IF EXISTS user_chat_provider_keys;
|
||||
DROP TABLE IF EXISTS chat_providers;
|
||||
Reference in New Issue
Block a user