diff --git a/backend/migrations/.frozen-sha256 b/backend/migrations/.frozen-sha256 index eb47e14c9..91831f0f8 100644 --- a/backend/migrations/.frozen-sha256 +++ b/backend/migrations/.frozen-sha256 @@ -36,6 +36,4 @@ bd73379456839e8a12d7591ad2a839901af0f5ba27871248569abdfa26bc83ef 0035_cpr_link_ d05442ee4cb85db8131e015dbed9c6ad988f93306abcda34647317674857ee44 0036_account_display_names.sql b215ea90d5c8753aeb8192b17ffe65f7a95c1d620aaeaf9fc4337d8cf6f2634e 0037_retry_after_wait_limit.sql 321f4a09367717eb13c3cf5dbfd1f4b014e31c615a74bf6e3b09b8e810d87198 0038_preserve_client_key_ledger.sql -80ba91cad23667ace80a43daf905ca78fd0f6de5fb57f444c9ebbfa2fab90c34 0039_queue_timeouts.sql -2438e107835cd69effdb37e4d008b3b631a287da9e41185b04dd239449cb6733 0040_quota_credit_policy.sql -825b9144f369eca39439d7da27f477915bd904c3df90940108d8a37fcc129bac 0041_client_key_installation_seed.sql +a6b4e81d38e5d70776a75eba22749354573ebcb186160ff9eb45fd91157b3e0d 0039_queue_timeouts_quota_credits_and_installation_seed.sql diff --git a/backend/migrations/0039_queue_timeouts.sql b/backend/migrations/0039_queue_timeouts.sql deleted file mode 100644 index e3e804359..000000000 --- a/backend/migrations/0039_queue_timeouts.sql +++ /dev/null @@ -1,10 +0,0 @@ --- 两层排队分别沿用实例已配置的时限,账号队满或超时默认返回错误 -ALTER TABLE runtime_settings - RENAME COLUMN concurrency_wait_timeout_seconds TO key_queue_timeout_seconds; - -ALTER TABLE runtime_settings - ADD COLUMN account_queue_timeout_seconds BIGINT NOT NULL DEFAULT 30 - CHECK (account_queue_timeout_seconds BETWEEN 1 AND 120), - ADD COLUMN switch_account_on_queue_failure BOOLEAN NOT NULL DEFAULT FALSE; - -UPDATE runtime_settings SET account_queue_timeout_seconds = key_queue_timeout_seconds; diff --git a/backend/migrations/0039_queue_timeouts_quota_credits_and_installation_seed.sql b/backend/migrations/0039_queue_timeouts_quota_credits_and_installation_seed.sql new file mode 100644 index 000000000..121a33c39 --- /dev/null +++ b/backend/migrations/0039_queue_timeouts_quota_credits_and_installation_seed.sql @@ -0,0 +1,71 @@ +-- 两层排队分别沿用实例已配置的时限,账号队满或超时默认返回错误 +ALTER TABLE runtime_settings + RENAME COLUMN concurrency_wait_timeout_seconds TO key_queue_timeout_seconds; + +ALTER TABLE runtime_settings + ADD COLUMN account_queue_timeout_seconds BIGINT NOT NULL DEFAULT 30 + CHECK (account_queue_timeout_seconds BETWEEN 1 AND 120), + ADD COLUMN switch_account_on_queue_failure BOOLEAN NOT NULL DEFAULT FALSE; + +UPDATE runtime_settings SET account_queue_timeout_seconds = key_queue_timeout_seconds; + +alter table provider_accounts + add column auto_use_quota_credits boolean not null default false, + drop constraint provider_accounts_quota_evidence_ck, + drop constraint provider_accounts_quota_fact_ck, + add constraint provider_accounts_quota_evidence_ck check ( + quota_evidence in ('provider_denied', 'account_limit_reached', 'usage_limit_reached', 'payment_required', 'credits_available') + ), + add constraint provider_accounts_quota_fact_ck check ( + (quota_access_state = 'unknown' and quota_evidence is null and quota_reset_at is null) + or (quota_access_state = 'allowed' and quota_access_observed_at is not null + and ((quota_evidence is null and quota_reset_at is null) or quota_evidence is not distinct from 'credits_available')) + or (quota_access_state = 'exhausted' and quota_evidence is not null and quota_evidence <> 'credits_available' and quota_access_observed_at is not null) + ); + +-- 在行锁内按当前配置投影仅点数可用的观测,晚返回的查询不能覆盖关闭开关的决定 +create function apply_quota_credit_policy() returns trigger language plpgsql as $$ +begin + new.quota_access_state := 'exhausted'; + new.quota_evidence := 'account_limit_reached'; + return new; +end +$$; + +create trigger provider_accounts_quota_credit_policy +before insert or update of auto_use_quota_credits, quota_evidence, quota_access_state on provider_accounts +for each row when (not new.auto_use_quota_credits and new.quota_evidence = 'credits_available') execute function apply_quota_credit_policy(); + +-- Key 安装身份只保存种子,现有安装 ID 转为种子后按 Key 与账号重新派生 +WITH migrated AS ( + UPDATE client_api_keys + SET provider_request_profiles_json = jsonb_set( + provider_request_profiles_json, + '{openai}', + CASE + WHEN provider_request_profiles_json #> '{openai,inherit}' ? 'installationId' + THEN jsonb_set( + provider_request_profiles_json -> 'openai', + '{inherit}', + ((provider_request_profiles_json #> '{openai,inherit}') - 'installationId') + || jsonb_build_object( + 'installationSeed', + provider_request_profiles_json #> '{openai,inherit,installationId}' + ) + ) + ELSE ((provider_request_profiles_json -> 'openai') - 'installationId') + || jsonb_build_object( + 'installationSeed', + provider_request_profiles_json #> '{openai,installationId}' + ) + END + ), + updated_at = GREATEST(now(), updated_at) + WHERE provider_request_profiles_json -> 'openai' ? 'installationId' + OR provider_request_profiles_json #> '{openai,inherit}' ? 'installationId' + RETURNING id +) +UPDATE runtime_settings +SET config_revision = config_revision + 1, + updated_at = GREATEST(now(), updated_at) +WHERE EXISTS (SELECT 1 FROM migrated); diff --git a/backend/migrations/0040_quota_credit_policy.sql b/backend/migrations/0040_quota_credit_policy.sql deleted file mode 100644 index ae4525ad4..000000000 --- a/backend/migrations/0040_quota_credit_policy.sql +++ /dev/null @@ -1,26 +0,0 @@ -alter table provider_accounts - add column auto_use_quota_credits boolean not null default false, - drop constraint provider_accounts_quota_evidence_ck, - drop constraint provider_accounts_quota_fact_ck, - add constraint provider_accounts_quota_evidence_ck check ( - quota_evidence in ('provider_denied', 'account_limit_reached', 'usage_limit_reached', 'payment_required', 'credits_available') - ), - add constraint provider_accounts_quota_fact_ck check ( - (quota_access_state = 'unknown' and quota_evidence is null and quota_reset_at is null) - or (quota_access_state = 'allowed' and quota_access_observed_at is not null - and ((quota_evidence is null and quota_reset_at is null) or quota_evidence is not distinct from 'credits_available')) - or (quota_access_state = 'exhausted' and quota_evidence is not null and quota_evidence <> 'credits_available' and quota_access_observed_at is not null) - ); - --- 在行锁内按当前配置投影仅点数可用的观测,晚返回的查询不能覆盖关闭开关的决定 -create function apply_quota_credit_policy() returns trigger language plpgsql as $$ -begin - new.quota_access_state := 'exhausted'; - new.quota_evidence := 'account_limit_reached'; - return new; -end -$$; - -create trigger provider_accounts_quota_credit_policy -before insert or update of auto_use_quota_credits, quota_evidence, quota_access_state on provider_accounts -for each row when (not new.auto_use_quota_credits and new.quota_evidence = 'credits_available') execute function apply_quota_credit_policy(); diff --git a/backend/migrations/0041_client_key_installation_seed.sql b/backend/migrations/0041_client_key_installation_seed.sql deleted file mode 100644 index 00f2f3a5c..000000000 --- a/backend/migrations/0041_client_key_installation_seed.sql +++ /dev/null @@ -1,33 +0,0 @@ --- Key 安装身份只保存种子,现有安装 ID 转为种子后按 Key 与账号重新派生 -WITH migrated AS ( - UPDATE client_api_keys - SET provider_request_profiles_json = jsonb_set( - provider_request_profiles_json, - '{openai}', - CASE - WHEN provider_request_profiles_json #> '{openai,inherit}' ? 'installationId' - THEN jsonb_set( - provider_request_profiles_json -> 'openai', - '{inherit}', - ((provider_request_profiles_json #> '{openai,inherit}') - 'installationId') - || jsonb_build_object( - 'installationSeed', - provider_request_profiles_json #> '{openai,inherit,installationId}' - ) - ) - ELSE ((provider_request_profiles_json -> 'openai') - 'installationId') - || jsonb_build_object( - 'installationSeed', - provider_request_profiles_json #> '{openai,installationId}' - ) - END - ), - updated_at = GREATEST(now(), updated_at) - WHERE provider_request_profiles_json -> 'openai' ? 'installationId' - OR provider_request_profiles_json #> '{openai,inherit}' ? 'installationId' - RETURNING id -) -UPDATE runtime_settings -SET config_revision = config_revision + 1, - updated_at = GREATEST(now(), updated_at) -WHERE EXISTS (SELECT 1 FROM migrated);