fix(wallet): 删除与过期删除 API Key 时同步禁用关联钱包 (#315)

- 在 delete_user_api_key 和 delete_standalone_api_key 事务中,先将关联 wallets.status 更新为 disabled
- 在过期 Key 自动清理流程中,删除前同步禁用对应钱包
- 保留 wallet 与交易流水,避免出现 orphaned 且 active 的钱包状态
This commit is contained in:
AAEE86
2026-04-20 14:03:17 +08:00
committed by GitHub
parent 13bf222b8d
commit b2ff7d2c28
3 changed files with 38 additions and 7 deletions

View File

@@ -570,6 +570,13 @@ const DELETE_EXPIRED_API_KEY_SQL: &str = r#"
DELETE FROM api_keys
WHERE id = $1
"#;
const DISABLE_EXPIRED_API_KEY_WALLET_SQL: &str = r#"
UPDATE wallets
SET status = 'disabled',
updated_at = NOW()
WHERE api_key_id = $1
AND status <> 'disabled'
"#;
const DISABLE_EXPIRED_API_KEY_SQL: &str = r#"
UPDATE api_keys
SET is_active = FALSE,

View File

@@ -19,13 +19,14 @@ use super::{
CLEAR_USAGE_HEADER_FIELDS_SQL, CLEAR_USAGE_HTTP_AUDIT_BODY_REFS_SQL,
CLEAR_USAGE_HTTP_AUDIT_HEADERS_SQL, DELETE_EMPTY_USAGE_HTTP_AUDITS_SQL,
DELETE_EXPIRED_API_KEY_SQL, DELETE_OLD_USAGE_RECORDS_SQL, DELETE_USAGE_BODY_BLOBS_SQL,
DISABLE_EXPIRED_API_KEY_SQL, EXPIRED_API_KEY_PRE_CLEAN_BATCH_SIZE,
NULLIFY_REQUEST_CANDIDATE_API_KEY_BATCH_SQL, NULLIFY_USAGE_API_KEY_BATCH_SQL,
SELECT_EXPIRED_ACTIVE_API_KEYS_SQL, SELECT_USAGE_BODY_COMPRESSION_BATCH_SQL,
SELECT_USAGE_BODY_COMPRESSION_ROW_SQL, SELECT_USAGE_HEADER_BATCH_SQL,
SELECT_USAGE_LEGACY_BODY_REF_METADATA_BATCH_SQL, SELECT_USAGE_STALE_BODY_BATCH_SQL,
UPDATE_USAGE_BODY_COMPRESSION_SQL, UPDATE_USAGE_REQUEST_METADATA_SQL,
UPSERT_USAGE_BODY_BLOB_SQL, UPSERT_USAGE_HTTP_AUDIT_BODY_REFS_SQL,
DISABLE_EXPIRED_API_KEY_SQL, DISABLE_EXPIRED_API_KEY_WALLET_SQL,
EXPIRED_API_KEY_PRE_CLEAN_BATCH_SIZE, NULLIFY_REQUEST_CANDIDATE_API_KEY_BATCH_SQL,
NULLIFY_USAGE_API_KEY_BATCH_SQL, SELECT_EXPIRED_ACTIVE_API_KEYS_SQL,
SELECT_USAGE_BODY_COMPRESSION_BATCH_SQL, SELECT_USAGE_BODY_COMPRESSION_ROW_SQL,
SELECT_USAGE_HEADER_BATCH_SQL, SELECT_USAGE_LEGACY_BODY_REF_METADATA_BATCH_SQL,
SELECT_USAGE_STALE_BODY_BATCH_SQL, UPDATE_USAGE_BODY_COMPRESSION_SQL,
UPDATE_USAGE_REQUEST_METADATA_SQL, UPSERT_USAGE_BODY_BLOB_SQL,
UPSERT_USAGE_HTTP_AUDIT_BODY_REFS_SQL,
};
pub(super) async fn perform_usage_cleanup_once(
@@ -655,6 +656,11 @@ async fn cleanup_expired_api_keys(
if should_delete {
nullify_expired_api_key_usage_refs(pool, key.id).await?;
nullify_expired_api_key_candidate_refs(pool, key.id).await?;
sqlx::query(DISABLE_EXPIRED_API_KEY_WALLET_SQL)
.bind(key.id)
.execute(pool)
.await
.map_err(postgres_error)?;
let deleted = sqlx::query(DELETE_EXPIRED_API_KEY_SQL)
.bind(key.id)
.execute(pool)

View File

@@ -656,6 +656,14 @@ SET api_key_id = NULL
WHERE api_key_id = $1
"#;
const DISABLE_WALLET_BY_API_KEY_ID_SQL: &str = r#"
UPDATE wallets
SET status = 'disabled',
updated_at = NOW()
WHERE api_key_id = $1
AND status <> 'disabled'
"#;
const DELETE_USER_API_KEY_SQL: &str = r#"
DELETE FROM api_keys
WHERE user_id = $1
@@ -1268,6 +1276,11 @@ impl AuthApiKeyWriteRepository for SqlxAuthApiKeySnapshotReadRepository {
.execute(&mut *tx)
.await
.map_postgres_err()?;
sqlx::query(DISABLE_WALLET_BY_API_KEY_ID_SQL)
.bind(api_key_id)
.execute(&mut *tx)
.await
.map_postgres_err()?;
let result = sqlx::query(DELETE_USER_API_KEY_SQL)
.bind(user_id)
.bind(api_key_id)
@@ -1290,6 +1303,11 @@ impl AuthApiKeyWriteRepository for SqlxAuthApiKeySnapshotReadRepository {
.execute(&mut *tx)
.await
.map_postgres_err()?;
sqlx::query(DISABLE_WALLET_BY_API_KEY_ID_SQL)
.bind(api_key_id)
.execute(&mut *tx)
.await
.map_postgres_err()?;
let result = sqlx::query(DELETE_STANDALONE_API_KEY_SQL)
.bind(api_key_id)
.execute(&mut *tx)