feat(retention): 删除用户/Key 时保留历史记录,外键改 SET NULL 并添加名称快照

- Usage/RequestCandidate/VideoTask/Stats 等表的 user_id/api_key_id 外键从
  CASCADE 改为 SET NULL,删除用户或 Key 后历史记录不再丢失
- 各表添加 username/api_key_name 快照字段,删除后仍可追溯归属
- 新增 bulk_cleanup 模块,分批置空大表外键避免长事务锁
- 删除用户/Key 流程集成预清理步骤,先置空再删除
- 精简 candidate_builder 冗余 debug 日志
- 修复 proxy_nodes 启动日志 format 占位符错误({} -> %s)
- 前端批量操作请求增加 5 分钟超时配置
This commit is contained in:
fawney19
2026-03-08 14:31:15 +08:00
parent 25c33846be
commit bd3f73c2fc
26 changed files with 799 additions and 96 deletions

View File

@@ -2,6 +2,8 @@ import client from '../client'
import { dedupedRequest } from '@/utils/cache'
import type { AllowedModels, ProxyConfig } from './types/provider'
const POOL_BATCH_ACTION_TIMEOUT_MS = 5 * 60 * 1000
export interface PoolKeyStatus {
key_id: string
key_name: string
@@ -212,13 +214,21 @@ export async function batchActionPoolKeys(
providerId: string,
body: PoolBatchAction,
): Promise<{ affected: number; message: string }> {
const response = await client.post(`/api/admin/pool/${providerId}/keys/batch-action`, body)
const response = await client.post(
`/api/admin/pool/${providerId}/keys/batch-action`,
body,
{ timeout: POOL_BATCH_ACTION_TIMEOUT_MS },
)
return response.data
}
export async function cleanupBannedPoolKeys(
providerId: string,
): Promise<{ affected: number; message: string }> {
const response = await client.post(`/api/admin/pool/${providerId}/keys/cleanup-banned`)
const response = await client.post(
`/api/admin/pool/${providerId}/keys/cleanup-banned`,
undefined,
{ timeout: POOL_BATCH_ACTION_TIMEOUT_MS },
)
return response.data
}