Просмотр исходного кода

refactor(provider): improve provider page performance (#782)

* fix: Providers 管理页批量化端点统计与测活日志

* perf: 优化 provider 统计与 my-usage 查询性能

* perf: Providers 管理页移除 refresh 放大器并按需加载端点区块

* fix: 跟进 review 补齐 Providers 批量与统计健壮性

* fix: 跟进 CodeRabbit 修复 in-view 与测活数据校验

* perf: 补齐 in-view 稳定化与 batch 404 复原

* perf: my-usage 配额/汇总减少 DB 往返

* perf(providers): 端点池热路径批量熔断查询与索引迁移 (#779)

- 运行时端点选择与严格审计统计改为批量读取端点熔断状态,减少 Redis 往返\n- probe 写入在端点并发删除时静默忽略,避免 FK 失败导致任务中断\n- 新增索引迁移:idx_provider_endpoints_pick_enabled / idx_providers_vendor_type_url_active\n- repository 批量查询模块改为 server-only,避免误暴露为 Server Action

* fix: 跟进 review 去重熔断 reset 与 scanEnd (#779)

* fix: 精确熔断 reset + repo 使用 server-only (#779)

* fix: my-usage 补齐 sessionId/warmup 过滤 (#779)

* perf: provider 统计 in-flight 去重更稳健 (#779)

* fix: ProviderForm 统一失效相关缓存 (#779)

* fix: Providers/Usage 细节修正与用例补齐 (#779)

* style: biome 格式化补齐 (#779)

* fix(#779): 熔断状态同步与 probeLogs 批量查询改进

* fix(#781): 清理孤儿端点并修正 Endpoint Health

* perf: 优化 usage logs 与端点同步(#779/#781)

* refactor: 移除端点冗余过滤(#779)

* fix: 熔断状态批量查询仅覆盖启用端点(#779)

* fix: Provider 统计兼容脏数据并稳定 probe logs 排序(#779)

* perf: 禁用 Providers 重查询的 window focus 自动刷新(#779)

* fix: 多实例熔断状态定期同步,并修复 backfill 遗留软删除端点(#779/#781)

* perf: probe scheduler 仅探测启用 provider 的端点(#781)

* perf: ProviderForm 避免重复 refetch 并稳定 hover circuit key(#779)

* perf: 全局 QueryClient 策略与 usage/user 索引优化(#779)

* perf: 时区统计索引命中与批量删除优化(#779)

* perf: 降低 logs/users 页面无效重算

* fix(provider): endpoint pool 仅基于启用 provider

- sync/backfill/delete:引用判断与回填仅考虑 is_enabled=true 的 provider,避免 disabled provider 复活旧 endpoint
- updateProvider:provider 从禁用启用时确保端点存在
- Dashboard Endpoint Health:避免并发刷新覆盖用户切换,vendor/type 仅从启用 provider 推导
- probe logs 批量接口:滚动发布场景下部分 404 不全局禁用 batch
- 补齐 endpoint-selector 单测以匹配 findEnabled* 语义

* perf: Dashboard vendor/type 轻量查询与 usage logs 并行查询

* fix(migrate): advisory lock 串行迁移并移除 emoji 日志

* fix: endpoint hover 兜底并规范 batch probe logs SQL

* perf(settings/providers): 减少冗余刷新并复用 endpoint/circuit 缓存

* perf(probe/statistics): 修正 probe 锁/计数并收敛统计与 usage 扫描

* perf(probe/ui): 优化 probe 目标筛选 SQL 并减少 sparkline 闪烁

* fix(db): 修复 Drizzle snapshot 链

* fix(perf): 补强 Providers 批量与缓存一致性

- Provider 统计:消除隐式 cross join,收敛 in-flight 清理;deleteProvidersBatch 降低事务内往返\n- Providers hover:按 QueryClient 隔离微批量并支持 AbortSignal,减少串扰与潜在泄漏\n- Probe/熔断/缓存:probe 目标查询改为 join;Redis 同步时更新计数字段;统计缓存保持 FIFO 语义\n- My Usage:userBreakdown 补齐 5m/1h cache 聚合列(当前 UI 未展示)

* chore: format code (issue-779-provider-performance-23b338e)

* chore: 触发 CI 重跑

* fix(provider): 批量启用时补齐 endpoint pool

- batchUpdateProviders 会走 updateProvidersBatch;当供应商从 disabled 批量启用时,best-effort 插入缺失的 provider_endpoints 记录\n- 避免历史/竞态导致启用后严格端点策略下无可用 endpoint 而被阻断

* fix(perf): 收敛 Providers 刷新放大并优化探测/分页

* perf: 收敛 availability/probe 轮询并优化 my-usage (#779/#781)

- AvailabilityDashboard: 抑制重叠/乱序刷新,前后台切换节流强刷\n- Probe scheduler/cleanup: idle DB poll + 锁续租,降低无意义扫描与并发清理\n- Endpoint circuit: Redis 同步节流(1s)\n- My Usage: key/user breakdown 合并为单次聚合\n- DB: 新增 message_request key+model/endpoint 部分索引迁移;修复 journal 单调性校验与迁移表 created_at 自愈

* fix(ui): 恢复全局 react-query 默认配置

* fix(availability): 刷新 vendors 时清理旧 endpoint 选择

* perf: 补强 Providers 探测与 Usage Logs 性能

* perf(ui): useInViewOnce 共享 IntersectionObserver 降低资源占用

- 按 (root+options) 复用 observer pool,减少长列表/大表格下的 observer 实例数\n- 补齐单测覆盖(test env 直通 + 共享/释放语义)

* perf: providers batch where 优化与 sparkline 降级并发修正

* perf: my-usage breakdown 补齐缓存字段并优化筛选缓存

* perf: 优化端点熔断 Redis 负载与探测候选

* fix(#781): Endpoint Health 仅展示启用 provider 引用端点

* 修正端点健康筛选并增强URL解析容错

* docs(provider-endpoints): 说明 keepPreviousWhenReferenced 语义

* perf(availability): EndpointTab 前后台切换节流刷新

* docs(availability): 补充 EndpointTab 刷新节流注释

* chore(review): 按 AI 审阅补齐注释并收敛细节

* fix: 修正 provider 统计 SQL 的 DST 日界

---------

Co-authored-by: tesgth032 <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
tesgth032 1 неделя назад
Родитель
Сommit
00912ac0a4
72 измененных файлов с 24827 добавлено и 1176 удалено
  1. 3 0
      .env.example
  2. 1 1
      biome.json
  3. 2 0
      drizzle/0068_fuzzy_quasar.sql
  4. 6 0
      drizzle/0069_broad_hellfire_club.sql
  5. 5 0
      drizzle/0070_warm_lilandra.sql
  6. 1 0
      drizzle/0071_motionless_wind_dancer.sql
  7. 5 0
      drizzle/0072_absurd_gwen_stacy.sql
  8. 1 0
      drizzle/0073_minor_franklin_richards.sql
  9. 3058 0
      drizzle/meta/0068_snapshot.json
  10. 3118 0
      drizzle/meta/0069_snapshot.json
  11. 3156 0
      drizzle/meta/0070_snapshot.json
  12. 3171 0
      drizzle/meta/0071_snapshot.json
  13. 3215 0
      drizzle/meta/0072_snapshot.json
  14. 3237 0
      drizzle/meta/0073_snapshot.json
  15. 42 0
      drizzle/meta/_journal.json
  16. 76 0
      scripts/validate-migrations.js
  17. 162 145
      src/actions/my-usage.ts
  18. 360 22
      src/actions/provider-endpoints.ts
  19. 3 5
      src/actions/providers.ts
  20. 143 54
      src/app/[locale]/dashboard/availability/_components/availability-dashboard.tsx
  21. 67 47
      src/app/[locale]/dashboard/availability/_components/endpoint-probe-history.tsx
  22. 263 86
      src/app/[locale]/dashboard/availability/_components/endpoint/endpoint-tab.tsx
  23. 22 3
      src/app/[locale]/dashboard/availability/_components/endpoint/probe-grid.tsx
  24. 15 20
      src/app/[locale]/dashboard/logs/_components/usage-logs-view-virtualized.tsx
  25. 5 3
      src/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsx
  26. 11 25
      src/app/[locale]/dashboard/users/users-page-client.tsx
  27. 0 8
      src/app/[locale]/settings/providers/_components/add-provider-dialog.tsx
  28. 451 23
      src/app/[locale]/settings/providers/_components/endpoint-latency-sparkline.tsx
  29. 15 5
      src/app/[locale]/settings/providers/_components/forms/provider-form/index.tsx
  30. 377 18
      src/app/[locale]/settings/providers/_components/provider-endpoint-hover.tsx
  31. 57 38
      src/app/[locale]/settings/providers/_components/provider-endpoints-table.tsx
  32. 15 0
      src/app/[locale]/settings/providers/_components/provider-list.tsx
  33. 4 27
      src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx
  34. 9 4
      src/app/[locale]/settings/providers/_components/provider-vendor-view.tsx
  35. 24 15
      src/app/[locale]/settings/providers/_components/vendor-keys-compact-list.tsx
  36. 40 0
      src/app/api/actions/[...route]/route.ts
  37. 5 2
      src/app/api/availability/endpoints/route.ts
  38. 49 0
      src/drizzle/schema.ts
  39. 56 30
      src/instrumentation.ts
  40. 222 14
      src/lib/endpoint-circuit-breaker.ts
  41. 238 0
      src/lib/hooks/use-in-view-once.ts
  42. 147 7
      src/lib/migrate.ts
  43. 44 31
      src/lib/provider-endpoints/endpoint-selector.ts
  44. 3 3
      src/lib/provider-endpoints/leader-lock.ts
  45. 61 0
      src/lib/provider-endpoints/probe-log-cleanup.ts
  46. 93 9
      src/lib/provider-endpoints/probe-scheduler.ts
  47. 19 8
      src/lib/provider-endpoints/probe.ts
  48. 3 2
      src/lib/redis/client.ts
  49. 92 2
      src/lib/redis/endpoint-circuit-breaker-state.ts
  50. 2 0
      src/repository/index.ts
  51. 29 9
      src/repository/leaderboard.ts
  52. 19 7
      src/repository/overview.ts
  53. 173 0
      src/repository/provider-endpoints-batch.ts
  54. 347 65
      src/repository/provider-endpoints.ts
  55. 387 119
      src/repository/provider.ts
  56. 367 143
      src/repository/statistics.ts
  57. 360 46
      src/repository/usage-logs.ts
  58. 3 4
      tests/integration/provider-endpoint-sync-race.test.ts
  59. 14 0
      tests/unit/actions/my-usage-concurrent-inherit.test.ts
  60. 8 8
      tests/unit/actions/my-usage-date-range-dst.test.ts
  61. 21 11
      tests/unit/actions/my-usage-token-aggregation.test.ts
  62. 170 33
      tests/unit/actions/provider-endpoints.test.ts
  63. 4 0
      tests/unit/actions/providers-recluster.test.ts
  64. 39 25
      tests/unit/actions/total-usage-semantics.test.ts
  65. 178 14
      tests/unit/lib/endpoint-circuit-breaker.test.ts
  66. 104 27
      tests/unit/lib/provider-endpoints/endpoint-selector.test.ts
  67. 167 0
      tests/unit/lib/use-in-view-once.test.tsx
  68. 14 7
      tests/unit/repository/provider-endpoint-sync-helper.test.ts
  69. 94 0
      tests/unit/repository/provider-endpoints-probe-result.test.ts
  70. 142 0
      tests/unit/repository/statistics-quota-costs-all-time.test.ts
  71. 4 1
      tests/unit/settings/providers/endpoint-latency-sparkline-ui.test.tsx
  72. 9 0
      tests/unit/settings/providers/provider-rich-list-item-endpoints.test.tsx

+ 3 - 0
.env.example

@@ -152,6 +152,9 @@ PROBE_TIMEOUT_MS=5000
 #
 # ENDPOINT_PROBE_INTERVAL_MS controls the base interval. Single-vendor and timeout intervals are fixed.
 ENDPOINT_PROBE_INTERVAL_MS=60000
+# When no endpoints are due, scheduler will still poll DB periodically to pick up config changes.
+# Default: min(ENDPOINT_PROBE_INTERVAL_MS, 30000)
+ENDPOINT_PROBE_IDLE_DB_POLL_INTERVAL_MS=30000
 ENDPOINT_PROBE_TIMEOUT_MS=5000
 ENDPOINT_PROBE_CONCURRENCY=10
 ENDPOINT_PROBE_CYCLE_JITTER_MS=1000

+ 1 - 1
biome.json

@@ -1,5 +1,5 @@
 {
-  "$schema": "https://biomejs.dev/schemas/2.3.14/schema.json",
+  "$schema": "https://biomejs.dev/schemas/2.3.15/schema.json",
   "vcs": {
     "enabled": true,
     "clientKind": "git",

+ 2 - 0
drizzle/0068_fuzzy_quasar.sql

@@ -0,0 +1,2 @@
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoints_pick_enabled" ON "provider_endpoints" USING btree ("vendor_id","provider_type","is_enabled","sort_order","id") WHERE "provider_endpoints"."deleted_at" IS NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_providers_vendor_type_url_active" ON "providers" USING btree ("provider_vendor_id","provider_type","url") WHERE "providers"."deleted_at" IS NULL;

+ 6 - 0
drizzle/0069_broad_hellfire_club.sql

@@ -0,0 +1,6 @@
+-- 注意:message_request 为高写入表,标准 CREATE INDEX 可能在建索引期间阻塞写入。
+-- Drizzle migrator 不支持 CREATE INDEX CONCURRENTLY;如对停写敏感,可在维护窗口升级,
+-- 或在升级前手动用 CONCURRENTLY 预创建同名索引(本迁移已使用 IF NOT EXISTS,预建不会冲突)。
+CREATE INDEX IF NOT EXISTS "idx_message_request_key_created_at_id" ON "message_request" USING btree ("key","created_at" DESC NULLS LAST,"id" DESC NULLS LAST) WHERE "message_request"."deleted_at" IS NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_message_request_model_active" ON "message_request" USING btree ("model") WHERE "message_request"."deleted_at" IS NULL AND "message_request"."model" IS NOT NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_message_request_status_code_active" ON "message_request" USING btree ("status_code") WHERE "message_request"."deleted_at" IS NULL AND "message_request"."status_code" IS NOT NULL;

+ 5 - 0
drizzle/0070_warm_lilandra.sql

@@ -0,0 +1,5 @@
+-- 注意:message_request 为高写入表,标准 CREATE INDEX 可能在建索引期间阻塞写入。
+-- Drizzle migrator 不支持 CREATE INDEX CONCURRENTLY;如对停写敏感,可在维护窗口升级,
+-- 或在升级前手动用 CONCURRENTLY 预创建同名索引(本迁移已使用 IF NOT EXISTS,预建不会冲突)。
+CREATE INDEX IF NOT EXISTS "idx_message_request_created_at_id_active" ON "message_request" USING btree ("created_at" DESC NULLS LAST,"id" DESC NULLS LAST) WHERE "message_request"."deleted_at" IS NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_users_tags_gin" ON "users" USING gin ("tags") WHERE "users"."deleted_at" IS NULL;

+ 1 - 0
drizzle/0071_motionless_wind_dancer.sql

@@ -0,0 +1 @@
+CREATE INDEX IF NOT EXISTS "idx_keys_key" ON "keys" USING btree ("key");

+ 5 - 0
drizzle/0072_absurd_gwen_stacy.sql

@@ -0,0 +1,5 @@
+-- 注意:message_request 为高写入表,标准 CREATE INDEX 可能在建索引期间阻塞写入。
+-- Drizzle migrator 不支持 CREATE INDEX CONCURRENTLY;如对停写敏感,可在维护窗口升级,
+-- 或在升级前手动用 CONCURRENTLY 预创建同名索引(本迁移已使用 IF NOT EXISTS,预建不会冲突)。
+CREATE INDEX IF NOT EXISTS "idx_message_request_key_model_active" ON "message_request" USING btree ("key","model") WHERE "message_request"."deleted_at" IS NULL AND "message_request"."model" IS NOT NULL AND ("message_request"."blocked_by" IS NULL OR "message_request"."blocked_by" <> 'warmup');--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_message_request_key_endpoint_active" ON "message_request" USING btree ("key","endpoint") WHERE "message_request"."deleted_at" IS NULL AND "message_request"."endpoint" IS NOT NULL AND ("message_request"."blocked_by" IS NULL OR "message_request"."blocked_by" <> 'warmup');

+ 1 - 0
drizzle/0073_minor_franklin_richards.sql

@@ -0,0 +1 @@
+CREATE INDEX IF NOT EXISTS "idx_providers_enabled_vendor_type" ON "providers" USING btree ("provider_vendor_id","provider_type") WHERE "providers"."deleted_at" IS NULL AND "providers"."is_enabled" = true AND "providers"."provider_vendor_id" IS NOT NULL AND "providers"."provider_vendor_id" > 0;

+ 3058 - 0
drizzle/meta/0068_snapshot.json

@@ -0,0 +1,3058 @@
+{
+  "id": "e6503137-9fe6-450f-9918-f2c5a7315001",
+  "prevId": "c4820501-71eb-4492-b9cb-dd19c5def277",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_pick_enabled": {
+          "name": "idx_provider_endpoints_pick_enabled",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "sort_order",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "group_priorities": {
+          "name": "group_priorities",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_max_tokens_preference": {
+          "name": "anthropic_max_tokens_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_thinking_budget_preference": {
+          "name": "anthropic_thinking_budget_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_adaptive_thinking": {
+          "name": "anthropic_adaptive_thinking",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "gemini_google_search_preference": {
+          "name": "gemini_google_search_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type_url_active": {
+          "name": "idx_providers_vendor_type_url_active",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "timezone": {
+          "name": "timezone",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_thinking_budget_rectifier": {
+          "name": "enable_thinking_budget_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_billing_header_rectifier": {
+          "name": "enable_billing_header_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_claude_metadata_user_id_injection": {
+          "name": "enable_claude_metadata_user_id_injection",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "quota_db_refresh_interval_seconds": {
+          "name": "quota_db_refresh_interval_seconds",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10
+        },
+        "quota_lease_percent_5h": {
+          "name": "quota_lease_percent_5h",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_daily": {
+          "name": "quota_lease_percent_daily",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_weekly": {
+          "name": "quota_lease_percent_weekly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_monthly": {
+          "name": "quota_lease_percent_monthly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_cap_usd": {
+          "name": "quota_lease_cap_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 3118 - 0
drizzle/meta/0069_snapshot.json

@@ -0,0 +1,3118 @@
+{
+  "id": "30ac31f0-6588-443f-a197-1c16dab31e1c",
+  "prevId": "e6503137-9fe6-450f-9918-f2c5a7315001",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_created_at_id": {
+          "name": "idx_message_request_key_created_at_id",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_model_active": {
+          "name": "idx_message_request_model_active",
+          "columns": [
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_status_code_active": {
+          "name": "idx_message_request_status_code_active",
+          "columns": [
+            {
+              "expression": "status_code",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"status_code\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_pick_enabled": {
+          "name": "idx_provider_endpoints_pick_enabled",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "sort_order",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "group_priorities": {
+          "name": "group_priorities",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_max_tokens_preference": {
+          "name": "anthropic_max_tokens_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_thinking_budget_preference": {
+          "name": "anthropic_thinking_budget_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_adaptive_thinking": {
+          "name": "anthropic_adaptive_thinking",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "gemini_google_search_preference": {
+          "name": "gemini_google_search_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type_url_active": {
+          "name": "idx_providers_vendor_type_url_active",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "timezone": {
+          "name": "timezone",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_thinking_budget_rectifier": {
+          "name": "enable_thinking_budget_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_billing_header_rectifier": {
+          "name": "enable_billing_header_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_claude_metadata_user_id_injection": {
+          "name": "enable_claude_metadata_user_id_injection",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "quota_db_refresh_interval_seconds": {
+          "name": "quota_db_refresh_interval_seconds",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10
+        },
+        "quota_lease_percent_5h": {
+          "name": "quota_lease_percent_5h",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_daily": {
+          "name": "quota_lease_percent_daily",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_weekly": {
+          "name": "quota_lease_percent_weekly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_monthly": {
+          "name": "quota_lease_percent_monthly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_cap_usd": {
+          "name": "quota_lease_cap_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 3156 - 0
drizzle/meta/0070_snapshot.json

@@ -0,0 +1,3156 @@
+{
+  "id": "6195c134-aa4e-4100-9017-495e7d2e2bae",
+  "prevId": "30ac31f0-6588-443f-a197-1c16dab31e1c",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_created_at_id": {
+          "name": "idx_message_request_key_created_at_id",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at_id_active": {
+          "name": "idx_message_request_created_at_id_active",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_model_active": {
+          "name": "idx_message_request_model_active",
+          "columns": [
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_status_code_active": {
+          "name": "idx_message_request_status_code_active",
+          "columns": [
+            {
+              "expression": "status_code",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"status_code\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_pick_enabled": {
+          "name": "idx_provider_endpoints_pick_enabled",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "sort_order",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "group_priorities": {
+          "name": "group_priorities",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_max_tokens_preference": {
+          "name": "anthropic_max_tokens_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_thinking_budget_preference": {
+          "name": "anthropic_thinking_budget_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_adaptive_thinking": {
+          "name": "anthropic_adaptive_thinking",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "gemini_google_search_preference": {
+          "name": "gemini_google_search_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type_url_active": {
+          "name": "idx_providers_vendor_type_url_active",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "timezone": {
+          "name": "timezone",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_thinking_budget_rectifier": {
+          "name": "enable_thinking_budget_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_billing_header_rectifier": {
+          "name": "enable_billing_header_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_claude_metadata_user_id_injection": {
+          "name": "enable_claude_metadata_user_id_injection",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "quota_db_refresh_interval_seconds": {
+          "name": "quota_db_refresh_interval_seconds",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10
+        },
+        "quota_lease_percent_5h": {
+          "name": "quota_lease_percent_5h",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_daily": {
+          "name": "quota_lease_percent_daily",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_weekly": {
+          "name": "quota_lease_percent_weekly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_monthly": {
+          "name": "quota_lease_percent_monthly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_cap_usd": {
+          "name": "quota_lease_cap_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_tags_gin": {
+          "name": "idx_users_tags_gin",
+          "columns": [
+            {
+              "expression": "tags",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "gin",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 3171 - 0
drizzle/meta/0071_snapshot.json

@@ -0,0 +1,3171 @@
+{
+  "id": "8ca11370-02da-476b-873f-6bee3a7fe4ad",
+  "prevId": "6195c134-aa4e-4100-9017-495e7d2e2bae",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_key": {
+          "name": "idx_keys_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_created_at_id": {
+          "name": "idx_message_request_key_created_at_id",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at_id_active": {
+          "name": "idx_message_request_created_at_id_active",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_model_active": {
+          "name": "idx_message_request_model_active",
+          "columns": [
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_status_code_active": {
+          "name": "idx_message_request_status_code_active",
+          "columns": [
+            {
+              "expression": "status_code",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"status_code\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_pick_enabled": {
+          "name": "idx_provider_endpoints_pick_enabled",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "sort_order",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "group_priorities": {
+          "name": "group_priorities",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_max_tokens_preference": {
+          "name": "anthropic_max_tokens_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_thinking_budget_preference": {
+          "name": "anthropic_thinking_budget_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_adaptive_thinking": {
+          "name": "anthropic_adaptive_thinking",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "gemini_google_search_preference": {
+          "name": "gemini_google_search_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type_url_active": {
+          "name": "idx_providers_vendor_type_url_active",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "timezone": {
+          "name": "timezone",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_thinking_budget_rectifier": {
+          "name": "enable_thinking_budget_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_billing_header_rectifier": {
+          "name": "enable_billing_header_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_claude_metadata_user_id_injection": {
+          "name": "enable_claude_metadata_user_id_injection",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "quota_db_refresh_interval_seconds": {
+          "name": "quota_db_refresh_interval_seconds",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10
+        },
+        "quota_lease_percent_5h": {
+          "name": "quota_lease_percent_5h",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_daily": {
+          "name": "quota_lease_percent_daily",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_weekly": {
+          "name": "quota_lease_percent_weekly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_monthly": {
+          "name": "quota_lease_percent_monthly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_cap_usd": {
+          "name": "quota_lease_cap_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_tags_gin": {
+          "name": "idx_users_tags_gin",
+          "columns": [
+            {
+              "expression": "tags",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "gin",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 3215 - 0
drizzle/meta/0072_snapshot.json

@@ -0,0 +1,3215 @@
+{
+  "id": "f9f36628-8ee9-464a-94da-8d6ef636ebdb",
+  "prevId": "8ca11370-02da-476b-873f-6bee3a7fe4ad",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_key": {
+          "name": "idx_keys_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_created_at_id": {
+          "name": "idx_message_request_key_created_at_id",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_model_active": {
+          "name": "idx_message_request_key_model_active",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_endpoint_active": {
+          "name": "idx_message_request_key_endpoint_active",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"endpoint\" IS NOT NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at_id_active": {
+          "name": "idx_message_request_created_at_id_active",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_model_active": {
+          "name": "idx_message_request_model_active",
+          "columns": [
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_status_code_active": {
+          "name": "idx_message_request_status_code_active",
+          "columns": [
+            {
+              "expression": "status_code",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"status_code\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_pick_enabled": {
+          "name": "idx_provider_endpoints_pick_enabled",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "sort_order",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "group_priorities": {
+          "name": "group_priorities",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_max_tokens_preference": {
+          "name": "anthropic_max_tokens_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_thinking_budget_preference": {
+          "name": "anthropic_thinking_budget_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_adaptive_thinking": {
+          "name": "anthropic_adaptive_thinking",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "gemini_google_search_preference": {
+          "name": "gemini_google_search_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type_url_active": {
+          "name": "idx_providers_vendor_type_url_active",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "timezone": {
+          "name": "timezone",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_thinking_budget_rectifier": {
+          "name": "enable_thinking_budget_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_billing_header_rectifier": {
+          "name": "enable_billing_header_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_claude_metadata_user_id_injection": {
+          "name": "enable_claude_metadata_user_id_injection",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "quota_db_refresh_interval_seconds": {
+          "name": "quota_db_refresh_interval_seconds",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10
+        },
+        "quota_lease_percent_5h": {
+          "name": "quota_lease_percent_5h",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_daily": {
+          "name": "quota_lease_percent_daily",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_weekly": {
+          "name": "quota_lease_percent_weekly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_monthly": {
+          "name": "quota_lease_percent_monthly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_cap_usd": {
+          "name": "quota_lease_cap_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_tags_gin": {
+          "name": "idx_users_tags_gin",
+          "columns": [
+            {
+              "expression": "tags",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "gin",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 3237 - 0
drizzle/meta/0073_snapshot.json

@@ -0,0 +1,3237 @@
+{
+  "id": "f72efbe3-232d-4af3-aa00-f0e8f7099bdf",
+  "prevId": "f9f36628-8ee9-464a-94da-8d6ef636ebdb",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_key": {
+          "name": "idx_keys_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "bigint",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_created_at_id": {
+          "name": "idx_message_request_key_created_at_id",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_model_active": {
+          "name": "idx_message_request_key_model_active",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key_endpoint_active": {
+          "name": "idx_message_request_key_endpoint_active",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"endpoint\" IS NOT NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at_id_active": {
+          "name": "idx_message_request_created_at_id_active",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_model_active": {
+          "name": "idx_message_request_model_active",
+          "columns": [
+            {
+              "expression": "model",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"model\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_status_code_active": {
+          "name": "idx_message_request_status_code_active",
+          "columns": [
+            {
+              "expression": "status_code",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND \"message_request\".\"status_code\" IS NOT NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_pick_enabled": {
+          "name": "idx_provider_endpoints_pick_enabled",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "sort_order",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "group_priorities": {
+          "name": "group_priorities",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_max_tokens_preference": {
+          "name": "anthropic_max_tokens_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_thinking_budget_preference": {
+          "name": "anthropic_thinking_budget_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "anthropic_adaptive_thinking": {
+          "name": "anthropic_adaptive_thinking",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "gemini_google_search_preference": {
+          "name": "gemini_google_search_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type_url_active": {
+          "name": "idx_providers_vendor_type_url_active",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_enabled_vendor_type": {
+          "name": "idx_providers_enabled_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL AND \"providers\".\"is_enabled\" = true AND \"providers\".\"provider_vendor_id\" IS NOT NULL AND \"providers\".\"provider_vendor_id\" > 0",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "timezone": {
+          "name": "timezone",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_thinking_budget_rectifier": {
+          "name": "enable_thinking_budget_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_billing_header_rectifier": {
+          "name": "enable_billing_header_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_claude_metadata_user_id_injection": {
+          "name": "enable_claude_metadata_user_id_injection",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "quota_db_refresh_interval_seconds": {
+          "name": "quota_db_refresh_interval_seconds",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10
+        },
+        "quota_lease_percent_5h": {
+          "name": "quota_lease_percent_5h",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_daily": {
+          "name": "quota_lease_percent_daily",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_weekly": {
+          "name": "quota_lease_percent_weekly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_percent_monthly": {
+          "name": "quota_lease_percent_monthly",
+          "type": "numeric(5, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.05'"
+        },
+        "quota_lease_cap_usd": {
+          "name": "quota_lease_cap_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_tags_gin": {
+          "name": "idx_users_tags_gin",
+          "columns": [
+            {
+              "expression": "tags",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "gin",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 42 - 0
drizzle/meta/_journal.json

@@ -477,6 +477,48 @@
       "when": 1771045274665,
       "tag": "0067_gorgeous_mulholland_black",
       "breakpoints": true
+    },
+    {
+      "idx": 68,
+      "version": "7",
+      "when": 1771062933911,
+      "tag": "0068_fuzzy_quasar",
+      "breakpoints": true
+    },
+    {
+      "idx": 69,
+      "version": "7",
+      "when": 1771062933912,
+      "tag": "0069_broad_hellfire_club",
+      "breakpoints": true
+    },
+    {
+      "idx": 70,
+      "version": "7",
+      "when": 1771073914978,
+      "tag": "0070_warm_lilandra",
+      "breakpoints": true
+    },
+    {
+      "idx": 71,
+      "version": "7",
+      "when": 1771075313248,
+      "tag": "0071_motionless_wind_dancer",
+      "breakpoints": true
+    },
+    {
+      "idx": 72,
+      "version": "7",
+      "when": 1771110659983,
+      "tag": "0072_absurd_gwen_stacy",
+      "breakpoints": true
+    },
+    {
+      "idx": 73,
+      "version": "7",
+      "when": 1771116859658,
+      "tag": "0073_minor_franklin_richards",
+      "breakpoints": true
     }
   ]
 }

+ 76 - 0
scripts/validate-migrations.js

@@ -132,6 +132,63 @@ function validateMigrationFile(filePath) {
   return { fileName, issues };
 }
 
+/**
+ * 校验 Drizzle journal 的时间戳单调性
+ *
+ * Drizzle PG migrator 仅通过 `created_at(folderMillis)` 与 DB 中最新一条迁移记录做比较来决定是否执行迁移:
+ * - 若 journal 中 `when` 非严格递增,可能导致“后续迁移被永久跳过”(无感升级会漏执行)
+ */
+function validateJournalMonotonicity(journalPath) {
+  const content = fs.readFileSync(journalPath, "utf-8");
+  const journal = JSON.parse(content);
+
+  if (!journal || !Array.isArray(journal.entries)) {
+    return {
+      fileName: path.basename(journalPath),
+      issues: [
+        {
+          type: "JOURNAL",
+          line: 0,
+          statement: "Invalid journal format: entries[] is missing",
+          suggestion: "Ensure drizzle/meta/_journal.json contains a valid { entries: [...] }",
+        },
+      ],
+    };
+  }
+
+  const issues = [];
+  let previousWhen = Number.NEGATIVE_INFINITY;
+  let previousTag = "";
+
+  for (const entry of journal.entries) {
+    const tag = typeof entry?.tag === "string" ? entry.tag : "(unknown)";
+    const when = entry?.when;
+    if (typeof when !== "number" || !Number.isFinite(when)) {
+      issues.push({
+        type: "JOURNAL",
+        line: 0,
+        statement: `Invalid journal entry 'when' for tag=${tag}`,
+        suggestion: "Ensure each journal entry has a numeric 'when' (folderMillis).",
+      });
+      continue;
+    }
+
+    if (when <= previousWhen) {
+      issues.push({
+        type: "JOURNAL",
+        line: 0,
+        statement: `Non-monotonic journal 'when': ${tag}(${when}) <= ${previousTag}(${previousWhen})`,
+        suggestion: "Ensure journal entries' 'when' are strictly increasing in execution order.",
+      });
+    }
+
+    previousWhen = when;
+    previousTag = tag;
+  }
+
+  return { fileName: path.basename(journalPath), issues };
+}
+
 /**
  * 主函数
  */
@@ -155,6 +212,25 @@ function main() {
   let totalIssues = 0;
   const filesWithIssues = [];
 
+  // 校验 meta/_journal.json 的单调性(避免漏迁移)
+  const journalPath = path.join(MIGRATIONS_DIR, "meta/_journal.json");
+  if (fs.existsSync(journalPath)) {
+    const journalResult = validateJournalMonotonicity(journalPath);
+    if (journalResult.issues.length > 0) {
+      totalIssues += journalResult.issues.length;
+      filesWithIssues.push(journalResult);
+      error(`${journalResult.fileName} - 发现 ${journalResult.issues.length} 个问题:`);
+      journalResult.issues.forEach((issue, index) => {
+        console.log(`\n  ${index + 1}. ${issue.type}`);
+        console.log(`     ${colors.red}✗${colors.reset} ${issue.statement}`);
+        console.log(`     ${colors.green}✓${colors.reset} ${issue.suggestion}`);
+      });
+      console.log("");
+    }
+  } else {
+    warn("未找到 meta/_journal.json,无法校验迁移顺序与时间戳单调性");
+  }
+
   // 检查每个文件
   files.forEach((filePath) => {
     const result = validateMigrationFile(filePath);

+ 162 - 145
src/actions/my-usage.ts

@@ -3,7 +3,7 @@
 import { fromZonedTime } from "date-fns-tz";
 import { and, eq, gte, isNull, lt, sql } from "drizzle-orm";
 import { db } from "@/drizzle/db";
-import { keys as keysTable, messageRequest } from "@/drizzle/schema";
+import { messageRequest } from "@/drizzle/schema";
 import { getSession } from "@/lib/auth";
 import { logger } from "@/lib/logger";
 import { resolveKeyConcurrentSessionLimit } from "@/lib/rate-limit/concurrent-session-limit";
@@ -14,11 +14,9 @@ import { resolveSystemTimezone } from "@/lib/utils/timezone";
 import { EXCLUDE_WARMUP_CONDITION } from "@/repository/_shared/message-request-conditions";
 import { getSystemSettings } from "@/repository/system-config";
 import {
-  findUsageLogsStats,
-  findUsageLogsWithDetails,
+  findUsageLogsForKeySlim,
   getDistinctEndpointsForKey,
   getDistinctModelsForKey,
-  type UsageLogFilters,
   type UsageLogSummary,
 } from "@/repository/usage-logs";
 import type { BillingModelSource } from "@/types/system-config";
@@ -179,27 +177,6 @@ export interface MyUsageLogsResult {
 // Infinity means "all time" - no date filter applied to the query
 const ALL_TIME_MAX_AGE_DAYS = Infinity;
 
-/**
- * 查询用户在指定周期内的消费
- * 使用与 Key 层级和限额检查相同的时间范围计算逻辑
- *
- * @deprecated 此函数已被重构为使用统一的时间范围计算逻辑
- */
-async function sumUserCost(userId: number, period: "5h" | "weekly" | "monthly" | "total") {
-  // 动态导入避免循环依赖
-  const { sumUserCostInTimeRange, sumUserTotalCost } = await import("@/repository/statistics");
-  const { getTimeRangeForPeriod } = await import("@/lib/rate-limit/time-utils");
-
-  // 总消费:使用专用函数,传递 ALL_TIME_MAX_AGE_DAYS 实现全时间语义
-  if (period === "total") {
-    return await sumUserTotalCost(userId, ALL_TIME_MAX_AGE_DAYS);
-  }
-
-  // 其他周期:使用统一的时间范围计算
-  const { startTime, endTime } = await getTimeRangeForPeriod(period);
-  return await sumUserCostInTimeRange(userId, startTime, endTime);
-}
-
 export async function getMyUsageMetadata(): Promise<ActionResult<MyUsageMetadata>> {
   try {
     const session = await getSession({ allowReadOnlyAccess: true });
@@ -242,9 +219,7 @@ export async function getMyQuota(): Promise<ActionResult<MyUsageQuota>> {
     const { getTimeRangeForPeriodWithMode, getTimeRangeForPeriod } = await import(
       "@/lib/rate-limit/time-utils"
     );
-    const { sumUserCostInTimeRange, sumKeyCostInTimeRange, sumKeyTotalCostById } = await import(
-      "@/repository/statistics"
-    );
+    const { sumKeyQuotaCostsById, sumUserQuotaCosts } = await import("@/repository/statistics");
 
     // 计算各周期的时间范围
     // Key 使用 Key 的 dailyResetTime/dailyResetMode 配置
@@ -271,36 +246,48 @@ export async function getMyQuota(): Promise<ActionResult<MyUsageQuota>> {
       user.limitConcurrentSessions ?? null
     );
 
-    const [
-      keyCost5h,
-      keyCostDaily,
-      keyCostWeekly,
-      keyCostMonthly,
-      keyTotalCost,
-      keyConcurrent,
-      userCost5h,
-      userCostDaily,
-      userCostWeekly,
-      userCostMonthly,
-      userTotalCost,
-      userKeyConcurrent,
-    ] = await Promise.all([
+    const [keyCosts, keyConcurrent, userCosts, userKeyConcurrent] = await Promise.all([
       // Key 配额:直接查 DB(与 User 保持一致,解决数据源不一致问题)
-      sumKeyCostInTimeRange(key.id, range5h.startTime, range5h.endTime),
-      sumKeyCostInTimeRange(key.id, keyDailyTimeRange.startTime, keyDailyTimeRange.endTime),
-      sumKeyCostInTimeRange(key.id, rangeWeekly.startTime, rangeWeekly.endTime),
-      sumKeyCostInTimeRange(key.id, rangeMonthly.startTime, rangeMonthly.endTime),
-      sumKeyTotalCostById(key.id, ALL_TIME_MAX_AGE_DAYS),
+      sumKeyQuotaCostsById(
+        key.id,
+        {
+          range5h,
+          rangeDaily: keyDailyTimeRange,
+          rangeWeekly,
+          rangeMonthly,
+        },
+        ALL_TIME_MAX_AGE_DAYS
+      ),
       SessionTracker.getKeySessionCount(key.id),
       // User 配额:直接查 DB
-      sumUserCost(user.id, "5h"),
-      sumUserCostInTimeRange(user.id, userDailyTimeRange.startTime, userDailyTimeRange.endTime),
-      sumUserCost(user.id, "weekly"),
-      sumUserCost(user.id, "monthly"),
-      sumUserCost(user.id, "total"),
+      sumUserQuotaCosts(
+        user.id,
+        {
+          range5h,
+          rangeDaily: userDailyTimeRange,
+          rangeWeekly,
+          rangeMonthly,
+        },
+        ALL_TIME_MAX_AGE_DAYS
+      ),
       getUserConcurrentSessions(user.id),
     ]);
 
+    const {
+      cost5h: keyCost5h,
+      costDaily: keyCostDaily,
+      costWeekly: keyCostWeekly,
+      costMonthly: keyCostMonthly,
+      costTotal: keyTotalCost,
+    } = keyCosts;
+    const {
+      cost5h: userCost5h,
+      costDaily: userCostDaily,
+      costWeekly: userCostWeekly,
+      costMonthly: userCostMonthly,
+      costTotal: userTotalCost,
+    } = userCosts;
+
     const quota: MyUsageQuota = {
       keyLimit5hUsd: key.limit5hUsd ?? null,
       keyLimitDailyUsd: key.limitDailyUsd ?? null,
@@ -370,24 +357,6 @@ export async function getMyTodayStats(): Promise<ActionResult<MyTodayStats>> {
       (session.key.dailyResetMode as DailyResetMode | undefined) ?? "fixed"
     );
 
-    const [aggregate] = await db
-      .select({
-        calls: sql<number>`count(*)::int`,
-        inputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}), 0)::double precision`,
-        outputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}), 0)::double precision`,
-        costUsd: sql<string>`COALESCE(sum(${messageRequest.costUsd}), 0)`,
-      })
-      .from(messageRequest)
-      .where(
-        and(
-          eq(messageRequest.key, session.key.key),
-          isNull(messageRequest.deletedAt),
-          EXCLUDE_WARMUP_CONDITION,
-          gte(messageRequest.createdAt, timeRange.startTime),
-          lt(messageRequest.createdAt, timeRange.endTime)
-        )
-      );
-
     const breakdown = await db
       .select({
         model: messageRequest.model,
@@ -409,23 +378,36 @@ export async function getMyTodayStats(): Promise<ActionResult<MyTodayStats>> {
       )
       .groupBy(messageRequest.model, messageRequest.originalModel);
 
+    let totalCalls = 0;
+    let totalInputTokens = 0;
+    let totalOutputTokens = 0;
+    let totalCostUsd = 0;
+
     const modelBreakdown = breakdown.map((row) => {
       const billingModel = billingModelSource === "original" ? row.originalModel : row.model;
+      const rawCostUsd = Number(row.costUsd ?? 0);
+      const costUsd = Number.isFinite(rawCostUsd) ? rawCostUsd : 0;
+
+      totalCalls += row.calls ?? 0;
+      totalInputTokens += row.inputTokens ?? 0;
+      totalOutputTokens += row.outputTokens ?? 0;
+      totalCostUsd += costUsd;
+
       return {
         model: row.model,
         billingModel,
         calls: row.calls,
-        costUsd: Number(row.costUsd ?? 0),
+        costUsd,
         inputTokens: row.inputTokens,
         outputTokens: row.outputTokens,
       };
     });
 
     const stats: MyTodayStats = {
-      calls: aggregate?.calls ?? 0,
-      inputTokens: aggregate?.inputTokens ?? 0,
-      outputTokens: aggregate?.outputTokens ?? 0,
-      costUsd: Number(aggregate?.costUsd ?? 0),
+      calls: totalCalls,
+      inputTokens: totalInputTokens,
+      outputTokens: totalOutputTokens,
+      costUsd: totalCostUsd,
       modelBreakdown,
       currencyCode,
       billingModelSource,
@@ -441,6 +423,8 @@ export async function getMyTodayStats(): Promise<ActionResult<MyTodayStats>> {
 export interface MyUsageLogsFilters {
   startDate?: string;
   endDate?: string;
+  /** Session ID(精确匹配;空字符串/空白视为不筛选) */
+  sessionId?: string;
   model?: string;
   statusCode?: number;
   excludeStatusCode200?: boolean;
@@ -469,9 +453,9 @@ export async function getMyUsageLogs(
       filters.endDate,
       timezone
     );
-
-    const usageFilters: UsageLogFilters = {
-      keyId: session.key.id,
+    const result = await findUsageLogsForKeySlim({
+      keyString: session.key.key,
+      sessionId: filters.sessionId,
       startTime,
       endTime,
       model: filters.model,
@@ -481,9 +465,7 @@ export async function getMyUsageLogs(
       minRetryCount: filters.minRetryCount,
       page,
       pageSize,
-    };
-
-    const result = await findUsageLogsWithDetails(usageFilters);
+    });
 
     const logs: MyUsageLogEntry[] = result.logs.map((log) => {
       const modelRedirect =
@@ -559,13 +541,8 @@ export async function getMyAvailableEndpoints(): Promise<ActionResult<string[]>>
 
 async function getUserConcurrentSessions(userId: number): Promise<number> {
   try {
-    const keys = await db
-      .select({ id: keysTable.id })
-      .from(keysTable)
-      .where(and(eq(keysTable.userId, userId), isNull(keysTable.deletedAt)));
-
-    const counts = await Promise.all(keys.map((k) => SessionTracker.getKeySessionCount(k.id)));
-    return counts.reduce((sum, value) => sum + value, 0);
+    // 直接使用 user 维度的活跃 session 集合,避免 keys × Redis 查询的 N+1
+    return await SessionTracker.getUserSessionCount(userId);
   } catch (error) {
     logger.error("[my-usage] getUserConcurrentSessions failed", error);
     return 0;
@@ -585,6 +562,8 @@ export interface ModelBreakdownItem {
   outputTokens: number;
   cacheCreationTokens: number;
   cacheReadTokens: number;
+  cacheCreation5mTokens: number;
+  cacheCreation1hTokens: number;
 }
 
 export interface MyStatsSummary extends UsageLogSummary {
@@ -595,7 +574,7 @@ export interface MyStatsSummary extends UsageLogSummary {
 
 /**
  * Get aggregated statistics for a date range
- * Uses findUsageLogsStats for efficient aggregation
+ * 通过 model breakdown 聚合,避免额外的 summary 聚合查询
  */
 export async function getMyStatsSummary(
   filters: MyStatsSummaryFilters = {}
@@ -614,80 +593,118 @@ export async function getMyStatsSummary(
       timezone
     );
 
-    // Get aggregated stats using existing repository function
-    const stats = await findUsageLogsStats({
-      keyId: session.key.id,
-      startTime,
-      endTime,
-    });
+    const startDate = startTime ? new Date(startTime) : undefined;
+    const endDate = endTime ? new Date(endTime) : undefined;
 
-    // Get model breakdown for current key
-    const keyBreakdown = await db
-      .select({
-        model: messageRequest.model,
-        requests: sql<number>`count(*)::int`,
-        cost: sql<string>`COALESCE(sum(${messageRequest.costUsd}), 0)`,
-        inputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}), 0)::double precision`,
-        outputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}), 0)::double precision`,
-        cacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}), 0)::double precision`,
-        cacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}), 0)::double precision`,
-      })
-      .from(messageRequest)
-      .where(
-        and(
-          eq(messageRequest.key, session.key.key),
-          isNull(messageRequest.deletedAt),
-          EXCLUDE_WARMUP_CONDITION,
-          startTime ? gte(messageRequest.createdAt, new Date(startTime)) : undefined,
-          endTime ? lt(messageRequest.createdAt, new Date(endTime)) : undefined
-        )
-      )
-      .groupBy(messageRequest.model)
-      .orderBy(sql`sum(${messageRequest.costUsd}) DESC`);
+    const userId = session.user.id;
+    const keyString = session.key.key;
 
-    // Get model breakdown for user (all keys)
-    const userBreakdown = await db
+    // Key 维度是 User 维度的子集:用一条聚合 SQL 扫描 userId 范围即可同时算出两套 breakdown。
+    const modelBreakdown = await db
       .select({
         model: messageRequest.model,
-        requests: sql<number>`count(*)::int`,
-        cost: sql<string>`COALESCE(sum(${messageRequest.costUsd}), 0)`,
-        inputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}), 0)::double precision`,
-        outputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}), 0)::double precision`,
-        cacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}), 0)::double precision`,
-        cacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}), 0)::double precision`,
+        // User breakdown(跨所有 Key)
+        userRequests: sql<number>`count(*)::int`,
+        userCost: sql<string>`COALESCE(sum(${messageRequest.costUsd}), 0)`,
+        userInputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}), 0)::double precision`,
+        userOutputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}), 0)::double precision`,
+        userCacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}), 0)::double precision`,
+        userCacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}), 0)::double precision`,
+        userCacheCreation5mTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation5mInputTokens}), 0)::double precision`,
+        userCacheCreation1hTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation1hInputTokens}), 0)::double precision`,
+        // Key breakdown(FILTER 聚合)
+        keyRequests: sql<number>`count(*) FILTER (WHERE ${messageRequest.key} = ${keyString})::int`,
+        keyCost: sql<string>`COALESCE(sum(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)`,
+        keyInputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)::double precision`,
+        keyOutputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)::double precision`,
+        keyCacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)::double precision`,
+        keyCacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)::double precision`,
+        keyCacheCreation5mTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation5mInputTokens}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)::double precision`,
+        keyCacheCreation1hTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation1hInputTokens}) FILTER (WHERE ${messageRequest.key} = ${keyString}), 0)::double precision`,
       })
       .from(messageRequest)
       .where(
         and(
-          eq(messageRequest.userId, session.user.id),
+          eq(messageRequest.userId, userId),
           isNull(messageRequest.deletedAt),
           EXCLUDE_WARMUP_CONDITION,
-          startTime ? gte(messageRequest.createdAt, new Date(startTime)) : undefined,
-          endTime ? lt(messageRequest.createdAt, new Date(endTime)) : undefined
+          startDate ? gte(messageRequest.createdAt, startDate) : undefined,
+          endDate ? lt(messageRequest.createdAt, endDate) : undefined
         )
       )
       .groupBy(messageRequest.model)
       .orderBy(sql`sum(${messageRequest.costUsd}) DESC`);
 
+    const keyOnlyBreakdown = modelBreakdown.filter((row) => (row.keyRequests ?? 0) > 0);
+
+    const summaryAcc = keyOnlyBreakdown.reduce(
+      (acc, row) => {
+        const cost = Number(row.keyCost ?? 0);
+        acc.totalRequests += row.keyRequests ?? 0;
+        acc.totalCost += Number.isFinite(cost) ? cost : 0;
+        acc.totalInputTokens += row.keyInputTokens ?? 0;
+        acc.totalOutputTokens += row.keyOutputTokens ?? 0;
+        acc.totalCacheCreationTokens += row.keyCacheCreationTokens ?? 0;
+        acc.totalCacheReadTokens += row.keyCacheReadTokens ?? 0;
+        acc.totalCacheCreation5mTokens += row.keyCacheCreation5mTokens ?? 0;
+        acc.totalCacheCreation1hTokens += row.keyCacheCreation1hTokens ?? 0;
+        return acc;
+      },
+      {
+        totalRequests: 0,
+        totalCost: 0,
+        totalInputTokens: 0,
+        totalOutputTokens: 0,
+        totalCacheCreationTokens: 0,
+        totalCacheReadTokens: 0,
+        totalCacheCreation5mTokens: 0,
+        totalCacheCreation1hTokens: 0,
+      }
+    );
+
+    const totalTokens =
+      summaryAcc.totalInputTokens +
+      summaryAcc.totalOutputTokens +
+      summaryAcc.totalCacheCreationTokens +
+      summaryAcc.totalCacheReadTokens;
+
+    const stats: UsageLogSummary = {
+      totalRequests: summaryAcc.totalRequests,
+      totalCost: summaryAcc.totalCost,
+      totalTokens,
+      totalInputTokens: summaryAcc.totalInputTokens,
+      totalOutputTokens: summaryAcc.totalOutputTokens,
+      totalCacheCreationTokens: summaryAcc.totalCacheCreationTokens,
+      totalCacheReadTokens: summaryAcc.totalCacheReadTokens,
+      totalCacheCreation5mTokens: summaryAcc.totalCacheCreation5mTokens,
+      totalCacheCreation1hTokens: summaryAcc.totalCacheCreation1hTokens,
+    };
+
     const result: MyStatsSummary = {
       ...stats,
-      keyModelBreakdown: keyBreakdown.map((row) => ({
+      keyModelBreakdown: keyOnlyBreakdown
+        .map((row) => ({
+          model: row.model,
+          requests: row.keyRequests,
+          cost: Number(row.keyCost ?? 0),
+          inputTokens: row.keyInputTokens,
+          outputTokens: row.keyOutputTokens,
+          cacheCreationTokens: row.keyCacheCreationTokens,
+          cacheReadTokens: row.keyCacheReadTokens,
+          cacheCreation5mTokens: row.keyCacheCreation5mTokens,
+          cacheCreation1hTokens: row.keyCacheCreation1hTokens,
+        }))
+        .sort((a, b) => b.cost - a.cost),
+      userModelBreakdown: modelBreakdown.map((row) => ({
         model: row.model,
-        requests: row.requests,
-        cost: Number(row.cost ?? 0),
-        inputTokens: row.inputTokens,
-        outputTokens: row.outputTokens,
-        cacheCreationTokens: row.cacheCreationTokens,
-        cacheReadTokens: row.cacheReadTokens,
-      })),
-      userModelBreakdown: userBreakdown.map((row) => ({
-        model: row.model,
-        requests: row.requests,
-        cost: Number(row.cost ?? 0),
-        inputTokens: row.inputTokens,
-        outputTokens: row.outputTokens,
-        cacheCreationTokens: row.cacheCreationTokens,
-        cacheReadTokens: row.cacheReadTokens,
+        requests: row.userRequests,
+        cost: Number(row.userCost ?? 0),
+        inputTokens: row.userInputTokens,
+        outputTokens: row.userOutputTokens,
+        cacheCreationTokens: row.userCacheCreationTokens,
+        cacheReadTokens: row.userCacheReadTokens,
+        cacheCreation5mTokens: row.userCacheCreation5mTokens,
+        cacheCreation1hTokens: row.userCacheCreation1hTokens,
       })),
       currencyCode,
     };

+ 360 - 22
src/actions/provider-endpoints.ts

@@ -4,12 +4,13 @@ import { z } from "zod";
 import { getSession } from "@/lib/auth";
 import { publishProviderCacheInvalidation } from "@/lib/cache/provider-cache";
 import {
+  getAllEndpointHealthStatusAsync,
   getEndpointHealthInfo,
   resetEndpointCircuit as resetEndpointCircuitState,
 } from "@/lib/endpoint-circuit-breaker";
 import { logger } from "@/lib/logger";
 import { PROVIDER_ENDPOINT_CONFLICT_CODE } from "@/lib/provider-endpoint-error-codes";
-import { probeProviderEndpointAndRecord } from "@/lib/provider-endpoints/probe";
+import { probeProviderEndpointAndRecordByEndpoint } from "@/lib/provider-endpoints/probe";
 import { ERROR_CODES } from "@/lib/utils/error-messages";
 import { extractZodErrorCode, formatZodError } from "@/lib/utils/zod-i18n";
 import {
@@ -26,11 +27,21 @@ import {
   findProviderEndpointsByVendorAndType,
   findProviderVendorById,
   findProviderVendors,
+  findProviderVendorsByIds,
   softDeleteProviderEndpoint,
   tryDeleteProviderVendorIfEmpty,
   updateProviderEndpoint,
   updateProviderVendor,
 } from "@/repository";
+import {
+  findDashboardProviderEndpointsByVendorAndType,
+  findEnabledProviderVendorTypePairs,
+  hasEnabledProviderReferenceForVendorTypeUrl,
+} from "@/repository/provider-endpoints";
+import {
+  findProviderEndpointProbeLogsBatch,
+  findVendorTypeEndpointStatsBatch,
+} from "@/repository/provider-endpoints-batch";
 import type {
   ProviderEndpoint,
   ProviderEndpointProbeLog,
@@ -127,6 +138,16 @@ const BatchGetEndpointCircuitInfoSchema = z.object({
   endpointIds: z.array(EndpointIdSchema).max(500),
 });
 
+const BatchGetVendorTypeEndpointStatsSchema = z.object({
+  vendorIds: z.array(VendorIdSchema).max(500),
+  providerType: ProviderTypeSchema,
+});
+
+const BatchGetProviderEndpointProbeLogsBatchSchema = z.object({
+  endpointIds: z.array(EndpointIdSchema).max(500),
+  limit: z.number().int().min(1).max(200).optional(),
+});
+
 async function getAdminSession() {
   const session = await getSession();
   if (!session || session.user.role !== "admin") {
@@ -170,6 +191,34 @@ function isDirectEndpointEditConflictError(error: unknown): boolean {
   );
 }
 
+function isForeignKeyViolationError(error: unknown): boolean {
+  if (!error || typeof error !== "object") {
+    return false;
+  }
+
+  const candidate = error as {
+    code?: string;
+    message?: string;
+    cause?: { code?: string; message?: string };
+  };
+
+  if (candidate.code === "23503" || candidate.cause?.code === "23503") {
+    return true;
+  }
+
+  if (
+    typeof candidate.message === "string" &&
+    candidate.message.includes("foreign key constraint")
+  ) {
+    return true;
+  }
+
+  return (
+    typeof candidate.cause?.message === "string" &&
+    candidate.cause.message.includes("foreign key constraint")
+  );
+}
+
 export async function getProviderVendors(): Promise<ProviderVendor[]> {
   try {
     const session = await getAdminSession();
@@ -184,6 +233,48 @@ export async function getProviderVendors(): Promise<ProviderVendor[]> {
   }
 }
 
+export type DashboardProviderVendor = ProviderVendor & { providerTypes: ProviderType[] };
+
+export async function getDashboardProviderVendors(): Promise<DashboardProviderVendor[]> {
+  try {
+    const session = await getAdminSession();
+    if (!session) {
+      return [];
+    }
+
+    const typeOrder = new Map<string, number>(
+      ProviderTypeSchema.options.map((value, index) => [value, index])
+    );
+
+    const typesByVendorId = new Map<number, Set<ProviderType>>();
+    const enabledVendorTypePairs = await findEnabledProviderVendorTypePairs();
+    for (const { vendorId, providerType } of enabledVendorTypePairs) {
+      const existing = typesByVendorId.get(vendorId) ?? new Set<ProviderType>();
+      existing.add(providerType);
+      typesByVendorId.set(vendorId, existing);
+    }
+
+    const vendorIds = [...typesByVendorId.keys()];
+    if (vendorIds.length === 0) {
+      return [];
+    }
+
+    const vendors = await findProviderVendorsByIds(vendorIds);
+
+    return vendors
+      .map((vendor) => {
+        const types = Array.from(typesByVendorId.get(vendor.id) ?? []).sort(
+          (left, right) => (typeOrder.get(left) ?? 999) - (typeOrder.get(right) ?? 999)
+        );
+        return { ...vendor, providerTypes: types };
+      })
+      .filter((vendor) => vendor.providerTypes.length > 0);
+  } catch (error) {
+    logger.error("getDashboardProviderVendors:error", error);
+    return [];
+  }
+}
+
 export async function getProviderVendorById(vendorId: number): Promise<ProviderVendor | null> {
   try {
     const session = await getAdminSession();
@@ -226,6 +317,34 @@ export async function getProviderEndpoints(input: {
   }
 }
 
+export async function getDashboardProviderEndpoints(input: {
+  vendorId: number;
+  providerType: ProviderType;
+}): Promise<ProviderEndpoint[]> {
+  try {
+    const session = await getAdminSession();
+    if (!session) {
+      return [];
+    }
+
+    const parsed = GetProviderEndpointsSchema.safeParse(input);
+    if (!parsed.success) {
+      logger.debug("getDashboardProviderEndpoints:invalid_input", {
+        error: parsed.error,
+      });
+      return [];
+    }
+
+    return await findDashboardProviderEndpointsByVendorAndType(
+      parsed.data.vendorId,
+      parsed.data.providerType as ProviderTypeInput
+    );
+  } catch (error) {
+    logger.error("getDashboardProviderEndpoints:error", error);
+    return [];
+  }
+}
+
 export async function getProviderEndpointsByVendor(input: {
   vendorId: number;
 }): Promise<ProviderEndpoint[]> {
@@ -281,9 +400,35 @@ export async function addProviderEndpoint(
       isEnabled: parsed.data.isEnabled ?? true,
     });
 
+    try {
+      await publishProviderCacheInvalidation();
+    } catch (error) {
+      logger.warn("addProviderEndpoint:cache_invalidation_failed", {
+        vendorId: parsed.data.vendorId,
+        error: error instanceof Error ? error.message : String(error),
+      });
+    }
+
     return { ok: true, data: { endpoint } };
   } catch (error) {
     logger.error("addProviderEndpoint:error", error);
+
+    if (isDirectEndpointEditConflictError(error)) {
+      return {
+        ok: false,
+        error: "端点 URL 与同供应商类型下的其他端点冲突",
+        errorCode: ERROR_CODES.CONFLICT,
+      };
+    }
+
+    if (isForeignKeyViolationError(error)) {
+      return {
+        ok: false,
+        error: "供应商不存在",
+        errorCode: ERROR_CODES.NOT_FOUND,
+      };
+    }
+
     const message = error instanceof Error ? error.message : "创建端点失败";
     return { ok: false, error: message, errorCode: ERROR_CODES.CREATE_FAILED };
   }
@@ -311,6 +456,15 @@ export async function editProviderEndpoint(
       };
     }
 
+    const previous = await findProviderEndpointById(parsed.data.endpointId);
+    if (!previous || previous.deletedAt !== null) {
+      return {
+        ok: false,
+        error: "端点不存在",
+        errorCode: ERROR_CODES.NOT_FOUND,
+      };
+    }
+
     const endpoint = await updateProviderEndpoint(parsed.data.endpointId, {
       url: parsed.data.url,
       label: parsed.data.label,
@@ -326,6 +480,32 @@ export async function editProviderEndpoint(
       };
     }
 
+    const shouldResetCircuit =
+      (parsed.data.url !== undefined && parsed.data.url !== previous.url) ||
+      (parsed.data.isEnabled === true && previous.isEnabled === false);
+
+    if (shouldResetCircuit) {
+      try {
+        await resetEndpointCircuitState(endpoint.id);
+      } catch (error) {
+        logger.warn("editProviderEndpoint:reset_circuit_failed", {
+          endpointId: endpoint.id,
+          vendorId: endpoint.vendorId,
+          error: error instanceof Error ? error.message : String(error),
+        });
+      }
+    }
+
+    try {
+      await publishProviderCacheInvalidation();
+    } catch (error) {
+      logger.warn("editProviderEndpoint:cache_invalidation_failed", {
+        endpointId: parsed.data.endpointId,
+        vendorId: endpoint.vendorId,
+        error: error instanceof Error ? error.message : String(error),
+      });
+    }
+
     return { ok: true, data: { endpoint } };
   } catch (error) {
     logger.error("editProviderEndpoint:error", error);
@@ -371,6 +551,21 @@ export async function removeProviderEndpoint(input: unknown): Promise<ActionResu
       };
     }
 
+    // 若该端点仍被启用 provider 引用,则不允许删除:否则会导致运行时 endpoint pool 变空/回填复活,
+    // 产生“删了但还在/仍被探测”的困惑(#781)。
+    const referencedByEnabledProvider = await hasEnabledProviderReferenceForVendorTypeUrl({
+      vendorId: endpoint.vendorId,
+      providerType: endpoint.providerType,
+      url: endpoint.url,
+    });
+    if (referencedByEnabledProvider) {
+      return {
+        ok: false,
+        error: "该端点仍被启用的供应商引用,请先修改或禁用相关供应商的 URL 后再删除",
+        errorCode: ERROR_CODES.CONFLICT,
+      };
+    }
+
     const ok = await softDeleteProviderEndpoint(parsed.data.endpointId);
     if (!ok) {
       return {
@@ -380,6 +575,16 @@ export async function removeProviderEndpoint(input: unknown): Promise<ActionResu
       };
     }
 
+    try {
+      await resetEndpointCircuitState(endpoint.id);
+    } catch (error) {
+      logger.warn("removeProviderEndpoint:reset_circuit_failed", {
+        endpointId: parsed.data.endpointId,
+        vendorId: endpoint.vendorId,
+        error: error instanceof Error ? error.message : String(error),
+      });
+    }
+
     // Auto cleanup: if the vendor has no active providers/endpoints, delete it as well.
     try {
       await tryDeleteProviderVendorIfEmpty(endpoint.vendorId);
@@ -391,6 +596,16 @@ export async function removeProviderEndpoint(input: unknown): Promise<ActionResu
       });
     }
 
+    try {
+      await publishProviderCacheInvalidation();
+    } catch (error) {
+      logger.warn("removeProviderEndpoint:cache_invalidation_failed", {
+        endpointId: parsed.data.endpointId,
+        vendorId: endpoint.vendorId,
+        error: error instanceof Error ? error.message : String(error),
+      });
+    }
+
     return { ok: true };
   } catch (error) {
     logger.error("removeProviderEndpoint:error", error);
@@ -440,20 +655,12 @@ export async function probeProviderEndpoint(input: unknown): Promise<
       };
     }
 
-    const result = await probeProviderEndpointAndRecord({
-      endpointId: endpoint.id,
+    const result = await probeProviderEndpointAndRecordByEndpoint({
+      endpoint,
       source: "manual",
       timeoutMs: parsed.data.timeoutMs,
     });
 
-    if (!result) {
-      return {
-        ok: false,
-        error: "端点不存在",
-        errorCode: ERROR_CODES.NOT_FOUND,
-      };
-    }
-
     return { ok: true, data: { endpoint, result } };
   } catch (error) {
     logger.error("probeProviderEndpoint:error", error);
@@ -498,6 +705,125 @@ export async function getProviderEndpointProbeLogs(
   }
 }
 
+export async function batchGetProviderEndpointProbeLogs(
+  input: unknown
+): Promise<ActionResult<Array<{ endpointId: number; logs: ProviderEndpointProbeLog[] }>>> {
+  try {
+    const session = await getAdminSession();
+    if (!session) {
+      return {
+        ok: false,
+        error: "无权限执行此操作",
+        errorCode: ERROR_CODES.PERMISSION_DENIED,
+      };
+    }
+
+    const parsed = BatchGetProviderEndpointProbeLogsBatchSchema.safeParse(input);
+    if (!parsed.success) {
+      return {
+        ok: false,
+        error: formatZodError(parsed.error),
+        errorCode: extractZodErrorCode(parsed.error),
+      };
+    }
+
+    const endpointIds = Array.from(new Set(parsed.data.endpointIds));
+    if (endpointIds.length === 0) {
+      return { ok: true, data: [] };
+    }
+
+    const limitPerEndpoint = parsed.data.limit ?? 12;
+    const logsByEndpointId = await findProviderEndpointProbeLogsBatch({
+      endpointIds,
+      limitPerEndpoint,
+    });
+
+    return {
+      ok: true,
+      data: endpointIds.map((endpointId) => ({
+        endpointId,
+        logs: logsByEndpointId.get(endpointId) ?? [],
+      })),
+    };
+  } catch (error) {
+    logger.error("batchGetProviderEndpointProbeLogs:error", error);
+    return {
+      ok: false,
+      error: "批量获取端点测活历史失败",
+      errorCode: ERROR_CODES.OPERATION_FAILED,
+    };
+  }
+}
+
+export async function batchGetVendorTypeEndpointStats(input: unknown): Promise<
+  ActionResult<
+    Array<{
+      vendorId: number;
+      providerType: ProviderType;
+      total: number;
+      enabled: number;
+      healthy: number;
+      unhealthy: number;
+      unknown: number;
+    }>
+  >
+> {
+  try {
+    const session = await getAdminSession();
+    if (!session) {
+      return {
+        ok: false,
+        error: "无权限执行此操作",
+        errorCode: ERROR_CODES.PERMISSION_DENIED,
+      };
+    }
+
+    const parsed = BatchGetVendorTypeEndpointStatsSchema.safeParse(input);
+    if (!parsed.success) {
+      return {
+        ok: false,
+        error: formatZodError(parsed.error),
+        errorCode: extractZodErrorCode(parsed.error),
+      };
+    }
+
+    const vendorIds = Array.from(new Set(parsed.data.vendorIds));
+    if (vendorIds.length === 0) {
+      return { ok: true, data: [] };
+    }
+
+    const rows = await findVendorTypeEndpointStatsBatch({
+      vendorIds,
+      providerType: parsed.data.providerType as ProviderTypeInput,
+    });
+
+    const statsByVendorId = new Map(rows.map((row) => [row.vendorId, row]));
+
+    return {
+      ok: true,
+      data: vendorIds.map((vendorId) => {
+        const stats = statsByVendorId.get(vendorId);
+        return {
+          vendorId,
+          providerType: parsed.data.providerType,
+          total: stats?.total ?? 0,
+          enabled: stats?.enabled ?? 0,
+          healthy: stats?.healthy ?? 0,
+          unhealthy: stats?.unhealthy ?? 0,
+          unknown: stats?.unknown ?? 0,
+        };
+      }),
+    };
+  } catch (error) {
+    logger.error("batchGetVendorTypeEndpointStats:error", error);
+    return {
+      ok: false,
+      error: "批量获取供应商端点统计失败",
+      errorCode: ERROR_CODES.OPERATION_FAILED,
+    };
+  }
+}
+
 export async function getEndpointCircuitInfo(input: unknown): Promise<
   ActionResult<{
     endpointId: number;
@@ -584,17 +910,20 @@ export async function batchGetEndpointCircuitInfo(input: unknown): Promise<
       return { ok: true, data: [] };
     }
 
-    const results = await Promise.all(
-      parsed.data.endpointIds.map(async (endpointId) => {
-        const { health } = await getEndpointHealthInfo(endpointId);
-        return {
-          endpointId,
-          circuitState: health.circuitState,
-          failureCount: health.failureCount,
-          circuitOpenUntil: health.circuitOpenUntil,
-        };
-      })
-    );
+    const endpointIds = parsed.data.endpointIds;
+    const uniqueEndpointIds = Array.from(new Set(endpointIds));
+    const healthStatus = await getAllEndpointHealthStatusAsync(uniqueEndpointIds);
+
+    const results = endpointIds.map((endpointId) => {
+      const info = healthStatus[endpointId];
+
+      return {
+        endpointId,
+        circuitState: info?.circuitState ?? "closed",
+        failureCount: info?.failureCount ?? 0,
+        circuitOpenUntil: info?.circuitOpenUntil ?? null,
+      };
+    });
 
     return { ok: true, data: results };
   } catch (error) {
@@ -795,6 +1124,15 @@ export async function editProviderVendor(
       };
     }
 
+    try {
+      await publishProviderCacheInvalidation();
+    } catch (error) {
+      logger.warn("editProviderVendor:cache_invalidation_failed", {
+        vendorId: parsed.data.vendorId,
+        error: error instanceof Error ? error.message : String(error),
+      });
+    }
+
     return { ok: true, data: { vendor } };
   } catch (error) {
     logger.error("editProviderVendor:error", error);

+ 3 - 5
src/actions/providers.ts

@@ -50,7 +50,7 @@ import {
 import {
   backfillProviderEndpointsFromProviders,
   computeVendorKey,
-  findProviderVendorById,
+  findProviderVendorsByIds,
   getOrCreateProviderVendorIdFromUrls,
   tryDeleteProviderVendorIfEmpty,
 } from "@/repository/provider-endpoints";
@@ -3663,10 +3663,8 @@ export async function reclusterProviderVendors(args: {
           .filter((id): id is number => id !== null && id !== undefined && id > 0)
       ),
     ];
-    const vendors = await Promise.all(uniqueVendorIds.map((id) => findProviderVendorById(id)));
-    const vendorMap = new Map(
-      vendors.filter((v): v is NonNullable<typeof v> => v !== null).map((v) => [v.id, v])
-    );
+    const vendors = await findProviderVendorsByIds(uniqueVendorIds);
+    const vendorMap = new Map(vendors.map((vendor) => [vendor.id, vendor]));
 
     // Build provider map for quick lookup in transaction
     const providerMap = new Map(allProviders.map((p) => [p.id, p]));

+ 143 - 54
src/app/[locale]/dashboard/availability/_components/availability-dashboard.tsx

@@ -1,7 +1,7 @@
 "use client";
 
 import { useTranslations } from "next-intl";
-import { useCallback, useEffect, useState } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
 import type { AvailabilityQueryResult } from "@/lib/availability";
 import { cn } from "@/lib/utils";
@@ -37,79 +37,166 @@ export function AvailabilityDashboard() {
   const [refreshing, setRefreshing] = useState(false);
   const [error, setError] = useState<string | null>(null);
 
-  const fetchData = useCallback(async () => {
-    try {
-      setRefreshing(true);
-      const now = new Date();
-      const timeRangeMs = TIME_RANGE_MAP[timeRange];
-      const startTime = new Date(now.getTime() - timeRangeMs);
-      const bucketSizeMinutes = calculateBucketSize(timeRangeMs);
-
-      const params = new URLSearchParams({
-        startTime: startTime.toISOString(),
-        endTime: now.toISOString(),
-        bucketSizeMinutes: bucketSizeMinutes.toString(),
-        maxBuckets: TARGET_BUCKETS.toString(),
-      });
-
-      const res = await fetch(`/api/availability?${params}`);
-      if (!res.ok) {
-        throw new Error(t("states.fetchFailed"));
+  const requestIdRef = useRef(0);
+  const inFlightRef = useRef(false);
+  const abortControllerRef = useRef<AbortController | null>(null);
+  const lastFocusRefreshAtRef = useRef(0);
+
+  const fetchData = useCallback(
+    async (options?: { force?: boolean }) => {
+      const force = options?.force ?? false;
+
+      if (inFlightRef.current && !force) {
+        return;
       }
 
-      const result: AvailabilityQueryResult = await res.json();
-      setData(result);
-      setError(null);
-    } catch (err) {
-      console.error("Failed to fetch availability data:", err);
-      setError(err instanceof Error ? err.message : t("states.fetchFailed"));
-    } finally {
-      setLoading(false);
-      setRefreshing(false);
-    }
-  }, [timeRange, t]);
+      if (force) {
+        abortControllerRef.current?.abort();
+      }
+
+      const requestId = ++requestIdRef.current;
+      const controller = new AbortController();
+      abortControllerRef.current = controller;
+      inFlightRef.current = true;
+
+      try {
+        setRefreshing(true);
+        const now = new Date();
+        const timeRangeMs = TIME_RANGE_MAP[timeRange];
+        const startTime = new Date(now.getTime() - timeRangeMs);
+        const bucketSizeMinutes = calculateBucketSize(timeRangeMs);
+
+        const params = new URLSearchParams({
+          startTime: startTime.toISOString(),
+          endTime: now.toISOString(),
+          bucketSizeMinutes: bucketSizeMinutes.toString(),
+          maxBuckets: TARGET_BUCKETS.toString(),
+        });
+
+        const res = await fetch(`/api/availability?${params}`, {
+          signal: controller.signal,
+          cache: "no-store",
+        });
+        if (!res.ok) {
+          throw new Error(t("states.fetchFailed"));
+        }
+
+        const result: AvailabilityQueryResult = await res.json();
+        if (requestId !== requestIdRef.current) {
+          return;
+        }
+        setData(result);
+        setError(null);
+      } catch (err) {
+        if (controller.signal.aborted) {
+          return;
+        }
+        if (requestId !== requestIdRef.current) {
+          return;
+        }
+        console.error("Failed to fetch availability data:", err);
+        setError(err instanceof Error ? err.message : t("states.fetchFailed"));
+      } finally {
+        if (requestId === requestIdRef.current) {
+          setLoading(false);
+          setRefreshing(false);
+          inFlightRef.current = false;
+        }
+      }
+    },
+    [timeRange, t]
+  );
 
   useEffect(() => {
-    fetchData();
+    void fetchData({ force: true });
   }, [fetchData]);
 
   // Auto-refresh: 30s for provider tab, 10s for endpoint tab
   useEffect(() => {
     const interval = activeTab === "provider" ? 30000 : 10000;
-    const timer = setInterval(fetchData, interval);
+    const timer = setInterval(() => {
+      if (document.visibilityState === "hidden") return;
+      void fetchData();
+    }, interval);
     return () => clearInterval(timer);
   }, [activeTab, fetchData]);
 
-  // Calculate overview metrics
-  const providers = data?.providers ?? [];
-  const overviewMetrics = {
-    systemAvailability: data?.systemAvailability ?? 0,
-    avgLatency:
-      providers.length > 0
-        ? providers.reduce((sum, p) => {
+  // 当页面从后台回到前台时,做一次节流刷新,避免看到陈旧数据;同时配合 visibility 判断减少后台请求。
+  useEffect(() => {
+    const refresh = () => {
+      const now = Date.now();
+      if (now - lastFocusRefreshAtRef.current < 2000) return;
+      lastFocusRefreshAtRef.current = now;
+      void fetchData({ force: true });
+    };
+
+    const onFocus = () => refresh();
+    const onVisibilityChange = () => {
+      if (document.visibilityState === "visible") {
+        refresh();
+      }
+    };
+
+    window.addEventListener("focus", onFocus);
+    document.addEventListener("visibilitychange", onVisibilityChange);
+
+    return () => {
+      window.removeEventListener("focus", onFocus);
+      document.removeEventListener("visibilitychange", onVisibilityChange);
+    };
+  }, [fetchData]);
+
+  useEffect(() => {
+    return () => {
+      abortControllerRef.current?.abort();
+    };
+  }, []);
+
+  const overviewMetrics = useMemo(() => {
+    const providers = data?.providers ?? [];
+    const providersWithLatency = providers.filter((p) =>
+      p.timeBuckets.some((b) => b.avgLatencyMs > 0)
+    );
+
+    let activeProbes = 0;
+    let healthyCount = 0;
+    let unhealthyCount = 0;
+    for (const provider of providers) {
+      if (provider.currentStatus !== "unknown") activeProbes += 1;
+      if (provider.currentStatus === "green") healthyCount += 1;
+      if (provider.currentStatus === "red") unhealthyCount += 1;
+    }
+
+    const avgLatency =
+      providersWithLatency.length > 0
+        ? providersWithLatency.reduce((sum, p) => {
             const latencies = p.timeBuckets
               .filter((b) => b.avgLatencyMs > 0)
               .map((b) => b.avgLatencyMs);
-            return (
-              sum +
-              (latencies.length > 0 ? latencies.reduce((a, b) => a + b, 0) / latencies.length : 0)
-            );
-          }, 0) /
-          Math.max(1, providers.filter((p) => p.timeBuckets.some((b) => b.avgLatencyMs > 0)).length)
-        : 0,
-    errorRate:
+            if (latencies.length === 0) return sum;
+            return sum + latencies.reduce((a, b) => a + b, 0) / latencies.length;
+          }, 0) / providersWithLatency.length
+        : 0;
+
+    const errorRate =
       providers.length > 0
         ? providers.reduce((sum, p) => {
             const total = p.totalRequests;
             const errors = p.timeBuckets.reduce((s, b) => s + b.redCount, 0);
             return sum + (total > 0 ? errors / total : 0);
           }, 0) / providers.length
-        : 0,
-    activeProbes: providers.filter((p) => p.currentStatus !== "unknown").length,
-    totalProbes: providers.length,
-    healthyCount: providers.filter((p) => p.currentStatus === "green").length,
-    unhealthyCount: providers.filter((p) => p.currentStatus === "red").length,
-  };
+        : 0;
+
+    return {
+      systemAvailability: data?.systemAvailability ?? 0,
+      avgLatency,
+      errorRate,
+      activeProbes,
+      totalProbes: providers.length,
+      healthyCount,
+      unhealthyCount,
+    };
+  }, [data]);
 
   return (
     <div className="space-y-6">
@@ -157,7 +244,9 @@ export function AvailabilityDashboard() {
             error={error}
             timeRange={timeRange}
             onTimeRangeChange={setTimeRange}
-            onRefresh={fetchData}
+            onRefresh={() => {
+              void fetchData({ force: true });
+            }}
           />
         </TabsContent>
 

+ 67 - 47
src/app/[locale]/dashboard/availability/_components/endpoint-probe-history.tsx

@@ -5,7 +5,12 @@ import { Activity, CheckCircle2, Play, RefreshCw, XCircle } from "lucide-react";
 import { useTimeZone, useTranslations } from "next-intl";
 import { useCallback, useEffect, useState } from "react";
 import { toast } from "sonner";
-import { getProviderVendors, probeProviderEndpoint } from "@/actions/provider-endpoints";
+import {
+  type DashboardProviderVendor,
+  getDashboardProviderEndpoints,
+  getDashboardProviderVendors,
+  probeProviderEndpoint,
+} from "@/actions/provider-endpoints";
 import { Badge } from "@/components/ui/badge";
 import { Button } from "@/components/ui/button";
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
@@ -26,33 +31,19 @@ import {
 } from "@/components/ui/table";
 import { cn } from "@/lib/utils";
 import { getErrorMessage } from "@/lib/utils/error-messages";
-import type {
-  ProviderEndpoint,
-  ProviderEndpointProbeLog,
-  ProviderType,
-  ProviderVendor,
-} from "@/types/provider";
-
-const PROVIDER_TYPES: ProviderType[] = [
-  "claude",
-  "claude-auth",
-  "codex",
-  "gemini-cli",
-  "gemini",
-  "openai-compatible",
-];
+import type { ProviderEndpoint, ProviderEndpointProbeLog, ProviderType } from "@/types/provider";
 
 export function EndpointProbeHistory() {
   const t = useTranslations("dashboard.availability");
   const tErrors = useTranslations("errors");
   const timeZone = useTimeZone() ?? "UTC";
 
-  const [vendors, setVendors] = useState<ProviderVendor[]>([]);
-  const [selectedVendorId, setSelectedVendorId] = useState<string>("");
-  const [selectedType, setSelectedType] = useState<ProviderType | "">("");
+  const [vendors, setVendors] = useState<DashboardProviderVendor[]>([]);
+  const [selectedVendorId, setSelectedVendorId] = useState<number | null>(null);
+  const [selectedType, setSelectedType] = useState<ProviderType | null>(null);
 
   const [endpoints, setEndpoints] = useState<ProviderEndpoint[]>([]);
-  const [selectedEndpointId, setSelectedEndpointId] = useState<string>("");
+  const [selectedEndpointId, setSelectedEndpointId] = useState<number | null>(null);
   const [loadingEndpoints, setLoadingEndpoints] = useState(false);
 
   const [logs, setLogs] = useState<ProviderEndpointProbeLog[]>([]);
@@ -61,33 +52,35 @@ export function EndpointProbeHistory() {
   const [probing, setProbing] = useState(false);
 
   useEffect(() => {
-    getProviderVendors().then(setVendors).catch(console.error);
+    getDashboardProviderVendors()
+      .then((vendors) => {
+        setVendors(vendors);
+        if (vendors.length > 0) {
+          setSelectedVendorId(vendors[0].id);
+          setSelectedType(vendors[0].providerTypes[0] ?? null);
+        }
+      })
+      .catch(console.error);
   }, []);
 
   useEffect(() => {
     if (!selectedVendorId || !selectedType) {
       setEndpoints([]);
-      setSelectedEndpointId("");
+      setSelectedEndpointId(null);
       return;
     }
 
     setLoadingEndpoints(true);
-    const params = new URLSearchParams({
-      vendorId: selectedVendorId,
-      providerType: selectedType,
-    });
 
-    fetch(`/api/availability/endpoints?${params.toString()}`)
-      .then((res) => res.json())
+    getDashboardProviderEndpoints({ vendorId: selectedVendorId, providerType: selectedType })
       .then((data) => {
-        if (data.endpoints) {
-          setEndpoints(data.endpoints);
-          setSelectedEndpointId((prev) =>
-            prev && !data.endpoints.some((e: ProviderEndpoint) => e.id.toString() === prev)
-              ? ""
-              : prev
-          );
-        }
+        setEndpoints(data);
+        setSelectedEndpointId((prev) => {
+          if (!prev) {
+            return data[0]?.id ?? null;
+          }
+          return data.some((endpoint) => endpoint.id === prev) ? prev : (data[0]?.id ?? null);
+        });
       })
       .catch(console.error)
       .finally(() => setLoadingEndpoints(false));
@@ -102,7 +95,7 @@ export function EndpointProbeHistory() {
     setLoadingLogs(true);
     try {
       const params = new URLSearchParams({
-        endpointId: selectedEndpointId,
+        endpointId: selectedEndpointId.toString(),
         limit: "50",
       });
       const res = await fetch(`/api/availability/endpoints/probe-logs?${params.toString()}`);
@@ -127,7 +120,7 @@ export function EndpointProbeHistory() {
     setProbing(true);
     try {
       const result = await probeProviderEndpoint({
-        endpointId: Number.parseInt(selectedEndpointId, 10),
+        endpointId: selectedEndpointId,
         timeoutMs: 10000,
       });
 
@@ -163,7 +156,19 @@ export function EndpointProbeHistory() {
             <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
               {t("probeHistory.selectVendor")}
             </label>
-            <Select value={selectedVendorId} onValueChange={setSelectedVendorId}>
+            <Select
+              value={selectedVendorId?.toString() || ""}
+              onValueChange={(value) => {
+                const vendorId = Number.parseInt(value, 10);
+                if (!Number.isFinite(vendorId)) {
+                  return;
+                }
+                setSelectedVendorId(vendorId);
+                const vendor = vendors.find((v) => v.id === vendorId);
+                setSelectedType(vendor?.providerTypes[0] ?? null);
+                setSelectedEndpointId(null);
+              }}
+            >
               <SelectTrigger>
                 <SelectValue placeholder={t("probeHistory.selectVendor")} />
               </SelectTrigger>
@@ -181,16 +186,25 @@ export function EndpointProbeHistory() {
             <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
               {t("probeHistory.selectType")}
             </label>
-            <Select value={selectedType} onValueChange={(v) => setSelectedType(v as ProviderType)}>
+            <Select
+              value={selectedType || ""}
+              onValueChange={(v) => {
+                setSelectedType(v as ProviderType);
+                setSelectedEndpointId(null);
+              }}
+              disabled={!selectedVendorId}
+            >
               <SelectTrigger>
                 <SelectValue placeholder={t("probeHistory.selectType")} />
               </SelectTrigger>
               <SelectContent>
-                {PROVIDER_TYPES.map((type) => (
-                  <SelectItem key={type} value={type}>
-                    {type}
-                  </SelectItem>
-                ))}
+                {(vendors.find((v) => v.id === selectedVendorId)?.providerTypes ?? []).map(
+                  (type) => (
+                    <SelectItem key={type} value={type}>
+                      {type}
+                    </SelectItem>
+                  )
+                )}
               </SelectContent>
             </Select>
           </div>
@@ -200,8 +214,14 @@ export function EndpointProbeHistory() {
               {t("probeHistory.selectEndpoint")}
             </label>
             <Select
-              value={selectedEndpointId}
-              onValueChange={setSelectedEndpointId}
+              value={selectedEndpointId?.toString() || ""}
+              onValueChange={(value) => {
+                const endpointId = Number.parseInt(value, 10);
+                if (!Number.isFinite(endpointId)) {
+                  return;
+                }
+                setSelectedEndpointId(endpointId);
+              }}
               disabled={loadingEndpoints || endpoints.length === 0}
             >
               <SelectTrigger>

+ 263 - 86
src/app/[locale]/dashboard/availability/_components/endpoint/endpoint-tab.tsx

@@ -2,12 +2,13 @@
 
 import { Radio } from "lucide-react";
 import { useTranslations } from "next-intl";
-import { useCallback, useEffect, useState } from "react";
+import { useCallback, useEffect, useRef, useState } from "react";
 import { toast } from "sonner";
 import {
+  type DashboardProviderVendor,
+  getDashboardProviderEndpoints,
+  getDashboardProviderVendors,
   getProviderEndpointProbeLogs,
-  getProviderEndpoints,
-  getProviderVendors,
   probeProviderEndpoint,
 } from "@/actions/provider-endpoints";
 import { Button } from "@/components/ui/button";
@@ -20,33 +21,16 @@ import {
 } from "@/components/ui/select";
 import { Skeleton } from "@/components/ui/skeleton";
 import { cn } from "@/lib/utils";
-import type { ProviderEndpoint, ProviderEndpointProbeLog, ProviderVendor } from "@/types/provider";
+import type { ProviderEndpoint, ProviderEndpointProbeLog, ProviderType } from "@/types/provider";
 import { LatencyCurve } from "./latency-curve";
 import { ProbeGrid } from "./probe-grid";
 import { ProbeTerminal } from "./probe-terminal";
 
-type ProviderType =
-  | "claude"
-  | "claude-auth"
-  | "codex"
-  | "gemini"
-  | "gemini-cli"
-  | "openai-compatible";
-
-const PROVIDER_TYPES: ProviderType[] = [
-  "claude",
-  "claude-auth",
-  "codex",
-  "gemini",
-  "gemini-cli",
-  "openai-compatible",
-];
-
 export function EndpointTab() {
   const t = useTranslations("dashboard.availability");
 
   // State
-  const [vendors, setVendors] = useState<ProviderVendor[]>([]);
+  const [vendors, setVendors] = useState<DashboardProviderVendor[]>([]);
   const [selectedVendorId, setSelectedVendorId] = useState<number | null>(null);
   const [selectedType, setSelectedType] = useState<ProviderType | null>(null);
   const [endpoints, setEndpoints] = useState<ProviderEndpoint[]>([]);
@@ -59,109 +43,297 @@ export function EndpointTab() {
   const [loadingLogs, setLoadingLogs] = useState(false);
   const [probing, setProbing] = useState(false);
 
-  // Fetch vendors on mount
-  useEffect(() => {
-    const fetchVendors = async () => {
-      try {
-        const vendors = await getProviderVendors();
-        setVendors(vendors);
-        if (vendors.length > 0) {
-          setSelectedVendorId(vendors[0].id);
-        }
-      } catch (error) {
-        console.error("Failed to fetch vendors:", error);
-      } finally {
-        setLoadingVendors(false);
+  const vendorsRequestIdRef = useRef(0);
+  const endpointsRequestIdRef = useRef(0);
+  const probeLogsRequestIdRef = useRef(0);
+  // 切换浏览器标签页时 focus + visibilitychange 可能同时触发;节流避免重复刷新造成请求放大。
+  const lastFocusRefreshAtRef = useRef(0);
+  const latestSelectionRef = useRef<{
+    vendorId: number | null;
+    providerType: ProviderType | null;
+    endpointId: number | null;
+  }>({ vendorId: null, providerType: null, endpointId: null });
+
+  latestSelectionRef.current.vendorId = selectedVendorId;
+  latestSelectionRef.current.providerType = selectedType;
+  latestSelectionRef.current.endpointId = selectedEndpoint?.id ?? null;
+
+  const refreshVendors = useCallback(async (options?: { silent?: boolean }) => {
+    const requestId = ++vendorsRequestIdRef.current;
+    if (!options?.silent) {
+      setLoadingVendors(true);
+    }
+
+    try {
+      const currentVendorId = latestSelectionRef.current.vendorId;
+      const currentType = latestSelectionRef.current.providerType;
+      const nextVendors = await getDashboardProviderVendors();
+
+      if (requestId !== vendorsRequestIdRef.current) {
+        return null;
       }
-    };
-    fetchVendors();
-  }, []);
 
-  // Fetch endpoints when vendor or type changes
-  useEffect(() => {
-    if (!selectedVendorId || !selectedType) {
-      setEndpoints([]);
-      return;
+      setVendors(nextVendors);
+
+      if (nextVendors.length === 0) {
+        setSelectedVendorId(null);
+        setSelectedType(null);
+        setSelectedEndpoint(null);
+        return {
+          selectionChanged: currentVendorId != null || currentType != null,
+          vendorId: null,
+          providerType: null,
+        };
+      }
+
+      const vendor =
+        (currentVendorId ? nextVendors.find((v) => v.id === currentVendorId) : null) ??
+        nextVendors[0] ??
+        null;
+
+      if (!vendor) {
+        setSelectedVendorId(null);
+        setSelectedType(null);
+        setSelectedEndpoint(null);
+        return {
+          selectionChanged: currentVendorId != null || currentType != null,
+          vendorId: null,
+          providerType: null,
+        };
+      }
+
+      const nextVendorId = vendor.id;
+      const nextProviderType =
+        currentType && vendor.providerTypes.includes(currentType)
+          ? currentType
+          : (vendor.providerTypes[0] ?? null);
+
+      const selectionChanged = nextVendorId !== currentVendorId || nextProviderType !== currentType;
+
+      if (selectionChanged) {
+        // 避免 selection 自动切换期间仍能对旧 endpoint 发起探测请求(#781)。
+        setSelectedEndpoint(null);
+      }
+
+      setSelectedVendorId(nextVendorId);
+      setSelectedType(nextProviderType);
+
+      return {
+        selectionChanged,
+        vendorId: nextVendorId,
+        providerType: nextProviderType,
+      };
+    } catch (error) {
+      if (requestId !== vendorsRequestIdRef.current) {
+        return null;
+      }
+      console.error("Failed to fetch vendors:", error);
+      return null;
+    } finally {
+      if (!options?.silent && requestId === vendorsRequestIdRef.current) {
+        setLoadingVendors(false);
+      }
     }
+  }, []);
 
-    const fetchEndpoints = async () => {
+  const refreshEndpoints = useCallback(
+    async (params: {
+      vendorId: number;
+      providerType: ProviderType;
+      keepSelectedEndpointId?: number | null;
+    }) => {
+      const requestId = ++endpointsRequestIdRef.current;
       setLoadingEndpoints(true);
+
       try {
-        const endpoints = await getProviderEndpoints({
-          vendorId: selectedVendorId,
-          providerType: selectedType,
+        const nextEndpoints = await getDashboardProviderEndpoints({
+          vendorId: params.vendorId,
+          providerType: params.providerType,
         });
-        setEndpoints(endpoints);
-        if (endpoints.length > 0) {
-          setSelectedEndpoint(endpoints[0]);
-        } else {
-          setSelectedEndpoint(null);
+
+        if (requestId !== endpointsRequestIdRef.current) {
+          return;
+        }
+
+        setEndpoints(nextEndpoints);
+
+        const keepId = params.keepSelectedEndpointId ?? null;
+        if (keepId) {
+          const kept = nextEndpoints.find((e) => e.id === keepId) ?? null;
+          setSelectedEndpoint(kept ?? nextEndpoints[0] ?? null);
+          return;
         }
+
+        setSelectedEndpoint(nextEndpoints[0] ?? null);
       } catch (error) {
+        if (requestId !== endpointsRequestIdRef.current) {
+          return;
+        }
         console.error("Failed to fetch endpoints:", error);
+        setEndpoints([]);
+        setSelectedEndpoint(null);
       } finally {
-        setLoadingEndpoints(false);
+        if (requestId === endpointsRequestIdRef.current) {
+          setLoadingEndpoints(false);
+        }
       }
-    };
-    fetchEndpoints();
-  }, [selectedVendorId, selectedType]);
-
-  // Fetch probe logs when endpoint changes
-  const fetchProbeLogs = useCallback(async () => {
-    if (!selectedEndpoint) {
-      setProbeLogs([]);
-      return;
-    }
+    },
+    []
+  );
 
+  const refreshProbeLogs = useCallback(async (endpointId: number) => {
+    const requestId = ++probeLogsRequestIdRef.current;
     setLoadingLogs(true);
+
     try {
       const result = await getProviderEndpointProbeLogs({
-        endpointId: selectedEndpoint.id,
+        endpointId,
         limit: 100,
       });
+
+      if (requestId !== probeLogsRequestIdRef.current) {
+        return;
+      }
+
+      if (latestSelectionRef.current.endpointId !== endpointId) {
+        return;
+      }
+
       if (result.ok && result.data) {
         setProbeLogs(result.data.logs);
       }
     } catch (error) {
+      if (requestId !== probeLogsRequestIdRef.current) {
+        return;
+      }
       console.error("Failed to fetch probe logs:", error);
     } finally {
-      setLoadingLogs(false);
+      if (requestId === probeLogsRequestIdRef.current) {
+        setLoadingLogs(false);
+      }
     }
-  }, [selectedEndpoint]);
+  }, []);
+
+  // Fetch vendors on mount
+  useEffect(() => {
+    void refreshVendors();
+  }, [refreshVendors]);
 
+  // Fetch endpoints when vendor or type changes
   useEffect(() => {
-    fetchProbeLogs();
-  }, [fetchProbeLogs]);
+    if (!selectedVendorId || !selectedType) {
+      endpointsRequestIdRef.current += 1;
+      setEndpoints([]);
+      setSelectedEndpoint(null);
+      setLoadingEndpoints(false);
+      return;
+    }
+
+    void refreshEndpoints({ vendorId: selectedVendorId, providerType: selectedType });
+  }, [selectedVendorId, selectedType, refreshEndpoints]);
+
+  // Fetch probe logs when endpoint changes
+  useEffect(() => {
+    const endpointId = selectedEndpoint?.id ?? null;
+    if (!endpointId) {
+      probeLogsRequestIdRef.current += 1;
+      setProbeLogs([]);
+      setLoadingLogs(false);
+      return;
+    }
+
+    void refreshProbeLogs(endpointId);
+  }, [selectedEndpoint?.id, refreshProbeLogs]);
 
   // Auto-refresh logs every 10 seconds
   useEffect(() => {
-    if (!selectedEndpoint) return;
-    const timer = setInterval(fetchProbeLogs, 10000);
+    const endpointId = selectedEndpoint?.id;
+    if (!endpointId) return;
+    const timer = setInterval(() => {
+      void refreshProbeLogs(endpointId);
+    }, 10000);
     return () => clearInterval(timer);
-  }, [selectedEndpoint, fetchProbeLogs]);
+  }, [selectedEndpoint?.id, refreshProbeLogs]);
+
+  // 当用户从“设置页”修改/删除端点后返回本页,自动做一次轻量刷新,避免看到陈旧列表(#781)。
+  useEffect(() => {
+    const refresh = async () => {
+      const vendorResult = await refreshVendors({ silent: true });
+
+      const vendorId = vendorResult?.vendorId ?? latestSelectionRef.current.vendorId;
+      const providerType = vendorResult?.providerType ?? latestSelectionRef.current.providerType;
+      const endpointId = latestSelectionRef.current.endpointId;
+
+      if (!vendorResult?.selectionChanged && vendorId && providerType) {
+        void refreshEndpoints({
+          vendorId,
+          providerType,
+          keepSelectedEndpointId: endpointId,
+        });
+      }
+
+      if (!vendorResult?.selectionChanged && endpointId) {
+        void refreshProbeLogs(endpointId);
+      }
+    };
+
+    // 切回前台时,focus 与 visibilitychange 往往会连发;节流避免重复触发 refresh 链路。
+    const refreshThrottled = () => {
+      const now = Date.now();
+      if (now - lastFocusRefreshAtRef.current < 2000) return;
+      lastFocusRefreshAtRef.current = now;
+      void refresh();
+    };
+
+    const onFocus = () => {
+      refreshThrottled();
+    };
+    const onVisibilityChange = () => {
+      if (document.visibilityState === "visible") {
+        refreshThrottled();
+      }
+    };
+
+    window.addEventListener("focus", onFocus);
+    document.addEventListener("visibilitychange", onVisibilityChange);
+
+    return () => {
+      window.removeEventListener("focus", onFocus);
+      document.removeEventListener("visibilitychange", onVisibilityChange);
+    };
+  }, [refreshEndpoints, refreshProbeLogs, refreshVendors]);
 
   // Handle manual probe
   const handleProbe = async () => {
-    if (!selectedEndpoint) return;
+    const endpoint = selectedEndpoint;
+    const vendorId = selectedVendorId;
+    const providerType = selectedType;
+    if (!endpoint || !vendorId || !providerType) return;
 
     setProbing(true);
     try {
       const result = await probeProviderEndpoint({
-        endpointId: selectedEndpoint.id,
+        endpointId: endpoint.id,
       });
       if (result.ok) {
         toast.success(t("actions.probeSuccess"));
-        // Refresh logs and endpoints
-        fetchProbeLogs();
-        if (selectedVendorId && selectedType) {
-          const endpoints = await getProviderEndpoints({
-            vendorId: selectedVendorId,
-            providerType: selectedType,
+
+        // 避免 probe 完成后覆盖用户在 probe 期间切换的 vendor/type/endpoint。
+        const stillSameVendorType =
+          latestSelectionRef.current.vendorId === vendorId &&
+          latestSelectionRef.current.providerType === providerType;
+        const stillSameEndpoint = latestSelectionRef.current.endpointId === endpoint.id;
+
+        if (stillSameEndpoint) {
+          void refreshProbeLogs(endpoint.id);
+        }
+
+        if (stillSameVendorType) {
+          await refreshEndpoints({
+            vendorId,
+            providerType,
+            keepSelectedEndpointId: latestSelectionRef.current.endpointId,
           });
-          setEndpoints(endpoints);
-          // Update selected endpoint with new data
-          const updated = endpoints.find((e) => e.id === selectedEndpoint.id);
-          if (updated) setSelectedEndpoint(updated);
         }
       } else {
         toast.error(result.error || t("actions.probeFailed"));
@@ -190,6 +362,9 @@ export function EndpointTab() {
     );
   }
 
+  const selectedVendor = vendors.find((vendor) => vendor.id === selectedVendorId) ?? null;
+  const providerTypes = selectedVendor?.providerTypes ?? [];
+
   return (
     <div className="space-y-6">
       {/* Filters */}
@@ -199,8 +374,10 @@ export function EndpointTab() {
           <Select
             value={selectedVendorId?.toString() || ""}
             onValueChange={(v) => {
-              setSelectedVendorId(Number(v));
-              setSelectedType(null);
+              const vendorId = Number(v);
+              setSelectedVendorId(vendorId);
+              const nextVendor = vendors.find((vendor) => vendor.id === vendorId);
+              setSelectedType(nextVendor?.providerTypes[0] ?? null);
               setSelectedEndpoint(null);
             }}
           >
@@ -229,7 +406,7 @@ export function EndpointTab() {
               <SelectValue placeholder={t("endpoint.selectType")} />
             </SelectTrigger>
             <SelectContent>
-              {PROVIDER_TYPES.map((type) => (
+              {providerTypes.map((type) => (
                 <SelectItem key={type} value={type}>
                   {type}
                 </SelectItem>

+ 22 - 3
src/app/[locale]/dashboard/availability/_components/endpoint/probe-grid.tsx

@@ -51,6 +51,9 @@ function formatLatency(ms: number | null): string {
 function formatTime(date: Date | string | null, timeZone?: string): string {
   if (!date) return "-";
   const d = typeof date === "string" ? new Date(date) : date;
+  if (!Number.isFinite(d.getTime())) {
+    return "-";
+  }
   if (timeZone) {
     return formatInTimeZone(d, timeZone, "HH:mm:ss");
   }
@@ -61,6 +64,22 @@ function formatTime(date: Date | string | null, timeZone?: string): string {
   });
 }
 
+function safeHostnameFromUrl(input: string): string | null {
+  const url = input.trim();
+  if (!url) return null;
+
+  try {
+    return new URL(url).hostname || null;
+  } catch {
+    // 兼容历史/手工录入:允许 host:port 或无 scheme 的写法。
+    try {
+      return new URL(`https://${url}`).hostname || null;
+    } catch {
+      return null;
+    }
+  }
+}
+
 export function ProbeGrid({
   endpoints,
   selectedEndpointId,
@@ -85,6 +104,8 @@ export function ProbeGrid({
           const status = getStatusConfig(endpoint);
           const StatusIcon = status.icon;
           const isSelected = selectedEndpointId === endpoint.id;
+          const hostname = endpoint.label ? null : safeHostnameFromUrl(endpoint.url);
+          const displayName = endpoint.label || hostname || endpoint.url;
 
           return (
             <Tooltip key={endpoint.id}>
@@ -105,9 +126,7 @@ export function ProbeGrid({
                     <div className="flex-1 min-w-0">
                       <div className="flex items-center gap-2">
                         <StatusIcon className={cn("h-4 w-4 shrink-0", status.color)} />
-                        <span className="text-sm font-medium truncate">
-                          {endpoint.label || new URL(endpoint.url).hostname}
-                        </span>
+                        <span className="text-sm font-medium truncate">{displayName}</span>
                       </div>
                       <p className="text-xs text-muted-foreground truncate mt-1">{endpoint.url}</p>
                     </div>

+ 15 - 20
src/app/[locale]/dashboard/logs/_components/usage-logs-view-virtualized.tsx

@@ -1,6 +1,6 @@
 "use client";
 
-import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from "@tanstack/react-query";
+import { useQuery, useQueryClient } from "@tanstack/react-query";
 import { Expand, Filter, ListOrdered, Minimize2, Pause, Play, RefreshCw } from "lucide-react";
 import { useRouter, useSearchParams } from "next/navigation";
 import { useLocale, useTranslations } from "next-intl";
@@ -26,14 +26,8 @@ import { UsageLogsFilters } from "./usage-logs-filters";
 import { UsageLogsStatsPanel } from "./usage-logs-stats-panel";
 import { VirtualizedLogsTable, type VirtualizedLogsTableFilters } from "./virtualized-logs-table";
 
-const queryClient = new QueryClient({
-  defaultOptions: {
-    queries: {
-      refetchOnWindowFocus: false,
-      staleTime: 30000,
-    },
-  },
-});
+const EMPTY_PROVIDERS: ProviderDisplay[] = [];
+const EMPTY_KEYS: Key[] = [];
 
 interface UsageLogsViewVirtualizedProps {
   isAdmin: boolean;
@@ -141,11 +135,13 @@ function UsageLogsViewContent({
   const resolvedBillingModelSource =
     billingModelSource ?? systemSettings?.billingModelSource ?? "original";
 
-  const { data: providersData = [], isLoading: isProvidersLoading } = useQuery<ProviderDisplay[]>({
+  const { data: providersData = EMPTY_PROVIDERS, isLoading: isProvidersLoading } = useQuery<
+    ProviderDisplay[]
+  >({
     queryKey: ["usage-log-providers"],
     queryFn: getProviders,
     enabled: isAdmin && providers === undefined,
-    placeholderData: [],
+    placeholderData: EMPTY_PROVIDERS,
   });
 
   const { data: keysResult, isLoading: isKeysLoading } = useQuery({
@@ -155,12 +151,13 @@ function UsageLogsViewContent({
   });
 
   const resolvedProviders = providers ?? providersData;
-  const resolvedKeys = initialKeys ?? (keysResult?.ok && keysResult.data ? keysResult.data : []);
+  const resolvedKeys =
+    initialKeys ?? (keysResult?.ok && keysResult.data ? keysResult.data : EMPTY_KEYS);
 
   // Use useSearchParams hook for client-side URL reactivity
   // Note: searchParams props from server don't update on client-side navigation
-  const filters = useMemo<VirtualizedLogsTableFilters & { page?: number }>(() => {
-    return parseLogsUrlFilters({
+  const filters = useMemo<VirtualizedLogsTableFilters>(() => {
+    const { page: _page, ...parsed } = parseLogsUrlFilters({
       userId: _params.get("userId") ?? undefined,
       keyId: _params.get("keyId") ?? undefined,
       providerId: _params.get("providerId") ?? undefined,
@@ -172,7 +169,9 @@ function UsageLogsViewContent({
       endpoint: _params.get("endpoint") ?? undefined,
       minRetry: _params.get("minRetry") ?? undefined,
       page: _params.get("page") ?? undefined,
-    }) as VirtualizedLogsTableFilters & { page?: number };
+    });
+
+    return parsed;
   }, [_params]);
 
   const { data: overviewData } = useQuery<OverviewData>({
@@ -487,9 +486,5 @@ function UsageLogsViewContent({
 }
 
 export function UsageLogsViewVirtualized(props: UsageLogsViewVirtualizedProps) {
-  return (
-    <QueryClientProvider client={queryClient}>
-      <UsageLogsViewContent {...props} />
-    </QueryClientProvider>
-  );
+  return <UsageLogsViewContent {...props} />;
 }

+ 5 - 3
src/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsx

@@ -3,7 +3,7 @@
 import { useInfiniteQuery } from "@tanstack/react-query";
 import { ArrowUp, Loader2 } from "lucide-react";
 import { useTranslations } from "next-intl";
-import { type MouseEvent, useCallback, useEffect, useRef, useState } from "react";
+import { type MouseEvent, useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { toast } from "sonner";
 import { getUsageLogsBatch } from "@/actions/usage-logs";
 import { Badge } from "@/components/ui/badge";
@@ -72,6 +72,7 @@ export function VirtualizedLogsTable({
   const tChain = useTranslations("provider-chain");
   const parentRef = useRef<HTMLDivElement>(null);
   const [showScrollToTop, setShowScrollToTop] = useState(false);
+  const shouldPoll = autoRefreshEnabled && !showScrollToTop;
 
   const hideProviderColumn = hiddenColumns?.includes("provider") ?? false;
   const hideUserColumn = hiddenColumns?.includes("user") ?? false;
@@ -121,11 +122,12 @@ export function VirtualizedLogsTable({
       initialPageParam: undefined as { createdAt: string; id: number } | undefined,
       staleTime: 30000, // 30 seconds
       refetchOnWindowFocus: false,
-      refetchInterval: autoRefreshEnabled ? autoRefreshIntervalMs : false,
+      refetchInterval: shouldPoll ? autoRefreshIntervalMs : false,
     });
 
   // Flatten all pages into a single array
-  const allLogs = data?.pages.flatMap((page) => page.logs) ?? [];
+  const pages = data?.pages;
+  const allLogs = useMemo(() => pages?.flatMap((page) => page.logs) ?? [], [pages]);
 
   // Virtual list setup
   const rowVirtualizer = useVirtualizer({

+ 11 - 25
src/app/[locale]/dashboard/users/users-page-client.tsx

@@ -1,12 +1,6 @@
 "use client";
 
-import {
-  QueryClient,
-  QueryClientProvider,
-  useInfiniteQuery,
-  useQuery,
-  useQueryClient,
-} from "@tanstack/react-query";
+import { useInfiniteQuery, useQuery, useQueryClient } from "@tanstack/react-query";
 import { Layers, Loader2, Plus, Search, ShieldCheck } from "lucide-react";
 import { useTranslations } from "next-intl";
 import { useCallback, useEffect, useMemo, useState } from "react";
@@ -31,15 +25,6 @@ import { CreateUserDialog } from "../_components/user/create-user-dialog";
 import { clearUsageCache } from "../_components/user/user-limit-badge";
 import { UserManagementTable } from "../_components/user/user-management-table";
 
-const queryClient = new QueryClient({
-  defaultOptions: {
-    queries: {
-      refetchOnWindowFocus: false,
-      staleTime: 30000,
-    },
-  },
-});
-
 /**
  * Split comma-separated tags into an array of trimmed, non-empty strings.
  * This matches the server-side providerGroup handling in provider-selector.ts
@@ -57,11 +42,7 @@ interface UsersPageClientProps {
 }
 
 export function UsersPageClient(props: UsersPageClientProps) {
-  return (
-    <QueryClientProvider client={queryClient}>
-      <UsersPageContent {...props} />
-    </QueryClientProvider>
-  );
+  return <UsersPageContent {...props} />;
 }
 
 function UsersPageContent({ currentUser }: UsersPageClientProps) {
@@ -96,11 +77,16 @@ function UsersPageContent({ currentUser }: UsersPageClientProps) {
 
   // Debounce search term to avoid frequent API requests
   const debouncedSearchTerm = useDebounce(searchTerm, 300);
-  const debouncedPendingTagsKey = useDebounce(pendingTagFilters.slice().sort().join("|"), 300);
-  const debouncedPendingKeyGroupsKey = useDebounce(
-    pendingKeyGroupFilters.slice().sort().join("|"),
-    300
+  const pendingTagFiltersKey = useMemo(
+    () => pendingTagFilters.slice().sort().join("|"),
+    [pendingTagFilters]
+  );
+  const pendingKeyGroupFiltersKey = useMemo(
+    () => pendingKeyGroupFilters.slice().sort().join("|"),
+    [pendingKeyGroupFilters]
   );
+  const debouncedPendingTagsKey = useDebounce(pendingTagFiltersKey, 300);
+  const debouncedPendingKeyGroupsKey = useDebounce(pendingKeyGroupFiltersKey, 300);
 
   // Use debounced value for API queries, raw value for UI highlighting
   const resolvedSearchTerm = debouncedSearchTerm.trim() ? debouncedSearchTerm.trim() : undefined;

+ 0 - 8
src/app/[locale]/settings/providers/_components/add-provider-dialog.tsx

@@ -1,7 +1,5 @@
 "use client";
-import { useQueryClient } from "@tanstack/react-query";
 import { ServerCog } from "lucide-react";
-import { useRouter } from "next/navigation";
 import { useTranslations } from "next-intl";
 import { useState } from "react";
 import { FormErrorBoundary } from "@/components/form-error-boundary";
@@ -14,8 +12,6 @@ interface AddProviderDialogProps {
 }
 
 export function AddProviderDialog({ enableMultiProviderTypes }: AddProviderDialogProps) {
-  const router = useRouter();
-  const queryClient = useQueryClient();
   const t = useTranslations("settings.providers");
   const [open, setOpen] = useState(false);
   return (
@@ -32,10 +28,6 @@ export function AddProviderDialog({ enableMultiProviderTypes }: AddProviderDialo
             enableMultiProviderTypes={enableMultiProviderTypes}
             onSuccess={() => {
               setOpen(false);
-              queryClient.invalidateQueries({ queryKey: ["providers"] });
-              queryClient.invalidateQueries({ queryKey: ["providers-health"] });
-              // 刷新页面数据以显示新添加的服务商
-              router.refresh();
             }}
           />
         </FormErrorBoundary>

+ 451 - 23
src/app/[locale]/settings/providers/_components/endpoint-latency-sparkline.tsx

@@ -4,6 +4,7 @@ import { useQuery } from "@tanstack/react-query";
 import { useMemo } from "react";
 import { Line, LineChart, ResponsiveContainer, Tooltip, YAxis } from "recharts";
 import { getProviderEndpointProbeLogs } from "@/actions/provider-endpoints";
+import { useInViewOnce } from "@/lib/hooks/use-in-view-once";
 import { cn } from "@/lib/utils";
 
 type SparkPoint = {
@@ -13,6 +14,46 @@ type SparkPoint = {
   timestamp?: number;
 };
 
+type ProbeLog = {
+  ok: boolean;
+  latencyMs: number | null;
+  createdAt?: string | number | Date | null;
+};
+
+function normalizeProbeLog(value: unknown): ProbeLog | null {
+  if (!value || typeof value !== "object") return null;
+
+  const rawOk = (value as { ok?: unknown }).ok;
+  if (typeof rawOk !== "boolean") return null;
+
+  const rawLatencyMs = (value as { latencyMs?: unknown }).latencyMs;
+  const latencyMs =
+    typeof rawLatencyMs === "number" && Number.isFinite(rawLatencyMs) ? rawLatencyMs : null;
+
+  const rawCreatedAt = (value as { createdAt?: unknown }).createdAt;
+  const createdAt =
+    rawCreatedAt === undefined ||
+    rawCreatedAt === null ||
+    typeof rawCreatedAt === "string" ||
+    typeof rawCreatedAt === "number" ||
+    rawCreatedAt instanceof Date
+      ? rawCreatedAt
+      : undefined;
+
+  return { ok: rawOk, latencyMs, createdAt };
+}
+
+function normalizeProbeLogs(value: unknown): ProbeLog[] {
+  if (!Array.isArray(value)) return [];
+
+  const logs: ProbeLog[] = [];
+  for (const item of value) {
+    const normalized = normalizeProbeLog(item);
+    if (normalized) logs.push(normalized);
+  }
+  return logs;
+}
+
 function formatLatency(ms: number | null): string {
   if (ms === null) return "-";
   if (ms < 1000) return `${Math.round(ms)}ms`;
@@ -38,51 +79,438 @@ function CustomTooltip({
   );
 }
 
-export function EndpointLatencySparkline(props: { endpointId: number; limit?: number }) {
-  const { data: points = [] } = useQuery({
-    queryKey: ["endpoint-probe-logs", props.endpointId, props.limit ?? 12],
-    queryFn: async (): Promise<SparkPoint[]> => {
-      const res = await getProviderEndpointProbeLogs({
-        endpointId: props.endpointId,
-        limit: props.limit ?? 12,
+function normalizeProbeLogsByEndpointId(data: unknown): Record<number, ProbeLog[]> | null {
+  if (!data || typeof data !== "object") return null;
+
+  if (Array.isArray(data)) {
+    const map: Record<number, ProbeLog[]> = {};
+    for (const item of data) {
+      if (!item || typeof item !== "object") continue;
+      const endpointId = (item as { endpointId?: unknown }).endpointId;
+      const logs = (item as { logs?: unknown }).logs;
+      if (typeof endpointId !== "number" || !Array.isArray(logs)) continue;
+      map[endpointId] = normalizeProbeLogs(logs);
+    }
+    return map;
+  }
+
+  const obj = data as Record<string, unknown>;
+
+  const logsByEndpointId = obj.logsByEndpointId;
+  if (logsByEndpointId && typeof logsByEndpointId === "object") {
+    const raw = logsByEndpointId as Record<string, unknown>;
+    const map: Record<number, ProbeLog[]> = {};
+    for (const [k, v] of Object.entries(raw)) {
+      const endpointId = Number.parseInt(k, 10);
+      if (!Number.isFinite(endpointId) || !Array.isArray(v)) continue;
+      map[endpointId] = normalizeProbeLogs(v);
+    }
+    return map;
+  }
+
+  const items = obj.items;
+  if (Array.isArray(items)) {
+    const map: Record<number, ProbeLog[]> = {};
+    for (const item of items) {
+      if (!item || typeof item !== "object") continue;
+      const endpointId = (item as { endpointId?: unknown }).endpointId;
+      const logs = (item as { logs?: unknown }).logs;
+      if (typeof endpointId !== "number" || !Array.isArray(logs)) continue;
+      map[endpointId] = normalizeProbeLogs(logs);
+    }
+    return map;
+  }
+
+  return null;
+}
+
+let isBatchProbeLogsEndpointAvailable: boolean | undefined;
+let batchProbeLogsEndpointDisabledAt: number | null = null;
+const BATCH_PROBE_LOGS_RETRY_INTERVAL_MS = 5 * 60 * 1000;
+
+function isBatchProbeLogsDisabled(): boolean {
+  if (isBatchProbeLogsEndpointAvailable !== false) return false;
+  if (batchProbeLogsEndpointDisabledAt === null) {
+    // Defensive:避免异常态(disabledAt 丢失)导致永久禁用 batch 路由
+    isBatchProbeLogsEndpointAvailable = undefined;
+    return false;
+  }
+  if (Date.now() - batchProbeLogsEndpointDisabledAt > BATCH_PROBE_LOGS_RETRY_INTERVAL_MS) {
+    isBatchProbeLogsEndpointAvailable = undefined;
+    batchProbeLogsEndpointDisabledAt = null;
+    return false;
+  }
+  return true;
+}
+
+async function tryFetchBatchProbeLogsByEndpointIds(
+  endpointIds: number[],
+  limit: number
+): Promise<Record<number, ProbeLog[]> | null> {
+  if (endpointIds.length <= 1) return null;
+  if (isBatchProbeLogsDisabled()) return null;
+  if (process.env.NODE_ENV === "test") return null;
+
+  const MAX_ENDPOINT_IDS_PER_BATCH = 500;
+  const chunks: number[][] = [];
+  for (let index = 0; index < endpointIds.length; index += MAX_ENDPOINT_IDS_PER_BATCH) {
+    chunks.push(endpointIds.slice(index, index + MAX_ENDPOINT_IDS_PER_BATCH));
+  }
+
+  const merged: Record<number, ProbeLog[]> = {};
+  const fallbackEndpointIds = new Set<number>();
+  const missingFromSuccessfulChunks = new Set<number>();
+  let didAnyChunkSucceed = false;
+  let didAnyChunkFail = false;
+  let didAnyChunk404 = false;
+
+  for (const chunk of chunks) {
+    try {
+      const res = await fetch("/api/actions/providers/batchGetProviderEndpointProbeLogs", {
+        method: "POST",
+        headers: { "content-type": "application/json" },
+        credentials: "same-origin",
+        body: JSON.stringify({ endpointIds: chunk, limit }),
       });
 
-      if (!res.ok || !res.data) {
-        return [];
+      if (res.status === 404) {
+        didAnyChunkFail = true;
+        didAnyChunk404 = true;
+
+        // 404 通常意味着路由不存在(旧版本/未部署)。滚动发布场景下可能出现 404 与成功并存:
+        // - 若本次请求存在任一成功 chunk,则视为 batch 路由可用,仅对 404 的 chunk 降级。
+        // - 仅当所有 chunk 都 404 且无任何成功时,才短暂禁用 batch 路由,避免持续打 404。
+
+        for (const endpointId of chunk) fallbackEndpointIds.add(endpointId);
+        continue;
+      }
+
+      if (!res.ok) {
+        didAnyChunkFail = true;
+        for (const endpointId of chunk) fallbackEndpointIds.add(endpointId);
+        continue;
+      }
+
+      const json = (await res.json()) as { ok?: unknown; data?: unknown };
+      if (json.ok !== true) {
+        didAnyChunkFail = true;
+        for (const endpointId of chunk) fallbackEndpointIds.add(endpointId);
+        continue;
+      }
+
+      const normalized = normalizeProbeLogsByEndpointId(json.data);
+      if (!normalized) {
+        didAnyChunkFail = true;
+        for (const endpointId of chunk) fallbackEndpointIds.add(endpointId);
+        continue;
+      }
+
+      didAnyChunkSucceed = true;
+
+      const normalizedEndpointIds = new Set<number>();
+      for (const [endpointId, logs] of Object.entries(normalized)) {
+        const id = Number(endpointId);
+        normalizedEndpointIds.add(id);
+        merged[id] = logs;
       }
 
-      return res.data.logs
-        .slice()
-        .reverse()
-        .map((log, idx) => ({
+      for (const endpointId of chunk) {
+        if (!normalizedEndpointIds.has(endpointId)) missingFromSuccessfulChunks.add(endpointId);
+      }
+    } catch {
+      didAnyChunkFail = true;
+      for (const endpointId of chunk) fallbackEndpointIds.add(endpointId);
+    }
+  }
+
+  if (!didAnyChunkSucceed) {
+    if (didAnyChunk404) {
+      isBatchProbeLogsEndpointAvailable = false;
+      batchProbeLogsEndpointDisabledAt = Date.now();
+    }
+    return null;
+  }
+
+  // 至少有一个 chunk 成功,说明 batch 路由可用(允许部分失败并按需降级)。
+  isBatchProbeLogsEndpointAvailable = true;
+  batchProbeLogsEndpointDisabledAt = null;
+
+  if (!didAnyChunkFail) {
+    return merged;
+  }
+
+  const endpointIdsToFetchIndividually = new Set<number>();
+  for (const endpointId of fallbackEndpointIds) {
+    if (merged[endpointId] === undefined) endpointIdsToFetchIndividually.add(endpointId);
+  }
+  for (const endpointId of missingFromSuccessfulChunks) {
+    if (merged[endpointId] === undefined) endpointIdsToFetchIndividually.add(endpointId);
+  }
+
+  if (endpointIdsToFetchIndividually.size === 0) return merged;
+
+  const rest = await fetchProbeLogsByEndpointIdsIndividually(
+    Array.from(endpointIdsToFetchIndividually),
+    limit
+  ).catch(() => null);
+
+  if (rest) {
+    for (const [endpointId, logs] of Object.entries(rest)) {
+      merged[Number(endpointId)] = logs;
+    }
+  }
+
+  return merged;
+}
+
+async function fetchProbeLogsByEndpointIdsIndividually(
+  endpointIds: number[],
+  limit: number
+): Promise<Record<number, ProbeLog[]>> {
+  const map: Record<number, ProbeLog[]> = {};
+  const concurrency = 4;
+  let idx = 0;
+
+  const workers = Array.from({ length: Math.min(concurrency, endpointIds.length) }, async () => {
+    for (;;) {
+      const currentIndex = idx++;
+      if (currentIndex >= endpointIds.length) return;
+      const endpointId = endpointIds[currentIndex];
+
+      try {
+        const res = await getProviderEndpointProbeLogs({
+          endpointId,
+          limit,
+        });
+        map[endpointId] = res.ok && res.data ? normalizeProbeLogs(res.data.logs) : [];
+      } catch {
+        map[endpointId] = [];
+      }
+    }
+  });
+
+  await Promise.all(workers);
+  return map;
+}
+
+async function fetchProbeLogsByEndpointIds(
+  endpointIds: number[],
+  limit: number
+): Promise<Record<number, ProbeLog[]>> {
+  const batched = await tryFetchBatchProbeLogsByEndpointIds(endpointIds, limit);
+  if (batched) return batched;
+  return fetchProbeLogsByEndpointIdsIndividually(endpointIds, limit);
+}
+
+type BatchRequest = {
+  endpointId: number;
+  resolve: (logs: ProbeLog[]) => void;
+  reject: (error: unknown) => void;
+};
+
+function createAbortError(signal?: AbortSignal): unknown {
+  if (!signal) return new Error("Aborted");
+  if (signal.reason) return signal.reason;
+
+  try {
+    return new DOMException("Aborted", "AbortError");
+  } catch {
+    return new Error("Aborted");
+  }
+}
+
+class ProbeLogsBatcher {
+  private readonly pendingByLimit = new Map<number, Map<number, BatchRequest[]>>();
+  private flushTimer: ReturnType<typeof setTimeout> | null = null;
+
+  load(endpointId: number, limit: number, options?: { signal?: AbortSignal }): Promise<ProbeLog[]> {
+    return new Promise((resolve, reject) => {
+      const signal = options?.signal;
+      if (signal?.aborted) {
+        reject(createAbortError(signal));
+        return;
+      }
+
+      let settled = false;
+      let request: BatchRequest;
+
+      const onAbort = () => {
+        if (settled) return;
+        settled = true;
+        this.removePendingRequest(limit, endpointId, request);
+        this.maybeCancelFlushTimer();
+        reject(createAbortError(signal));
+      };
+
+      request = {
+        endpointId,
+        resolve: (logs) => {
+          if (settled) return;
+          settled = true;
+          signal?.removeEventListener("abort", onAbort);
+          resolve(logs);
+        },
+        reject: (error) => {
+          if (settled) return;
+          settled = true;
+          signal?.removeEventListener("abort", onAbort);
+          reject(error);
+        },
+      };
+
+      if (signal) {
+        signal.addEventListener("abort", onAbort, { once: true });
+      }
+
+      const group = this.pendingByLimit.get(limit) ?? new Map<number, BatchRequest[]>();
+      const list = group.get(endpointId) ?? [];
+      list.push(request);
+      group.set(endpointId, list);
+      this.pendingByLimit.set(limit, group);
+
+      if (this.flushTimer) return;
+      const delayMs = process.env.NODE_ENV === "test" ? 0 : 10;
+      this.flushTimer = setTimeout(() => {
+        this.flushTimer = null;
+        void this.flush().catch(() => {});
+      }, delayMs);
+    });
+  }
+
+  private maybeCancelFlushTimer() {
+    if (!this.flushTimer) return;
+    if (this.pendingByLimit.size > 0) return;
+    clearTimeout(this.flushTimer);
+    this.flushTimer = null;
+  }
+
+  private removePendingRequest(limit: number, endpointId: number, request: BatchRequest) {
+    const group = this.pendingByLimit.get(limit);
+    if (!group) return;
+    const list = group.get(endpointId);
+    if (!list) return;
+
+    const next = list.filter((item) => item !== request);
+    if (next.length > 0) {
+      group.set(endpointId, next);
+      return;
+    }
+
+    group.delete(endpointId);
+    if (group.size === 0) {
+      this.pendingByLimit.delete(limit);
+    }
+  }
+
+  private async flush() {
+    const snapshot = new Map(this.pendingByLimit);
+    this.pendingByLimit.clear();
+
+    try {
+      await Promise.all(
+        Array.from(snapshot.entries(), async ([limit, group]) => {
+          const endpointIds = Array.from(group.keys());
+          if (endpointIds.length === 0) return;
+
+          try {
+            const map = await fetchProbeLogsByEndpointIds(endpointIds, limit);
+            for (const [endpointId, requests] of group.entries()) {
+              const logs = map[endpointId] ?? [];
+              for (const req of requests) req.resolve(logs);
+            }
+          } catch (error) {
+            for (const requests of group.values()) {
+              for (const req of requests) req.reject(error);
+            }
+          }
+        })
+      );
+    } catch (error) {
+      for (const group of snapshot.values()) {
+        for (const requests of group.values()) {
+          for (const req of requests) req.reject(error);
+        }
+      }
+    }
+  }
+}
+
+const probeLogsBatcher = new ProbeLogsBatcher();
+
+export function EndpointLatencySparkline(props: { endpointId: number; limit?: number }) {
+  const limit = props.limit ?? 12;
+  const { ref, isInView } = useInViewOnce<HTMLDivElement>();
+
+  const { data: points = [], isLoading } = useQuery({
+    queryKey: ["endpoint-probe-logs", props.endpointId, limit],
+    queryFn: async ({ signal }): Promise<SparkPoint[]> => {
+      const logs = await probeLogsBatcher.load(props.endpointId, limit, { signal });
+
+      const points: SparkPoint[] = new Array(logs.length);
+      for (let i = logs.length - 1, idx = 0; i >= 0; i -= 1, idx += 1) {
+        const log = logs[i];
+        const rawTimestamp =
+          log.createdAt === undefined || log.createdAt === null
+            ? undefined
+            : new Date(log.createdAt).getTime();
+        const timestamp =
+          rawTimestamp !== undefined && Number.isFinite(rawTimestamp) ? rawTimestamp : undefined;
+
+        points[idx] = {
           index: idx,
           latencyMs: log.latencyMs ?? null,
           ok: log.ok,
-          timestamp: log.createdAt ? new Date(log.createdAt).getTime() : undefined,
-        }));
+          timestamp,
+        };
+      }
+
+      return points;
     },
     staleTime: 30_000,
+    refetchOnWindowFocus: false,
+    enabled: isInView,
   });
 
   const avgLatency = useMemo(() => {
     const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
-    const recentPoints = points.filter(
-      (p) => p.latencyMs !== null && p.timestamp && p.timestamp >= fiveMinutesAgo
-    );
-    if (recentPoints.length === 0) return null;
-    const sum = recentPoints.reduce((acc, p) => acc + (p.latencyMs ?? 0), 0);
-    return sum / recentPoints.length;
+    let sum = 0;
+    let count = 0;
+
+    for (const point of points) {
+      if (point.latencyMs === null) continue;
+      const timestamp = point.timestamp;
+      if (timestamp === undefined || timestamp < fiveMinutesAgo) continue;
+      sum += point.latencyMs;
+      count += 1;
+    }
+
+    return count > 0 ? sum / count : null;
   }, [points]);
 
+  // useInViewOnce 保证 isInView 只会 false -> true,不会反复切回,因此不会因 refetch 闪烁骨架屏。
+  const showSkeleton = !isInView || isLoading;
+
+  if (showSkeleton) {
+    return (
+      <div ref={ref} className="flex items-center gap-2">
+        <div className="h-6 w-32 rounded bg-muted/20" />
+      </div>
+    );
+  }
+
   if (points.length === 0) {
-    return <div className="h-6 w-32 rounded bg-muted/20" />;
+    return (
+      <div ref={ref} className="flex items-center gap-2">
+        <div className="h-6 w-32 rounded bg-muted/10" />
+      </div>
+    );
   }
 
   const lastPoint = points[points.length - 1];
   const stroke = lastPoint?.ok ? "#16a34a" : "#dc2626";
 
   return (
-    <div className="flex items-center gap-2">
+    <div ref={ref} className="flex items-center gap-2">
       <div className="h-6 w-32">
         <ResponsiveContainer width="100%" height="100%">
           <LineChart data={points} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>

+ 15 - 5
src/app/[locale]/settings/providers/_components/forms/provider-form/index.tsx

@@ -35,6 +35,8 @@ import { NetworkSection } from "./sections/network-section";
 import { RoutingSection } from "./sections/routing-section";
 import { TestingSection } from "./sections/testing-section";
 
+const TAB_ORDER: TabId[] = ["basic", "routing", "limits", "network", "testing"];
+
 function normalizeWebsiteDomainFromUrl(rawUrl: string): string | null {
   const trimmed = rawUrl.trim();
   if (!trimmed) return null;
@@ -95,6 +97,8 @@ function ProviderFormContent({
   const { data: vendors = [] } = useQuery<ProviderVendor[]>({
     queryKey: ["provider-vendors"],
     queryFn: getProviderVendors,
+    staleTime: 60_000,
+    refetchOnWindowFocus: false,
   });
 
   const websiteDomain = useMemo(
@@ -134,6 +138,8 @@ function ProviderFormContent({
         providerType: state.routing.providerType,
       });
     },
+    staleTime: 30_000,
+    refetchOnWindowFocus: false,
   });
 
   const enabledEndpointPoolEndpoints = useMemo(
@@ -183,9 +189,6 @@ function ProviderFormContent({
   });
   const isScrollingToSection = useRef(false);
 
-  // Tab order for navigation
-  const tabOrder: TabId[] = ["basic", "routing", "limits", "network", "testing"];
-
   // Scroll to section when tab is clicked
   const scrollToSection = useCallback((tab: TabId) => {
     const section = sectionRefs.current[tab];
@@ -213,7 +216,7 @@ function ProviderFormContent({
     let activeSection: TabId = "basic";
     let minDistance = Infinity;
 
-    for (const tab of tabOrder) {
+    for (const tab of TAB_ORDER) {
       const section = sectionRefs.current[tab];
       if (!section) continue;
 
@@ -360,6 +363,11 @@ function ProviderFormContent({
             return;
           }
           toast.success(t("success.updated"));
+
+          void queryClient.invalidateQueries({ queryKey: ["providers"] });
+          void queryClient.invalidateQueries({ queryKey: ["providers-health"] });
+          void queryClient.invalidateQueries({ queryKey: ["providers-statistics"] });
+          void queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
         } else {
           // For create: key is required
           const createFormData = { ...baseFormData, key: trimmedKey };
@@ -369,8 +377,10 @@ function ProviderFormContent({
             return;
           }
 
+          void queryClient.invalidateQueries({ queryKey: ["providers"] });
+          void queryClient.invalidateQueries({ queryKey: ["providers-health"] });
+          void queryClient.invalidateQueries({ queryKey: ["providers-statistics"] });
           void queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
-          void queryClient.invalidateQueries({ queryKey: ["provider-endpoints"] });
 
           toast.success(t("success.created"));
           dispatch({ type: "RESET_FORM" });

+ 377 - 18
src/app/[locale]/settings/providers/_components/provider-endpoint-hover.tsx

@@ -1,29 +1,336 @@
 "use client";
 
-import { useQuery } from "@tanstack/react-query";
+import { type QueryClient, useQuery, useQueryClient } from "@tanstack/react-query";
 import { Server } from "lucide-react";
 import { useTranslations } from "next-intl";
 import { useMemo, useState } from "react";
-import { getEndpointCircuitInfo, getProviderEndpointsByVendor } from "@/actions/provider-endpoints";
+import {
+  batchGetEndpointCircuitInfo,
+  batchGetVendorTypeEndpointStats,
+  getProviderEndpointsByVendor,
+} from "@/actions/provider-endpoints";
 import { Badge } from "@/components/ui/badge";
 import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
 import { cn } from "@/lib/utils";
 import type { ProviderEndpoint, ProviderType } from "@/types/provider";
-import { getEndpointStatusModel } from "./endpoint-status";
+import { type EndpointCircuitState, getEndpointStatusModel } from "./endpoint-status";
 
 interface ProviderEndpointHoverProps {
   vendorId: number;
   providerType: ProviderType;
 }
 
+const MAX_VENDOR_IDS_PER_BATCH = 500;
+
+type VendorTypeEndpointStats = {
+  vendorId: number;
+  total: number;
+  enabled: number;
+  healthy: number;
+  unhealthy: number;
+  unknown: number;
+};
+
+type VendorStatsDeferred = {
+  resolve: (value: VendorTypeEndpointStats) => void;
+  reject: (reason: unknown) => void;
+};
+
+function createAbortError(signal?: AbortSignal): unknown {
+  if (!signal) return new Error("Aborted");
+  if (signal.reason) return signal.reason;
+
+  try {
+    return new DOMException("Aborted", "AbortError");
+  } catch {
+    return new Error("Aborted");
+  }
+}
+
+class VendorTypeEndpointStatsBatcher {
+  private readonly pendingVendorIdsByProviderType = new Map<ProviderType, Set<number>>();
+  private readonly deferredByProviderTypeVendorId = new Map<
+    ProviderType,
+    Map<number, VendorStatsDeferred[]>
+  >();
+  private flushTimer: ReturnType<typeof setTimeout> | null = null;
+
+  load(
+    vendorId: number,
+    providerType: ProviderType,
+    options?: { signal?: AbortSignal }
+  ): Promise<VendorTypeEndpointStats> {
+    if (!Number.isFinite(vendorId) || vendorId <= 0) {
+      return Promise.resolve({
+        vendorId,
+        total: 0,
+        enabled: 0,
+        healthy: 0,
+        unhealthy: 0,
+        unknown: 0,
+      });
+    }
+
+    return new Promise<VendorTypeEndpointStats>((resolve, reject) => {
+      const signal = options?.signal;
+      if (signal?.aborted) {
+        reject(createAbortError(signal));
+        return;
+      }
+
+      let settled = false;
+      let deferred: VendorStatsDeferred;
+
+      const onAbort = () => {
+        if (settled) return;
+        settled = true;
+        this.removePendingRequest(providerType, vendorId, deferred);
+        this.maybeCancelFlushTimer();
+        reject(createAbortError(signal));
+      };
+
+      deferred = {
+        resolve: (value) => {
+          if (settled) return;
+          settled = true;
+          signal?.removeEventListener("abort", onAbort);
+          resolve(value);
+        },
+        reject: (reason) => {
+          if (settled) return;
+          settled = true;
+          signal?.removeEventListener("abort", onAbort);
+          reject(reason);
+        },
+      };
+
+      if (signal) {
+        signal.addEventListener("abort", onAbort, { once: true });
+      }
+
+      const pending = this.pendingVendorIdsByProviderType.get(providerType) ?? new Set<number>();
+      pending.add(vendorId);
+      this.pendingVendorIdsByProviderType.set(providerType, pending);
+
+      const deferredByVendorId =
+        this.deferredByProviderTypeVendorId.get(providerType) ??
+        new Map<number, VendorStatsDeferred[]>();
+      const list = deferredByVendorId.get(vendorId) ?? [];
+      list.push(deferred);
+      deferredByVendorId.set(vendorId, list);
+      this.deferredByProviderTypeVendorId.set(providerType, deferredByVendorId);
+
+      if (this.flushTimer) return;
+
+      this.flushTimer = setTimeout(() => {
+        this.flushTimer = null;
+        void this.flush().catch(() => {});
+      }, 0);
+    });
+  }
+
+  private maybeCancelFlushTimer() {
+    if (!this.flushTimer) return;
+    if (this.pendingVendorIdsByProviderType.size > 0) return;
+    clearTimeout(this.flushTimer);
+    this.flushTimer = null;
+  }
+
+  private removePendingRequest(
+    providerType: ProviderType,
+    vendorId: number,
+    deferred: VendorStatsDeferred
+  ) {
+    const deferredByVendorId = this.deferredByProviderTypeVendorId.get(providerType);
+    if (!deferredByVendorId) return;
+    const list = deferredByVendorId.get(vendorId);
+    if (!list) return;
+
+    const next = list.filter((item) => item !== deferred);
+    if (next.length > 0) {
+      deferredByVendorId.set(vendorId, next);
+      return;
+    }
+
+    deferredByVendorId.delete(vendorId);
+    if (deferredByVendorId.size === 0) {
+      this.deferredByProviderTypeVendorId.delete(providerType);
+    }
+
+    const pending = this.pendingVendorIdsByProviderType.get(providerType);
+    if (!pending) return;
+    pending.delete(vendorId);
+    if (pending.size === 0) {
+      this.pendingVendorIdsByProviderType.delete(providerType);
+    }
+  }
+
+  private async flush() {
+    const entries = Array.from(this.pendingVendorIdsByProviderType.entries());
+    this.pendingVendorIdsByProviderType.clear();
+
+    if (entries.length === 0) {
+      return;
+    }
+
+    await Promise.all(
+      entries.map(async ([providerType, vendorIdSet]) => {
+        const vendorIds = Array.from(vendorIdSet);
+        vendorIds.sort((a, b) => a - b);
+
+        for (let index = 0; index < vendorIds.length; index += MAX_VENDOR_IDS_PER_BATCH) {
+          const chunk = vendorIds.slice(index, index + MAX_VENDOR_IDS_PER_BATCH);
+          const deferredMap = this.deferredByProviderTypeVendorId.get(providerType);
+          if (!deferredMap) continue;
+
+          const deferredEntries = chunk
+            .map((vendorId) => ({
+              vendorId,
+              deferred: deferredMap.get(vendorId) ?? [],
+            }))
+            .filter(({ deferred }) => deferred.length > 0);
+
+          const vendorIdsToFetch = deferredEntries.map(({ vendorId }) => vendorId);
+          vendorIdsToFetch.forEach((vendorId) => deferredMap.delete(vendorId));
+          if (deferredMap.size === 0) {
+            this.deferredByProviderTypeVendorId.delete(providerType);
+          }
+
+          if (vendorIdsToFetch.length === 0) continue;
+
+          try {
+            const res = await batchGetVendorTypeEndpointStats({
+              vendorIds: vendorIdsToFetch,
+              providerType,
+            });
+            const items = res.ok && res.data ? res.data : [];
+
+            const statsByVendorId = new Map<number, VendorTypeEndpointStats>();
+            vendorIdsToFetch.forEach((vendorId) =>
+              statsByVendorId.set(vendorId, {
+                vendorId,
+                total: 0,
+                enabled: 0,
+                healthy: 0,
+                unhealthy: 0,
+                unknown: 0,
+              })
+            );
+
+            items.forEach((item) => {
+              statsByVendorId.set(item.vendorId, {
+                vendorId: item.vendorId,
+                total: item.total,
+                enabled: item.enabled,
+                healthy: item.healthy,
+                unhealthy: item.unhealthy,
+                unknown: item.unknown,
+              });
+            });
+
+            deferredEntries.forEach(({ vendorId, deferred }) => {
+              const value = statsByVendorId.get(vendorId);
+              if (value) {
+                deferred.forEach((d) => d.resolve(value));
+              } else {
+                deferred.forEach((d) =>
+                  d.resolve({
+                    vendorId,
+                    total: 0,
+                    enabled: 0,
+                    healthy: 0,
+                    unhealthy: 0,
+                    unknown: 0,
+                  })
+                );
+              }
+            });
+          } catch {
+            // 降级路径:batch action 异常时按 vendorId 逐个查询。为避免 chunk 较大时触发请求风暴,这里限制并发。
+            const concurrency = 8;
+            let idx = 0;
+
+            const workers = Array.from(
+              { length: Math.min(concurrency, deferredEntries.length) },
+              async () => {
+                for (;;) {
+                  const currentIndex = idx++;
+                  if (currentIndex >= deferredEntries.length) return;
+
+                  const { vendorId, deferred } = deferredEntries[currentIndex];
+
+                  try {
+                    const endpoints = await getProviderEndpointsByVendor({ vendorId });
+                    const filtered = endpoints.filter(
+                      (ep) =>
+                        ep.providerType === providerType &&
+                        ep.isEnabled === true &&
+                        ep.deletedAt === null
+                    );
+
+                    const healthy = filtered.filter((ep) => ep.lastProbeOk === true).length;
+                    const unhealthy = filtered.filter((ep) => ep.lastProbeOk === false).length;
+                    const unknown = filtered.filter((ep) => ep.lastProbeOk == null).length;
+
+                    const value: VendorTypeEndpointStats = {
+                      vendorId,
+                      total: endpoints.filter(
+                        (ep) => ep.providerType === providerType && ep.deletedAt === null
+                      ).length,
+                      enabled: filtered.length,
+                      healthy,
+                      unhealthy,
+                      unknown,
+                    };
+
+                    deferred.forEach((d) => d.resolve(value));
+                  } catch (innerError) {
+                    deferred.forEach((d) => d.reject(innerError));
+                  }
+                }
+              }
+            );
+
+            await Promise.all(workers);
+          }
+        }
+      })
+    );
+  }
+}
+
+const vendorStatsBatcherByQueryClient = new WeakMap<QueryClient, VendorTypeEndpointStatsBatcher>();
+
+function getVendorStatsBatcher(queryClient: QueryClient): VendorTypeEndpointStatsBatcher {
+  const existing = vendorStatsBatcherByQueryClient.get(queryClient);
+  if (existing) return existing;
+
+  const batcher = new VendorTypeEndpointStatsBatcher();
+  vendorStatsBatcherByQueryClient.set(queryClient, batcher);
+  return batcher;
+}
+
 export function ProviderEndpointHover({ vendorId, providerType }: ProviderEndpointHoverProps) {
   const t = useTranslations("settings.providers");
   const [isOpen, setIsOpen] = useState(false);
+  const queryClient = useQueryClient();
+  const statsBatcher = useMemo(() => getVendorStatsBatcher(queryClient), [queryClient]);
+
+  const { data: stats } = useQuery({
+    queryKey: ["provider-endpoints", vendorId, providerType, "hover-stats"],
+    queryFn: ({ signal }) => statsBatcher.load(vendorId, providerType, { signal }),
+    staleTime: 1000 * 30,
+    refetchOnWindowFocus: false,
+  });
+
+  const count = stats?.enabled ?? 0;
 
-  const { data: allEndpoints = [] } = useQuery({
+  const { data: allEndpoints = [], isLoading: endpointsLoading } = useQuery({
     queryKey: ["provider-endpoints", vendorId],
     queryFn: async () => getProviderEndpointsByVendor({ vendorId }),
+    enabled: isOpen || process.env.NODE_ENV === "test",
     staleTime: 1000 * 30,
+    refetchOnWindowFocus: false,
   });
 
   const endpoints = useMemo(() => {
@@ -53,7 +360,55 @@ export function ProviderEndpointHover({ vendorId, providerType }: ProviderEndpoi
       });
   }, [allEndpoints, providerType]);
 
-  const count = endpoints.length;
+  const endpointIds = useMemo(() => endpoints.map((ep) => ep.id), [endpoints]);
+  const endpointIdsKey = useMemo(() => {
+    if (endpointIds.length === 0) return "";
+    return endpointIds
+      .slice()
+      .sort((a, b) => a - b)
+      .join(",");
+  }, [endpointIds]);
+
+  const { data: circuitInfoMap = {} } = useQuery({
+    queryKey: ["endpoint-circuit-info", endpointIdsKey],
+    queryFn: async () => {
+      if (endpointIds.length === 0) return {};
+
+      const map: Record<number, EndpointCircuitState> = {};
+      const sortedEndpointIds = endpointIds.slice().sort((a, b) => a - b);
+      const MAX_ENDPOINT_IDS_PER_BATCH = 500;
+      const chunks: number[][] = [];
+      for (let index = 0; index < sortedEndpointIds.length; index += MAX_ENDPOINT_IDS_PER_BATCH) {
+        chunks.push(sortedEndpointIds.slice(index, index + MAX_ENDPOINT_IDS_PER_BATCH));
+      }
+
+      const results = await Promise.all(
+        chunks.map(async (chunk) => {
+          const res = await batchGetEndpointCircuitInfo({ endpointIds: chunk });
+          return res.ok && res.data ? res.data : [];
+        })
+      );
+
+      for (const item of results.flat()) {
+        map[item.endpointId] = item.circuitState as EndpointCircuitState;
+      }
+
+      return map;
+    },
+    enabled: isOpen && endpointIds.length > 0,
+    staleTime: 1000 * 10,
+    refetchOnWindowFocus: false,
+  });
+
+  const circuitStateByEndpointId = useMemo(() => {
+    const map = new Map<number, EndpointCircuitState>();
+    for (const [rawId, circuitState] of Object.entries(circuitInfoMap)) {
+      const endpointId = Number(rawId);
+      if (!Number.isFinite(endpointId)) continue;
+      map.set(endpointId, circuitState);
+    }
+    return map;
+  }, [circuitInfoMap]);
 
   return (
     <TooltipProvider>
@@ -80,14 +435,22 @@ export function ProviderEndpointHover({ vendorId, providerType }: ProviderEndpoi
             </h4>
           </div>
           <div className="max-h-[300px] overflow-y-auto py-1">
-            {count === 0 ? (
+            {endpointsLoading ? (
+              <div className="px-3 py-4 text-center text-xs text-muted-foreground">
+                {t("keyLoading")}
+              </div>
+            ) : count === 0 ? (
               <div className="px-3 py-4 text-center text-xs text-muted-foreground">
                 {t("endpointStatus.noEndpoints")}
               </div>
             ) : (
               <div className="flex flex-col gap-0.5">
                 {endpoints.map((endpoint) => (
-                  <EndpointRow key={endpoint.id} endpoint={endpoint} isOpen={isOpen} />
+                  <EndpointRow
+                    key={endpoint.id}
+                    endpoint={endpoint}
+                    circuitState={circuitStateByEndpointId.get(endpoint.id)}
+                  />
                 ))}
               </div>
             )}
@@ -98,19 +461,15 @@ export function ProviderEndpointHover({ vendorId, providerType }: ProviderEndpoi
   );
 }
 
-function EndpointRow({ endpoint, isOpen }: { endpoint: ProviderEndpoint; isOpen: boolean }) {
+function EndpointRow({
+  endpoint,
+  circuitState,
+}: {
+  endpoint: ProviderEndpoint;
+  circuitState?: "closed" | "open" | "half-open";
+}) {
   const t = useTranslations("settings.providers");
 
-  const { data: circuitResult } = useQuery({
-    queryKey: ["endpoint-circuit", endpoint.id],
-    queryFn: async () => getEndpointCircuitInfo({ endpointId: endpoint.id }),
-    enabled: isOpen,
-    staleTime: 1000 * 10,
-  });
-
-  const circuitState =
-    circuitResult?.ok && circuitResult.data ? circuitResult.data.health.circuitState : undefined;
-
   const statusModel = getEndpointStatusModel(endpoint, circuitState);
   const Icon = statusModel.icon;
 

+ 57 - 38
src/app/[locale]/settings/providers/_components/provider-endpoints-table.tsx

@@ -52,6 +52,7 @@ import {
   TableRow,
 } from "@/components/ui/table";
 import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
+import { useInViewOnce } from "@/lib/hooks/use-in-view-once";
 import {
   getAllProviderTypes,
   getProviderTypeConfig,
@@ -113,6 +114,8 @@ export function ProviderEndpointsTable({
       }
       return await getProviderEndpointsByVendor({ vendorId });
     },
+    staleTime: 30_000,
+    refetchOnWindowFocus: false,
   });
 
   // Sort endpoints by type order (from getAllProviderTypes) then by sortOrder
@@ -132,20 +135,42 @@ export function ProviderEndpointsTable({
 
   // Fetch circuit breaker states for all endpoints in batch
   const endpointIds = useMemo(() => endpoints.map((ep) => ep.id), [endpoints]);
+  const endpointIdsQueryKey = useMemo(
+    () =>
+      endpointIds
+        .slice()
+        .sort((a, b) => a - b)
+        .join(","),
+    [endpointIds]
+  );
   const { data: circuitInfoMap = {} } = useQuery({
-    queryKey: ["endpoint-circuit-info", endpointIds.toSorted((a, b) => a - b).join(",")],
+    queryKey: ["endpoint-circuit-info", endpointIdsQueryKey],
     queryFn: async () => {
       if (endpointIds.length === 0) return {};
-      const res = await batchGetEndpointCircuitInfo({ endpointIds });
-      if (!res.ok || !res.data) return {};
       const map: Record<number, EndpointCircuitState> = {};
-      for (const item of res.data) {
+
+      const MAX_ENDPOINT_IDS_PER_BATCH = 500;
+      const chunks: number[][] = [];
+      for (let index = 0; index < endpointIds.length; index += MAX_ENDPOINT_IDS_PER_BATCH) {
+        chunks.push(endpointIds.slice(index, index + MAX_ENDPOINT_IDS_PER_BATCH));
+      }
+
+      const results = await Promise.all(
+        chunks.map(async (chunk) => {
+          const res = await batchGetEndpointCircuitInfo({ endpointIds: chunk });
+          return res.ok && res.data ? res.data : [];
+        })
+      );
+
+      for (const item of results.flat()) {
         map[item.endpointId] = item.circuitState as EndpointCircuitState;
       }
+
       return map;
     },
     enabled: endpointIds.length > 0,
     staleTime: 15_000,
+    refetchOnWindowFocus: false,
   });
 
   if (isLoading) {
@@ -228,7 +253,8 @@ function EndpointRow({
     onMutate: () => setIsProbing(true),
     onSettled: () => setIsProbing(false),
     onSuccess: (data) => {
-      queryClient.invalidateQueries({ queryKey: ["provider-endpoints"] });
+      queryClient.invalidateQueries({ queryKey: ["provider-endpoints", endpoint.vendorId] });
+      queryClient.invalidateQueries({ queryKey: ["endpoint-probe-logs", endpoint.id] });
       if (data?.result.ok) {
         toast.success(t("probeSuccess"));
       } else {
@@ -251,7 +277,7 @@ function EndpointRow({
       return res.data;
     },
     onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: ["provider-endpoints"] });
+      queryClient.invalidateQueries({ queryKey: ["provider-endpoints", endpoint.vendorId] });
       queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
       toast.success(t("endpointDeleteSuccess"));
     },
@@ -272,7 +298,7 @@ function EndpointRow({
     onMutate: () => setIsToggling(true),
     onSettled: () => setIsToggling(false),
     onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: ["provider-endpoints"] });
+      queryClient.invalidateQueries({ queryKey: ["provider-endpoints", endpoint.vendorId] });
       toast.success(t("endpointUpdateSuccess"));
     },
     onError: () => {
@@ -287,18 +313,19 @@ function EndpointRow({
       return res;
     },
     onMutate: () => {
-      // Optimistic update: immediately set circuit state to closed
+      // 乐观更新:仅更新包含该 endpointId 的 circuit-info 查询,避免污染其它 cache;
+      // 同时避免在成功后做过宽 invalidation 引发“刷新放大/请求风暴”(#779/#781 相关)。
       queryClient.setQueriesData<Record<number, EndpointCircuitState>>(
         { queryKey: ["endpoint-circuit-info"] },
         (old) => {
           if (!old) return old;
+          if (!Object.hasOwn(old, endpoint.id)) return old;
+          if (old[endpoint.id] === "closed") return old;
           return { ...old, [endpoint.id]: "closed" as EndpointCircuitState };
         }
       );
     },
     onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: ["endpoint-circuit-info"] });
-      queryClient.invalidateQueries({ queryKey: ["provider-endpoints"] });
       toast.success(tStatus("resetCircuitSuccess"));
     },
     onError: () => {
@@ -450,14 +477,11 @@ export interface AddEndpointButtonProps {
   vendorId: number;
   /** If provided, locks the type selector to this value */
   providerType?: ProviderType;
-  /** Custom query key suffix for cache invalidation */
-  queryKeySuffix?: string;
 }
 
 export function AddEndpointButton({
   vendorId,
   providerType: fixedProviderType,
-  queryKeySuffix,
 }: AddEndpointButtonProps) {
   const t = useTranslations("settings.providers");
   const tErrors = useTranslations("errors");
@@ -507,20 +531,11 @@ export function AddEndpointButton({
       if (res.ok) {
         toast.success(t("endpointAddSuccess"));
         setOpen(false);
-        // Invalidate both specific and general queries
-        // Explicitly suppress rejections to avoid double toast
+        // 仅失效 vendor 维度即可:前缀匹配会覆盖 providerType 等变体,避免重复 invalidation。
+        // 显式吞掉 rejections,避免错误状态下二次 toast。
         queryClient
           .invalidateQueries({ queryKey: ["provider-endpoints", vendorId] })
           .catch(() => undefined);
-        if (fixedProviderType) {
-          queryClient
-            .invalidateQueries({
-              queryKey: ["provider-endpoints", vendorId, fixedProviderType, queryKeySuffix].filter(
-                (value) => value != null
-              ),
-            })
-            .catch(() => undefined);
-        }
         return;
       }
 
@@ -684,7 +699,9 @@ function EditEndpointDialog({ endpoint }: { endpoint: ProviderEndpoint }) {
       if (res.ok) {
         toast.success(t("endpointUpdateSuccess"));
         setOpen(false);
-        queryClient.invalidateQueries({ queryKey: ["provider-endpoints"] }).catch(() => undefined);
+        queryClient
+          .invalidateQueries({ queryKey: ["provider-endpoints", endpoint.vendorId] })
+          .catch(() => undefined);
         return;
       }
 
@@ -768,6 +785,7 @@ export interface ProviderEndpointsSectionProps {
   readOnly?: boolean;
   hideTypeColumn?: boolean;
   queryKeySuffix?: string;
+  deferUntilInView?: boolean;
 }
 
 /**
@@ -780,31 +798,32 @@ export function ProviderEndpointsSection({
   readOnly = false,
   hideTypeColumn = false,
   queryKeySuffix,
+  deferUntilInView = false,
 }: ProviderEndpointsSectionProps) {
   const t = useTranslations("settings.providers");
+  const { ref, isInView } = useInViewOnce<HTMLDivElement>();
+  const shouldLoad = !deferUntilInView || isInView;
 
   return (
-    <div>
+    <div ref={ref}>
       <div className="px-6 py-3 bg-muted/10 border-b font-medium text-sm text-muted-foreground flex items-center justify-between">
         <span>{t("endpoints")}</span>
-        {!readOnly && (
-          <AddEndpointButton
+        {!readOnly && <AddEndpointButton vendorId={vendorId} providerType={providerType} />}
+      </div>
+
+      <div className="p-6">
+        {shouldLoad ? (
+          <ProviderEndpointsTable
             vendorId={vendorId}
             providerType={providerType}
+            readOnly={readOnly}
+            hideTypeColumn={hideTypeColumn}
             queryKeySuffix={queryKeySuffix}
           />
+        ) : (
+          <div className="h-24 rounded-md bg-muted/20" />
         )}
       </div>
-
-      <div className="p-6">
-        <ProviderEndpointsTable
-          vendorId={vendorId}
-          providerType={providerType}
-          readOnly={readOnly}
-          hideTypeColumn={hideTypeColumn}
-          queryKeySuffix={queryKeySuffix}
-        />
-      </div>
     </div>
   );
 }

+ 15 - 0
src/app/[locale]/settings/providers/_components/provider-list.tsx

@@ -1,6 +1,9 @@
 "use client";
+import { useQuery } from "@tanstack/react-query";
 import { Globe } from "lucide-react";
 import { useTranslations } from "next-intl";
+import { useMemo } from "react";
+import { getProviderVendors } from "@/actions/provider-endpoints";
 import type { CurrencyCode } from "@/lib/utils/currency";
 import type { ProviderDisplay, ProviderStatisticsMap } from "@/types/provider";
 import type { User } from "@/types/user";
@@ -54,6 +57,17 @@ export function ProviderList({
 }: ProviderListProps) {
   const t = useTranslations("settings.providers");
 
+  const { data: vendors = [] } = useQuery({
+    queryKey: ["provider-vendors"],
+    queryFn: getProviderVendors,
+    staleTime: 60_000,
+    refetchOnWindowFocus: false,
+  });
+
+  const vendorById = useMemo(() => {
+    return new Map(vendors.map((vendor) => [vendor.id, vendor]));
+  }, [vendors]);
+
   if (providers.length === 0) {
     return (
       <div className="flex flex-col items-center justify-center py-12 px-4">
@@ -72,6 +86,7 @@ export function ProviderList({
         <ProviderRichListItem
           key={provider.id}
           provider={provider}
+          vendor={provider.providerVendorId ? vendorById.get(provider.providerVendorId) : undefined}
           currentUser={currentUser}
           healthStatus={healthStatus[provider.id]}
           endpointCircuitInfo={endpointCircuitInfo[provider.id]}

+ 4 - 27
src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx

@@ -1,5 +1,5 @@
 "use client";
-import { useQuery, useQueryClient } from "@tanstack/react-query";
+import { useQueryClient } from "@tanstack/react-query";
 import {
   AlertTriangle,
   CheckCircle,
@@ -12,11 +12,9 @@ import {
   Trash,
   XCircle,
 } from "lucide-react";
-import { useRouter } from "next/navigation";
 import { useTranslations } from "next-intl";
 import { useEffect, useState, useTransition } from "react";
 import { toast } from "sonner";
-import { getProviderVendors } from "@/actions/provider-endpoints";
 import {
   editProvider,
   getUnmaskedProviderKey,
@@ -60,7 +58,7 @@ import { copyToClipboard, isClipboardSupported } from "@/lib/utils/clipboard";
 import { getContrastTextColor, getGroupColor } from "@/lib/utils/color";
 import type { CurrencyCode } from "@/lib/utils/currency";
 import { formatCurrency } from "@/lib/utils/currency";
-import type { ProviderDisplay, ProviderStatistics } from "@/types/provider";
+import type { ProviderDisplay, ProviderStatistics, ProviderVendor } from "@/types/provider";
 import type { User } from "@/types/user";
 import { ProviderForm } from "./forms/provider-form";
 import { GroupEditCombobox } from "./group-edit-combobox";
@@ -70,6 +68,7 @@ import { ProviderEndpointHover } from "./provider-endpoint-hover";
 
 interface ProviderRichListItemProps {
   provider: ProviderDisplay;
+  vendor?: ProviderVendor;
   currentUser?: User;
   healthStatus?: {
     circuitState: "closed" | "open" | "half-open";
@@ -103,6 +102,7 @@ interface ProviderRichListItemProps {
 
 export function ProviderRichListItem({
   provider,
+  vendor,
   currentUser,
   healthStatus,
   endpointCircuitInfo = [],
@@ -121,13 +121,7 @@ export function ProviderRichListItem({
   userGroups = [],
   isAdmin = false,
 }: ProviderRichListItemProps) {
-  const router = useRouter();
   const queryClient = useQueryClient();
-  const { data: vendors = [] } = useQuery({
-    queryKey: ["provider-vendors"],
-    queryFn: async () => await getProviderVendors(),
-    staleTime: 60000,
-  });
 
   const [openEdit, setOpenEdit] = useState(false);
   const [openClone, setOpenClone] = useState(false);
@@ -182,10 +176,6 @@ export function ProviderRichListItem({
   const typeLabel = tTypes(`${typeKey}.label`);
   const typeDescription = tTypes(`${typeKey}.description`);
 
-  const vendor = provider.providerVendorId
-    ? vendors.find((v) => v.id === provider.providerVendorId)
-    : undefined;
-
   useEffect(() => {
     setClipboardAvailable(isClipboardSupported());
   }, []);
@@ -223,7 +213,6 @@ export function ProviderRichListItem({
             queryClient.invalidateQueries({ queryKey: ["providers"] });
             queryClient.invalidateQueries({ queryKey: ["providers-health"] });
             queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
-            router.refresh();
           } else {
             toast.error(tList("deleteFailed"), {
               description: res.error || tList("unknownError"),
@@ -294,7 +283,6 @@ export function ProviderRichListItem({
           });
           queryClient.invalidateQueries({ queryKey: ["providers"] });
           queryClient.invalidateQueries({ queryKey: ["providers-health"] });
-          router.refresh();
         } else {
           toast.error(tList("resetCircuitFailed"), {
             description: res.error || tList("unknownError"),
@@ -320,7 +308,6 @@ export function ProviderRichListItem({
           });
           queryClient.invalidateQueries({ queryKey: ["providers"] });
           queryClient.invalidateQueries({ queryKey: ["providers-health"] });
-          router.refresh();
         } else {
           toast.error(tList("resetUsageFailed"), {
             description: res.error || tList("unknownError"),
@@ -349,7 +336,6 @@ export function ProviderRichListItem({
           });
           queryClient.invalidateQueries({ queryKey: ["providers"] });
           queryClient.invalidateQueries({ queryKey: ["providers-health"] });
-          router.refresh();
         } else {
           toast.error(tList("toggleFailed"), {
             description: res.error || tList("unknownError"),
@@ -373,7 +359,6 @@ export function ProviderRichListItem({
         if (res.ok) {
           toast.success(tInline("saveSuccess"));
           queryClient.invalidateQueries({ queryKey: ["providers"] });
-          router.refresh();
           return true;
         }
         toast.error(tInline("saveFailed"), { description: res.error || tList("unknownError") });
@@ -403,7 +388,6 @@ export function ProviderRichListItem({
       if (res.ok) {
         toast.success(tInline("saveSuccess"));
         queryClient.invalidateQueries({ queryKey: ["providers"] });
-        router.refresh();
         return true;
       }
       toast.error(tInline("groupSaveError"), {
@@ -429,7 +413,6 @@ export function ProviderRichListItem({
       if (res.ok) {
         toast.success(tInline("saveSuccess"));
         queryClient.invalidateQueries({ queryKey: ["providers"] });
-        router.refresh();
         return true;
       }
       toast.error(tInline("saveFailed"), { description: res.error || tList("unknownError") });
@@ -971,9 +954,6 @@ export function ProviderRichListItem({
               provider={provider}
               onSuccess={() => {
                 setOpenEdit(false);
-                queryClient.invalidateQueries({ queryKey: ["providers"] });
-                queryClient.invalidateQueries({ queryKey: ["providers-health"] });
-                router.refresh();
               }}
               enableMultiProviderTypes={enableMultiProviderTypes}
             />
@@ -990,9 +970,6 @@ export function ProviderRichListItem({
               cloneProvider={provider}
               onSuccess={() => {
                 setOpenClone(false);
-                queryClient.invalidateQueries({ queryKey: ["providers"] });
-                queryClient.invalidateQueries({ queryKey: ["providers-health"] });
-                router.refresh();
               }}
               enableMultiProviderTypes={enableMultiProviderTypes}
             />

+ 9 - 4
src/app/[locale]/settings/providers/_components/provider-vendor-view.tsx

@@ -51,10 +51,15 @@ export function ProviderVendorView(props: ProviderVendorViewProps) {
 
   const { data: vendors = [], isLoading: isVendorsLoading } = useQuery({
     queryKey: ["provider-vendors"],
-    queryFn: async () => await getProviderVendors(),
-    staleTime: 60000,
+    queryFn: getProviderVendors,
+    staleTime: 60_000,
+    refetchOnWindowFocus: false,
   });
 
+  const vendorById = useMemo(() => {
+    return new Map(vendors.map((vendor) => [vendor.id, vendor]));
+  }, [vendors]);
+
   const providersByVendor = useMemo(() => {
     const grouped: Record<number, ProviderDisplay[]> = {};
     const orphaned: ProviderDisplay[] = [];
@@ -95,7 +100,7 @@ export function ProviderVendorView(props: ProviderVendorViewProps) {
   return (
     <div className="space-y-8">
       {allVendorIds.map((vendorId) => {
-        const vendor = vendors.find((v) => v.id === vendorId);
+        const vendor = vendorId > 0 ? vendorById.get(vendorId) : undefined;
         const vendorProviders = providersByVendor[vendorId] || [];
 
         if (vendorProviders.length === 0) return null;
@@ -209,7 +214,7 @@ function VendorCard({
         />
 
         {enableMultiProviderTypes && vendorId > 0 && (
-          <ProviderEndpointsSection vendorId={vendorId} />
+          <ProviderEndpointsSection vendorId={vendorId} deferUntilInView />
         )}
       </CardContent>
     </Card>

+ 24 - 15
src/app/[locale]/settings/providers/_components/vendor-keys-compact-list.tsx

@@ -2,7 +2,6 @@
 
 import { useMutation, useQueryClient } from "@tanstack/react-query";
 import { CheckCircle, Copy, Edit2, Loader2, Plus, Trash2 } from "lucide-react";
-import { useRouter } from "next/navigation";
 import { useTranslations } from "next-intl";
 import { useEffect, useState } from "react";
 import { toast } from "sonner";
@@ -42,7 +41,12 @@ import { PROVIDER_LIMITS } from "@/lib/constants/provider.constants";
 import { getProviderTypeConfig, getProviderTypeTranslationKey } from "@/lib/provider-type-utils";
 import { copyToClipboard, isClipboardSupported } from "@/lib/utils/clipboard";
 import { type CurrencyCode, formatCurrency } from "@/lib/utils/currency";
-import type { ProviderDisplay, ProviderStatisticsMap, ProviderType } from "@/types/provider";
+import type {
+  ProviderDisplay,
+  ProviderEndpoint,
+  ProviderStatisticsMap,
+  ProviderType,
+} from "@/types/provider";
 import type { User } from "@/types/user";
 import { ProviderForm } from "./forms/provider-form";
 import { InlineEditPopover } from "./inline-edit-popover";
@@ -112,17 +116,26 @@ export function VendorKeysCompactList(props: {
                   }}
                   urlResolver={async (type) => {
                     if (props.vendorId <= 0) return null;
-                    const endpoints = await getProviderEndpoints({
-                      vendorId: props.vendorId,
-                      providerType: type,
-                    });
+
+                    const queryKey = ["provider-endpoints", props.vendorId, type] as const;
+                    const cached = queryClient.getQueryData<ProviderEndpoint[]>(queryKey);
+                    const endpoints =
+                      cached ??
+                      (await queryClient.fetchQuery<ProviderEndpoint[]>({
+                        queryKey,
+                        queryFn: async () =>
+                          await getProviderEndpoints({
+                            vendorId: props.vendorId,
+                            providerType: type,
+                          }),
+                        staleTime: 30_000,
+                      })) ??
+                      [];
                     const enabled = endpoints.find((e) => e.isEnabled);
                     return (enabled ?? endpoints[0])?.url ?? null;
                   }}
                   onSuccess={() => {
                     setCreateOpen(false);
-                    queryClient.invalidateQueries({ queryKey: ["providers"] });
-                    queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
                   }}
                 />
               </FormErrorBoundary>
@@ -201,7 +214,6 @@ function VendorKeyRow(props: {
   const tTypes = useTranslations("settings.providers.types");
 
   const queryClient = useQueryClient();
-  const router = useRouter();
 
   const validatePriority = (raw: string) => {
     if (raw.length === 0) return tInline("priorityInvalid");
@@ -239,7 +251,6 @@ function VendorKeyRow(props: {
           toast.success(tInline("saveSuccess"));
           queryClient.invalidateQueries({ queryKey: ["providers"] });
           queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
-          router.refresh();
           return true;
         }
         toast.error(tInline("saveFailed"), { description: res.error || tList("unknownError") });
@@ -278,8 +289,8 @@ function VendorKeyRow(props: {
     },
     onSuccess: () => {
       queryClient.invalidateQueries({ queryKey: ["providers"] });
+      queryClient.invalidateQueries({ queryKey: ["providers-health"] });
       queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
-      router.refresh();
     },
     onError: () => {
       toast.error(t("toggleFailed"));
@@ -293,12 +304,13 @@ function VendorKeyRow(props: {
     },
     onSuccess: () => {
       queryClient.invalidateQueries({ queryKey: ["providers"] });
+      queryClient.invalidateQueries({ queryKey: ["providers-health"] });
+      queryClient.invalidateQueries({ queryKey: ["providers-statistics"] });
       queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
       setDeleteDialogOpen(false);
       toast.success(tList("deleteSuccess"), {
         description: tList("deleteSuccessDesc", { name: props.provider.name }),
       });
-      router.refresh();
     },
     onError: () => {
       toast.error(tList("deleteFailed"));
@@ -469,9 +481,6 @@ function VendorKeyRow(props: {
                       }
                       onSuccess={() => {
                         setEditOpen(false);
-                        queryClient.invalidateQueries({ queryKey: ["providers"] });
-                        queryClient.invalidateQueries({ queryKey: ["provider-vendors"] });
-                        router.refresh();
                       }}
                     />
                   </FormErrorBoundary>

+ 40 - 0
src/app/api/actions/[...route]/route.ts

@@ -515,6 +515,46 @@ const { route: getProviderEndpointProbeLogsRoute, handler: getProviderEndpointPr
   );
 app.openapi(getProviderEndpointProbeLogsRoute, getProviderEndpointProbeLogsHandler);
 
+const {
+  route: batchGetProviderEndpointProbeLogsRoute,
+  handler: batchGetProviderEndpointProbeLogsHandler,
+} = createActionRoute(
+  "providers",
+  "batchGetProviderEndpointProbeLogs",
+  providerEndpointActions.batchGetProviderEndpointProbeLogs,
+  {
+    requestSchema: z.object({
+      endpointIds: z.array(z.number().int().positive()).max(500),
+      limit: z.number().int().min(1).max(200).optional(),
+    }),
+    description: "批量读取多个端点的测活历史(每端点取最近 N 条) (管理员)",
+    summary: "批量读取测活历史",
+    tags: ["供应商管理"],
+    requiredRole: "admin",
+  }
+);
+app.openapi(batchGetProviderEndpointProbeLogsRoute, batchGetProviderEndpointProbeLogsHandler);
+
+const {
+  route: batchGetVendorTypeEndpointStatsRoute,
+  handler: batchGetVendorTypeEndpointStatsHandler,
+} = createActionRoute(
+  "providers",
+  "batchGetVendorTypeEndpointStats",
+  providerEndpointActions.batchGetVendorTypeEndpointStats,
+  {
+    requestSchema: z.object({
+      vendorIds: z.array(z.number().int().positive()).max(500),
+      providerType: ProviderTypeSchema,
+    }),
+    description: "批量统计 vendor+type 维度端点数量与健康分布 (管理员)",
+    summary: "批量端点统计",
+    tags: ["供应商管理"],
+    requiredRole: "admin",
+  }
+);
+app.openapi(batchGetVendorTypeEndpointStatsRoute, batchGetVendorTypeEndpointStatsHandler);
+
 const { route: getEndpointCircuitInfoRoute, handler: getEndpointCircuitInfoHandler } =
   createActionRoute(
     "providers",

+ 5 - 2
src/app/api/availability/endpoints/route.ts

@@ -1,6 +1,6 @@
 import { type NextRequest, NextResponse } from "next/server";
 import { getSession } from "@/lib/auth";
-import { findProviderEndpointsByVendorAndType } from "@/repository";
+import { findDashboardProviderEndpointsByVendorAndType } from "@/repository/provider-endpoints";
 import type { ProviderType } from "@/types/provider";
 
 const PROVIDER_TYPES: ProviderType[] = [
@@ -36,7 +36,10 @@ export async function GET(request: NextRequest) {
   }
 
   try {
-    const endpoints = await findProviderEndpointsByVendorAndType(vendorId, providerTypeRaw);
+    const endpoints = await findDashboardProviderEndpointsByVendorAndType(
+      vendorId,
+      providerTypeRaw
+    );
     return NextResponse.json({ vendorId, providerType: providerTypeRaw, endpoints });
   } catch (error) {
     console.error("Endpoint availability API error:", error);

+ 49 - 0
src/drizzle/schema.ts

@@ -82,6 +82,10 @@ export const users = pgTable('users', {
   usersEnabledExpiresAtIdx: index('idx_users_enabled_expires_at')
     .on(table.isEnabled, table.expiresAt)
     .where(sql`${table.deletedAt} IS NULL`),
+  // Tag 筛选(@>)的 GIN 索引:加速用户管理列表页的标签过滤
+  usersTagsGinIdx: index('idx_users_tags_gin')
+    .using('gin', table.tags)
+    .where(sql`${table.deletedAt} IS NULL`),
   // 基础索引
   usersCreatedAtIdx: index('idx_users_created_at').on(table.createdAt),
   usersDeletedAtIdx: index('idx_users_deleted_at').on(table.deletedAt),
@@ -125,6 +129,7 @@ export const keys = pgTable('keys', {
 }, (table) => ({
   // 基础索引(详细的复合索引通过迁移脚本管理)
   keysUserIdIdx: index('idx_keys_user_id').on(table.userId),
+  keysKeyIdx: index('idx_keys_key').on(table.key),
   keysCreatedAtIdx: index('idx_keys_created_at').on(table.createdAt),
   keysDeletedAtIdx: index('idx_keys_deleted_at').on(table.deletedAt),
 }));
@@ -309,10 +314,19 @@ export const providers = pgTable('providers', {
   providersEnabledPriorityIdx: index('idx_providers_enabled_priority').on(table.isEnabled, table.priority, table.weight).where(sql`${table.deletedAt} IS NULL`),
   // 分组查询优化
   providersGroupIdx: index('idx_providers_group').on(table.groupTag).where(sql`${table.deletedAt} IS NULL`),
+  // #779:加速“旧 URL 是否仍被引用”的判断(vendor/type/url 精确匹配)
+  providersVendorTypeUrlActiveIdx: index('idx_providers_vendor_type_url_active').on(table.providerVendorId, table.providerType, table.url).where(sql`${table.deletedAt} IS NULL`),
   // 基础索引
   providersCreatedAtIdx: index('idx_providers_created_at').on(table.createdAt),
   providersDeletedAtIdx: index('idx_providers_deleted_at').on(table.deletedAt),
   providersVendorTypeIdx: index('idx_providers_vendor_type').on(table.providerVendorId, table.providerType).where(sql`${table.deletedAt} IS NULL`),
+  // #779/#781:Dashboard/Probe scheduler 的 enabled vendor/type 去重热路径
+  providersEnabledVendorTypeIdx: index('idx_providers_enabled_vendor_type').on(
+    table.providerVendorId,
+    table.providerType
+  ).where(
+    sql`${table.deletedAt} IS NULL AND ${table.isEnabled} = true AND ${table.providerVendorId} IS NOT NULL AND ${table.providerVendorId} > 0`
+  ),
 }));
 
 // Provider Endpoints table - 供应商(官网域名) + 类型 维度的端点池
@@ -356,6 +370,14 @@ export const providerEndpoints = pgTable('provider_endpoints', {
     table.vendorId,
     table.providerType
   ).where(sql`${table.deletedAt} IS NULL`),
+  // #779:运行时端点选择热路径(vendor/type/enabled 定位 + sort_order 有序扫描)
+  providerEndpointsPickEnabledIdx: index('idx_provider_endpoints_pick_enabled').on(
+    table.vendorId,
+    table.providerType,
+    table.isEnabled,
+    table.sortOrder,
+    table.id
+  ).where(sql`${table.deletedAt} IS NULL`),
   providerEndpointsCreatedAtIdx: index('idx_provider_endpoints_created_at').on(table.createdAt),
   providerEndpointsDeletedAtIdx: index('idx_provider_endpoints_deleted_at').on(table.deletedAt),
 }));
@@ -471,6 +493,33 @@ export const messageRequest = pgTable('message_request', {
   messageRequestProviderIdIdx: index('idx_message_request_provider_id').on(table.providerId),
   messageRequestUserIdIdx: index('idx_message_request_user_id').on(table.userId),
   messageRequestKeyIdx: index('idx_message_request_key').on(table.key),
+  // #779:Key 维度分页/时间范围查询热路径(my-usage / usage logs)
+  messageRequestKeyCreatedAtIdIdx: index('idx_message_request_key_created_at_id').on(
+    table.key,
+    table.createdAt.desc(),
+    table.id.desc()
+  ).where(sql`${table.deletedAt} IS NULL`),
+  // #779:my-usage 下拉筛选 DISTINCT model / endpoint(Key 维度热路径)
+  messageRequestKeyModelActiveIdx: index('idx_message_request_key_model_active').on(
+    table.key,
+    table.model
+  ).where(
+    sql`${table.deletedAt} IS NULL AND ${table.model} IS NOT NULL AND (${table.blockedBy} IS NULL OR ${table.blockedBy} <> 'warmup')`
+  ),
+  messageRequestKeyEndpointActiveIdx: index('idx_message_request_key_endpoint_active').on(
+    table.key,
+    table.endpoint
+  ).where(
+    sql`${table.deletedAt} IS NULL AND ${table.endpoint} IS NOT NULL AND (${table.blockedBy} IS NULL OR ${table.blockedBy} <> 'warmup')`
+  ),
+  // #779:全局 usage logs keyset 分页热路径(按 created_at + id 倒序)
+  messageRequestCreatedAtIdActiveIdx: index('idx_message_request_created_at_id_active').on(
+    table.createdAt.desc(),
+    table.id.desc()
+  ).where(sql`${table.deletedAt} IS NULL`),
+  // #779:筛选器 DISTINCT model / status_code 加速(admin usage logs)
+  messageRequestModelActiveIdx: index('idx_message_request_model_active').on(table.model).where(sql`${table.deletedAt} IS NULL AND ${table.model} IS NOT NULL`),
+  messageRequestStatusCodeActiveIdx: index('idx_message_request_status_code_active').on(table.statusCode).where(sql`${table.deletedAt} IS NULL AND ${table.statusCode} IS NOT NULL`),
   messageRequestCreatedAtIdx: index('idx_message_request_created_at').on(table.createdAt),
   messageRequestDeletedAtIdx: index('idx_message_request_deleted_at').on(table.deletedAt),
 }));

+ 56 - 30
src/instrumentation.ts

@@ -252,7 +252,9 @@ export async function register() {
 
     // 生产环境: 执行完整初始化(迁移 + 价格表 + 清理任务 + 通知任务)
     if (process.env.NODE_ENV === "production") {
-      const { checkDatabaseConnection, runMigrations } = await import("@/lib/migrate");
+      const { checkDatabaseConnection, runMigrations, withAdvisoryLock } = await import(
+        "@/lib/migrate"
+      );
 
       logger.info("Initializing Claude Code Hub");
 
@@ -264,42 +266,66 @@ export async function register() {
       }
 
       // 执行迁移(可通过 AUTO_MIGRATE=false 跳过)
-      if (process.env.AUTO_MIGRATE !== "false") {
+      const autoMigrateRaw = process.env.AUTO_MIGRATE?.trim().toLowerCase();
+      const autoMigrateDisabled =
+        autoMigrateRaw === "false" ||
+        autoMigrateRaw === "0" ||
+        autoMigrateRaw === "no" ||
+        autoMigrateRaw === "off";
+
+      if (!autoMigrateDisabled) {
         await runMigrations();
       } else {
-        logger.info("[Instrumentation] AUTO_MIGRATE=false: skipping migrations");
+        logger.info("[Instrumentation] AUTO_MIGRATE disabled: skipping migrations", {
+          value: process.env.AUTO_MIGRATE,
+        });
       }
 
       warmupApiKeyVacuumFilter();
 
-      // 回填 provider_vendors(按域名自动聚合旧 providers)
-      try {
-        const { backfillProviderVendorsFromProviders } = await import(
-          "@/repository/provider-endpoints"
-        );
-        const vendorResult = await backfillProviderVendorsFromProviders();
-        logger.info("[Instrumentation] Provider vendors backfill completed", {
-          processed: vendorResult.processed,
-          providersUpdated: vendorResult.providersUpdated,
-          vendorsCreatedCount: vendorResult.vendorsCreated.size,
-          skippedInvalidUrl: vendorResult.skippedInvalidUrl,
-        });
-      } catch (error) {
-        logger.warn("[Instrumentation] Failed to backfill provider vendors", {
-          error: error instanceof Error ? error.message : String(error),
-        });
-      }
+      // 回填 provider_vendors/provider_endpoints(幂等)
+      // 多实例启动时仅允许一个实例执行,避免重复扫描/写入导致的启动抖动(#779/#781)。
+      const backfillLockName = "claude-code-hub:backfill:providers";
+      const backfill = await withAdvisoryLock(
+        backfillLockName,
+        async () => {
+          // 回填 provider_vendors(按域名自动聚合旧 providers)
+          try {
+            const { backfillProviderVendorsFromProviders } = await import(
+              "@/repository/provider-endpoints"
+            );
+            const vendorResult = await backfillProviderVendorsFromProviders();
+            logger.info("[Instrumentation] Provider vendors backfill completed", {
+              processed: vendorResult.processed,
+              providersUpdated: vendorResult.providersUpdated,
+              vendorsCreatedCount: vendorResult.vendorsCreated.size,
+              skippedInvalidUrl: vendorResult.skippedInvalidUrl,
+            });
+          } catch (error) {
+            logger.warn("[Instrumentation] Failed to backfill provider vendors", {
+              error: error instanceof Error ? error.message : String(error),
+            });
+          }
 
-      // 回填 provider_endpoints(从 providers.url/类型 生成端点池,幂等)
-      try {
-        const { backfillProviderEndpointsFromProviders } = await import(
-          "@/repository/provider-endpoints"
-        );
-        const result = await backfillProviderEndpointsFromProviders();
-        logger.info("[Instrumentation] Provider endpoints backfill completed", result);
-      } catch (error) {
-        logger.warn("[Instrumentation] Failed to backfill provider endpoints", {
-          error: error instanceof Error ? error.message : String(error),
+          // 回填 provider_endpoints(从 providers.url/类型 生成端点池,幂等)
+          try {
+            const { backfillProviderEndpointsFromProviders } = await import(
+              "@/repository/provider-endpoints"
+            );
+            const result = await backfillProviderEndpointsFromProviders();
+            logger.info("[Instrumentation] Provider endpoints backfill completed", result);
+          } catch (error) {
+            logger.warn("[Instrumentation] Failed to backfill provider endpoints", {
+              error: error instanceof Error ? error.message : String(error),
+            });
+          }
+        },
+        { skipIfLocked: true }
+      );
+
+      if (!backfill.ran) {
+        logger.info("[Instrumentation] Provider backfill skipped (lock not acquired)", {
+          lockName: backfillLockName,
         });
       }
 

+ 222 - 14
src/lib/endpoint-circuit-breaker.ts

@@ -6,6 +6,7 @@ import {
   type EndpointCircuitBreakerState,
   type EndpointCircuitState,
   loadEndpointCircuitState,
+  loadEndpointCircuitStates,
   saveEndpointCircuitState,
 } from "@/lib/redis/endpoint-circuit-breaker-state";
 
@@ -30,7 +31,51 @@ export interface EndpointHealth {
 }
 
 const healthMap = new Map<number, EndpointHealth>();
-const loadedFromRedis = new Set<number>();
+const loadedFromRedisAt = new Map<number, number>();
+const redisSyncInFlight = new Map<number, Promise<void>>();
+const REDIS_SYNC_TTL_MS = 1_000;
+
+function readPositiveIntEnv(name: string, fallback: number): number {
+  const raw = process.env[name];
+  if (!raw) return fallback;
+
+  const parsed = Number.parseInt(raw, 10);
+  if (!Number.isFinite(parsed) || parsed <= 0) {
+    return fallback;
+  }
+
+  return parsed;
+}
+
+const ENDPOINT_HEALTH_CACHE_MAX_SIZE = readPositiveIntEnv(
+  "ENDPOINT_CIRCUIT_HEALTH_CACHE_MAX_SIZE",
+  10_000
+);
+
+function bumpLRU<K, V>(map: Map<K, V>, key: K): void {
+  if (!map.has(key)) return;
+  const value = map.get(key) as V;
+  map.delete(key);
+  map.set(key, value);
+}
+
+function enforceEndpointHealthCacheMaxSize(): void {
+  if (ENDPOINT_HEALTH_CACHE_MAX_SIZE <= 0) return;
+
+  while (healthMap.size > ENDPOINT_HEALTH_CACHE_MAX_SIZE) {
+    const oldest = healthMap.keys().next().value as number | undefined;
+    if (oldest === undefined) break;
+    healthMap.delete(oldest);
+    loadedFromRedisAt.delete(oldest);
+  }
+
+  while (loadedFromRedisAt.size > ENDPOINT_HEALTH_CACHE_MAX_SIZE) {
+    const oldest = loadedFromRedisAt.keys().next().value as number | undefined;
+    if (oldest === undefined) break;
+    loadedFromRedisAt.delete(oldest);
+    healthMap.delete(oldest);
+  }
+}
 
 function getOrCreateHealthSync(endpointId: number): EndpointHealth {
   let health = healthMap.get(endpointId);
@@ -44,30 +89,50 @@ function getOrCreateHealthSync(endpointId: number): EndpointHealth {
     };
     healthMap.set(endpointId, health);
   }
+
+  bumpLRU(healthMap, endpointId);
+  bumpLRU(loadedFromRedisAt, endpointId);
+
   return health;
 }
 
 async function getOrCreateHealth(endpointId: number): Promise<EndpointHealth> {
+  const inFlight = redisSyncInFlight.get(endpointId);
+  if (inFlight) {
+    await inFlight;
+  }
+
   let health = healthMap.get(endpointId);
+  const loadedAt = loadedFromRedisAt.get(endpointId);
+  const now = Date.now();
   const needsRedisCheck =
-    (!health && !loadedFromRedis.has(endpointId)) || (health && health.circuitState !== "closed");
+    loadedAt === undefined || (loadedAt !== undefined && now - loadedAt > REDIS_SYNC_TTL_MS);
 
   if (needsRedisCheck) {
-    loadedFromRedis.add(endpointId);
+    loadedFromRedisAt.set(endpointId, now);
 
     try {
       const redisState = await loadEndpointCircuitState(endpointId);
       if (redisState) {
-        if (!health || redisState.circuitState !== health.circuitState) {
-          health = {
-            failureCount: redisState.failureCount,
-            lastFailureTime: redisState.lastFailureTime,
-            circuitState: redisState.circuitState,
-            circuitOpenUntil: redisState.circuitOpenUntil,
-            halfOpenSuccessCount: redisState.halfOpenSuccessCount,
-          };
-          healthMap.set(endpointId, health);
+        // 从 Redis 同步到内存时,不能只在 circuitState 变化时才更新:
+        // failureCount / halfOpenSuccessCount 等字段也可能在其它实例中发生变化。
+        if (health) {
+          health.failureCount = redisState.failureCount;
+          health.lastFailureTime = redisState.lastFailureTime;
+          health.circuitState = redisState.circuitState;
+          health.circuitOpenUntil = redisState.circuitOpenUntil;
+          health.halfOpenSuccessCount = redisState.halfOpenSuccessCount;
+          return health;
         }
+
+        health = {
+          failureCount: redisState.failureCount,
+          lastFailureTime: redisState.lastFailureTime,
+          circuitState: redisState.circuitState,
+          circuitOpenUntil: redisState.circuitOpenUntil,
+          halfOpenSuccessCount: redisState.halfOpenSuccessCount,
+        };
+        healthMap.set(endpointId, health);
         return health;
       }
 
@@ -86,7 +151,9 @@ async function getOrCreateHealth(endpointId: number): Promise<EndpointHealth> {
     }
   }
 
-  return getOrCreateHealthSync(endpointId);
+  const result = getOrCreateHealthSync(endpointId);
+  enforceEndpointHealthCacheMaxSize();
+  return result;
 }
 
 function persistStateToRedis(endpointId: number, health: EndpointHealth): void {
@@ -98,6 +165,23 @@ function persistStateToRedis(endpointId: number, health: EndpointHealth): void {
     halfOpenSuccessCount: health.halfOpenSuccessCount,
   };
 
+  const isDefaultClosedState =
+    state.circuitState === "closed" &&
+    state.failureCount <= 0 &&
+    state.halfOpenSuccessCount <= 0 &&
+    state.lastFailureTime == null &&
+    state.circuitOpenUntil == null;
+
+  if (isDefaultClosedState) {
+    deleteEndpointCircuitState(endpointId).catch((error) => {
+      logger.warn("[EndpointCircuitBreaker] Failed to delete default state from Redis", {
+        endpointId,
+        error: error instanceof Error ? error.message : String(error),
+      });
+    });
+    return;
+  }
+
   saveEndpointCircuitState(endpointId, state).catch((error) => {
     logger.warn("[EndpointCircuitBreaker] Failed to persist state to Redis", {
       endpointId,
@@ -113,6 +197,129 @@ export async function getEndpointHealthInfo(
   return { health, config: DEFAULT_ENDPOINT_CIRCUIT_BREAKER_CONFIG };
 }
 
+async function syncHealthFromRedisBatch(endpointIds: readonly number[], refreshNow: number) {
+  const uniqueEndpointIds = Array.from(new Set(endpointIds));
+  const toLoad: number[] = [];
+  const waitPromises: Promise<void>[] = [];
+
+  for (const endpointId of uniqueEndpointIds) {
+    const inFlight = redisSyncInFlight.get(endpointId);
+    if (inFlight) {
+      waitPromises.push(inFlight);
+      continue;
+    }
+
+    toLoad.push(endpointId);
+  }
+
+  if (toLoad.length > 0) {
+    const promise = (async () => {
+      try {
+        const redisStates = await loadEndpointCircuitStates(toLoad);
+
+        for (const endpointId of toLoad) {
+          const redisState = redisStates.get(endpointId) ?? null;
+          loadedFromRedisAt.set(endpointId, refreshNow);
+
+          const health = getOrCreateHealthSync(endpointId);
+          if (redisState) {
+            // 从 Redis 同步到内存时,不能只在 circuitState 变化时才更新:
+            // failureCount / halfOpenSuccessCount 等字段在 forceRefresh 下也应保持一致。
+            health.failureCount = redisState.failureCount;
+            health.lastFailureTime = redisState.lastFailureTime;
+            health.circuitState = redisState.circuitState;
+            health.circuitOpenUntil = redisState.circuitOpenUntil;
+            health.halfOpenSuccessCount = redisState.halfOpenSuccessCount;
+            continue;
+          }
+
+          if (health.circuitState !== "closed") {
+            health.circuitState = "closed";
+            health.failureCount = 0;
+            health.lastFailureTime = null;
+            health.circuitOpenUntil = null;
+            health.halfOpenSuccessCount = 0;
+          }
+        }
+      } catch (error) {
+        logger.warn("[EndpointCircuitBreaker] Failed to batch sync state from Redis", {
+          count: toLoad.length,
+          error: error instanceof Error ? error.message : String(error),
+        });
+      }
+    })().finally(() => {
+      for (const endpointId of toLoad) {
+        if (redisSyncInFlight.get(endpointId) === promise) {
+          redisSyncInFlight.delete(endpointId);
+        }
+      }
+    });
+
+    for (const endpointId of toLoad) {
+      redisSyncInFlight.set(endpointId, promise);
+    }
+
+    waitPromises.push(promise);
+  }
+
+  if (waitPromises.length > 0) {
+    await Promise.all(waitPromises);
+  }
+}
+
+export async function getAllEndpointHealthStatusAsync(
+  endpointIds: number[],
+  options?: { forceRefresh?: boolean }
+): Promise<Record<number, EndpointHealth>> {
+  const { forceRefresh = false } = options || {};
+
+  if (endpointIds.length === 0) {
+    return {};
+  }
+
+  const uniqueEndpointIds = Array.from(new Set(endpointIds));
+
+  if (forceRefresh) {
+    for (const endpointId of uniqueEndpointIds) {
+      loadedFromRedisAt.delete(endpointId);
+    }
+  }
+
+  const refreshNow = Date.now();
+  const needsRefresh = uniqueEndpointIds.filter((endpointId) => {
+    const memoryState = healthMap.get(endpointId);
+    if (!memoryState) return true;
+
+    const loadedAt = loadedFromRedisAt.get(endpointId);
+    if (loadedAt === undefined) return true;
+    return refreshNow - loadedAt > REDIS_SYNC_TTL_MS;
+  });
+
+  if (needsRefresh.length > 0) {
+    await syncHealthFromRedisBatch(needsRefresh, refreshNow);
+  }
+
+  const now = Date.now();
+  const status: Record<number, EndpointHealth> = {};
+
+  for (const endpointId of uniqueEndpointIds) {
+    const health = getOrCreateHealthSync(endpointId);
+
+    if (health.circuitState === "open") {
+      if (health.circuitOpenUntil && now > health.circuitOpenUntil) {
+        health.circuitState = "half-open";
+        health.halfOpenSuccessCount = 0;
+        persistStateToRedis(endpointId, health);
+      }
+    }
+
+    status[endpointId] = { ...health };
+  }
+
+  enforceEndpointHealthCacheMaxSize();
+  return status;
+}
+
 export async function isEndpointCircuitOpen(endpointId: number): Promise<boolean> {
   const { getEnvConfig } = await import("@/lib/config/env.schema");
   if (!getEnvConfig().ENABLE_ENDPOINT_CIRCUIT_BREAKER) {
@@ -232,6 +439,7 @@ export async function resetEndpointCircuit(endpointId: number): Promise<void> {
   health.halfOpenSuccessCount = 0;
 
   await deleteEndpointCircuitState(endpointId);
+  enforceEndpointHealthCacheMaxSize();
 }
 
 /**
@@ -315,7 +523,7 @@ export async function initEndpointCircuitBreaker(): Promise<void> {
   }
 
   healthMap.clear();
-  loadedFromRedis.clear();
+  loadedFromRedisAt.clear();
 
   try {
     const { getRedisClient } = await import("@/lib/redis/client");

+ 238 - 0
src/lib/hooks/use-in-view-once.ts

@@ -0,0 +1,238 @@
+import { useCallback, useEffect, useMemo, useState } from "react";
+
+type StableIntersectionObserverInit = IntersectionObserverInit & {
+  delay?: number;
+  trackVisibility?: boolean;
+};
+
+type ObserverTargetCallback = (entry: IntersectionObserverEntry) => void;
+type ObserverRootKey = Element | Document;
+
+const sharedObserversForNullRoot = new Map<string, SharedIntersectionObserver>();
+const sharedObserversByRoot = new WeakMap<
+  ObserverRootKey,
+  Map<string, SharedIntersectionObserver>
+>();
+
+function getObserverOptionsKey(options: StableIntersectionObserverInit): string {
+  const rootMargin = options.rootMargin ?? "0px";
+  const threshold = options.threshold;
+  const thresholdKey =
+    threshold === undefined
+      ? "0"
+      : Array.isArray(threshold)
+        ? threshold.join(",")
+        : String(threshold);
+  const trackVisibilityKey =
+    options.trackVisibility === undefined ? "" : options.trackVisibility ? "1" : "0";
+  const delayKey = options.delay === undefined ? "" : String(options.delay);
+  return `${rootMargin}|${thresholdKey}|${trackVisibilityKey}|${delayKey}`;
+}
+
+function releaseSharedObserver(
+  root: ObserverRootKey | null,
+  optionsKey: string,
+  observer: SharedIntersectionObserver
+): void {
+  if (root === null) {
+    if (sharedObserversForNullRoot.get(optionsKey) === observer) {
+      sharedObserversForNullRoot.delete(optionsKey);
+    }
+    return;
+  }
+
+  const pool = sharedObserversByRoot.get(root);
+  if (!pool) return;
+  if (pool.get(optionsKey) !== observer) return;
+
+  pool.delete(optionsKey);
+  if (pool.size === 0) {
+    sharedObserversByRoot.delete(root);
+  }
+}
+
+function getSharedObserver(options: StableIntersectionObserverInit): SharedIntersectionObserver {
+  const root = options.root ?? null;
+  const optionsKey = getObserverOptionsKey(options);
+
+  if (root === null) {
+    const existing = sharedObserversForNullRoot.get(optionsKey);
+    if (existing) return existing;
+
+    const observer = new SharedIntersectionObserver(root, optionsKey, options);
+    sharedObserversForNullRoot.set(optionsKey, observer);
+    return observer;
+  }
+
+  const rootKey = root as ObserverRootKey;
+  const pool = sharedObserversByRoot.get(rootKey) ?? new Map<string, SharedIntersectionObserver>();
+  if (!sharedObserversByRoot.has(rootKey)) {
+    sharedObserversByRoot.set(rootKey, pool);
+  }
+
+  const existing = pool.get(optionsKey);
+  if (existing) return existing;
+
+  const observer = new SharedIntersectionObserver(rootKey, optionsKey, options);
+  pool.set(optionsKey, observer);
+  return observer;
+}
+
+class SharedIntersectionObserver {
+  private readonly callbacksByTarget = new Map<Element, Set<ObserverTargetCallback>>();
+  private readonly observer: IntersectionObserver;
+  private disposed = false;
+
+  constructor(
+    private readonly root: ObserverRootKey | null,
+    private readonly optionsKey: string,
+    options: StableIntersectionObserverInit
+  ) {
+    this.observer = new IntersectionObserver((entries) => {
+      for (const entry of entries) {
+        const callbacks = this.callbacksByTarget.get(entry.target);
+        if (!callbacks) continue;
+
+        for (const callback of Array.from(callbacks)) {
+          callback(entry);
+        }
+      }
+    }, options);
+  }
+
+  observe(target: Element, callback: ObserverTargetCallback): () => void {
+    if (this.disposed) {
+      return () => {};
+    }
+
+    const callbacks = this.callbacksByTarget.get(target);
+    if (!callbacks) {
+      const next = new Set<ObserverTargetCallback>();
+      next.add(callback);
+      this.callbacksByTarget.set(target, next);
+      this.observer.observe(target);
+    } else {
+      callbacks.add(callback);
+    }
+
+    return () => {
+      this.unobserve(target, callback);
+    };
+  }
+
+  private unobserve(target: Element, callback: ObserverTargetCallback) {
+    const callbacks = this.callbacksByTarget.get(target);
+    if (!callbacks) return;
+
+    callbacks.delete(callback);
+    if (callbacks.size > 0) return;
+
+    this.callbacksByTarget.delete(target);
+
+    try {
+      this.observer.unobserve(target);
+    } catch {
+      // Ignore: target might already be gone/unobserved
+    }
+
+    if (this.callbacksByTarget.size === 0) {
+      this.dispose();
+    }
+  }
+
+  private dispose() {
+    if (this.disposed) return;
+    this.disposed = true;
+    this.observer.disconnect();
+    releaseSharedObserver(this.root, this.optionsKey, this);
+  }
+}
+
+function useStableIntersectionObserverOptions(options?: IntersectionObserverInit) {
+  const stableOptions = options as StableIntersectionObserverInit | undefined;
+
+  // 关键点:保持 `{ rootMargin: "200px", ...options }` 的语义不变;
+  // 并避免在渲染期间读写 ref,减少严格模式下的潜在隐患。
+  const root = stableOptions?.root ?? null;
+  const rootMargin = stableOptions?.rootMargin ?? "200px";
+  const threshold = stableOptions?.threshold;
+  const thresholdKey =
+    threshold === undefined
+      ? "0"
+      : Array.isArray(threshold)
+        ? threshold.join(",")
+        : String(threshold);
+  const stableThreshold = useMemo<StableIntersectionObserverInit["threshold"]>(() => {
+    if (!thresholdKey) return 0;
+
+    if (thresholdKey.includes(",")) {
+      const values = thresholdKey
+        .split(",")
+        .map((value) => Number.parseFloat(value))
+        .filter((value) => Number.isFinite(value));
+
+      return values.length > 0 ? values : 0;
+    }
+
+    const value = Number.parseFloat(thresholdKey);
+    return Number.isFinite(value) ? value : 0;
+  }, [thresholdKey]);
+  const trackVisibility = stableOptions?.trackVisibility;
+  const delay = stableOptions?.delay;
+
+  return useMemo<StableIntersectionObserverInit>(() => {
+    const init: StableIntersectionObserverInit = { root, rootMargin, threshold: stableThreshold };
+    if (trackVisibility !== undefined) init.trackVisibility = trackVisibility;
+    if (delay !== undefined) init.delay = delay;
+    return init;
+  }, [delay, root, rootMargin, stableThreshold, trackVisibility]);
+}
+
+/**
+ * 仅在元素首次进入视窗(含 rootMargin 预取)后变为 true 的 Hook。
+ *
+ * - 用于将“按行/按卡片”的请求从挂载时触发,延迟到可视区域附近触发,避免首屏请求风暴。
+ * - 在 test 环境或缺少 IntersectionObserver 时会直接视为可见,保证可预测性。
+ */
+export function useInViewOnce<T extends Element>(options?: IntersectionObserverInit) {
+  const [element, setElement] = useState<T | null>(null);
+  const [isInView, setIsInView] = useState(false);
+  const stableOptions = useStableIntersectionObserverOptions(options);
+
+  const ref = useCallback((node: T | null) => {
+    setElement(node);
+  }, []);
+
+  useEffect(() => {
+    if (isInView) return;
+
+    if (process.env.NODE_ENV === "test" || typeof IntersectionObserver === "undefined") {
+      setIsInView(true);
+      return;
+    }
+
+    if (!element) return;
+
+    let disposed = false;
+    const sharedObserver = getSharedObserver(stableOptions);
+    let unsubscribe: (() => void) | null = null;
+
+    const onEntry = (entry: IntersectionObserverEntry) => {
+      if (disposed) return;
+      if (!entry.isIntersecting) return;
+
+      setIsInView(true);
+      unsubscribe?.();
+      unsubscribe = null;
+    };
+
+    unsubscribe = sharedObserver.observe(element, onEntry);
+    return () => {
+      disposed = true;
+      unsubscribe?.();
+      unsubscribe = null;
+    };
+  }, [element, isInView, stableOptions]);
+
+  return { ref, isInView };
+}

+ 147 - 7
src/lib/migrate.ts

@@ -1,38 +1,178 @@
-"use server";
+import "server-only";
 
 import path from "node:path";
+import { readMigrationFiles } from "drizzle-orm/migrator";
 import { drizzle } from "drizzle-orm/postgres-js";
 import { migrate } from "drizzle-orm/postgres-js/migrator";
 import postgres from "postgres";
 import { logger } from "@/lib/logger";
 
+const MIGRATION_ADVISORY_LOCK_NAME = "claude-code-hub:migrations";
+
+export async function withAdvisoryLock<T>(
+  lockName: string,
+  fn: () => Promise<T>,
+  options?: { skipIfLocked?: boolean }
+): Promise<{ ran: boolean; result?: T }> {
+  if (!process.env.DSN) {
+    logger.error("DSN environment variable is not set");
+    process.exit(1);
+  }
+
+  const client = postgres(process.env.DSN, { max: 1 });
+  let acquired = false;
+
+  try {
+    if (options?.skipIfLocked) {
+      const [row] = await client`SELECT pg_try_advisory_lock(hashtext(${lockName})) as locked`;
+      acquired = row?.locked === true;
+      if (!acquired) {
+        return { ran: false };
+      }
+    } else {
+      await client`SELECT pg_advisory_lock(hashtext(${lockName}))`;
+      acquired = true;
+    }
+
+    const result = await fn();
+    return { ran: true, result };
+  } finally {
+    if (acquired) {
+      try {
+        await client`SELECT pg_advisory_unlock(hashtext(${lockName}))`;
+      } catch (unlockError) {
+        logger.error("Failed to release advisory lock", {
+          lockName,
+          error: unlockError instanceof Error ? unlockError.message : String(unlockError),
+        });
+      }
+    }
+
+    await client.end();
+  }
+}
+
+async function ensureDrizzleMigrationsTableExists(
+  client: ReturnType<typeof postgres>
+): Promise<void> {
+  await client`CREATE SCHEMA IF NOT EXISTS "drizzle"`;
+  await client`
+    CREATE TABLE IF NOT EXISTS "drizzle"."__drizzle_migrations" (
+      id SERIAL PRIMARY KEY,
+      hash text NOT NULL,
+      created_at numeric
+    )
+  `;
+}
+
+async function repairDrizzleMigrationsCreatedAt(input: {
+  client: ReturnType<typeof postgres>;
+  migrationsFolder: string;
+}): Promise<void> {
+  const { client, migrationsFolder } = input;
+
+  // drizzle-orm migrator 仅比较 `created_at(folderMillis)` 来决定是否执行迁移。
+  // 若历史 journal 的 `when` 被修正(或曾出现非单调),旧实例可能会因为 `created_at` 偏大而永久跳过后续迁移。
+  // 这里用 hash 对齐并修复 created_at,让升级对用户无感(Docker 拉新镜像重启即可)。
+  const migrations = readMigrationFiles({ migrationsFolder });
+
+  const expectedCreatedAtByHash = new Map<string, number>();
+  for (const migration of migrations) {
+    expectedCreatedAtByHash.set(migration.hash, migration.folderMillis);
+  }
+
+  const rows = (await client`
+    SELECT id, hash, created_at
+    FROM "drizzle"."__drizzle_migrations"
+  `) as Array<{
+    id: number;
+    hash: string;
+    created_at: string | number | null;
+  }>;
+
+  const pendingFixes: Array<{ id: number; hash: string; from: number | null; to: number }> = [];
+
+  for (const row of rows) {
+    const expected = expectedCreatedAtByHash.get(row.hash);
+    if (expected == null) {
+      continue;
+    }
+
+    const currentRaw = row.created_at;
+    const current =
+      typeof currentRaw === "number"
+        ? currentRaw
+        : typeof currentRaw === "string"
+          ? Number(currentRaw)
+          : null;
+
+    if (current == null || !Number.isFinite(current) || current !== expected) {
+      pendingFixes.push({
+        id: row.id,
+        hash: row.hash,
+        from: current,
+        to: expected,
+      });
+    }
+  }
+
+  if (pendingFixes.length === 0) {
+    return;
+  }
+
+  for (const fix of pendingFixes) {
+    await client`
+      UPDATE "drizzle"."__drizzle_migrations"
+      SET created_at = ${fix.to}
+      WHERE id = ${fix.id}
+    `;
+  }
+
+  logger.info("Repaired drizzle.__drizzle_migrations created_at", {
+    repaired: pendingFixes.length,
+  });
+}
+
 /**
  * 自动执行数据库迁移
  * 在生产环境启动时自动运行
  */
 export async function runMigrations() {
   if (!process.env.DSN) {
-    logger.error("❌ DSN environment variable is not set");
+    logger.error("DSN environment variable is not set");
     process.exit(1);
   }
 
-  logger.info("🔄 Starting database migrations...");
+  logger.info("Starting database migrations...");
 
   const migrationClient = postgres(process.env.DSN, { max: 1 });
   const db = drizzle(migrationClient);
 
   try {
+    logger.info("Waiting for database migration lock...");
+    await migrationClient`SELECT pg_advisory_lock(hashtext(${MIGRATION_ADVISORY_LOCK_NAME}))`;
+    logger.info("Database migration lock acquired");
+
     // 获取迁移文件路径
     const migrationsFolder = path.join(process.cwd(), "drizzle");
 
+    await ensureDrizzleMigrationsTableExists(migrationClient);
+    await repairDrizzleMigrationsCreatedAt({ client: migrationClient, migrationsFolder });
+
     // 执行迁移
     await migrate(db, { migrationsFolder });
 
-    logger.info("✅ Database migrations completed successfully!");
+    logger.info("Database migrations completed successfully");
   } catch (error) {
-    logger.error("❌ Migration failed:", error);
+    logger.error("Migration failed", error);
     process.exit(1);
   } finally {
+    try {
+      await migrationClient`SELECT pg_advisory_unlock(hashtext(${MIGRATION_ADVISORY_LOCK_NAME}))`;
+    } catch (unlockError) {
+      logger.error("Failed to release database migration lock", unlockError);
+    }
+
     // 关闭连接
     await migrationClient.end();
   }
@@ -43,7 +183,7 @@ export async function runMigrations() {
  */
 export async function checkDatabaseConnection(retries = 30, delay = 2000): Promise<boolean> {
   if (!process.env.DSN) {
-    logger.error("DSN environment variable is not set");
+    logger.error("DSN environment variable is not set");
     return false;
   }
 
@@ -55,7 +195,7 @@ export async function checkDatabaseConnection(retries = 30, delay = 2000): Promi
       logger.info("Database connection established");
       return true;
     } catch (error) {
-      logger.error("⏳ Waiting for database... (${i + 1}/${retries})", error);
+      logger.error(`Waiting for database... (${i + 1}/${retries})`, error);
       if (i < retries - 1) {
         await new Promise((resolve) => setTimeout(resolve, delay));
       }

+ 44 - 31
src/lib/provider-endpoints/endpoint-selector.ts

@@ -1,19 +1,23 @@
 import "server-only";
 
-import { isEndpointCircuitOpen } from "@/lib/endpoint-circuit-breaker";
-import { findProviderEndpointsByVendorAndType } from "@/repository";
+import { getEnvConfig } from "@/lib/config/env.schema";
+import { getAllEndpointHealthStatusAsync } from "@/lib/endpoint-circuit-breaker";
+import {
+  findEnabledProviderEndpointsByVendorAndType,
+  findProviderEndpointsByVendorAndType,
+} from "@/repository";
 import type { ProviderEndpoint, ProviderType } from "@/types/provider";
 
-export function rankProviderEndpoints(endpoints: ProviderEndpoint[]): ProviderEndpoint[] {
-  const enabled = endpoints.filter((e) => e.isEnabled && !e.deletedAt);
+function priorityRank(endpoint: ProviderEndpoint): number {
+  if (endpoint.lastProbeOk === true) return 0;
+  if (endpoint.lastProbeOk === null) return 1;
+  return 2;
+}
 
-  const priorityRank = (endpoint: ProviderEndpoint): number => {
-    if (endpoint.lastProbeOk === true) return 0;
-    if (endpoint.lastProbeOk === null) return 1;
-    return 2;
-  };
+function rankActiveProviderEndpoints(endpoints: ProviderEndpoint[]): ProviderEndpoint[] {
+  if (endpoints.length <= 1) return endpoints;
 
-  return enabled.slice().sort((a, b) => {
+  endpoints.sort((a, b) => {
     const rankDiff = priorityRank(a) - priorityRank(b);
     if (rankDiff !== 0) return rankDiff;
 
@@ -25,6 +29,13 @@ export function rankProviderEndpoints(endpoints: ProviderEndpoint[]): ProviderEn
 
     return a.id - b.id;
   });
+
+  return endpoints;
+}
+
+export function rankProviderEndpoints(endpoints: ProviderEndpoint[]): ProviderEndpoint[] {
+  const enabled = endpoints.filter((e) => e.isEnabled && !e.deletedAt);
+  return rankActiveProviderEndpoints(enabled);
 }
 
 export async function getPreferredProviderEndpoints(input: {
@@ -32,30 +43,30 @@ export async function getPreferredProviderEndpoints(input: {
   providerType: ProviderType;
   excludeEndpointIds?: number[];
 }): Promise<ProviderEndpoint[]> {
-  const excludeSet = new Set(input.excludeEndpointIds ?? []);
+  const excludeIds = input.excludeEndpointIds ?? [];
+  const excludeSet = excludeIds.length > 0 ? new Set(excludeIds) : null;
 
-  const endpoints = await findProviderEndpointsByVendorAndType(input.vendorId, input.providerType);
-  const filtered = endpoints.filter((e) => e.isEnabled && !e.deletedAt && !excludeSet.has(e.id));
+  const endpoints = await findEnabledProviderEndpointsByVendorAndType(
+    input.vendorId,
+    input.providerType
+  );
+  // `findEnabledProviderEndpointsByVendorAndType` 已保证 isEnabled=true 且 deletedAt IS NULL
+  const circuitCandidates = excludeSet ? endpoints.filter((e) => !excludeSet.has(e.id)) : endpoints;
 
-  if (filtered.length === 0) {
+  if (circuitCandidates.length === 0) {
     return [];
   }
 
   // When endpoint circuit breaker is disabled, skip circuit check entirely
-  const { getEnvConfig } = await import("@/lib/config/env.schema");
   if (!getEnvConfig().ENABLE_ENDPOINT_CIRCUIT_BREAKER) {
-    return rankProviderEndpoints(filtered);
+    return rankProviderEndpoints(circuitCandidates);
   }
 
-  const circuitResults = await Promise.all(
-    filtered.map(async (endpoint) => ({
-      endpoint,
-      isOpen: await isEndpointCircuitOpen(endpoint.id),
-    }))
+  const healthStatus = await getAllEndpointHealthStatusAsync(circuitCandidates.map((e) => e.id));
+  const candidates = circuitCandidates.filter(
+    (endpoint) => healthStatus[endpoint.id]?.circuitState !== "open"
   );
 
-  const candidates = circuitResults.filter(({ isOpen }) => !isOpen).map(({ endpoint }) => endpoint);
-
   return rankProviderEndpoints(candidates);
 }
 
@@ -78,20 +89,22 @@ export async function getEndpointFilterStats(input: {
 }): Promise<EndpointFilterStats> {
   const endpoints = await findProviderEndpointsByVendorAndType(input.vendorId, input.providerType);
   const total = endpoints.length;
-  const enabled = endpoints.filter((e) => e.isEnabled && !e.deletedAt).length;
+  const enabledEndpoints = endpoints.filter((e) => e.isEnabled && !e.deletedAt);
+  const enabled = enabledEndpoints.length;
 
   // When endpoint circuit breaker is disabled, no endpoints can be circuit-open
-  const { getEnvConfig } = await import("@/lib/config/env.schema");
   if (!getEnvConfig().ENABLE_ENDPOINT_CIRCUIT_BREAKER) {
     return { total, enabled, circuitOpen: 0, available: enabled };
   }
 
-  const circuitResults = await Promise.all(
-    endpoints
-      .filter((e) => e.isEnabled && !e.deletedAt)
-      .map(async (e) => isEndpointCircuitOpen(e.id))
-  );
-  const circuitOpen = circuitResults.filter(Boolean).length;
+  if (enabledEndpoints.length === 0) {
+    return { total, enabled: 0, circuitOpen: 0, available: 0 };
+  }
+
+  const healthStatus = await getAllEndpointHealthStatusAsync(enabledEndpoints.map((e) => e.id));
+  const circuitOpen = enabledEndpoints.filter(
+    (e) => healthStatus[e.id]?.circuitState === "open"
+  ).length;
   const available = enabled - circuitOpen;
 
   return { total, enabled, circuitOpen, available };

+ 3 - 3
src/lib/provider-endpoints/leader-lock.ts

@@ -25,7 +25,7 @@ function cleanupExpiredMemoryLocks(now: number): void {
 
 export async function acquireLeaderLock(key: string, ttlMs: number): Promise<LeaderLock | null> {
   const lockId = generateLockId();
-  const redis = getRedisClient();
+  const redis = getRedisClient({ allowWhenRateLimitDisabled: true });
 
   if (redis && redis.status === "ready") {
     try {
@@ -60,7 +60,7 @@ export async function acquireLeaderLock(key: string, ttlMs: number): Promise<Lea
 }
 
 export async function renewLeaderLock(lock: LeaderLock, ttlMs: number): Promise<boolean> {
-  const redis = getRedisClient();
+  const redis = getRedisClient({ allowWhenRateLimitDisabled: true });
 
   if (lock.lockType === "memory") {
     // If Redis becomes available, force callers to re-acquire a distributed lock.
@@ -117,7 +117,7 @@ export async function releaseLeaderLock(lock: LeaderLock): Promise<void> {
     return;
   }
 
-  const redis = getRedisClient();
+  const redis = getRedisClient({ allowWhenRateLimitDisabled: true });
   if (!redis || redis.status !== "ready") {
     return;
   }

+ 61 - 0
src/lib/provider-endpoints/probe-log-cleanup.ts

@@ -3,6 +3,7 @@ import {
   acquireLeaderLock,
   type LeaderLock,
   releaseLeaderLock,
+  renewLeaderLock,
 } from "@/lib/provider-endpoints/leader-lock";
 import { deleteProviderEndpointProbeLogsBeforeDateBatch } from "@/repository";
 
@@ -31,6 +32,55 @@ const cleanupState = globalThis as unknown as {
   __CCH_ENDPOINT_PROBE_LOG_CLEANUP_RUNNING__?: boolean;
 };
 
+function startLeaderLockKeepAlive(onLost: () => void): () => void {
+  let stopped = false;
+  let renewing = false;
+  let intervalId: ReturnType<typeof setInterval> | undefined;
+
+  const stop = () => {
+    if (stopped) return;
+    stopped = true;
+    if (intervalId) clearInterval(intervalId);
+  };
+
+  const tick = async () => {
+    if (stopped || renewing) return;
+
+    const current = cleanupState.__CCH_ENDPOINT_PROBE_LOG_CLEANUP_LOCK__;
+    if (!current) {
+      stop();
+      onLost();
+      return;
+    }
+
+    renewing = true;
+    try {
+      const ok = await renewLeaderLock(current, LOCK_TTL_MS);
+      if (!ok) {
+        cleanupState.__CCH_ENDPOINT_PROBE_LOG_CLEANUP_LOCK__ = undefined;
+        stop();
+        onLost();
+        logger.warn("[EndpointProbeLogCleanup] Lost leader lock during cleanup", {
+          key: current.key,
+          lockType: current.lockType,
+        });
+      }
+    } finally {
+      renewing = false;
+    }
+  };
+
+  const intervalMs = Math.max(1000, Math.floor(LOCK_TTL_MS / 2));
+  intervalId = setInterval(() => {
+    void tick();
+  }, intervalMs);
+
+  const timer = intervalId as unknown as { unref?: () => void };
+  timer.unref?.();
+
+  return stop;
+}
+
 async function runCleanupOnce(): Promise<void> {
   if (cleanupState.__CCH_ENDPOINT_PROBE_LOG_CLEANUP_RUNNING__) {
     return;
@@ -39,6 +89,8 @@ async function runCleanupOnce(): Promise<void> {
   cleanupState.__CCH_ENDPOINT_PROBE_LOG_CLEANUP_RUNNING__ = true;
 
   let lock: LeaderLock | null = null;
+  let leadershipLost = false;
+  let stopKeepAlive: (() => void) | undefined;
 
   try {
     lock = await acquireLeaderLock(LOCK_KEY, LOCK_TTL_MS);
@@ -48,12 +100,20 @@ async function runCleanupOnce(): Promise<void> {
 
     cleanupState.__CCH_ENDPOINT_PROBE_LOG_CLEANUP_LOCK__ = lock;
 
+    stopKeepAlive = startLeaderLockKeepAlive(() => {
+      leadershipLost = true;
+    });
+
     const now = Date.now();
     const retentionMs = Math.max(0, RETENTION_DAYS) * 24 * 60 * 60 * 1000;
     const beforeDate = new Date(now - retentionMs);
 
     let totalDeleted = 0;
     while (true) {
+      if (leadershipLost) {
+        return;
+      }
+
       const deleted = await deleteProviderEndpointProbeLogsBeforeDateBatch({
         beforeDate,
         batchSize: CLEANUP_BATCH_SIZE,
@@ -81,6 +141,7 @@ async function runCleanupOnce(): Promise<void> {
       error: error instanceof Error ? error.message : String(error),
     });
   } finally {
+    stopKeepAlive?.();
     cleanupState.__CCH_ENDPOINT_PROBE_LOG_CLEANUP_RUNNING__ = false;
 
     if (lock) {

+ 93 - 9
src/lib/provider-endpoints/probe-scheduler.ts

@@ -29,6 +29,15 @@ const SINGLE_VENDOR_INTERVAL_MS = 600_000;
 const TIMEOUT_OVERRIDE_INTERVAL_MS = 10_000;
 // Scheduler tick interval - use shortest possible interval to support timeout override
 const TICK_INTERVAL_MS = Math.min(BASE_INTERVAL_MS, TIMEOUT_OVERRIDE_INTERVAL_MS);
+// Max idle DB polling interval (default 30s, bounded by base interval)
+const DEFAULT_IDLE_DB_POLL_INTERVAL_MS = Math.min(BASE_INTERVAL_MS, 30_000);
+const IDLE_DB_POLL_INTERVAL_MS = Math.max(
+  1,
+  parseIntWithDefault(
+    process.env.ENDPOINT_PROBE_IDLE_DB_POLL_INTERVAL_MS,
+    DEFAULT_IDLE_DB_POLL_INTERVAL_MS
+  )
+);
 const TIMEOUT_MS = Math.max(1, parseIntWithDefault(process.env.ENDPOINT_PROBE_TIMEOUT_MS, 5_000));
 const CONCURRENCY = Math.max(1, parseIntWithDefault(process.env.ENDPOINT_PROBE_CONCURRENCY, 10));
 const CYCLE_JITTER_MS = Math.max(
@@ -46,6 +55,8 @@ const schedulerState = globalThis as unknown as {
   __CCH_ENDPOINT_PROBE_SCHEDULER_RUNNING__?: boolean;
   __CCH_ENDPOINT_PROBE_SCHEDULER_LOCK__?: LeaderLock;
   __CCH_ENDPOINT_PROBE_SCHEDULER_STOP_REQUESTED__?: boolean;
+  __CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DUE_AT_MS__?: number;
+  __CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DB_POLL_AT_MS__?: number;
 };
 
 function sleep(ms: number): Promise<void> {
@@ -65,12 +76,13 @@ function shuffleInPlace<T>(arr: T[]): void {
 }
 
 /**
- * Count enabled endpoints per vendor
+ * Count enabled endpoints per vendor/type
  */
-function countEndpointsByVendor(endpoints: ProviderEndpointProbeTarget[]): Map<number, number> {
-  const counts = new Map<number, number>();
+function countEndpointsByVendorType(endpoints: ProviderEndpointProbeTarget[]): Map<string, number> {
+  const counts = new Map<string, number>();
   for (const ep of endpoints) {
-    counts.set(ep.vendorId, (counts.get(ep.vendorId) ?? 0) + 1);
+    const key = `${ep.vendorId}:${ep.providerType}`;
+    counts.set(key, (counts.get(key) ?? 0) + 1);
   }
   return counts;
 }
@@ -85,7 +97,7 @@ function countEndpointsByVendor(endpoints: ProviderEndpointProbeTarget[]): Map<n
  */
 function getEffectiveIntervalMs(
   endpoint: ProviderEndpointProbeTarget,
-  vendorEndpointCounts: Map<number, number>
+  vendorEndpointCounts: Map<string, number>
 ): number {
   // Timeout override takes highest priority
   const hasTimeoutError =
@@ -95,7 +107,8 @@ function getEffectiveIntervalMs(
   }
 
   // Single-vendor interval
-  const vendorCount = vendorEndpointCounts.get(endpoint.vendorId) ?? 0;
+  const vendorCount =
+    vendorEndpointCounts.get(`${endpoint.vendorId}:${endpoint.providerType}`) ?? 0;
   if (vendorCount === 1) {
     return SINGLE_VENDOR_INTERVAL_MS;
   }
@@ -109,7 +122,7 @@ function getEffectiveIntervalMs(
  */
 function filterDueEndpoints(
   endpoints: ProviderEndpointProbeTarget[],
-  vendorEndpointCounts: Map<number, number>,
+  vendorEndpointCounts: Map<string, number>,
   now: Date
 ): ProviderEndpointProbeTarget[] {
   const nowMs = now.getTime();
@@ -125,6 +138,38 @@ function filterDueEndpoints(
   });
 }
 
+function computeNextDueAtMs(
+  endpoints: ProviderEndpointProbeTarget[],
+  vendorEndpointCounts: Map<string, number>,
+  nowMs: number
+): number {
+  let nextDueAtMs = Number.POSITIVE_INFINITY;
+  for (const ep of endpoints) {
+    // Never probed - treat as immediately due (force refresh on next tick)
+    if (ep.lastProbedAt === null) {
+      return nowMs;
+    }
+
+    const effectiveInterval = getEffectiveIntervalMs(ep, vendorEndpointCounts);
+    const dueAtMs = ep.lastProbedAt.getTime() + effectiveInterval;
+    if (dueAtMs < nextDueAtMs) {
+      nextDueAtMs = dueAtMs;
+    }
+  }
+  return nextDueAtMs;
+}
+
+function clearNextWorkHints(): void {
+  schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DUE_AT_MS__ = undefined;
+  schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DB_POLL_AT_MS__ = undefined;
+}
+
+function updateNextWorkHints(input: { nextDueAtMs: number; nowMs: number }): void {
+  schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DUE_AT_MS__ = input.nextDueAtMs;
+  schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DB_POLL_AT_MS__ =
+    input.nowMs + IDLE_DB_POLL_INTERVAL_MS;
+}
+
 async function ensureLeaderLock(): Promise<boolean> {
   const current = schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_LOCK__;
   if (current) {
@@ -212,11 +257,23 @@ async function runProbeCycle(): Promise<void> {
   try {
     const isLeader = await ensureLeaderLock();
     if (!isLeader) {
+      clearNextWorkHints();
       return;
     }
 
+    const nowMsBeforeCycle = Date.now();
+    const nextDueAtMs = schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DUE_AT_MS__;
+    const nextDbPollAtMs = schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_NEXT_DB_POLL_AT_MS__;
+    if (typeof nextDueAtMs === "number" && typeof nextDbPollAtMs === "number") {
+      const nextWorkAtMs = Math.min(nextDueAtMs, nextDbPollAtMs);
+      if (nowMsBeforeCycle < nextWorkAtMs) {
+        return;
+      }
+    }
+
     stopKeepAlive = startLeaderLockKeepAlive(() => {
       leadershipLost = true;
+      clearNextWorkHints();
     });
 
     const jitter = CYCLE_JITTER_MS > 0 ? Math.floor(Math.random() * CYCLE_JITTER_MS) : 0;
@@ -228,16 +285,22 @@ async function runProbeCycle(): Promise<void> {
 
     const allEndpoints = await findEnabledProviderEndpointsForProbing();
     if (allEndpoints.length === 0) {
+      updateNextWorkHints({ nextDueAtMs: Number.POSITIVE_INFINITY, nowMs: Date.now() });
       return;
     }
 
     // Calculate vendor endpoint counts for interval decisions
-    const vendorEndpointCounts = countEndpointsByVendor(allEndpoints);
+    const vendorEndpointCounts = countEndpointsByVendorType(allEndpoints);
 
     // Filter to only endpoints that are due for probing
     const now = new Date();
     const endpoints = filterDueEndpoints(allEndpoints, vendorEndpointCounts, now);
     if (endpoints.length === 0) {
+      const nowMs = now.getTime();
+      updateNextWorkHints({
+        nextDueAtMs: computeNextDueAtMs(allEndpoints, vendorEndpointCounts, nowMs),
+        nowMs,
+      });
       return;
     }
 
@@ -267,11 +330,15 @@ async function runProbeCycle(): Promise<void> {
         }
 
         try {
-          await probeProviderEndpointAndRecordByEndpoint({
+          const result = await probeProviderEndpointAndRecordByEndpoint({
             endpoint,
             source: "scheduled",
             timeoutMs: TIMEOUT_MS,
           });
+
+          endpoint.lastProbedAt = new Date();
+          endpoint.lastProbeOk = result.ok;
+          endpoint.lastProbeErrorType = result.ok ? null : result.errorType;
         } catch (error) {
           logger.warn("[EndpointProbeScheduler] Probe failed", {
             endpointId: endpoint.id,
@@ -282,7 +349,19 @@ async function runProbeCycle(): Promise<void> {
     };
 
     await Promise.all(Array.from({ length: concurrency }, () => worker()));
+
+    if (leadershipLost || schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_STOP_REQUESTED__) {
+      clearNextWorkHints();
+      return;
+    }
+
+    const cycleNowMs = Date.now();
+    updateNextWorkHints({
+      nextDueAtMs: computeNextDueAtMs(allEndpoints, vendorEndpointCounts, cycleNowMs),
+      nowMs: cycleNowMs,
+    });
   } catch (error) {
+    clearNextWorkHints();
     logger.warn("[EndpointProbeScheduler] Probe cycle error", {
       error: error instanceof Error ? error.message : String(error),
     });
@@ -299,6 +378,7 @@ export function startEndpointProbeScheduler(): void {
 
   schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_STOP_REQUESTED__ = false;
   schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_STARTED__ = true;
+  clearNextWorkHints();
 
   void runProbeCycle();
 
@@ -311,6 +391,7 @@ export function startEndpointProbeScheduler(): void {
     singleVendorIntervalMs: SINGLE_VENDOR_INTERVAL_MS,
     timeoutOverrideIntervalMs: TIMEOUT_OVERRIDE_INTERVAL_MS,
     tickIntervalMs: TICK_INTERVAL_MS,
+    idleDbPollIntervalMs: IDLE_DB_POLL_INTERVAL_MS,
     timeoutMs: TIMEOUT_MS,
     concurrency: CONCURRENCY,
     jitterMs: CYCLE_JITTER_MS,
@@ -320,6 +401,7 @@ export function startEndpointProbeScheduler(): void {
 
 export function stopEndpointProbeScheduler(): void {
   schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_STOP_REQUESTED__ = true;
+  clearNextWorkHints();
 
   const intervalId = schedulerState.__CCH_ENDPOINT_PROBE_SCHEDULER_INTERVAL_ID__;
   if (intervalId) {
@@ -343,6 +425,7 @@ export function getEndpointProbeSchedulerStatus(): {
   singleVendorIntervalMs: number;
   timeoutOverrideIntervalMs: number;
   tickIntervalMs: number;
+  idleDbPollIntervalMs: number;
   timeoutMs: number;
   concurrency: number;
   jitterMs: number;
@@ -355,6 +438,7 @@ export function getEndpointProbeSchedulerStatus(): {
     singleVendorIntervalMs: SINGLE_VENDOR_INTERVAL_MS,
     timeoutOverrideIntervalMs: TIMEOUT_OVERRIDE_INTERVAL_MS,
     tickIntervalMs: TICK_INTERVAL_MS,
+    idleDbPollIntervalMs: IDLE_DB_POLL_INTERVAL_MS,
     timeoutMs: TIMEOUT_MS,
     concurrency: CONCURRENCY,
     jitterMs: CYCLE_JITTER_MS,

+ 19 - 8
src/lib/provider-endpoints/probe.ts

@@ -1,6 +1,7 @@
 import "server-only";
 
 import net from "node:net";
+import { getEnvConfig } from "@/lib/config/env.schema";
 import {
   getEndpointCircuitStateSync,
   recordEndpointFailure,
@@ -234,14 +235,24 @@ export async function probeProviderEndpointAndRecordByEndpoint(input: {
       : result.errorType || "probe_failed";
     await recordEndpointFailure(input.endpoint.id, new Error(message));
   } else {
-    // Probe success: reset circuit breaker if endpoint was open/half-open
-    const currentState = getEndpointCircuitStateSync(input.endpoint.id);
-    if (currentState !== "closed") {
-      await resetEndpointCircuit(input.endpoint.id);
-      logger.info("[EndpointProbe] Probe success, circuit reset", {
-        endpointId: input.endpoint.id,
-        previousState: currentState,
-      });
+    // Probe success: best-effort reset circuit breaker state (cross-instance safe).
+    // Note: do not rely on in-memory state only; Redis may contain open/half-open state from another instance.
+    if (getEnvConfig().ENABLE_ENDPOINT_CIRCUIT_BREAKER) {
+      const previousState = getEndpointCircuitStateSync(input.endpoint.id);
+      try {
+        await resetEndpointCircuit(input.endpoint.id);
+        if (previousState !== "closed") {
+          logger.info("[EndpointProbe] Probe success, circuit reset", {
+            endpointId: input.endpoint.id,
+            previousState,
+          });
+        }
+      } catch (error) {
+        logger.warn("[EndpointProbe] Probe success but failed to reset circuit", {
+          endpointId: input.endpoint.id,
+          error: error instanceof Error ? error.message : String(error),
+        });
+      }
     }
   }
 

+ 3 - 2
src/lib/redis/client.ts

@@ -73,7 +73,7 @@ export function buildRedisOptionsForUrl(redisUrl: string) {
   return { isTLS, options: { ...baseOptions, ...tlsOptions } };
 }
 
-export function getRedisClient(): Redis | null {
+export function getRedisClient(input?: { allowWhenRateLimitDisabled?: boolean }): Redis | null {
   // Skip Redis connection during CI/build phase (avoid connection attempts)
   if (process.env.CI === "true" || process.env.NEXT_PHASE === "phase-production-build") {
     return null;
@@ -82,8 +82,9 @@ export function getRedisClient(): Redis | null {
   const redisUrl = process.env.REDIS_URL;
   const rateLimitRaw = process.env.ENABLE_RATE_LIMIT?.trim();
   const isEnabled = rateLimitRaw !== "false" && rateLimitRaw !== "0";
+  const allowWhenRateLimitDisabled = input?.allowWhenRateLimitDisabled === true;
 
-  if (!isEnabled || !redisUrl) {
+  if ((!isEnabled && !allowWhenRateLimitDisabled) || !redisUrl) {
     logger.warn("[Redis] Rate limiting disabled or REDIS_URL not configured");
     return null;
   }

+ 92 - 2
src/lib/redis/endpoint-circuit-breaker-state.ts

@@ -47,6 +47,94 @@ function deserializeState(data: Record<string, string>): EndpointCircuitBreakerS
   };
 }
 
+export async function loadEndpointCircuitStates(
+  endpointIds: readonly number[]
+): Promise<Map<number, EndpointCircuitBreakerState | null>> {
+  const uniqueEndpointIds = Array.from(new Set(endpointIds));
+  const stateMap = new Map<number, EndpointCircuitBreakerState | null>();
+
+  for (const endpointId of uniqueEndpointIds) {
+    stateMap.set(endpointId, null);
+  }
+
+  const redis = getRedisClient();
+
+  if (!redis || uniqueEndpointIds.length === 0) {
+    if (!redis && uniqueEndpointIds.length > 0) {
+      logger.debug("[EndpointCircuitState] Redis not available, returning null", {
+        count: uniqueEndpointIds.length,
+      });
+    }
+    return stateMap;
+  }
+
+  const PIPELINE_BATCH_SIZE = 200;
+
+  try {
+    for (let i = 0; i < uniqueEndpointIds.length; i += PIPELINE_BATCH_SIZE) {
+      const batchIds = uniqueEndpointIds.slice(i, i + PIPELINE_BATCH_SIZE);
+      const pipeline = redis.pipeline();
+
+      for (const endpointId of batchIds) {
+        pipeline.hgetall(getStateKey(endpointId));
+      }
+
+      const results = await pipeline.exec();
+      if (!results) {
+        logger.warn("[EndpointCircuitState] Pipeline exec returned null", {
+          count: batchIds.length,
+        });
+        continue;
+      }
+
+      let errorCount = 0;
+      const errorSamples: Array<{ endpointId: number; error: string }> = [];
+
+      for (let index = 0; index < batchIds.length; index++) {
+        const endpointId = batchIds[index];
+        const [error, data] = results[index] ?? [];
+
+        if (error) {
+          errorCount += 1;
+          if (errorSamples.length < 3) {
+            errorSamples.push({
+              endpointId,
+              error: error instanceof Error ? error.message : String(error),
+            });
+          }
+          continue;
+        }
+
+        if (!data || typeof data !== "object" || Array.isArray(data)) {
+          continue;
+        }
+
+        const record = data as Record<string, string>;
+        if (Object.keys(record).length === 0) {
+          continue;
+        }
+
+        stateMap.set(endpointId, deserializeState(record));
+      }
+
+      if (errorCount > 0) {
+        logger.warn("[EndpointCircuitState] Partial batch load failures", {
+          errorCount,
+          sample: errorSamples,
+        });
+      }
+    }
+
+    return stateMap;
+  } catch (error) {
+    logger.warn("[EndpointCircuitState] Failed to batch load from Redis", {
+      count: uniqueEndpointIds.length,
+      error: error instanceof Error ? error.message : String(error),
+    });
+    return stateMap;
+  }
+}
+
 export async function loadEndpointCircuitState(
   endpointId: number
 ): Promise<EndpointCircuitBreakerState | null> {
@@ -89,8 +177,10 @@ export async function saveEndpointCircuitState(
   try {
     const key = getStateKey(endpointId);
     const data = serializeState(state);
-    await redis.hset(key, data);
-    await redis.expire(key, STATE_TTL_SECONDS);
+    const pipeline = redis.pipeline();
+    pipeline.hset(key, data);
+    pipeline.expire(key, STATE_TTL_SECONDS);
+    await pipeline.exec();
   } catch (error) {
     logger.warn("[EndpointCircuitState] Failed to save to Redis", {
       endpointId,

+ 2 - 0
src/repository/index.ts

@@ -49,6 +49,7 @@ export {
   createProviderEndpoint,
   deleteProviderEndpointProbeLogsBeforeDateBatch,
   deleteProviderVendor,
+  findEnabledProviderEndpointsByVendorAndType,
   findEnabledProviderEndpointsForProbing,
   findProviderEndpointById,
   findProviderEndpointProbeLogs,
@@ -56,6 +57,7 @@ export {
   findProviderEndpointsByVendorAndType,
   findProviderVendorById,
   findProviderVendors,
+  findProviderVendorsByIds,
   recordProviderEndpointProbeResult,
   softDeleteProviderEndpoint,
   tryDeleteProviderVendorIfEmpty,

+ 29 - 9
src/repository/leaderboard.ts

@@ -158,23 +158,43 @@ function buildDateCondition(
   timezone: string,
   dateRange?: DateRangeParams
 ) {
+  const nowLocal = sql`CURRENT_TIMESTAMP AT TIME ZONE ${timezone}`;
+
   if (period === "custom" && dateRange) {
-    // 自定义日期范围:startDate <= date <= endDate
-    return sql`(${messageRequest.createdAt} AT TIME ZONE ${timezone})::date >= ${dateRange.startDate}::date
-      AND (${messageRequest.createdAt} AT TIME ZONE ${timezone})::date <= ${dateRange.endDate}::date`;
+    // 自定义日期范围:startDate <= local_date <= endDate
+    const startLocal = sql`(${dateRange.startDate}::date)::timestamp`;
+    const endExclusiveLocal = sql`(${dateRange.endDate}::date + INTERVAL '1 day')`;
+    const start = sql`(${startLocal} AT TIME ZONE ${timezone})`;
+    const endExclusive = sql`(${endExclusiveLocal} AT TIME ZONE ${timezone})`;
+    return sql`${messageRequest.createdAt} >= ${start} AND ${messageRequest.createdAt} < ${endExclusive}`;
   }
 
   switch (period) {
     case "allTime":
       return sql`1=1`;
-    case "daily":
-      return sql`(${messageRequest.createdAt} AT TIME ZONE ${timezone})::date = (CURRENT_TIMESTAMP AT TIME ZONE ${timezone})::date`;
+    case "daily": {
+      const startLocal = sql`DATE_TRUNC('day', ${nowLocal})`;
+      const endExclusiveLocal = sql`${startLocal} + INTERVAL '1 day'`;
+      const start = sql`(${startLocal} AT TIME ZONE ${timezone})`;
+      const endExclusive = sql`(${endExclusiveLocal} AT TIME ZONE ${timezone})`;
+      return sql`${messageRequest.createdAt} >= ${start} AND ${messageRequest.createdAt} < ${endExclusive}`;
+    }
     case "last24h":
       return sql`${messageRequest.createdAt} >= (CURRENT_TIMESTAMP - INTERVAL '24 hours')`;
-    case "weekly":
-      return sql`date_trunc('week', ${messageRequest.createdAt} AT TIME ZONE ${timezone}) = date_trunc('week', CURRENT_TIMESTAMP AT TIME ZONE ${timezone})`;
-    case "monthly":
-      return sql`date_trunc('month', ${messageRequest.createdAt} AT TIME ZONE ${timezone}) = date_trunc('month', CURRENT_TIMESTAMP AT TIME ZONE ${timezone})`;
+    case "weekly": {
+      const startLocal = sql`DATE_TRUNC('week', ${nowLocal})`;
+      const endExclusiveLocal = sql`${startLocal} + INTERVAL '1 week'`;
+      const start = sql`(${startLocal} AT TIME ZONE ${timezone})`;
+      const endExclusive = sql`(${endExclusiveLocal} AT TIME ZONE ${timezone})`;
+      return sql`${messageRequest.createdAt} >= ${start} AND ${messageRequest.createdAt} < ${endExclusive}`;
+    }
+    case "monthly": {
+      const startLocal = sql`DATE_TRUNC('month', ${nowLocal})`;
+      const endExclusiveLocal = sql`${startLocal} + INTERVAL '1 month'`;
+      const start = sql`(${startLocal} AT TIME ZONE ${timezone})`;
+      const endExclusive = sql`(${endExclusiveLocal} AT TIME ZONE ${timezone})`;
+      return sql`${messageRequest.createdAt} >= ${start} AND ${messageRequest.createdAt} < ${endExclusive}`;
+    }
     default:
       return sql`1=1`;
   }

+ 19 - 7
src/repository/overview.ts

@@ -1,6 +1,6 @@
 "use server";
 
-import { and, avg, count, eq, gte, isNull, sql, sum } from "drizzle-orm";
+import { and, avg, count, eq, gte, isNull, lt, lte, sql, sum } from "drizzle-orm";
 import { db } from "@/drizzle/db";
 import { messageRequest } from "@/drizzle/schema";
 import { Decimal, toCostDecimal } from "@/lib/utils/currency";
@@ -42,6 +42,10 @@ export interface OverviewMetricsWithComparison extends OverviewMetrics {
  */
 export async function getOverviewMetrics(): Promise<OverviewMetrics> {
   const timezone = await resolveSystemTimezone();
+  const nowLocal = sql`CURRENT_TIMESTAMP AT TIME ZONE ${timezone}`;
+  const todayStartLocal = sql`DATE_TRUNC('day', ${nowLocal})`;
+  const todayStart = sql`(${todayStartLocal} AT TIME ZONE ${timezone})`;
+  const tomorrowStart = sql`((${todayStartLocal} + INTERVAL '1 day') AT TIME ZONE ${timezone})`;
 
   const [result] = await db
     .select({
@@ -55,7 +59,8 @@ export async function getOverviewMetrics(): Promise<OverviewMetrics> {
       and(
         isNull(messageRequest.deletedAt),
         EXCLUDE_WARMUP_CONDITION,
-        sql`(${messageRequest.createdAt} AT TIME ZONE ${timezone})::date = (CURRENT_TIMESTAMP AT TIME ZONE ${timezone})::date`
+        gte(messageRequest.createdAt, todayStart),
+        lt(messageRequest.createdAt, tomorrowStart)
       )
     );
 
@@ -89,6 +94,14 @@ export async function getOverviewMetricsWithComparison(
   userId?: number
 ): Promise<OverviewMetricsWithComparison> {
   const timezone = await resolveSystemTimezone();
+  const nowLocal = sql`CURRENT_TIMESTAMP AT TIME ZONE ${timezone}`;
+  const todayStartLocal = sql`DATE_TRUNC('day', ${nowLocal})`;
+  const todayStart = sql`(${todayStartLocal} AT TIME ZONE ${timezone})`;
+  const tomorrowStart = sql`((${todayStartLocal} + INTERVAL '1 day') AT TIME ZONE ${timezone})`;
+  const yesterdayStartLocal = sql`${todayStartLocal} - INTERVAL '1 day'`;
+  const yesterdayStart = sql`(${yesterdayStartLocal} AT TIME ZONE ${timezone})`;
+  const yesterdayEndLocal = sql`${yesterdayStartLocal} + (${nowLocal} - ${todayStartLocal})`;
+  const yesterdayEnd = sql`(${yesterdayEndLocal} AT TIME ZONE ${timezone})`;
 
   // 用户过滤条件
   const userCondition = userId ? eq(messageRequest.userId, userId) : undefined;
@@ -109,7 +122,8 @@ export async function getOverviewMetricsWithComparison(
           isNull(messageRequest.deletedAt),
           EXCLUDE_WARMUP_CONDITION,
           userCondition,
-          sql`(${messageRequest.createdAt} AT TIME ZONE ${timezone})::date = (CURRENT_TIMESTAMP AT TIME ZONE ${timezone})::date`
+          gte(messageRequest.createdAt, todayStart),
+          lt(messageRequest.createdAt, tomorrowStart)
         )
       ),
 
@@ -126,10 +140,8 @@ export async function getOverviewMetricsWithComparison(
           isNull(messageRequest.deletedAt),
           EXCLUDE_WARMUP_CONDITION,
           userCondition,
-          // 昨日同一天
-          sql`(${messageRequest.createdAt} AT TIME ZONE ${timezone})::date = ((CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '1 day')::date`,
-          // 且时间不超过昨日的当前时刻
-          sql`(${messageRequest.createdAt} AT TIME ZONE ${timezone})::time <= (CURRENT_TIMESTAMP AT TIME ZONE ${timezone})::time`
+          gte(messageRequest.createdAt, yesterdayStart),
+          lte(messageRequest.createdAt, yesterdayEnd)
         )
       ),
 

+ 173 - 0
src/repository/provider-endpoints-batch.ts

@@ -0,0 +1,173 @@
+import "server-only";
+
+import { and, eq, inArray, isNull, sql } from "drizzle-orm";
+import { db } from "@/drizzle/db";
+import { providerEndpointProbeLogs, providerEndpoints } from "@/drizzle/schema";
+import { logger } from "@/lib/logger";
+import type { ProviderEndpointProbeLog, ProviderType } from "@/types/provider";
+
+function toDate(value: unknown): Date {
+  if (value instanceof Date) return value;
+  if (typeof value === "string" || typeof value === "number") return new Date(value);
+  return new Date();
+}
+
+function toNullableNumber(value: unknown): number | null {
+  if (value === null || value === undefined) return null;
+  const n = typeof value === "number" ? value : Number(value);
+  return Number.isFinite(n) ? n : null;
+}
+
+export type VendorTypeEndpointStats = {
+  vendorId: number;
+  total: number;
+  enabled: number;
+  healthy: number;
+  unhealthy: number;
+  unknown: number;
+};
+
+export async function findVendorTypeEndpointStatsBatch(input: {
+  vendorIds: number[];
+  providerType: ProviderType;
+}): Promise<VendorTypeEndpointStats[]> {
+  const vendorIds = Array.from(new Set(input.vendorIds));
+  if (vendorIds.length === 0) {
+    return [];
+  }
+
+  const rows = await db
+    .select({
+      vendorId: providerEndpoints.vendorId,
+      total: sql<number>`COUNT(*)::int`,
+      enabled: sql<number>`(COUNT(*) FILTER (WHERE ${providerEndpoints.isEnabled} = true))::int`,
+      healthy: sql<number>`(COUNT(*) FILTER (WHERE ${providerEndpoints.isEnabled} = true AND ${providerEndpoints.lastProbeOk} = true))::int`,
+      unhealthy: sql<number>`(COUNT(*) FILTER (WHERE ${providerEndpoints.isEnabled} = true AND ${providerEndpoints.lastProbeOk} = false))::int`,
+      unknown: sql<number>`(COUNT(*) FILTER (WHERE ${providerEndpoints.isEnabled} = true AND ${providerEndpoints.lastProbeOk} IS NULL))::int`,
+    })
+    .from(providerEndpoints)
+    .where(
+      and(
+        inArray(providerEndpoints.vendorId, vendorIds),
+        eq(providerEndpoints.providerType, input.providerType),
+        isNull(providerEndpoints.deletedAt)
+      )
+    )
+    .groupBy(providerEndpoints.vendorId);
+
+  return rows.map((row) => ({
+    vendorId: row.vendorId,
+    total: Number(row.total),
+    enabled: Number(row.enabled),
+    healthy: Number(row.healthy),
+    unhealthy: Number(row.unhealthy),
+    unknown: Number(row.unknown),
+  }));
+}
+
+export async function findProviderEndpointProbeLogsBatch(input: {
+  endpointIds: number[];
+  limitPerEndpoint: number;
+}): Promise<Map<number, ProviderEndpointProbeLog[]>> {
+  const endpointIds = Array.from(new Set(input.endpointIds)).filter((id) =>
+    Number.isSafeInteger(id)
+  );
+  if (endpointIds.length === 0) {
+    return new Map();
+  }
+
+  const limitPerEndpoint = Math.max(1, input.limitPerEndpoint);
+
+  // 性能:避免 `ROW_NUMBER() OVER (PARTITION BY ...)` 在单个端点 logs 很多时退化为更重的扫描/排序。
+  // 改为 LATERAL + LIMIT:每个 endpoint_id 仅取最新 N 条,能更好利用 (endpoint_id, created_at desc) 索引。
+  // 安全:VALUES 列表使用 drizzle sql 参数化占位符拼接(不会把 endpointId 作为 raw 字符串注入)。
+  const endpointValues = sql.join(
+    endpointIds.map((id) => sql`(${id})`),
+    sql`, `
+  );
+
+  const query = sql`
+    WITH endpoint_ids(endpoint_id) AS (
+      VALUES ${endpointValues}
+    )
+    SELECT
+      l.id,
+      l.endpoint_id as "endpointId",
+      l.source,
+      l.ok,
+      l.status_code as "statusCode",
+      l.latency_ms as "latencyMs",
+      l.error_type as "errorType",
+      l.error_message as "errorMessage",
+      l.created_at as "createdAt"
+    FROM endpoint_ids e
+    CROSS JOIN LATERAL (
+      SELECT
+        id,
+        endpoint_id,
+        source,
+        ok,
+        status_code,
+        latency_ms,
+        error_type,
+        error_message,
+        created_at
+      FROM ${providerEndpointProbeLogs}
+      WHERE endpoint_id = e.endpoint_id
+      ORDER BY created_at DESC NULLS LAST, id DESC
+      LIMIT ${limitPerEndpoint}
+    ) l
+    ORDER BY l.endpoint_id ASC, l.created_at DESC NULLS LAST, l.id DESC
+  `;
+
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  const result = (await db.execute(query)) as any;
+  const map = new Map<number, ProviderEndpointProbeLog[]>();
+
+  for (const row of Array.from(result) as Array<Record<string, unknown>>) {
+    const endpointId = Number(row.endpointId);
+    if (!Number.isFinite(endpointId)) {
+      continue;
+    }
+
+    const id = Number(row.id);
+    if (!Number.isFinite(id)) {
+      continue;
+    }
+
+    const log: ProviderEndpointProbeLog = {
+      id,
+      endpointId,
+      source: row.source as ProviderEndpointProbeLog["source"],
+      ok: Boolean(row.ok),
+      statusCode: toNullableNumber(row.statusCode),
+      latencyMs: toNullableNumber(row.latencyMs),
+      errorType: (row.errorType as string | null) ?? null,
+      errorMessage: (row.errorMessage as string | null) ?? null,
+      createdAt: toDate(row.createdAt),
+    };
+
+    const existing = map.get(endpointId);
+    if (existing) {
+      existing.push(log);
+    } else {
+      map.set(endpointId, [log]);
+    }
+  }
+
+  // Defensive: ensure per-endpoint limit, even if SQL changes or driver behavior differs.
+  for (const [endpointId, logs] of map) {
+    if (logs.length > limitPerEndpoint) {
+      map.set(endpointId, logs.slice(0, limitPerEndpoint));
+    }
+  }
+
+  if (map.size === 0) {
+    logger.debug("[ProviderEndpointProbeLogsBatch] No logs found", {
+      endpointCount: endpointIds.length,
+      limitPerEndpoint,
+    });
+  }
+
+  return map;
+}

+ 347 - 65
src/repository/provider-endpoints.ts

@@ -1,4 +1,4 @@
-"use server";
+import "server-only";
 
 import { and, asc, desc, eq, gt, inArray, isNotNull, isNull, ne, or, sql } from "drizzle-orm";
 import { db } from "@/drizzle/db";
@@ -311,32 +311,53 @@ function toProviderEndpointProbeLog(row: any): ProviderEndpointProbeLog {
 
 export type ProviderEndpointProbeTarget = Pick<
   ProviderEndpoint,
-  "id" | "url" | "vendorId" | "lastProbedAt" | "lastProbeOk" | "lastProbeErrorType"
+  "id" | "url" | "vendorId" | "providerType" | "lastProbedAt" | "lastProbeOk" | "lastProbeErrorType"
 >;
 
 export async function findEnabledProviderEndpointsForProbing(): Promise<
   ProviderEndpointProbeTarget[]
 > {
-  const rows = await db
-    .select({
-      id: providerEndpoints.id,
-      url: providerEndpoints.url,
-      vendorId: providerEndpoints.vendorId,
-      lastProbedAt: providerEndpoints.lastProbedAt,
-      lastProbeOk: providerEndpoints.lastProbeOk,
-      lastProbeErrorType: providerEndpoints.lastProbeErrorType,
-    })
-    .from(providerEndpoints)
-    .where(and(eq(providerEndpoints.isEnabled, true), isNull(providerEndpoints.deletedAt)))
-    .orderBy(asc(providerEndpoints.id));
+  // #779/#781:probe scheduler 热路径:
+  // - 仅探测仍存在「启用 provider」的 vendor/type 下的端点(避免全禁用/孤儿 vendor 仍被持续探测)
+  // - 仍需覆盖端点池内“手动添加”的端点(未必与 provider.url 一一对应),因此只按 vendor/type 维度 gating。
+  const query = sql`
+    WITH enabled_vendor_types AS (
+      SELECT DISTINCT p.provider_vendor_id AS vendor_id, p.provider_type
+      FROM ${providers} p
+      WHERE p.is_enabled = true
+        AND p.deleted_at IS NULL
+        AND p.provider_vendor_id IS NOT NULL
+        AND p.provider_vendor_id > 0
+    )
+    SELECT
+      e.id,
+      e.url,
+      e.vendor_id AS "vendorId",
+      e.provider_type AS "providerType",
+      e.last_probed_at AS "lastProbedAt",
+      e.last_probe_ok AS "lastProbeOk",
+      e.last_probe_error_type AS "lastProbeErrorType"
+    FROM ${providerEndpoints} e
+    INNER JOIN enabled_vendor_types vt
+      ON vt.vendor_id = e.vendor_id
+     AND vt.provider_type = e.provider_type
+    WHERE e.is_enabled = true
+      AND e.deleted_at IS NULL
+    ORDER BY e.id ASC
+  `;
+
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  const result = (await db.execute(query)) as any;
+  const rows = Array.from(result) as Array<Record<string, unknown>>;
 
   return rows.map((row) => ({
-    id: row.id,
-    url: row.url,
-    vendorId: row.vendorId,
+    id: Number(row.id),
+    url: String(row.url),
+    vendorId: Number(row.vendorId),
+    providerType: row.providerType as ProviderType,
     lastProbedAt: toNullableDate(row.lastProbedAt),
-    lastProbeOk: row.lastProbeOk ?? null,
-    lastProbeErrorType: row.lastProbeErrorType ?? null,
+    lastProbeOk: (row.lastProbeOk as boolean | null) ?? null,
+    lastProbeErrorType: (row.lastProbeErrorType as string | null) ?? null,
   }));
 }
 
@@ -412,11 +433,35 @@ export async function getOrCreateProviderVendorIdFromUrls(
   }
 
   const existing = await executor
-    .select({ id: providerVendors.id })
+    .select({
+      id: providerVendors.id,
+      displayName: providerVendors.displayName,
+      websiteUrl: providerVendors.websiteUrl,
+      faviconUrl: providerVendors.faviconUrl,
+    })
     .from(providerVendors)
     .where(eq(providerVendors.websiteDomain, websiteDomain))
     .limit(1);
   if (existing[0]) {
+    const updates: Partial<typeof providerVendors.$inferInsert> = {};
+
+    const current = existing[0];
+    const nextDisplayName = input.displayName?.trim() || null;
+    if ((current.displayName == null || current.displayName.trim() === "") && nextDisplayName) {
+      updates.displayName = nextDisplayName;
+    }
+    if (current.websiteUrl == null && input.websiteUrl) {
+      updates.websiteUrl = input.websiteUrl;
+    }
+    if (current.faviconUrl == null && input.faviconUrl) {
+      updates.faviconUrl = input.faviconUrl;
+    }
+
+    if (Object.keys(updates).length > 0) {
+      updates.updatedAt = new Date();
+      await executor.update(providerVendors).set(updates).where(eq(providerVendors.id, current.id));
+    }
+
     return existing[0].id;
   }
 
@@ -600,6 +645,136 @@ export async function findProviderVendors(
   return rows.map(toProviderVendor);
 }
 
+export async function findProviderVendorsByIds(vendorIds: number[]): Promise<ProviderVendor[]> {
+  const ids = Array.from(new Set(vendorIds)).filter((id) => Number.isInteger(id) && id > 0);
+  if (ids.length === 0) {
+    return [];
+  }
+
+  const rows = await db
+    .select({
+      id: providerVendors.id,
+      websiteDomain: providerVendors.websiteDomain,
+      displayName: providerVendors.displayName,
+      websiteUrl: providerVendors.websiteUrl,
+      faviconUrl: providerVendors.faviconUrl,
+      createdAt: providerVendors.createdAt,
+      updatedAt: providerVendors.updatedAt,
+    })
+    .from(providerVendors)
+    .where(inArray(providerVendors.id, ids))
+    .orderBy(desc(providerVendors.createdAt));
+
+  return rows.map(toProviderVendor);
+}
+
+/**
+ * Dashboard/Endpoint Health 用:推导 vendor/type 筛选项(仅基于启用的 provider)。
+ *
+ * 相比 `findAllProvidersFresh` 读取全量 provider 字段,这里只取 vendorId/providerType,并做 DISTINCT 去重,
+ * 可显著减少数据传输与反序列化开销(#779/#781)。
+ */
+export async function findEnabledProviderVendorTypePairs(): Promise<
+  Array<{ vendorId: number; providerType: ProviderType }>
+> {
+  const rows = await db
+    .selectDistinct({
+      vendorId: providers.providerVendorId,
+      providerType: providers.providerType,
+    })
+    .from(providers)
+    .where(
+      and(
+        isNull(providers.deletedAt),
+        eq(providers.isEnabled, true),
+        isNotNull(providers.providerVendorId),
+        gt(providers.providerVendorId, 0)
+      )
+    )
+    .orderBy(asc(providers.providerVendorId), asc(providers.providerType));
+
+  return rows
+    .map((row) => ({
+      vendorId: row.vendorId as number,
+      providerType: row.providerType as ProviderType,
+    }))
+    .filter(
+      (row) => Number.isFinite(row.vendorId) && row.vendorId > 0 && Boolean(row.providerType)
+    );
+}
+
+/**
+ * 判断某个 (vendor/type/url) 是否仍被启用的 provider 引用。
+ *
+ * 用于:端点删除/同步时的“引用检查”,避免出现“删了端点但启动回填/启用 provider 又复活”的困惑(#781)。
+ */
+export async function hasEnabledProviderReferenceForVendorTypeUrl(input: {
+  vendorId: number;
+  providerType: ProviderType;
+  url: string;
+  excludeProviderId?: number;
+}): Promise<boolean> {
+  const trimmedUrl = input.url.trim();
+  if (!trimmedUrl) {
+    return false;
+  }
+
+  const whereClauses = [
+    eq(providers.providerVendorId, input.vendorId),
+    eq(providers.providerType, input.providerType),
+    eq(providers.url, trimmedUrl),
+    eq(providers.isEnabled, true),
+    isNull(providers.deletedAt),
+  ];
+
+  if (input.excludeProviderId != null) {
+    whereClauses.push(ne(providers.id, input.excludeProviderId));
+  }
+
+  const [row] = await db
+    .select({ id: providers.id })
+    .from(providers)
+    .where(and(...whereClauses))
+    .limit(1);
+
+  return Boolean(row);
+}
+
+/**
+ * Dashboard/Endpoint Health 用:仅在存在启用 provider 的前提下返回该 vendor/type 的端点池。
+ *
+ * #781:避免“没有任何启用 provider 的 vendor/type”仍在 Dashboard 中展示与被探测。
+ *
+ * 注意:端点池允许手动添加端点,未必与 `providers.url` 一一对应;这里按 vendor/type 维度 gating,
+ * 以尽量保持端点池的展示语义不变。
+ */
+export async function findDashboardProviderEndpointsByVendorAndType(
+  vendorId: number,
+  providerType: ProviderType
+): Promise<ProviderEndpoint[]> {
+  const rows = await db
+    .select(providerEndpointSelectFields)
+    .from(providerEndpoints)
+    .where(
+      and(
+        eq(providerEndpoints.vendorId, vendorId),
+        eq(providerEndpoints.providerType, providerType),
+        isNull(providerEndpoints.deletedAt),
+        sql`EXISTS (
+          SELECT 1
+          FROM ${providers} p
+          WHERE p.provider_vendor_id = ${vendorId}
+            AND p.provider_type = ${providerType}
+            AND p.is_enabled = true
+            AND p.deleted_at IS NULL
+        )`
+      )
+    )
+    .orderBy(asc(providerEndpoints.sortOrder), asc(providerEndpoints.id));
+
+  return rows.map(toProviderEndpoint);
+}
+
 export async function findProviderVendorById(vendorId: number): Promise<ProviderVendor | null> {
   const rows = await db
     .select({
@@ -790,6 +965,31 @@ export async function findProviderEndpointsByVendorAndType(
   return rows.map(toProviderEndpoint);
 }
 
+/**
+ * 仅返回启用的端点(运行时热路径),用于减少不必要的数据传输与排序开销。
+ *
+ * #779:配合索引 `idx_provider_endpoints_pick_enabled`,可按 vendor/type 有序扫描。
+ */
+export async function findEnabledProviderEndpointsByVendorAndType(
+  vendorId: number,
+  providerType: ProviderType
+): Promise<ProviderEndpoint[]> {
+  const rows = await db
+    .select(providerEndpointSelectFields)
+    .from(providerEndpoints)
+    .where(
+      and(
+        eq(providerEndpoints.vendorId, vendorId),
+        eq(providerEndpoints.providerType, providerType),
+        eq(providerEndpoints.isEnabled, true),
+        isNull(providerEndpoints.deletedAt)
+      )
+    )
+    .orderBy(asc(providerEndpoints.sortOrder), asc(providerEndpoints.id));
+
+  return rows.map(toProviderEndpoint);
+}
+
 export async function findProviderEndpointsByVendor(vendorId: number): Promise<ProviderEndpoint[]> {
   const rows = await db
     .select({
@@ -909,6 +1109,13 @@ export interface SyncProviderEndpointOnProviderEditInput {
   previousProviderType?: ProviderType | null;
   previousUrl: string;
   nextUrl: string;
+  /**
+   * 是否在旧 URL 仍被其它「启用 provider」引用时保留旧端点。
+   *
+   * - `true`(默认):仅当旧 URL 仍被其它启用 provider 引用时保留旧端点;否则会尝试移动/软删除旧端点,
+   *   以避免 orphan endpoint 长期残留并造成“明明已改/删仍在被探测或展示”的困惑(#781)。
+   * - `false`:忽略引用关系,尽量清理旧端点(谨慎使用:可能影响仍在使用旧 URL 的 provider)。
+   */
   keepPreviousWhenReferenced?: boolean;
 }
 
@@ -972,6 +1179,9 @@ export async function syncProviderEndpointOnProviderEdit(
             eq(providerEndpoints.url, args.url)
           )
         )
+        // 兼容历史/并发导致的脏数据:同一 (vendor/type/url) 下可能同时存在 active 行与软删除历史行。
+        // partial unique 只约束 deleted_at IS NULL,因此这里必须稳定地优先选择 active 行,避免误选历史行后 revive 触发 23505。
+        .orderBy(desc(providerEndpoints.deletedAt), desc(providerEndpoints.id))
         .limit(1);
 
       return row
@@ -992,6 +1202,7 @@ export async function syncProviderEndpointOnProviderEdit(
             eq(providers.providerVendorId, previousVendorId),
             eq(providers.providerType, previousProviderType),
             eq(providers.url, previousUrl),
+            eq(providers.isEnabled, true),
             isNull(providers.deletedAt),
             ne(providers.id, input.providerId)
           )
@@ -1042,14 +1253,45 @@ export async function syncProviderEndpointOnProviderEdit(
         }
 
         if (concurrentEndpoint.deletedAt !== null) {
-          await tx
-            .update(providerEndpoints)
-            .set({
-              deletedAt: null,
-              isEnabled: true,
-              updatedAt: now,
-            })
-            .where(eq(providerEndpoints.id, concurrentEndpoint.id));
+          try {
+            await tx
+              .update(providerEndpoints)
+              .set({
+                deletedAt: null,
+                isEnabled: true,
+                updatedAt: now,
+              })
+              .where(eq(providerEndpoints.id, concurrentEndpoint.id));
+          } catch (error) {
+            if (!isUniqueViolationError(error)) {
+              throw error;
+            }
+
+            const activeEndpoint = await loadEndpoint({
+              vendorId: input.vendorId,
+              providerType: input.providerType,
+              url: nextUrl,
+            });
+
+            if (!activeEndpoint) {
+              throw new Error(
+                "[ProviderEndpointSync] failed to load next endpoint after revive conflict"
+              );
+            }
+
+            if (reactivateDisabled && !activeEndpoint.isEnabled) {
+              await tx
+                .update(providerEndpoints)
+                .set({
+                  isEnabled: true,
+                  updatedAt: now,
+                })
+                .where(eq(providerEndpoints.id, activeEndpoint.id));
+              return "revived-next";
+            }
+
+            return "noop";
+          }
 
           return "revived-next";
         }
@@ -1070,14 +1312,45 @@ export async function syncProviderEndpointOnProviderEdit(
       }
 
       if (nextEndpoint.deletedAt !== null) {
-        await tx
-          .update(providerEndpoints)
-          .set({
-            deletedAt: null,
-            isEnabled: true,
-            updatedAt: now,
-          })
-          .where(eq(providerEndpoints.id, nextEndpoint.id));
+        try {
+          await tx
+            .update(providerEndpoints)
+            .set({
+              deletedAt: null,
+              isEnabled: true,
+              updatedAt: now,
+            })
+            .where(eq(providerEndpoints.id, nextEndpoint.id));
+        } catch (error) {
+          if (!isUniqueViolationError(error)) {
+            throw error;
+          }
+
+          const activeEndpoint = await loadEndpoint({
+            vendorId: input.vendorId,
+            providerType: input.providerType,
+            url: nextUrl,
+          });
+
+          if (!activeEndpoint) {
+            throw new Error(
+              "[ProviderEndpointSync] failed to load next endpoint after revive conflict"
+            );
+          }
+
+          if (reactivateDisabled && !activeEndpoint.isEnabled) {
+            await tx
+              .update(providerEndpoints)
+              .set({
+                isEnabled: true,
+                updatedAt: now,
+              })
+              .where(eq(providerEndpoints.id, activeEndpoint.id));
+            return "revived-next";
+          }
+
+          return "noop";
+        }
 
         return "revived-next";
       }
@@ -1188,12 +1461,6 @@ export async function syncProviderEndpointOnProviderEdit(
 
         const ensureResult = await ensureNextEndpointActive();
 
-        if (keepPreviousWhenReferenced) {
-          return {
-            action: mapEnsureResultToKeptAction(ensureResult),
-          };
-        }
-
         await tx
           .update(providerEndpoints)
           .set({
@@ -1231,12 +1498,6 @@ export async function syncProviderEndpointOnProviderEdit(
         keepPreviousWhenReferenced && (await hasActiveReferencesOnPreviousUrl());
 
       if (!previousIsReferenced) {
-        if (keepPreviousWhenReferenced) {
-          return {
-            action: mapEnsureResultToKeptAction(ensureResult),
-          };
-        }
-
         await tx
           .update(providerEndpoints)
           .set({
@@ -1422,7 +1683,13 @@ export async function backfillProviderEndpointsFromProviders(
   const invalidSamples: BackfillProviderEndpointSample[] = [];
 
   while (true) {
-    const whereClauses = [isNull(providers.deletedAt), gt(providers.id, lastProviderId)];
+    const whereClauses = [
+      isNull(providers.deletedAt),
+      // 仅 backfill 启用中的 providers:disabled -> enabled 的场景由 updateProvider/updateProvidersBatch
+      // 在启用时 best-effort 确保 endpoint pool,不依赖 backfill 扫描。
+      eq(providers.isEnabled, true),
+      gt(providers.id, lastProviderId),
+    ];
     if (scopedVendorIds.length > 0) {
       whereClauses.push(inArray(providers.providerVendorId, scopedVendorIds));
     }
@@ -1628,6 +1895,7 @@ export async function backfillProviderEndpointsFromProviders(
   const deterministicSamples: BackfillProviderEndpointSample[] = [];
   const reportOnlyHistoricalSamples: BackfillProviderEndpointSample[] = [];
   const deterministicCandidates: BackfillProviderEndpointCandidate[] = [];
+  const historicalCandidates: BackfillProviderEndpointCandidate[] = [];
   let reportOnlyHistoricalCandidates = 0;
 
   for (const candidate of missingCandidates) {
@@ -1646,6 +1914,9 @@ export async function backfillProviderEndpointsFromProviders(
         },
         sampleLimit
       );
+      // 兼容升级:即使存在历史 soft-deleted 行,也需要为当前活跃 provider 确保存在 active endpoint,
+      // 否则 strict endpoint pool 策略可能在端点池为空时阻断请求。
+      historicalCandidates.push(candidate);
       continue;
     }
 
@@ -1666,7 +1937,8 @@ export async function backfillProviderEndpointsFromProviders(
   }
 
   let repaired = 0;
-  if (mode === "apply" && deterministicCandidates.length > 0) {
+  const candidatesToInsert = [...deterministicCandidates, ...historicalCandidates];
+  if (mode === "apply" && candidatesToInsert.length > 0) {
     const pending: Array<{ vendorId: number; providerType: ProviderType; url: string }> = [];
     const flush = async (): Promise<void> => {
       if (pending.length === 0) {
@@ -1686,7 +1958,7 @@ export async function backfillProviderEndpointsFromProviders(
       pending.length = 0;
     };
 
-    for (const candidate of deterministicCandidates) {
+    for (const candidate of candidatesToInsert) {
       pending.push({
         vendorId: candidate.vendorId,
         providerType: candidate.providerType,
@@ -1832,18 +2104,7 @@ export async function recordProviderEndpointProbeResult(input: {
   const probedAt = input.probedAt ?? new Date();
 
   await db.transaction(async (tx) => {
-    await tx.insert(providerEndpointProbeLogs).values({
-      endpointId: input.endpointId,
-      source: input.source,
-      ok: input.ok,
-      statusCode: input.statusCode ?? null,
-      latencyMs: input.latencyMs ?? null,
-      errorType: input.errorType ?? null,
-      errorMessage: input.errorMessage ?? null,
-      createdAt: probedAt,
-    });
-
-    await tx
+    const updated = await tx
       .update(providerEndpoints)
       .set({
         lastProbedAt: probedAt,
@@ -1854,7 +2115,25 @@ export async function recordProviderEndpointProbeResult(input: {
         lastProbeErrorMessage: input.ok ? null : (input.errorMessage ?? null),
         updatedAt: new Date(),
       })
-      .where(and(eq(providerEndpoints.id, input.endpointId), isNull(providerEndpoints.deletedAt)));
+      .where(and(eq(providerEndpoints.id, input.endpointId), isNull(providerEndpoints.deletedAt)))
+      .returning({ id: providerEndpoints.id });
+
+    // 端点可能在探测过程中被删除(vendor cascade / 管理后台操作)。
+    // 这类情况属于“已不存在的端点”,应直接忽略,避免 probe scheduler 因 FK 失败而中断。
+    if (updated.length === 0) {
+      return;
+    }
+
+    await tx.insert(providerEndpointProbeLogs).values({
+      endpointId: input.endpointId,
+      source: input.source,
+      ok: input.ok,
+      statusCode: input.statusCode ?? null,
+      latencyMs: input.latencyMs ?? null,
+      errorType: input.errorType ?? null,
+      errorMessage: input.errorMessage ?? null,
+      createdAt: probedAt,
+    });
   });
 }
 
@@ -1877,7 +2156,10 @@ export async function findProviderEndpointProbeLogs(
     })
     .from(providerEndpointProbeLogs)
     .where(eq(providerEndpointProbeLogs.endpointId, endpointId))
-    .orderBy(desc(providerEndpointProbeLogs.createdAt))
+    .orderBy(
+      sql`${providerEndpointProbeLogs.createdAt} DESC NULLS LAST`,
+      desc(providerEndpointProbeLogs.id)
+    )
     .limit(limit)
     .offset(offset);
 

+ 387 - 119
src/repository/provider.ts

@@ -1,8 +1,8 @@
-"use server";
+import "server-only";
 
-import { and, desc, eq, isNotNull, isNull, ne, sql } from "drizzle-orm";
+import { and, desc, eq, inArray, isNotNull, isNull, ne, sql } from "drizzle-orm";
 import { db } from "@/drizzle/db";
-import { providers } from "@/drizzle/schema";
+import { providerEndpoints, providers } from "@/drizzle/schema";
 import { getCachedProviders } from "@/lib/cache/provider-cache";
 import { resetEndpointCircuit } from "@/lib/endpoint-circuit-breaker";
 import { logger } from "@/lib/logger";
@@ -499,12 +499,16 @@ export async function updateProvider(
 
   const shouldRefreshVendor =
     providerData.url !== undefined || providerData.website_url !== undefined;
-  const shouldSyncEndpoint = shouldRefreshVendor || providerData.provider_type !== undefined;
+  const shouldSyncEndpoint =
+    shouldRefreshVendor ||
+    providerData.provider_type !== undefined ||
+    providerData.is_enabled === true;
 
   const updateResult = await db.transaction(async (tx) => {
     let previousVendorId: number | null = null;
     let previousUrl: string | null = null;
     let previousProviderType: Provider["providerType"] | null = null;
+    let previousIsEnabled: boolean | null = null;
     let endpointCircuitResetId: number | null = null;
 
     if (shouldSyncEndpoint) {
@@ -516,6 +520,7 @@ export async function updateProvider(
           name: providers.name,
           providerVendorId: providers.providerVendorId,
           providerType: providers.providerType,
+          isEnabled: providers.isEnabled,
         })
         .from(providers)
         .where(and(eq(providers.id, id), isNull(providers.deletedAt)))
@@ -525,6 +530,7 @@ export async function updateProvider(
         previousVendorId = current.providerVendorId;
         previousUrl = current.url;
         previousProviderType = current.providerType;
+        previousIsEnabled = current.isEnabled;
 
         if (shouldRefreshVendor) {
           const providerVendorId = await getOrCreateProviderVendorIdFromUrls(
@@ -606,7 +612,16 @@ export async function updateProvider(
     const transformed = toProvider(provider);
 
     if (shouldSyncEndpoint && transformed.providerVendorId) {
-      if (previousUrl && previousProviderType) {
+      // 注意:即使 provider 当前处于禁用态,只要 vendor/type/url 发生变化也同步 endpoint pool:
+      // - 避免旧 URL 残留为 orphan endpoints(#781)
+      // - 保证后续启用/其它同 vendor/type 的 provider 能直接复用端点池
+      if (
+        previousUrl &&
+        previousProviderType &&
+        (previousUrl !== transformed.url ||
+          previousProviderType !== transformed.providerType ||
+          (previousVendorId != null && previousVendorId !== transformed.providerVendorId))
+      ) {
         const syncResult = await syncProviderEndpointOnProviderEdit(
           {
             providerId: transformed.id,
@@ -622,7 +637,7 @@ export async function updateProvider(
         );
 
         endpointCircuitResetId = syncResult.resetCircuitEndpointId ?? null;
-      } else {
+      } else if (previousIsEnabled === false && transformed.isEnabled === true) {
         await ensureProviderEndpointExistsForUrl(
           {
             vendorId: transformed.providerVendorId,
@@ -713,13 +728,71 @@ export async function updateProviderPrioritiesBatch(
 }
 
 export async function deleteProvider(id: number): Promise<boolean> {
-  const result = await db
-    .update(providers)
-    .set({ deletedAt: new Date() })
-    .where(and(eq(providers.id, id), isNull(providers.deletedAt)))
-    .returning({ id: providers.id });
+  const now = new Date();
 
-  return result.length > 0;
+  const deleted = await db.transaction(async (tx) => {
+    const [current] = await tx
+      .select({
+        providerVendorId: providers.providerVendorId,
+        providerType: providers.providerType,
+        url: providers.url,
+      })
+      .from(providers)
+      .where(and(eq(providers.id, id), isNull(providers.deletedAt)))
+      .limit(1);
+
+    if (!current) {
+      return false;
+    }
+
+    const result = await tx
+      .update(providers)
+      .set({ deletedAt: now })
+      .where(and(eq(providers.id, id), isNull(providers.deletedAt)))
+      .returning({ id: providers.id });
+
+    if (result.length === 0) {
+      return false;
+    }
+
+    if (current.providerVendorId != null && current.url) {
+      const [activeReference] = await tx
+        .select({ id: providers.id })
+        .from(providers)
+        .where(
+          and(
+            eq(providers.providerVendorId, current.providerVendorId),
+            eq(providers.providerType, current.providerType),
+            eq(providers.url, current.url),
+            eq(providers.isEnabled, true),
+            isNull(providers.deletedAt)
+          )
+        )
+        .limit(1);
+
+      if (!activeReference) {
+        await tx
+          .update(providerEndpoints)
+          .set({
+            deletedAt: now,
+            isEnabled: false,
+            updatedAt: now,
+          })
+          .where(
+            and(
+              eq(providerEndpoints.vendorId, current.providerVendorId),
+              eq(providerEndpoints.providerType, current.providerType),
+              eq(providerEndpoints.url, current.url),
+              isNull(providerEndpoints.deletedAt)
+            )
+          );
+      }
+    }
+
+    return true;
+  });
+
+  return deleted;
 }
 
 export interface BatchProviderUpdates {
@@ -739,7 +812,8 @@ export async function updateProvidersBatch(
   }
 
   const uniqueIds = [...new Set(ids)];
-  const setClauses: Record<string, unknown> = { updatedAt: new Date() };
+  const now = new Date();
+  const setClauses: Record<string, unknown> = { updatedAt: now };
 
   if (updates.isEnabled !== undefined) {
     setClauses.isEnabled = updates.isEnabled;
@@ -761,16 +835,94 @@ export async function updateProvidersBatch(
     return 0;
   }
 
-  const idList = sql.join(
-    uniqueIds.map((id) => sql`${id}`),
-    sql`, `
-  );
-
   const result = await db
     .update(providers)
     .set(setClauses)
-    .where(sql`id IN (${idList}) AND deleted_at IS NULL`)
-    .returning({ id: providers.id });
+    .where(and(inArray(providers.id, uniqueIds), isNull(providers.deletedAt)))
+    .returning({
+      id: providers.id,
+      providerVendorId: providers.providerVendorId,
+      providerType: providers.providerType,
+      url: providers.url,
+    });
+
+  // #779/#781:批量启用供应商时,best-effort 确保 endpoint pool 中存在对应 URL(避免历史/竞态导致启用后严格端点被阻断)。
+  if (updates.isEnabled === true && result.length > 0) {
+    const endpointKeys = new Map<
+      string,
+      { vendorId: number; providerType: Provider["providerType"]; url: string }
+    >();
+
+    for (const row of result) {
+      if (row.providerVendorId == null || typeof row.url !== "string") {
+        continue;
+      }
+
+      const trimmedUrl = row.url.trim();
+      if (!trimmedUrl) {
+        continue;
+      }
+
+      try {
+        // eslint-disable-next-line no-new
+        new URL(trimmedUrl);
+      } catch {
+        logger.warn("updateProvidersBatch:skip_invalid_url", {
+          providerId: row.id,
+          vendorId: row.providerVendorId,
+          providerType: row.providerType,
+          url: trimmedUrl,
+        });
+        continue;
+      }
+
+      const key = `${row.providerVendorId}::${row.providerType}::${trimmedUrl}`;
+      if (endpointKeys.has(key)) continue;
+
+      endpointKeys.set(key, {
+        vendorId: row.providerVendorId,
+        providerType: row.providerType,
+        url: trimmedUrl,
+      });
+    }
+
+    if (endpointKeys.size > 0) {
+      try {
+        const inserted = await db
+          .insert(providerEndpoints)
+          .values(
+            Array.from(endpointKeys.values()).map((endpoint) => ({
+              vendorId: endpoint.vendorId,
+              providerType: endpoint.providerType,
+              url: endpoint.url,
+              label: null,
+              updatedAt: now,
+            }))
+          )
+          .onConflictDoNothing({
+            target: [
+              providerEndpoints.vendorId,
+              providerEndpoints.providerType,
+              providerEndpoints.url,
+            ],
+            where: sql`${providerEndpoints.deletedAt} IS NULL`,
+          })
+          .returning({ id: providerEndpoints.id });
+
+        logger.debug("updateProvidersBatch:ensured_provider_endpoints", {
+          updatedProviders: result.length,
+          candidateEndpoints: endpointKeys.size,
+          insertedEndpoints: inserted.length,
+        });
+      } catch (error) {
+        logger.warn("updateProvidersBatch:ensure_provider_endpoints_failed", {
+          updatedProviders: result.length,
+          candidateEndpoints: endpointKeys.size,
+          error: error instanceof Error ? error.message : String(error),
+        });
+      }
+    }
+  }
 
   logger.debug("updateProvidersBatch:completed", {
     requestedIds: uniqueIds.length,
@@ -787,23 +939,95 @@ export async function deleteProvidersBatch(ids: number[]): Promise<number> {
   }
 
   const uniqueIds = [...new Set(ids)];
-  const idList = sql.join(
-    uniqueIds.map((id) => sql`${id}`),
-    sql`, `
-  );
+  const now = new Date();
 
-  const result = await db
-    .update(providers)
-    .set({ deletedAt: new Date(), updatedAt: new Date() })
-    .where(sql`id IN (${idList}) AND deleted_at IS NULL`)
-    .returning({ id: providers.id });
+  const deletedCount = await db.transaction(async (tx) => {
+    const result = await tx
+      .update(providers)
+      .set({ deletedAt: now, updatedAt: now })
+      .where(and(inArray(providers.id, uniqueIds), isNull(providers.deletedAt)))
+      .returning({
+        id: providers.id,
+        providerVendorId: providers.providerVendorId,
+        providerType: providers.providerType,
+        url: providers.url,
+      });
+
+    if (result.length === 0) {
+      return 0;
+    }
+
+    const endpointKeys = new Map<
+      string,
+      { vendorId: number; providerType: Provider["providerType"]; url: string }
+    >();
+
+    for (const candidate of result) {
+      if (candidate.providerVendorId == null || !candidate.url) {
+        continue;
+      }
+
+      const key = `${candidate.providerVendorId}::${candidate.providerType}::${candidate.url}`;
+      if (endpointKeys.has(key)) {
+        continue;
+      }
+
+      endpointKeys.set(key, {
+        vendorId: candidate.providerVendorId,
+        providerType: candidate.providerType,
+        url: candidate.url,
+      });
+    }
+
+    const endpoints = Array.from(endpointKeys.values());
+    if (endpoints.length === 0) {
+      return result.length;
+    }
+
+    const chunkSize = 200;
+
+    for (let i = 0; i < endpoints.length; i += chunkSize) {
+      const chunk = endpoints.slice(i, i + chunkSize);
+      const tupleList = sql.join(
+        chunk.map(
+          (endpoint) => sql`(${endpoint.vendorId}, ${endpoint.providerType}, ${endpoint.url})`
+        ),
+        sql`, `
+      );
+
+      await tx
+        .update(providerEndpoints)
+        .set({
+          deletedAt: now,
+          isEnabled: false,
+          updatedAt: now,
+        })
+        .where(
+          and(
+            isNull(providerEndpoints.deletedAt),
+            sql`(${providerEndpoints.vendorId}, ${providerEndpoints.providerType}, ${providerEndpoints.url}) IN (${tupleList})`,
+            sql`NOT EXISTS (
+              SELECT 1
+              FROM providers p
+              WHERE p.is_enabled = true
+                AND p.deleted_at IS NULL
+                AND p.provider_vendor_id = ${providerEndpoints.vendorId}
+                AND p.provider_type = ${providerEndpoints.providerType}
+                AND p.url = ${providerEndpoints.url}
+            )`
+          )
+        );
+    }
+
+    return result.length;
+  });
 
   logger.debug("deleteProvidersBatch:completed", {
     requestedIds: uniqueIds.length,
-    deletedCount: result.length,
+    deletedCount,
   });
 
-  return result.length;
+  return deletedCount;
 }
 
 /**
@@ -863,105 +1087,149 @@ export async function getDistinctProviderGroups(): Promise<string[]> {
  * 包括:今天的总金额、今天的调用次数、最近一次调用时间和模型
  *
  * 性能优化:
- * - provider_stats CTE: LEFT JOIN 添加日期过滤,仅扫描今日数据(避免全表扫描)
- * - latest_call CTE: 添加 7 天时间范围限制(避免扫描历史数据)
+ * - provider_stats: 先按最终供应商聚合,再与 providers 做 LEFT JOIN,避免 providers × message_request 的笛卡尔积
+ * - bounds: 用“按时区计算的时间范围”过滤 created_at,便于命中 created_at 索引
+ * - DST 兼容:对“本地日界/近 7 日”先在 timestamp 上做 +interval,再 AT TIME ZONE 回到 timestamptz,避免夏令时跨日偏移
+ * - latest_call: 限制近 7 天范围,避免扫描历史数据
  */
-export async function getProviderStatistics(): Promise<
-  Array<{
-    id: number;
-    today_cost: string;
-    today_calls: number;
-    last_call_time: Date | null;
-    last_call_model: string | null;
-  }>
-> {
+export type ProviderStatisticsRow = {
+  id: number;
+  today_cost: string;
+  today_calls: number;
+  last_call_time: Date | null;
+  last_call_model: string | null;
+};
+
+// 轻量内存缓存:降低后台轮询/重复加载导致的重复扫描
+const PROVIDER_STATISTICS_CACHE_TTL_MS = 10 * 1000; // 10 秒
+let providerStatisticsCache: {
+  timezone: string;
+  expiresAt: number;
+  data: ProviderStatisticsRow[];
+} | null = null;
+
+// in-flight 去重:避免缓存过期瞬间并发触发多次相同查询(thundering herd)
+let providerStatisticsInFlight: {
+  timezone: string;
+  promise: Promise<ProviderStatisticsRow[]>;
+} | null = null;
+
+export async function getProviderStatistics(): Promise<ProviderStatisticsRow[]> {
   try {
     // 统一的时区处理:使用 PostgreSQL AT TIME ZONE + 系统时区配置
     // 参考 getUserStatisticsFromDB 的实现,避免 Node.js Date 带来的时区偏移
     const timezone = await resolveSystemTimezone();
+    const now = Date.now();
+    if (
+      providerStatisticsCache &&
+      providerStatisticsCache.expiresAt > now &&
+      providerStatisticsCache.timezone === timezone
+    ) {
+      return providerStatisticsCache.data;
+    }
+
+    if (providerStatisticsInFlight && providerStatisticsInFlight.timezone === timezone) {
+      return await providerStatisticsInFlight.promise;
+    }
 
-    // ⭐ 使用 providerChain 最后一项的 providerId 来确定最终供应商(兼容重试切换)
-    // 如果 provider_chain 为空(无重试),则使用 provider_id 字段
-    const query = sql`
-      WITH provider_stats AS (
+    const promise = (async () => {
+      // 使用 providerChain 最后一项的 providerId 来确定最终供应商(兼容重试切换)
+      // 如果 provider_chain 为空(无重试),则使用 provider_id 字段
+      const query = sql`
+         WITH bounds AS (
+           SELECT
+             (DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) AT TIME ZONE ${timezone}) AS today_start,
+             ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone}) AS tomorrow_start,
+             ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '7 days') AT TIME ZONE ${timezone}) AS last7_start
+         ),
+         provider_stats AS (
+           -- 先按最终供应商聚合,再与 providers 做 LEFT JOIN,避免 providers × 今日请求 的笛卡尔积
+           SELECT
+            mr.final_provider_id,
+            COALESCE(SUM(mr.cost_usd), 0) AS today_cost,
+            COUNT(*)::integer AS today_calls
+          FROM (
+            SELECT
+              CASE
+                WHEN provider_chain IS NULL OR provider_chain = '[]'::jsonb THEN provider_id
+                WHEN (provider_chain->-1->>'id') ~ '^[0-9]+$' THEN (provider_chain->-1->>'id')::int
+                ELSE provider_id
+              END AS final_provider_id,
+              cost_usd
+            FROM message_request
+            WHERE deleted_at IS NULL
+              AND (blocked_by IS NULL OR blocked_by <> 'warmup')
+              AND created_at >= (SELECT today_start FROM bounds)
+              AND created_at < (SELECT tomorrow_start FROM bounds)
+          ) mr
+          GROUP BY mr.final_provider_id
+        ),
+        latest_call AS (
+          SELECT DISTINCT ON (final_provider_id)
+            final_provider_id,
+            created_at AS last_call_time,
+            model AS last_call_model
+          FROM (
+            SELECT
+              CASE
+                WHEN provider_chain IS NULL OR provider_chain = '[]'::jsonb THEN provider_id
+                WHEN (provider_chain->-1->>'id') ~ '^[0-9]+$' THEN (provider_chain->-1->>'id')::int
+                ELSE provider_id
+              END AS final_provider_id,
+              id,
+              created_at,
+              model
+            FROM message_request
+            WHERE deleted_at IS NULL
+              AND (blocked_by IS NULL OR blocked_by <> 'warmup')
+              AND created_at >= (SELECT last7_start FROM bounds)
+          ) mr
+          -- 性能优化:添加 7 天时间范围限制(避免扫描历史数据)
+          ORDER BY final_provider_id, created_at DESC, id DESC
+        )
         SELECT
           p.id,
-          COALESCE(
-            SUM(CASE
-              WHEN (mr.created_at AT TIME ZONE ${timezone})::date = (CURRENT_TIMESTAMP AT TIME ZONE ${timezone})::date
-                AND (
-                  -- 情况1:无重试(provider_chain 为 NULL 或空数组),使用 provider_id
-                  (mr.provider_chain IS NULL OR jsonb_array_length(mr.provider_chain) = 0) AND mr.provider_id = p.id
-                  OR
-                  -- 情况2:有重试,使用 providerChain 最后一项的 id
-                  (mr.provider_chain IS NOT NULL AND jsonb_array_length(mr.provider_chain) > 0
-                   AND (mr.provider_chain->-1->>'id')::int = p.id)
-                )
-              THEN mr.cost_usd ELSE 0 END),
-            0
-          ) AS today_cost,
-          COUNT(CASE
-            WHEN (mr.created_at AT TIME ZONE ${timezone})::date = (CURRENT_TIMESTAMP AT TIME ZONE ${timezone})::date
-              AND (
-                (mr.provider_chain IS NULL OR jsonb_array_length(mr.provider_chain) = 0) AND mr.provider_id = p.id
-                OR
-                (mr.provider_chain IS NOT NULL AND jsonb_array_length(mr.provider_chain) > 0
-                 AND (mr.provider_chain->-1->>'id')::int = p.id)
-              )
-            THEN 1 END)::integer AS today_calls
+          COALESCE(ps.today_cost, 0) AS today_cost,
+          COALESCE(ps.today_calls, 0) AS today_calls,
+          lc.last_call_time,
+          lc.last_call_model
         FROM providers p
-        -- 性能优化:添加日期过滤条件,仅扫描今日数据(避免全表扫描)
-        LEFT JOIN message_request mr ON mr.deleted_at IS NULL
-          AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          AND mr.created_at >= (CURRENT_DATE AT TIME ZONE ${timezone})
+        LEFT JOIN provider_stats ps ON p.id = ps.final_provider_id
+        LEFT JOIN latest_call lc ON p.id = lc.final_provider_id
         WHERE p.deleted_at IS NULL
-        GROUP BY p.id
-      ),
-      latest_call AS (
-        SELECT DISTINCT ON (final_provider_id)
-          -- 计算最终供应商ID:优先使用 providerChain 最后一项的 id
-          CASE
-            WHEN provider_chain IS NULL OR jsonb_array_length(provider_chain) = 0 THEN provider_id
-            ELSE (provider_chain->-1->>'id')::int
-          END AS final_provider_id,
-          created_at AS last_call_time,
-          model AS last_call_model
-        FROM message_request
-        -- 性能优化:添加 7 天时间范围限制(避免扫描历史数据)
-        WHERE deleted_at IS NULL
-          AND (blocked_by IS NULL OR blocked_by <> 'warmup')
-          AND created_at >= (CURRENT_DATE AT TIME ZONE ${timezone} - INTERVAL '7 days')
-        ORDER BY final_provider_id, created_at DESC
-      )
-      SELECT
-        ps.id,
-        ps.today_cost,
-        ps.today_calls,
-        lc.last_call_time,
-        lc.last_call_model
-      FROM provider_stats ps
-      LEFT JOIN latest_call lc ON ps.id = lc.final_provider_id
-      ORDER BY ps.id ASC
-    `;
-
-    logger.trace("getProviderStatistics:executing_query");
-
-    const result = await db.execute(query);
-
-    logger.trace("getProviderStatistics:result", {
-      count: Array.isArray(result) ? result.length : 0,
-    });
+        ORDER BY p.id ASC
+      `;
+
+      logger.trace("getProviderStatistics:executing_query");
+
+      const result = await db.execute(query);
+      const data = Array.from(result) as ProviderStatisticsRow[];
+
+      logger.trace("getProviderStatistics:result", {
+        count: data.length,
+      });
 
-    // 注意:返回结果中的 today_cost 为 numeric,使用字符串表示;
-    // last_call_time 由数据库返回为时间戳(UTC)。
-    // 这里保持原样,交由上层进行展示格式化。
-    return result as unknown as Array<{
-      id: number;
-      today_cost: string;
-      today_calls: number;
-      last_call_time: Date | null;
-      last_call_model: string | null;
-    }>;
+      // 注意:返回结果中的 today_cost 为 numeric,使用字符串表示;
+      // last_call_time 由数据库返回为时间戳(UTC)。
+      // 这里保持原样,交由上层进行展示格式化。
+      providerStatisticsCache = {
+        timezone,
+        expiresAt: Date.now() + PROVIDER_STATISTICS_CACHE_TTL_MS,
+        data,
+      };
+
+      return data;
+    })();
+
+    providerStatisticsInFlight = { timezone, promise };
+
+    try {
+      return await promise;
+    } finally {
+      if (providerStatisticsInFlight?.promise === promise) {
+        providerStatisticsInFlight = null;
+      }
+    }
   } catch (error) {
     logger.trace("getProviderStatistics:error", {
       message: error instanceof Error ? error.message : String(error),

+ 367 - 143
src/repository/statistics.ts

@@ -1,4 +1,4 @@
-"use server";
+import "server-only";
 
 import { and, eq, gte, inArray, isNull, lt, sql } from "drizzle-orm";
 import { db } from "@/drizzle/db";
@@ -16,6 +16,70 @@ import type {
 } from "@/types/statistics";
 import { EXCLUDE_WARMUP_CONDITION } from "./_shared/message-request-conditions";
 
+/**
+ * Key ID -> key 字符串缓存
+ *
+ * 背景:message_request.key 存储的是 key 字符串,但上层多以 keyId 传参;
+ * 在配额检查/Redis 降级等高频路径中,重复查询 keys 表会放大 DB 压力。
+ *
+ * 说明:
+ * - 短 TTL 允许轻微陈旧(key 一般不变)
+ * - 简单 size 控制,避免在多租户场景无限增长
+ */
+const KEY_STRING_BY_ID_CACHE_TTL_MS = 5 * 60 * 1000; // 5 分钟
+const KEY_STRING_BY_ID_CACHE_MAX_SIZE = 1000;
+const keyStringByIdCache = new Map<number, { key: string; expiresAt: number }>();
+
+async function getKeyStringByIdCached(keyId: number): Promise<string | null> {
+  const now = Date.now();
+  const cached = keyStringByIdCache.get(keyId);
+  if (cached && cached.expiresAt > now) {
+    // LRU-like:刷新 TTL 并 bump 插入顺序(delete+set),让热点 key 不容易被淘汰。
+    cached.expiresAt = now + KEY_STRING_BY_ID_CACHE_TTL_MS;
+    keyStringByIdCache.delete(keyId);
+    keyStringByIdCache.set(keyId, cached);
+    return cached.key;
+  }
+
+  const keyRecord = await db
+    .select({ key: keys.key })
+    .from(keys)
+    .where(eq(keys.id, keyId))
+    .limit(1);
+
+  const keyString = keyRecord?.[0]?.key ?? null;
+  if (!keyString) {
+    keyStringByIdCache.delete(keyId);
+    return null;
+  }
+
+  // Size 控制:先清理过期;仍超限则淘汰最早的一小部分,避免一次性清空导致缓存击穿
+  if (keyStringByIdCache.size >= KEY_STRING_BY_ID_CACHE_MAX_SIZE) {
+    for (const [id, value] of keyStringByIdCache) {
+      if (value.expiresAt <= now) {
+        keyStringByIdCache.delete(id);
+      }
+    }
+
+    if (keyStringByIdCache.size >= KEY_STRING_BY_ID_CACHE_MAX_SIZE) {
+      const evictCount = Math.max(1, Math.ceil(KEY_STRING_BY_ID_CACHE_MAX_SIZE * 0.1));
+      let remaining = evictCount;
+
+      for (const id of keyStringByIdCache.keys()) {
+        keyStringByIdCache.delete(id);
+        remaining -= 1;
+        if (remaining <= 0) break;
+      }
+    }
+  }
+
+  keyStringByIdCache.set(keyId, {
+    key: keyString,
+    expiresAt: now + KEY_STRING_BY_ID_CACHE_TTL_MS,
+  });
+  return keyString;
+}
+
 /**
  * 根据时间范围获取用户消费和API调用统计
  * 注意:这个函数使用原生SQL,因为涉及到PostgreSQL特定的generate_series函数
@@ -45,6 +109,8 @@ export async function getUserStatisticsFromDB(timeRange: TimeRange): Promise<Dat
           FROM users u
           CROSS JOIN hour_range hr
           LEFT JOIN message_request mr ON u.id = mr.user_id
+            AND mr.created_at >= (DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND DATE_TRUNC('hour', mr.created_at AT TIME ZONE ${timezone}) = hr.hour
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           WHERE u.deleted_at IS NULL
@@ -81,6 +147,8 @@ export async function getUserStatisticsFromDB(timeRange: TimeRange): Promise<Dat
           FROM users u
           CROSS JOIN date_range dr
           LEFT JOIN message_request mr ON u.id = mr.user_id
+            AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '6 days') AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           WHERE u.deleted_at IS NULL
@@ -117,6 +185,8 @@ export async function getUserStatisticsFromDB(timeRange: TimeRange): Promise<Dat
           FROM users u
           CROSS JOIN date_range dr
           LEFT JOIN message_request mr ON u.id = mr.user_id
+            AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '29 days') AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           WHERE u.deleted_at IS NULL
@@ -153,6 +223,8 @@ export async function getUserStatisticsFromDB(timeRange: TimeRange): Promise<Dat
           FROM users u
           CROSS JOIN date_range dr
           LEFT JOIN message_request mr ON u.id = mr.user_id
+            AND mr.created_at >= ((DATE_TRUNC('month', CURRENT_TIMESTAMP AT TIME ZONE ${timezone})) AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           WHERE u.deleted_at IS NULL
@@ -229,6 +301,8 @@ export async function getKeyStatisticsFromDB(
           CROSS JOIN hour_range hr
           LEFT JOIN message_request mr ON mr.key = k.key
             AND mr.user_id = ${userId}
+            AND mr.created_at >= (DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND DATE_TRUNC('hour', mr.created_at AT TIME ZONE ${timezone}) = hr.hour
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           GROUP BY k.id, k.name, hr.hour
@@ -270,6 +344,8 @@ export async function getKeyStatisticsFromDB(
           CROSS JOIN date_range dr
           LEFT JOIN message_request mr ON mr.key = k.key
             AND mr.user_id = ${userId}
+            AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '6 days') AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           GROUP BY k.id, k.name, dr.date
@@ -311,6 +387,8 @@ export async function getKeyStatisticsFromDB(
           CROSS JOIN date_range dr
           LEFT JOIN message_request mr ON mr.key = k.key
             AND mr.user_id = ${userId}
+            AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '29 days') AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           GROUP BY k.id, k.name, dr.date
@@ -352,6 +430,8 @@ export async function getKeyStatisticsFromDB(
           CROSS JOIN date_range dr
           LEFT JOIN message_request mr ON mr.key = k.key
             AND mr.user_id = ${userId}
+            AND mr.created_at >= ((DATE_TRUNC('month', CURRENT_TIMESTAMP AT TIME ZONE ${timezone})) AT TIME ZONE ${timezone})
+            AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
           GROUP BY k.id, k.name, dr.date
@@ -423,21 +503,23 @@ export async function getMixedStatisticsFromDB(
           WHERE user_id = ${userId}
             AND deleted_at IS NULL
         ),
-        hourly_stats AS (
-          SELECT
-            k.id AS key_id,
-            k.name AS key_name,
-            hr.hour,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM user_keys k
-          CROSS JOIN hour_range hr
-          LEFT JOIN message_request mr ON mr.key = k.key
-            AND mr.user_id = ${userId}
-            AND DATE_TRUNC('hour', mr.created_at AT TIME ZONE ${timezone}) = hr.hour
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY k.id, k.name, hr.hour
-        )
+         hourly_stats AS (
+           SELECT
+             k.id AS key_id,
+             k.name AS key_name,
+             hr.hour,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM user_keys k
+           CROSS JOIN hour_range hr
+           LEFT JOIN message_request mr ON mr.key = k.key
+             AND mr.user_id = ${userId}
+             AND mr.created_at >= (DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND DATE_TRUNC('hour', mr.created_at AT TIME ZONE ${timezone}) = hr.hour
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY k.id, k.name, hr.hour
+         )
         SELECT
           key_id,
           key_name,
@@ -457,17 +539,19 @@ export async function getMixedStatisticsFromDB(
             '1 hour'::interval
           ) AS hour
         ),
-        hourly_stats AS (
-          SELECT
-            hr.hour,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM hour_range hr
-          LEFT JOIN message_request mr ON DATE_TRUNC('hour', mr.created_at AT TIME ZONE ${timezone}) = hr.hour
-            AND mr.user_id != ${userId}
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY hr.hour
-        )
+         hourly_stats AS (
+           SELECT
+             hr.hour,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM hour_range hr
+            LEFT JOIN message_request mr ON DATE_TRUNC('hour', mr.created_at AT TIME ZONE ${timezone}) = hr.hour
+             AND mr.created_at >= (DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', TIMEZONE(${timezone}, NOW())) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND mr.user_id != ${userId}
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY hr.hour
+         )
         SELECT
           -1 AS user_id,
           '其他用户' AS user_name,
@@ -495,21 +579,23 @@ export async function getMixedStatisticsFromDB(
           WHERE user_id = ${userId}
             AND deleted_at IS NULL
         ),
-        daily_stats AS (
-          SELECT
-            k.id AS key_id,
-            k.name AS key_name,
-            dr.date,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM user_keys k
-          CROSS JOIN date_range dr
-          LEFT JOIN message_request mr ON mr.key = k.key
-            AND mr.user_id = ${userId}
-            AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY k.id, k.name, dr.date
-        )
+         daily_stats AS (
+           SELECT
+             k.id AS key_id,
+             k.name AS key_name,
+             dr.date,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM user_keys k
+           CROSS JOIN date_range dr
+           LEFT JOIN message_request mr ON mr.key = k.key
+             AND mr.user_id = ${userId}
+             AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '6 days') AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY k.id, k.name, dr.date
+         )
         SELECT
           key_id,
           key_name,
@@ -529,17 +615,19 @@ export async function getMixedStatisticsFromDB(
             '1 day'::interval
           )::date AS date
         ),
-        daily_stats AS (
-          SELECT
-            dr.date,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM date_range dr
-          LEFT JOIN message_request mr ON (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
-            AND mr.user_id != ${userId}
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY dr.date
-        )
+         daily_stats AS (
+           SELECT
+             dr.date,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM date_range dr
+            LEFT JOIN message_request mr ON (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
+             AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '6 days') AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND mr.user_id != ${userId}
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY dr.date
+         )
         SELECT
           -1 AS user_id,
           '其他用户' AS user_name,
@@ -567,21 +655,23 @@ export async function getMixedStatisticsFromDB(
           WHERE user_id = ${userId}
             AND deleted_at IS NULL
         ),
-        daily_stats AS (
-          SELECT
-            k.id AS key_id,
-            k.name AS key_name,
-            dr.date,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM user_keys k
-          CROSS JOIN date_range dr
-          LEFT JOIN message_request mr ON mr.key = k.key
-            AND mr.user_id = ${userId}
-            AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY k.id, k.name, dr.date
-        )
+         daily_stats AS (
+           SELECT
+             k.id AS key_id,
+             k.name AS key_name,
+             dr.date,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM user_keys k
+           CROSS JOIN date_range dr
+           LEFT JOIN message_request mr ON mr.key = k.key
+             AND mr.user_id = ${userId}
+             AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '29 days') AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY k.id, k.name, dr.date
+         )
         SELECT
           key_id,
           key_name,
@@ -601,17 +691,19 @@ export async function getMixedStatisticsFromDB(
             '1 day'::interval
           )::date AS date
         ),
-        daily_stats AS (
-          SELECT
-            dr.date,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM date_range dr
-          LEFT JOIN message_request mr ON (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
-            AND mr.user_id != ${userId}
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY dr.date
-        )
+         daily_stats AS (
+           SELECT
+             dr.date,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM date_range dr
+            LEFT JOIN message_request mr ON (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
+             AND mr.created_at >= ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) - INTERVAL '29 days') AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND mr.user_id != ${userId}
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY dr.date
+         )
         SELECT
           -1 AS user_id,
           '其他用户' AS user_name,
@@ -639,21 +731,23 @@ export async function getMixedStatisticsFromDB(
           WHERE user_id = ${userId}
             AND deleted_at IS NULL
         ),
-        daily_stats AS (
-          SELECT
-            k.id AS key_id,
-            k.name AS key_name,
-            dr.date,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM user_keys k
-          CROSS JOIN date_range dr
-          LEFT JOIN message_request mr ON mr.key = k.key
-            AND mr.user_id = ${userId}
-            AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY k.id, k.name, dr.date
-        )
+         daily_stats AS (
+           SELECT
+             k.id AS key_id,
+             k.name AS key_name,
+             dr.date,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM user_keys k
+           CROSS JOIN date_range dr
+           LEFT JOIN message_request mr ON mr.key = k.key
+             AND mr.user_id = ${userId}
+             AND mr.created_at >= ((DATE_TRUNC('month', CURRENT_TIMESTAMP AT TIME ZONE ${timezone})) AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY k.id, k.name, dr.date
+         )
         SELECT
           key_id,
           key_name,
@@ -673,17 +767,19 @@ export async function getMixedStatisticsFromDB(
             '1 day'::interval
           )::date AS date
         ),
-        daily_stats AS (
-          SELECT
-            dr.date,
-            COUNT(mr.id) AS api_calls,
-            COALESCE(SUM(mr.cost_usd), 0) AS total_cost
-          FROM date_range dr
-          LEFT JOIN message_request mr ON (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
-            AND mr.user_id != ${userId}
-            AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
-          GROUP BY dr.date
-        )
+         daily_stats AS (
+           SELECT
+             dr.date,
+             COUNT(mr.id) AS api_calls,
+             COALESCE(SUM(mr.cost_usd), 0) AS total_cost
+           FROM date_range dr
+            LEFT JOIN message_request mr ON (mr.created_at AT TIME ZONE ${timezone})::date = dr.date
+             AND mr.created_at >= ((DATE_TRUNC('month', CURRENT_TIMESTAMP AT TIME ZONE ${timezone})) AT TIME ZONE ${timezone})
+             AND mr.created_at < ((DATE_TRUNC('day', CURRENT_TIMESTAMP AT TIME ZONE ${timezone}) + INTERVAL '1 day') AT TIME ZONE ${timezone})
+             AND mr.user_id != ${userId}
+             AND mr.deleted_at IS NULL AND (mr.blocked_by IS NULL OR mr.blocked_by <> 'warmup')
+           GROUP BY dr.date
+         )
         SELECT
           -1 AS user_id,
           '其他用户' AS user_name,
@@ -747,16 +843,9 @@ export async function sumKeyTotalCostById(
   keyId: number,
   maxAgeDays: number = 365
 ): Promise<number> {
-  // 先查询 key 字符串
-  const keyRecord = await db
-    .select({ key: keys.key })
-    .from(keys)
-    .where(eq(keys.id, keyId))
-    .limit(1);
-
-  if (!keyRecord || keyRecord.length === 0) return 0;
-
-  return sumKeyTotalCost(keyRecord[0].key, maxAgeDays);
+  const keyString = await getKeyStringByIdCached(keyId);
+  if (!keyString) return 0;
+  return sumKeyTotalCost(keyString, maxAgeDays);
 }
 
 /**
@@ -945,16 +1034,8 @@ export async function sumKeyCostInTimeRange(
   startTime: Date,
   endTime: Date
 ): Promise<number> {
-  // 注意:message_request.key 存储的是 API key 字符串,需要先查询 keys 表获取 key 值
-  const keyRecord = await db
-    .select({ key: keys.key })
-    .from(keys)
-    .where(eq(keys.id, keyId))
-    .limit(1);
-
-  if (!keyRecord || keyRecord.length === 0) return 0;
-
-  const keyString = keyRecord[0].key;
+  const keyString = await getKeyStringByIdCached(keyId);
+  if (!keyString) return 0;
 
   const result = await db
     .select({ total: sql<number>`COALESCE(SUM(${messageRequest.costUsd}), 0)` })
@@ -972,6 +1053,163 @@ export async function sumKeyCostInTimeRange(
   return Number(result[0]?.total || 0);
 }
 
+export interface QuotaCostRanges {
+  range5h: { startTime: Date; endTime: Date };
+  rangeDaily: { startTime: Date; endTime: Date };
+  rangeWeekly: { startTime: Date; endTime: Date };
+  rangeMonthly: { startTime: Date; endTime: Date };
+}
+
+export interface QuotaCostSummary {
+  cost5h: number;
+  costDaily: number;
+  costWeekly: number;
+  costMonthly: number;
+  costTotal: number;
+}
+
+/**
+ * 合并查询:一次 SQL 返回用户各周期消费与总消费
+ *
+ * 说明:
+ * - 通过 FILTER 子句避免多次往返/重复扫描
+ * - scanStart/scanEnd 仅用于缩小扫描范围(不改变语义)
+ * - total 使用 maxAgeDays 做时间截断(与 sumUserTotalCost 语义一致)
+ */
+export async function sumUserQuotaCosts(
+  userId: number,
+  ranges: QuotaCostRanges,
+  maxAgeDays: number = 365
+): Promise<QuotaCostSummary> {
+  const cutoffDate =
+    Number.isFinite(maxAgeDays) && maxAgeDays > 0
+      ? new Date(Date.now() - Math.floor(maxAgeDays) * 24 * 60 * 60 * 1000)
+      : null;
+
+  const scanStart = cutoffDate
+    ? new Date(
+        Math.min(
+          ranges.range5h.startTime.getTime(),
+          ranges.rangeDaily.startTime.getTime(),
+          ranges.rangeWeekly.startTime.getTime(),
+          ranges.rangeMonthly.startTime.getTime(),
+          cutoffDate.getTime()
+        )
+      )
+    : null;
+  const scanEnd = new Date(
+    Math.max(
+      ranges.range5h.endTime.getTime(),
+      ranges.rangeDaily.endTime.getTime(),
+      ranges.rangeWeekly.endTime.getTime(),
+      ranges.rangeMonthly.endTime.getTime(),
+      Date.now()
+    )
+  );
+
+  const costTotal = cutoffDate
+    ? sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${cutoffDate}), 0)`
+    : sql<string>`COALESCE(SUM(${messageRequest.costUsd}), 0)`;
+
+  const [row] = await db
+    .select({
+      cost5h: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.range5h.startTime} AND ${messageRequest.createdAt} < ${ranges.range5h.endTime}), 0)`,
+      costDaily: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.rangeDaily.startTime} AND ${messageRequest.createdAt} < ${ranges.rangeDaily.endTime}), 0)`,
+      costWeekly: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.rangeWeekly.startTime} AND ${messageRequest.createdAt} < ${ranges.rangeWeekly.endTime}), 0)`,
+      costMonthly: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.rangeMonthly.startTime} AND ${messageRequest.createdAt} < ${ranges.rangeMonthly.endTime}), 0)`,
+      costTotal,
+    })
+    .from(messageRequest)
+    .where(
+      and(
+        eq(messageRequest.userId, userId),
+        isNull(messageRequest.deletedAt),
+        EXCLUDE_WARMUP_CONDITION,
+        ...(scanStart ? [gte(messageRequest.createdAt, scanStart)] : []),
+        lt(messageRequest.createdAt, scanEnd)
+      )
+    );
+
+  return {
+    cost5h: Number(row?.cost5h ?? 0),
+    costDaily: Number(row?.costDaily ?? 0),
+    costWeekly: Number(row?.costWeekly ?? 0),
+    costMonthly: Number(row?.costMonthly ?? 0),
+    costTotal: Number(row?.costTotal ?? 0),
+  };
+}
+
+/**
+ * 合并查询:一次 SQL 返回 Key 各周期消费与总消费(通过 keyId)
+ */
+export async function sumKeyQuotaCostsById(
+  keyId: number,
+  ranges: QuotaCostRanges,
+  maxAgeDays: number = 365
+): Promise<QuotaCostSummary> {
+  const keyString = await getKeyStringByIdCached(keyId);
+  if (!keyString) {
+    return { cost5h: 0, costDaily: 0, costWeekly: 0, costMonthly: 0, costTotal: 0 };
+  }
+
+  const cutoffDate =
+    Number.isFinite(maxAgeDays) && maxAgeDays > 0
+      ? new Date(Date.now() - Math.floor(maxAgeDays) * 24 * 60 * 60 * 1000)
+      : null;
+
+  const scanStart = cutoffDate
+    ? new Date(
+        Math.min(
+          ranges.range5h.startTime.getTime(),
+          ranges.rangeDaily.startTime.getTime(),
+          ranges.rangeWeekly.startTime.getTime(),
+          ranges.rangeMonthly.startTime.getTime(),
+          cutoffDate.getTime()
+        )
+      )
+    : null;
+  const scanEnd = new Date(
+    Math.max(
+      ranges.range5h.endTime.getTime(),
+      ranges.rangeDaily.endTime.getTime(),
+      ranges.rangeWeekly.endTime.getTime(),
+      ranges.rangeMonthly.endTime.getTime(),
+      Date.now()
+    )
+  );
+
+  const costTotal = cutoffDate
+    ? sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${cutoffDate}), 0)`
+    : sql<string>`COALESCE(SUM(${messageRequest.costUsd}), 0)`;
+
+  const [row] = await db
+    .select({
+      cost5h: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.range5h.startTime} AND ${messageRequest.createdAt} < ${ranges.range5h.endTime}), 0)`,
+      costDaily: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.rangeDaily.startTime} AND ${messageRequest.createdAt} < ${ranges.rangeDaily.endTime}), 0)`,
+      costWeekly: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.rangeWeekly.startTime} AND ${messageRequest.createdAt} < ${ranges.rangeWeekly.endTime}), 0)`,
+      costMonthly: sql<string>`COALESCE(SUM(${messageRequest.costUsd}) FILTER (WHERE ${messageRequest.createdAt} >= ${ranges.rangeMonthly.startTime} AND ${messageRequest.createdAt} < ${ranges.rangeMonthly.endTime}), 0)`,
+      costTotal,
+    })
+    .from(messageRequest)
+    .where(
+      and(
+        eq(messageRequest.key, keyString),
+        isNull(messageRequest.deletedAt),
+        EXCLUDE_WARMUP_CONDITION,
+        ...(scanStart ? [gte(messageRequest.createdAt, scanStart)] : []),
+        lt(messageRequest.createdAt, scanEnd)
+      )
+    );
+
+  return {
+    cost5h: Number(row?.cost5h ?? 0),
+    costDaily: Number(row?.costDaily ?? 0),
+    costWeekly: Number(row?.costWeekly ?? 0),
+    costMonthly: Number(row?.costMonthly ?? 0),
+    costTotal: Number(row?.costTotal ?? 0),
+  };
+}
+
 export interface CostEntryInTimeRange {
   id: number;
   createdAt: Date;
@@ -1056,16 +1294,8 @@ export async function findKeyCostEntriesInTimeRange(
   startTime: Date,
   endTime: Date
 ): Promise<CostEntryInTimeRange[]> {
-  // 注意:message_request.key 存储的是 API key 字符串,需要先查询 keys 表获取 key 值
-  const keyRecord = await db
-    .select({ key: keys.key })
-    .from(keys)
-    .where(eq(keys.id, keyId))
-    .limit(1);
-
-  if (!keyRecord || keyRecord.length === 0) return [];
-
-  const keyString = keyRecord[0].key;
+  const keyString = await getKeyStringByIdCached(keyId);
+  if (!keyString) return [];
 
   const rows = await db
     .select({
@@ -1139,14 +1369,8 @@ export async function getRateLimitEventStats(
   // Key ID 过滤需要先查询 key 字符串
   let keyString: string | null = null;
   if (key_id !== undefined) {
-    const keyRecord = await db
-      .select({ key: keys.key })
-      .from(keys)
-      .where(eq(keys.id, key_id))
-      .limit(1);
-
-    if (keyRecord && keyRecord.length > 0) {
-      keyString = keyRecord[0].key;
+    keyString = await getKeyStringByIdCached(key_id);
+    if (keyString) {
       conditions.push(`${messageRequest.key.name} = $${paramIndex++}`);
       params.push(keyString);
     } else {

+ 360 - 46
src/repository/usage-logs.ts

@@ -1,6 +1,6 @@
-"use server";
+import "server-only";
 
-import { and, desc, eq, isNull, sql } from "drizzle-orm";
+import { and, desc, eq, gte, isNull, lt, sql } from "drizzle-orm";
 import { db } from "@/drizzle/db";
 import { keys as keysTable, messageRequest, providers, users } from "@/drizzle/schema";
 import { buildUnifiedSpecialSettings } from "@/lib/utils/special-settings";
@@ -152,12 +152,12 @@ export async function findUsageLogsBatch(
 
   if (startTime !== undefined) {
     const startDate = new Date(startTime);
-    conditions.push(sql`${messageRequest.createdAt} >= ${startDate.toISOString()}::timestamptz`);
+    conditions.push(gte(messageRequest.createdAt, startDate));
   }
 
   if (endTime !== undefined) {
     const endDate = new Date(endTime);
-    conditions.push(sql`${messageRequest.createdAt} < ${endDate.toISOString()}::timestamptz`);
+    conditions.push(lt(messageRequest.createdAt, endDate));
   }
 
   if (statusCode !== undefined) {
@@ -281,6 +281,263 @@ export async function findUsageLogsBatch(
   return { logs, nextCursor, hasMore };
 }
 
+export interface UsageLogSlimFilters {
+  keyString: string;
+  /** Session ID(精确匹配;空字符串/空白视为不筛选) */
+  sessionId?: string;
+  /** 开始时间戳(毫秒),用于 >= 比较 */
+  startTime?: number;
+  /** 结束时间戳(毫秒),用于 < 比较 */
+  endTime?: number;
+  statusCode?: number;
+  /** 排除 200 状态码(筛选所有非 200 的请求,包括 NULL) */
+  excludeStatusCode200?: boolean;
+  model?: string;
+  endpoint?: string;
+  /** 最低重试次数(provider_chain 长度 - 1) */
+  minRetryCount?: number;
+  page?: number;
+  pageSize?: number;
+}
+
+export interface UsageLogSlimRow {
+  id: number;
+  createdAt: Date | null;
+  model: string | null;
+  originalModel: string | null;
+  endpoint: string | null;
+  statusCode: number | null;
+  inputTokens: number | null;
+  outputTokens: number | null;
+  costUsd: string | null;
+  durationMs: number | null;
+  cacheCreationInputTokens: number | null;
+  cacheReadInputTokens: number | null;
+  cacheCreation5mInputTokens: number | null;
+  cacheCreation1hInputTokens: number | null;
+  cacheTtlApplied: string | null;
+}
+
+// my-usage logs:分页需要 totalPages,COUNT(*) 在大表上仍可能较重。
+// 这里对“相同筛选条件”的 total 做短 TTL 缓存,避免用户翻页/轮询时重复 COUNT。
+const USAGE_LOG_SLIM_TOTAL_CACHE_TTL_MS = 10 * 1000; // 10 秒
+const USAGE_LOG_SLIM_TOTAL_CACHE_MAX_SIZE = 1000;
+const usageLogSlimTotalCache = new Map<string, { total: number; expiresAt: number }>();
+
+function getUsageLogSlimTotalFromCache(key: string): number | null {
+  const now = Date.now();
+  const cached = usageLogSlimTotalCache.get(key);
+  if (!cached) return null;
+  if (cached.expiresAt <= now) {
+    usageLogSlimTotalCache.delete(key);
+    return null;
+  }
+
+  // LRU-like bump
+  usageLogSlimTotalCache.delete(key);
+  usageLogSlimTotalCache.set(key, cached);
+  return cached.total;
+}
+
+function setUsageLogSlimTotalToCache(key: string, total: number): void {
+  const now = Date.now();
+
+  if (usageLogSlimTotalCache.size >= USAGE_LOG_SLIM_TOTAL_CACHE_MAX_SIZE) {
+    for (const [k, v] of usageLogSlimTotalCache) {
+      if (v.expiresAt <= now) {
+        usageLogSlimTotalCache.delete(k);
+      }
+    }
+
+    if (usageLogSlimTotalCache.size >= USAGE_LOG_SLIM_TOTAL_CACHE_MAX_SIZE) {
+      const evictCount = Math.max(1, Math.ceil(USAGE_LOG_SLIM_TOTAL_CACHE_MAX_SIZE * 0.1));
+      let remaining = evictCount;
+
+      for (const k of usageLogSlimTotalCache.keys()) {
+        usageLogSlimTotalCache.delete(k);
+        remaining -= 1;
+        if (remaining <= 0) break;
+      }
+    }
+  }
+
+  usageLogSlimTotalCache.set(key, {
+    total,
+    expiresAt: now + USAGE_LOG_SLIM_TOTAL_CACHE_TTL_MS,
+  });
+}
+
+export async function findUsageLogsForKeySlim(
+  filters: UsageLogSlimFilters
+): Promise<{ logs: UsageLogSlimRow[]; total: number }> {
+  const {
+    keyString,
+    sessionId,
+    startTime,
+    endTime,
+    statusCode,
+    excludeStatusCode200,
+    model,
+    endpoint,
+    minRetryCount,
+    page = 1,
+    pageSize = 50,
+  } = filters;
+
+  const safePage = page > 0 ? page : 1;
+  const safePageSize = Math.min(100, Math.max(1, pageSize));
+
+  const conditions = [
+    isNull(messageRequest.deletedAt),
+    eq(messageRequest.key, keyString),
+    EXCLUDE_WARMUP_CONDITION,
+  ];
+
+  const trimmedSessionId = sessionId?.trim();
+  if (trimmedSessionId) {
+    conditions.push(eq(messageRequest.sessionId, trimmedSessionId));
+  }
+
+  const totalCacheKey = [
+    keyString,
+    trimmedSessionId ?? "",
+    startTime ?? "",
+    endTime ?? "",
+    statusCode ?? "",
+    excludeStatusCode200 ? "1" : "0",
+    model ?? "",
+    endpoint ?? "",
+    minRetryCount ?? "",
+  ].join("\u0001");
+
+  if (startTime !== undefined) {
+    const startDate = new Date(startTime);
+    conditions.push(gte(messageRequest.createdAt, startDate));
+  }
+
+  if (endTime !== undefined) {
+    const endDate = new Date(endTime);
+    conditions.push(lt(messageRequest.createdAt, endDate));
+  }
+
+  if (statusCode !== undefined) {
+    conditions.push(eq(messageRequest.statusCode, statusCode));
+  } else if (excludeStatusCode200) {
+    conditions.push(
+      sql`(${messageRequest.statusCode} IS NULL OR ${messageRequest.statusCode} <> 200)`
+    );
+  }
+
+  if (model) {
+    conditions.push(eq(messageRequest.model, model));
+  }
+
+  if (endpoint) {
+    conditions.push(eq(messageRequest.endpoint, endpoint));
+  }
+
+  if (minRetryCount !== undefined) {
+    conditions.push(
+      sql`GREATEST(COALESCE(jsonb_array_length(${messageRequest.providerChain}) - 1, 0), 0) >= ${minRetryCount}`
+    );
+  }
+
+  const offset = (safePage - 1) * safePageSize;
+  const results = await db
+    .select({
+      id: messageRequest.id,
+      createdAt: messageRequest.createdAt,
+      model: messageRequest.model,
+      originalModel: messageRequest.originalModel,
+      endpoint: messageRequest.endpoint,
+      statusCode: messageRequest.statusCode,
+      inputTokens: messageRequest.inputTokens,
+      outputTokens: messageRequest.outputTokens,
+      costUsd: messageRequest.costUsd,
+      durationMs: messageRequest.durationMs,
+      cacheCreationInputTokens: messageRequest.cacheCreationInputTokens,
+      cacheReadInputTokens: messageRequest.cacheReadInputTokens,
+      cacheCreation5mInputTokens: messageRequest.cacheCreation5mInputTokens,
+      cacheCreation1hInputTokens: messageRequest.cacheCreation1hInputTokens,
+      cacheTtlApplied: messageRequest.cacheTtlApplied,
+    })
+    .from(messageRequest)
+    .where(and(...conditions))
+    .orderBy(desc(messageRequest.createdAt), desc(messageRequest.id))
+    .limit(safePageSize + 1)
+    .offset(offset);
+
+  const hasMore = results.length > safePageSize;
+  const pageRows = hasMore ? results.slice(0, safePageSize) : results;
+
+  let total = offset + pageRows.length;
+
+  const cachedTotal = getUsageLogSlimTotalFromCache(totalCacheKey);
+  if (cachedTotal !== null) {
+    total = Math.max(cachedTotal, total);
+    return {
+      logs: pageRows.map((row) => ({ ...row, costUsd: row.costUsd?.toString() ?? null })),
+      total,
+    };
+  }
+
+  if (pageRows.length === 0 && offset > 0) {
+    const countResults = await db
+      .select({ totalRows: sql<number>`count(*)::double precision` })
+      .from(messageRequest)
+      .where(and(...conditions));
+    total = countResults[0]?.totalRows ?? 0;
+  } else if (hasMore) {
+    const countResults = await db
+      .select({ totalRows: sql<number>`count(*)::double precision` })
+      .from(messageRequest)
+      .where(and(...conditions));
+    total = countResults[0]?.totalRows ?? 0;
+  }
+
+  const logs: UsageLogSlimRow[] = pageRows.map((row) => ({
+    ...row,
+    costUsd: row.costUsd?.toString() ?? null,
+  }));
+
+  setUsageLogSlimTotalToCache(totalCacheKey, total);
+  return { logs, total };
+}
+
+const DISTINCT_KEY_OPTIONS_CACHE_TTL_MS = 5 * 60 * 1000; // 5 分钟
+const DISTINCT_KEY_OPTIONS_CACHE_MAX_SIZE = 200;
+
+const distinctModelsByKeyCache = new Map<string, { data: string[]; expiresAt: number }>();
+const distinctEndpointsByKeyCache = new Map<string, { data: string[]; expiresAt: number }>();
+
+function setDistinctKeyOptionsCache(
+  cache: Map<string, { data: string[]; expiresAt: number }>,
+  key: string,
+  data: string[]
+): void {
+  const now = Date.now();
+  if (cache.size >= DISTINCT_KEY_OPTIONS_CACHE_MAX_SIZE) {
+    for (const [k, v] of cache) {
+      if (v.expiresAt <= now) {
+        cache.delete(k);
+      }
+    }
+
+    if (cache.size >= DISTINCT_KEY_OPTIONS_CACHE_MAX_SIZE) {
+      const evictCount = Math.max(1, Math.ceil(DISTINCT_KEY_OPTIONS_CACHE_MAX_SIZE * 0.1));
+      let remaining = evictCount;
+
+      for (const k of cache.keys()) {
+        cache.delete(k);
+        remaining -= 1;
+        if (remaining <= 0) break;
+      }
+    }
+  }
+
+  cache.set(key, { data, expiresAt: now + DISTINCT_KEY_OPTIONS_CACHE_TTL_MS });
+}
+
 export async function getTotalUsageForKey(keyString: string): Promise<number> {
   const [row] = await db
     .select({ total: sql<string>`COALESCE(sum(${messageRequest.costUsd}), 0)` })
@@ -297,33 +554,61 @@ export async function getTotalUsageForKey(keyString: string): Promise<number> {
 }
 
 export async function getDistinctModelsForKey(keyString: string): Promise<string[]> {
+  const now = Date.now();
+  const cached = distinctModelsByKeyCache.get(keyString);
+  if (cached && cached.expiresAt > now) {
+    // LRU-like bump + sliding TTL
+    cached.expiresAt = now + DISTINCT_KEY_OPTIONS_CACHE_TTL_MS;
+    distinctModelsByKeyCache.delete(keyString);
+    distinctModelsByKeyCache.set(keyString, cached);
+    return cached.data;
+  }
+
   const result = await db.execute(
     sql`select distinct ${messageRequest.model} as model
         from ${messageRequest}
         where ${messageRequest.key} = ${keyString}
           and ${messageRequest.deletedAt} is null
+          and (${EXCLUDE_WARMUP_CONDITION})
           and ${messageRequest.model} is not null
         order by model asc`
   );
 
-  return Array.from(result)
+  const models = Array.from(result)
     .map((row) => (row as { model?: string }).model)
     .filter((model): model is string => !!model && model.trim().length > 0);
+
+  setDistinctKeyOptionsCache(distinctModelsByKeyCache, keyString, models);
+  return models;
 }
 
 export async function getDistinctEndpointsForKey(keyString: string): Promise<string[]> {
+  const now = Date.now();
+  const cached = distinctEndpointsByKeyCache.get(keyString);
+  if (cached && cached.expiresAt > now) {
+    // LRU-like bump + sliding TTL
+    cached.expiresAt = now + DISTINCT_KEY_OPTIONS_CACHE_TTL_MS;
+    distinctEndpointsByKeyCache.delete(keyString);
+    distinctEndpointsByKeyCache.set(keyString, cached);
+    return cached.data;
+  }
+
   const result = await db.execute(
     sql`select distinct ${messageRequest.endpoint} as endpoint
         from ${messageRequest}
         where ${messageRequest.key} = ${keyString}
           and ${messageRequest.deletedAt} is null
+          and (${EXCLUDE_WARMUP_CONDITION})
           and ${messageRequest.endpoint} is not null
         order by endpoint asc`
   );
 
-  return Array.from(result)
+  const endpoints = Array.from(result)
     .map((row) => (row as { endpoint?: string }).endpoint)
     .filter((endpoint): endpoint is string => !!endpoint && endpoint.trim().length > 0);
+
+  setDistinctKeyOptionsCache(distinctEndpointsByKeyCache, keyString, endpoints);
+  return endpoints;
 }
 
 /**
@@ -347,6 +632,9 @@ export async function findUsageLogsWithDetails(filters: UsageLogFilters): Promis
     pageSize = 50,
   } = filters;
 
+  const safePage = page > 0 ? page : 1;
+  const safePageSize = Math.min(200, Math.max(1, pageSize));
+
   // 构建查询条件
   const conditions = [isNull(messageRequest.deletedAt)];
 
@@ -372,12 +660,12 @@ export async function findUsageLogsWithDetails(filters: UsageLogFilters): Promis
   // PostgreSQL 会自动处理时区转换
   if (startTime !== undefined) {
     const startDate = new Date(startTime);
-    conditions.push(sql`${messageRequest.createdAt} >= ${startDate.toISOString()}::timestamptz`);
+    conditions.push(gte(messageRequest.createdAt, startDate));
   }
 
   if (endTime !== undefined) {
     const endDate = new Date(endTime);
-    conditions.push(sql`${messageRequest.createdAt} < ${endDate.toISOString()}::timestamptz`);
+    conditions.push(lt(messageRequest.createdAt, endDate));
   }
 
   if (statusCode !== undefined) {
@@ -404,37 +692,47 @@ export async function findUsageLogsWithDetails(filters: UsageLogFilters): Promis
     );
   }
 
-  // 查询总数和统计数据(添加 innerJoin keysTable 以支持 keyId 过滤)
-  const [summaryResult] = await db
-    .select({
-      // total:用于分页/审计,必须包含 warmup
-      totalRows: sql<number>`count(*)::double precision`,
-      // summary:所有统计字段必须排除 warmup(不计入任何统计)
-      totalRequests: sql<number>`count(*) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision`,
-      totalCost: sql<string>`COALESCE(sum(${messageRequest.costUsd}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION}), 0)`,
-      totalInputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
-      totalOutputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
-      totalCacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
-      totalCacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
-      totalCacheCreation5mTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation5mInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
-      totalCacheCreation1hTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation1hInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
-    })
-    .from(messageRequest)
-    .innerJoin(keysTable, eq(messageRequest.key, keysTable.key))
-    .where(and(...conditions));
-
-  const total = summaryResult?.totalRows ?? 0;
-  const totalRequests = summaryResult?.totalRequests ?? 0;
-  const totalCost = parseFloat(summaryResult?.totalCost ?? "0");
-  const totalTokens =
-    (summaryResult?.totalInputTokens ?? 0) +
-    (summaryResult?.totalOutputTokens ?? 0) +
-    (summaryResult?.totalCacheCreationTokens ?? 0) +
-    (summaryResult?.totalCacheReadTokens ?? 0);
+  const offset = (safePage - 1) * safePageSize;
+
+  // 查询总数和统计数据(仅在需要 keyId 过滤时才 join keysTable,避免无效 join)
+  const summaryQuery =
+    keyId === undefined
+      ? db
+          .select({
+            // total:用于分页/审计,必须包含 warmup
+            totalRows: sql<number>`count(*)::double precision`,
+            // summary:所有统计字段必须排除 warmup(不计入任何统计)
+            totalRequests: sql<number>`count(*) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision`,
+            totalCost: sql<string>`COALESCE(sum(${messageRequest.costUsd}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION}), 0)`,
+            totalInputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalOutputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheCreation5mTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation5mInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheCreation1hTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation1hInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+          })
+          .from(messageRequest)
+          .where(and(...conditions))
+      : db
+          .select({
+            // total:用于分页/审计,必须包含 warmup
+            totalRows: sql<number>`count(*)::double precision`,
+            // summary:所有统计字段必须排除 warmup(不计入任何统计)
+            totalRequests: sql<number>`count(*) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision`,
+            totalCost: sql<string>`COALESCE(sum(${messageRequest.costUsd}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION}), 0)`,
+            totalInputTokens: sql<number>`COALESCE(sum(${messageRequest.inputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalOutputTokens: sql<number>`COALESCE(sum(${messageRequest.outputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheCreationTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreationInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheReadTokens: sql<number>`COALESCE(sum(${messageRequest.cacheReadInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheCreation5mTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation5mInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+            totalCacheCreation1hTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation1hInputTokens}) FILTER (WHERE ${EXCLUDE_WARMUP_CONDITION})::double precision, 0::double precision)`,
+          })
+          .from(messageRequest)
+          .innerJoin(keysTable, eq(messageRequest.key, keysTable.key))
+          .where(and(...conditions));
 
   // 查询分页数据(使用 LEFT JOIN 以包含被拦截的请求)
-  const offset = (page - 1) * pageSize;
-  const results = await db
+  const logsQuery = db
     .select({
       id: messageRequest.id,
       createdAt: messageRequest.createdAt,
@@ -472,10 +770,22 @@ export async function findUsageLogsWithDetails(filters: UsageLogFilters): Promis
     .innerJoin(keysTable, eq(messageRequest.key, keysTable.key))
     .leftJoin(providers, eq(messageRequest.providerId, providers.id)) // 改为 leftJoin
     .where(and(...conditions))
-    .orderBy(desc(messageRequest.createdAt))
-    .limit(pageSize)
+    .orderBy(desc(messageRequest.createdAt), desc(messageRequest.id))
+    .limit(safePageSize)
     .offset(offset);
 
+  const [summaryRows, results] = await Promise.all([summaryQuery, logsQuery]);
+  const summaryResult = summaryRows[0];
+
+  const total = summaryResult?.totalRows ?? 0;
+  const totalRequests = summaryResult?.totalRequests ?? 0;
+  const totalCost = parseFloat(summaryResult?.totalCost ?? "0");
+  const totalTokens =
+    (summaryResult?.totalInputTokens ?? 0) +
+    (summaryResult?.totalOutputTokens ?? 0) +
+    (summaryResult?.totalCacheCreationTokens ?? 0) +
+    (summaryResult?.totalCacheReadTokens ?? 0);
+
   const logs: UsageLogRow[] = results.map((row) => {
     const totalRowTokens =
       (row.inputTokens ?? 0) +
@@ -671,12 +981,12 @@ export async function findUsageLogsStats(
 
   if (startTime !== undefined) {
     const startDate = new Date(startTime);
-    conditions.push(sql`${messageRequest.createdAt} >= ${startDate.toISOString()}::timestamptz`);
+    conditions.push(gte(messageRequest.createdAt, startDate));
   }
 
   if (endTime !== undefined) {
     const endDate = new Date(endTime);
-    conditions.push(sql`${messageRequest.createdAt} < ${endDate.toISOString()}::timestamptz`);
+    conditions.push(lt(messageRequest.createdAt, endDate));
   }
 
   if (statusCode !== undefined) {
@@ -703,8 +1013,7 @@ export async function findUsageLogsStats(
 
   const statsConditions = [...conditions, EXCLUDE_WARMUP_CONDITION];
 
-  // 执行聚合查询(添加 innerJoin keysTable 以支持 keyId 过滤)
-  const [summaryResult] = await db
+  const baseQuery = db
     .select({
       totalRequests: sql<number>`count(*)::double precision`,
       totalCost: sql<string>`COALESCE(sum(${messageRequest.costUsd}), 0)`,
@@ -715,9 +1024,14 @@ export async function findUsageLogsStats(
       totalCacheCreation5mTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation5mInputTokens})::double precision, 0::double precision)`,
       totalCacheCreation1hTokens: sql<number>`COALESCE(sum(${messageRequest.cacheCreation1hInputTokens})::double precision, 0::double precision)`,
     })
-    .from(messageRequest)
-    .innerJoin(keysTable, eq(messageRequest.key, keysTable.key))
-    .where(and(...statsConditions));
+    .from(messageRequest);
+
+  const query =
+    keyId !== undefined
+      ? baseQuery.innerJoin(keysTable, eq(messageRequest.key, keysTable.key))
+      : baseQuery;
+
+  const [summaryResult] = await query.where(and(...statsConditions));
 
   const totalRequests = summaryResult?.totalRequests ?? 0;
   const totalCost = parseFloat(summaryResult?.totalCost ?? "0");

+ 3 - 4
tests/integration/provider-endpoint-sync-race.test.ts

@@ -115,8 +115,8 @@ run("Provider endpoint sync on edit (integration race)", () => {
 
       expect(previousAfter).toBeDefined();
       expect(previousAfter?.url).toBe(oldUrl);
-      expect(previousAfter?.deletedAt).toBeNull();
-      expect(previousAfter?.isEnabled).toBe(true);
+      expect(previousAfter?.deletedAt).not.toBeNull();
+      expect(previousAfter?.isEnabled).toBe(false);
 
       const activeEndpoints = await findProviderEndpointsByVendorAndType(
         vendorId!,
@@ -127,8 +127,7 @@ run("Provider endpoint sync on edit (integration race)", () => {
       const previousActive = activeEndpoints.filter((endpoint) => endpoint.url === oldUrl);
       expect(nextActive).toHaveLength(1);
       expect(nextActive[0]?.isEnabled).toBe(true);
-      expect(previousActive).toHaveLength(1);
-      expect(previousActive[0]?.isEnabled).toBe(true);
+      expect(previousActive).toHaveLength(0);
 
       const providerAfter = await findProviderById(created.id);
       expect(providerAfter?.url).toBe(nextUrl);

+ 14 - 0
tests/unit/actions/my-usage-concurrent-inherit.test.ts

@@ -28,8 +28,22 @@ vi.mock("@/lib/rate-limit/time-utils", () => ({
 const statisticsMock = {
   sumUserCostInTimeRange: vi.fn(async () => 0),
   sumUserTotalCost: vi.fn(async () => 0),
+  sumUserQuotaCosts: vi.fn(async () => ({
+    cost5h: 0,
+    costDaily: 0,
+    costWeekly: 0,
+    costMonthly: 0,
+    costTotal: 0,
+  })),
   sumKeyCostInTimeRange: vi.fn(async () => 0),
   sumKeyTotalCostById: vi.fn(async () => 0),
+  sumKeyQuotaCostsById: vi.fn(async () => ({
+    cost5h: 0,
+    costDaily: 0,
+    costWeekly: 0,
+    costMonthly: 0,
+    costTotal: 0,
+  })),
 };
 vi.mock("@/repository/statistics", () => statisticsMock);
 

+ 8 - 8
tests/unit/actions/my-usage-date-range-dst.test.ts

@@ -4,7 +4,7 @@ import { fromZonedTime } from "date-fns-tz";
 const mocks = vi.hoisted(() => ({
   getSession: vi.fn(),
   getSystemSettings: vi.fn(),
-  findUsageLogsWithDetails: vi.fn(),
+  findUsageLogsForKeySlim: vi.fn(),
   resolveSystemTimezone: vi.fn(),
 }));
 
@@ -20,7 +20,7 @@ vi.mock("@/repository/usage-logs", async (importOriginal) => {
   const actual = await importOriginal<typeof import("@/repository/usage-logs")>();
   return {
     ...actual,
-    findUsageLogsWithDetails: mocks.findUsageLogsWithDetails,
+    findUsageLogsForKeySlim: mocks.findUsageLogsForKeySlim,
   };
 });
 
@@ -43,15 +43,15 @@ describe("my-usage date range parsing", () => {
       billingModelSource: "original",
     });
 
-    mocks.findUsageLogsWithDetails.mockResolvedValue({ logs: [], total: 0 });
+    mocks.findUsageLogsForKeySlim.mockResolvedValue({ logs: [], total: 0 });
 
     const { getMyUsageLogs } = await import("@/actions/my-usage");
     const res = await getMyUsageLogs({ startDate: "2024-03-10", endDate: "2024-03-10" });
 
     expect(res.ok).toBe(true);
-    expect(mocks.findUsageLogsWithDetails).toHaveBeenCalledTimes(1);
+    expect(mocks.findUsageLogsForKeySlim).toHaveBeenCalledTimes(1);
 
-    const args = mocks.findUsageLogsWithDetails.mock.calls[0]?.[0];
+    const args = mocks.findUsageLogsForKeySlim.mock.calls[0]?.[0];
     expect(args.startTime).toBe(fromZonedTime("2024-03-10T00:00:00", tz).getTime());
     expect(args.endTime).toBe(fromZonedTime("2024-03-11T00:00:00", tz).getTime());
 
@@ -72,15 +72,15 @@ describe("my-usage date range parsing", () => {
       billingModelSource: "original",
     });
 
-    mocks.findUsageLogsWithDetails.mockResolvedValue({ logs: [], total: 0 });
+    mocks.findUsageLogsForKeySlim.mockResolvedValue({ logs: [], total: 0 });
 
     const { getMyUsageLogs } = await import("@/actions/my-usage");
     const res = await getMyUsageLogs({ startDate: "2024-11-03", endDate: "2024-11-03" });
 
     expect(res.ok).toBe(true);
-    expect(mocks.findUsageLogsWithDetails).toHaveBeenCalledTimes(1);
+    expect(mocks.findUsageLogsForKeySlim).toHaveBeenCalledTimes(1);
 
-    const args = mocks.findUsageLogsWithDetails.mock.calls[0]?.[0];
+    const args = mocks.findUsageLogsForKeySlim.mock.calls[0]?.[0];
     expect(args.startTime).toBe(fromZonedTime("2024-11-03T00:00:00", tz).getTime());
     expect(args.endTime).toBe(fromZonedTime("2024-11-04T00:00:00", tz).getTime());
 

+ 21 - 11
tests/unit/actions/my-usage-token-aggregation.test.ts

@@ -148,11 +148,9 @@ describe("my-usage token aggregation", () => {
     const res = await getMyTodayStats();
     expect(res.ok).toBe(true);
 
-    expect(capturedSelections.length).toBeGreaterThanOrEqual(2);
+    expect(capturedSelections.length).toBeGreaterThanOrEqual(1);
     expectNoIntTokenSum(capturedSelections[0], "inputTokens");
     expectNoIntTokenSum(capturedSelections[0], "outputTokens");
-    expectNoIntTokenSum(capturedSelections[1], "inputTokens");
-    expectNoIntTokenSum(capturedSelections[1], "outputTokens");
   });
 
   test("getMyStatsSummary: token sum 不应使用 ::int", async () => {
@@ -161,7 +159,6 @@ describe("my-usage token aggregation", () => {
     const capturedSelections: Array<Record<string, unknown>> = [];
     const selectQueue: any[] = [];
     selectQueue.push(createThenableQuery([]));
-    selectQueue.push(createThenableQuery([]));
 
     mocks.select.mockImplementation((selection: unknown) => {
       capturedSelections.push(selection as Record<string, unknown>);
@@ -196,13 +193,26 @@ describe("my-usage token aggregation", () => {
     const res = await getMyStatsSummary({ startDate: "2024-01-01", endDate: "2024-01-01" });
     expect(res.ok).toBe(true);
 
-    expect(capturedSelections).toHaveLength(2);
-
-    for (const selection of capturedSelections) {
-      expectNoIntTokenSum(selection, "inputTokens");
-      expectNoIntTokenSum(selection, "outputTokens");
-      expectNoIntTokenSum(selection, "cacheCreationTokens");
-      expectNoIntTokenSum(selection, "cacheReadTokens");
+    expect(capturedSelections).toHaveLength(1);
+
+    const selection = capturedSelections[0];
+    const tokenFields = [
+      "userInputTokens",
+      "userOutputTokens",
+      "userCacheCreationTokens",
+      "userCacheReadTokens",
+      "userCacheCreation5mTokens",
+      "userCacheCreation1hTokens",
+      "keyInputTokens",
+      "keyOutputTokens",
+      "keyCacheCreationTokens",
+      "keyCacheReadTokens",
+      "keyCacheCreation5mTokens",
+      "keyCacheCreation1hTokens",
+    ];
+
+    for (const field of tokenFields) {
+      expectNoIntTokenSum(selection, field);
     }
   });
 });

+ 170 - 33
tests/unit/actions/provider-endpoints.test.ts

@@ -10,6 +10,10 @@ const findProviderEndpointByIdMock = vi.fn();
 const softDeleteProviderEndpointMock = vi.fn();
 const tryDeleteProviderVendorIfEmptyMock = vi.fn();
 const updateProviderEndpointMock = vi.fn();
+const findProviderEndpointProbeLogsBatchMock = vi.fn();
+const findVendorTypeEndpointStatsBatchMock = vi.fn();
+const hasEnabledProviderReferenceForVendorTypeUrlMock = vi.fn();
+const findDashboardProviderEndpointsByVendorAndTypeMock = vi.fn();
 
 vi.mock("@/lib/auth", () => ({
   getSession: getSessionMock,
@@ -30,6 +34,7 @@ vi.mock("@/lib/logger", () => ({
 }));
 
 vi.mock("@/lib/endpoint-circuit-breaker", () => ({
+  getAllEndpointHealthStatusAsync: vi.fn(async () => ({})),
   getEndpointHealthInfo: vi.fn(async () => ({ health: {}, config: {} })),
   resetEndpointCircuit: vi.fn(async () => {}),
 }));
@@ -48,7 +53,18 @@ vi.mock("@/lib/vendor-type-circuit-breaker", () => ({
 }));
 
 vi.mock("@/lib/provider-endpoints/probe", () => ({
-  probeProviderEndpointAndRecord: vi.fn(async () => null),
+  probeProviderEndpointAndRecordByEndpoint: vi.fn(async () => null),
+}));
+
+vi.mock("@/repository/provider-endpoints-batch", () => ({
+  findProviderEndpointProbeLogsBatch: findProviderEndpointProbeLogsBatchMock,
+  findVendorTypeEndpointStatsBatch: findVendorTypeEndpointStatsBatchMock,
+}));
+
+vi.mock("@/repository/provider-endpoints", () => ({
+  findDashboardProviderEndpointsByVendorAndType: findDashboardProviderEndpointsByVendorAndTypeMock,
+  findEnabledProviderVendorTypePairs: vi.fn(async () => []),
+  hasEnabledProviderReferenceForVendorTypeUrl: hasEnabledProviderReferenceForVendorTypeUrlMock,
 }));
 
 vi.mock("@/repository", () => ({
@@ -68,6 +84,8 @@ vi.mock("@/repository", () => ({
 describe("provider-endpoints actions", () => {
   beforeEach(() => {
     vi.clearAllMocks();
+    hasEnabledProviderReferenceForVendorTypeUrlMock.mockResolvedValue(false);
+    findDashboardProviderEndpointsByVendorAndTypeMock.mockResolvedValue([]);
   });
 
   it("editProviderVendor: requires admin", async () => {
@@ -80,6 +98,59 @@ describe("provider-endpoints actions", () => {
     expect(res.errorCode).toBe("PERMISSION_DENIED");
   });
 
+  it("getDashboardProviderEndpoints: requires admin", async () => {
+    getSessionMock.mockResolvedValue({ user: { role: "user" } });
+
+    const { getDashboardProviderEndpoints } = await import("@/actions/provider-endpoints");
+    const res = await getDashboardProviderEndpoints({ vendorId: 1, providerType: "claude" });
+
+    expect(res).toEqual([]);
+    expect(findDashboardProviderEndpointsByVendorAndTypeMock).not.toHaveBeenCalled();
+  });
+
+  it("getDashboardProviderEndpoints: invalid input returns empty list", async () => {
+    getSessionMock.mockResolvedValue({ user: { role: "admin" } });
+
+    const { getDashboardProviderEndpoints } = await import("@/actions/provider-endpoints");
+    const res = await getDashboardProviderEndpoints({ vendorId: 0, providerType: "claude" });
+
+    expect(res).toEqual([]);
+    expect(findDashboardProviderEndpointsByVendorAndTypeMock).not.toHaveBeenCalled();
+  });
+
+  it("getDashboardProviderEndpoints: returns endpoints in use for enabled providers", async () => {
+    getSessionMock.mockResolvedValue({ user: { role: "admin" } });
+
+    const endpoints = [
+      {
+        id: 1,
+        vendorId: 10,
+        providerType: "claude",
+        url: "https://api.example.com",
+        label: null,
+        sortOrder: 0,
+        isEnabled: true,
+        lastProbedAt: null,
+        lastProbeOk: null,
+        lastProbeStatusCode: null,
+        lastProbeLatencyMs: null,
+        lastProbeErrorType: null,
+        lastProbeErrorMessage: null,
+        createdAt: new Date(),
+        updatedAt: new Date(),
+        deletedAt: null,
+      },
+    ];
+
+    findDashboardProviderEndpointsByVendorAndTypeMock.mockResolvedValue(endpoints);
+
+    const { getDashboardProviderEndpoints } = await import("@/actions/provider-endpoints");
+    const res = await getDashboardProviderEndpoints({ vendorId: 10, providerType: "claude" });
+
+    expect(res).toEqual(endpoints);
+    expect(findDashboardProviderEndpointsByVendorAndTypeMock).toHaveBeenCalledWith(10, "claude");
+  });
+
   it("editProviderVendor: computes favicon", async () => {
     getSessionMock.mockResolvedValue({ user: { role: "admin" } });
 
@@ -142,6 +213,26 @@ describe("provider-endpoints actions", () => {
 
   it("editProviderEndpoint: conflict maps to CONFLICT errorCode", async () => {
     getSessionMock.mockResolvedValue({ user: { role: "admin" } });
+
+    findProviderEndpointByIdMock.mockResolvedValue({
+      id: 42,
+      vendorId: 123,
+      providerType: "claude",
+      url: "https://api.example.com",
+      label: null,
+      sortOrder: 0,
+      isEnabled: true,
+      lastProbedAt: null,
+      lastProbeOk: null,
+      lastProbeStatusCode: null,
+      lastProbeLatencyMs: null,
+      lastProbeErrorType: null,
+      lastProbeErrorMessage: null,
+      createdAt: new Date(),
+      updatedAt: new Date(),
+      deletedAt: null,
+    });
+
     updateProviderEndpointMock.mockRejectedValue(
       Object.assign(new Error("[ProviderEndpointEdit] endpoint conflict"), {
         code: "PROVIDER_ENDPOINT_CONFLICT",
@@ -181,6 +272,7 @@ describe("provider-endpoints actions", () => {
       deletedAt: null,
     };
 
+    findProviderEndpointByIdMock.mockResolvedValue(endpoint);
     updateProviderEndpointMock.mockResolvedValue(endpoint);
 
     const { editProviderEndpoint } = await import("@/actions/provider-endpoints");
@@ -252,55 +344,100 @@ describe("provider-endpoints actions", () => {
     });
     softDeleteProviderEndpointMock.mockResolvedValue(true);
     tryDeleteProviderVendorIfEmptyMock.mockResolvedValue(true);
+    hasEnabledProviderReferenceForVendorTypeUrlMock.mockResolvedValue(false);
 
     const { removeProviderEndpoint } = await import("@/actions/provider-endpoints");
     const res = await removeProviderEndpoint({ endpointId: 99 });
 
     expect(res.ok).toBe(true);
+
+    const { resetEndpointCircuit } = await import("@/lib/endpoint-circuit-breaker");
+    expect(resetEndpointCircuit).toHaveBeenCalledWith(99);
     expect(tryDeleteProviderVendorIfEmptyMock).toHaveBeenCalledWith(123);
   });
 
+  it("probeProviderEndpoint: calls probeProviderEndpointAndRecordByEndpoint and returns result", async () => {
+    getSessionMock.mockResolvedValue({ user: { role: "admin" } });
+
+    const endpoint = {
+      id: 7,
+      vendorId: 123,
+      providerType: "claude",
+      url: "https://api.example.com",
+      label: null,
+      sortOrder: 0,
+      isEnabled: true,
+      lastProbedAt: null,
+      lastProbeOk: null,
+      lastProbeStatusCode: null,
+      lastProbeLatencyMs: null,
+      lastProbeErrorType: null,
+      lastProbeErrorMessage: null,
+      createdAt: new Date(),
+      updatedAt: new Date(),
+      deletedAt: null,
+    };
+    findProviderEndpointByIdMock.mockResolvedValue(endpoint);
+
+    const { probeProviderEndpointAndRecordByEndpoint } = await import(
+      "@/lib/provider-endpoints/probe"
+    );
+    const result = {
+      ok: true,
+      method: "HEAD",
+      statusCode: 200,
+      latencyMs: 10,
+      errorType: null,
+      errorMessage: null,
+    } as const;
+    vi.mocked(probeProviderEndpointAndRecordByEndpoint).mockResolvedValue(result);
+
+    const { probeProviderEndpoint } = await import("@/actions/provider-endpoints");
+    const res = await probeProviderEndpoint({ endpointId: 7, timeoutMs: 5000 });
+
+    expect(res.ok).toBe(true);
+    expect(probeProviderEndpointAndRecordByEndpoint).toHaveBeenCalledWith({
+      endpoint,
+      source: "manual",
+      timeoutMs: 5000,
+    });
+    expect(res.data?.result).toEqual(result);
+  });
+
   describe("batchGetEndpointCircuitInfo", () => {
     it("returns circuit info for multiple endpoints", async () => {
       getSessionMock.mockResolvedValue({ user: { role: "admin" } });
 
-      const { getEndpointHealthInfo } = await import("@/lib/endpoint-circuit-breaker");
-      vi.mocked(getEndpointHealthInfo)
-        .mockResolvedValueOnce({
-          health: {
-            failureCount: 0,
-            lastFailureTime: null,
-            circuitState: "closed" as const,
-            circuitOpenUntil: null,
-            halfOpenSuccessCount: 0,
-          },
-          config: { failureThreshold: 3, openDuration: 300000, halfOpenSuccessThreshold: 1 },
-        })
-        .mockResolvedValueOnce({
-          health: {
-            failureCount: 5,
-            lastFailureTime: Date.now(),
-            circuitState: "open" as const,
-            circuitOpenUntil: Date.now() + 60000,
-            halfOpenSuccessCount: 0,
-          },
-          config: { failureThreshold: 3, openDuration: 300000, halfOpenSuccessThreshold: 1 },
-        })
-        .mockResolvedValueOnce({
-          health: {
-            failureCount: 1,
-            lastFailureTime: Date.now() - 1000,
-            circuitState: "half-open" as const,
-            circuitOpenUntil: null,
-            halfOpenSuccessCount: 0,
-          },
-          config: { failureThreshold: 3, openDuration: 300000, halfOpenSuccessThreshold: 1 },
-        });
+      const { getAllEndpointHealthStatusAsync } = await import("@/lib/endpoint-circuit-breaker");
+      vi.mocked(getAllEndpointHealthStatusAsync).mockResolvedValue({
+        1: {
+          failureCount: 0,
+          lastFailureTime: null,
+          circuitState: "closed",
+          circuitOpenUntil: null,
+          halfOpenSuccessCount: 0,
+        },
+        2: {
+          failureCount: 5,
+          lastFailureTime: Date.now(),
+          circuitState: "open",
+          circuitOpenUntil: Date.now() + 60000,
+          halfOpenSuccessCount: 0,
+        },
+        3: {
+          failureCount: 1,
+          lastFailureTime: Date.now() - 1000,
+          circuitState: "half-open",
+          circuitOpenUntil: null,
+          halfOpenSuccessCount: 0,
+        },
+      });
 
       const { batchGetEndpointCircuitInfo } = await import("@/actions/provider-endpoints");
       const res = await batchGetEndpointCircuitInfo({ endpointIds: [1, 2, 3] });
 
       expect(res.ok).toBe(true);
+      expect(getAllEndpointHealthStatusAsync).toHaveBeenCalledWith([1, 2, 3]);
       expect(res.data).toHaveLength(3);
       expect(res.data?.[0]).toEqual({
         endpointId: 1,

+ 4 - 0
tests/unit/actions/providers-recluster.test.ts

@@ -26,6 +26,10 @@ vi.mock("@/repository/provider", () => ({
 vi.mock("@/repository/provider-endpoints", () => ({
   computeVendorKey: computeVendorKeyMock,
   findProviderVendorById: findProviderVendorByIdMock,
+  findProviderVendorsByIds: vi.fn(async (vendorIds: number[]) => {
+    const vendors = await Promise.all(vendorIds.map((id) => findProviderVendorByIdMock(id)));
+    return vendors.filter((vendor): vendor is NonNullable<typeof vendor> => vendor !== null);
+  }),
   getOrCreateProviderVendorIdFromUrls: getOrCreateProviderVendorIdFromUrlsMock,
   backfillProviderEndpointsFromProviders: backfillProviderEndpointsFromProvidersMock,
   tryDeleteProviderVendorIfEmpty: tryDeleteProviderVendorIfEmptyMock,

+ 39 - 25
tests/unit/actions/total-usage-semantics.test.ts

@@ -4,9 +4,9 @@
  * Verify that total usage reads in display paths use ALL_TIME_MAX_AGE_DAYS (Infinity)
  * to skip the date filter entirely, querying all-time data.
  *
- * Key insight: The functions sumKeyTotalCostById and sumUserTotalCost have a default
- * maxAgeDays of 365. For display purposes (showing "total" usage), we want all-time
- * semantics, which means passing Infinity to skip the date filter.
+ * Key insight: The usage/quota aggregation functions default maxAgeDays to 365.
+ * For display purposes (showing "total" usage), we want all-time semantics, which
+ * means passing Infinity to skip the date filter.
  *
  * IMPORTANT: This test only covers DISPLAY paths. Enforcement paths (RateLimitService)
  * are intentionally NOT modified.
@@ -19,13 +19,14 @@ const ALL_TIME_MAX_AGE_DAYS = Infinity;
 
 // Mock functions
 const getSessionMock = vi.fn();
-const sumKeyTotalCostByIdMock = vi.fn();
 const sumUserTotalCostMock = vi.fn();
-const sumKeyCostInTimeRangeMock = vi.fn();
+const sumKeyQuotaCostsByIdMock = vi.fn();
+const sumUserQuotaCostsMock = vi.fn();
 const sumUserCostInTimeRangeMock = vi.fn();
 const getTimeRangeForPeriodMock = vi.fn();
 const getTimeRangeForPeriodWithModeMock = vi.fn();
 const getKeySessionCountMock = vi.fn();
+const getUserSessionCountMock = vi.fn();
 const findUserByIdMock = vi.fn();
 
 // Mock modules
@@ -34,10 +35,10 @@ vi.mock("@/lib/auth", () => ({
 }));
 
 vi.mock("@/repository/statistics", () => ({
-  sumKeyTotalCostById: (...args: unknown[]) => sumKeyTotalCostByIdMock(...args),
-  sumUserTotalCost: (...args: unknown[]) => sumUserTotalCostMock(...args),
-  sumKeyCostInTimeRange: (...args: unknown[]) => sumKeyCostInTimeRangeMock(...args),
   sumUserCostInTimeRange: (...args: unknown[]) => sumUserCostInTimeRangeMock(...args),
+  sumUserTotalCost: (...args: unknown[]) => sumUserTotalCostMock(...args),
+  sumKeyQuotaCostsById: (...args: unknown[]) => sumKeyQuotaCostsByIdMock(...args),
+  sumUserQuotaCosts: (...args: unknown[]) => sumUserQuotaCostsMock(...args),
 }));
 
 vi.mock("@/lib/rate-limit/time-utils", () => ({
@@ -48,6 +49,7 @@ vi.mock("@/lib/rate-limit/time-utils", () => ({
 vi.mock("@/lib/session-tracker", () => ({
   SessionTracker: {
     getKeySessionCount: (...args: unknown[]) => getKeySessionCountMock(...args),
+    getUserSessionCount: (...args: unknown[]) => getUserSessionCountMock(...args),
   },
 }));
 
@@ -80,15 +82,24 @@ describe("total-usage-semantics", () => {
     getTimeRangeForPeriodWithModeMock.mockResolvedValue(defaultRange);
 
     // Default cost mocks
-    sumKeyCostInTimeRangeMock.mockResolvedValue(0);
-    sumUserCostInTimeRangeMock.mockResolvedValue(0);
-    sumKeyTotalCostByIdMock.mockResolvedValue(0);
     sumUserTotalCostMock.mockResolvedValue(0);
+    sumUserCostInTimeRangeMock.mockResolvedValue(0);
     getKeySessionCountMock.mockResolvedValue(0);
+    getUserSessionCountMock.mockResolvedValue(0);
+
+    const emptyCosts = {
+      cost5h: 0,
+      costDaily: 0,
+      costWeekly: 0,
+      costMonthly: 0,
+      costTotal: 0,
+    };
+    sumKeyQuotaCostsByIdMock.mockResolvedValue(emptyCosts);
+    sumUserQuotaCostsMock.mockResolvedValue(emptyCosts);
   });
 
   describe("getMyQuota in my-usage.ts", () => {
-    it("should call sumKeyTotalCostById with ALL_TIME_MAX_AGE_DAYS for key total cost", async () => {
+    it("should call sumKeyQuotaCostsById with ALL_TIME_MAX_AGE_DAYS for key total cost", async () => {
       // Setup session mock
       getSessionMock.mockResolvedValue({
         key: {
@@ -131,15 +142,14 @@ describe("total-usage-semantics", () => {
       const { getMyQuota } = await import("@/actions/my-usage");
       await getMyQuota();
 
-      // Verify sumKeyTotalCostById was called with Infinity (all-time)
-      expect(sumKeyTotalCostByIdMock).toHaveBeenCalledWith(1, Infinity);
+      expect(sumKeyQuotaCostsByIdMock).toHaveBeenCalledWith(
+        1,
+        expect.any(Object),
+        ALL_TIME_MAX_AGE_DAYS
+      );
     });
 
-    it.skip("should call sumUserTotalCost with ALL_TIME_MAX_AGE_DAYS for user total cost (via sumUserCost)", async () => {
-      // SKIPPED: Dynamic import in sumUserCost cannot be properly mocked with vi.mock()
-      // The source code verification test below proves the implementation is correct
-      // by checking the actual source code contains the correct function call pattern.
-
+    it("should call sumUserQuotaCosts with ALL_TIME_MAX_AGE_DAYS for user total cost", async () => {
       // Setup session mock
       getSessionMock.mockResolvedValue({
         key: {
@@ -182,8 +192,11 @@ describe("total-usage-semantics", () => {
       const { getMyQuota } = await import("@/actions/my-usage");
       await getMyQuota();
 
-      // Verify sumUserTotalCost was called with Infinity (all-time)
-      expect(sumUserTotalCostMock).toHaveBeenCalledWith(1, Infinity);
+      expect(sumUserQuotaCostsMock).toHaveBeenCalledWith(
+        1,
+        expect.any(Object),
+        ALL_TIME_MAX_AGE_DAYS
+      );
     });
   });
 
@@ -227,6 +240,8 @@ describe("total-usage-semantics", () => {
 
   describe("source code verification", () => {
     it("should verify sumUserCost passes ALL_TIME_MAX_AGE_DAYS when period is total", async () => {
+      // This test verifies the implementation by reading the source code pattern
+      // Ensure we call quota aggregation functions with ALL_TIME_MAX_AGE_DAYS for all-time usage.
       const fs = await import("node:fs/promises");
       const path = await import("node:path");
 
@@ -236,11 +251,10 @@ describe("total-usage-semantics", () => {
       // Verify the constant is defined as Infinity
       expect(content).toContain("const ALL_TIME_MAX_AGE_DAYS = Infinity");
 
-      // Verify sumUserTotalCost is called with the constant when period is total
-      expect(content).toContain("sumUserTotalCost(userId, ALL_TIME_MAX_AGE_DAYS)");
+      // Verify quota aggregation uses the constant for all-time usage
+      expect(content).toMatch(/sumUserQuotaCosts\([^)]*ALL_TIME_MAX_AGE_DAYS\s*\)/);
 
-      // Verify sumKeyTotalCostById is called with the constant
-      expect(content).toContain("sumKeyTotalCostById(key.id, ALL_TIME_MAX_AGE_DAYS)");
+      expect(content).toMatch(/sumKeyQuotaCostsById\([^)]*ALL_TIME_MAX_AGE_DAYS\s*\)/);
     });
 
     it("should verify getUserAllLimitUsage passes ALL_TIME_MAX_AGE_DAYS", async () => {

+ 178 - 14
tests/unit/lib/endpoint-circuit-breaker.test.ts

@@ -27,6 +27,7 @@ async function flushPromises(rounds = 2): Promise<void> {
 
 afterEach(() => {
   vi.useRealTimers();
+  delete process.env.ENDPOINT_CIRCUIT_HEALTH_CACHE_MAX_SIZE;
 });
 
 describe("endpoint-circuit-breaker", () => {
@@ -61,6 +62,7 @@ describe("endpoint-circuit-breaker", () => {
 
     const {
       isEndpointCircuitOpen,
+      getEndpointHealthInfo,
       recordEndpointFailure,
       recordEndpointSuccess,
       resetEndpointCircuit,
@@ -92,19 +94,20 @@ describe("endpoint-circuit-breaker", () => {
     expect(halfOpenState.circuitState).toBe("half-open");
 
     await recordEndpointSuccess(1);
-    const closedState = saveMock.mock.calls[
-      saveMock.mock.calls.length - 1
-    ]?.[1] as SavedEndpointCircuitState;
-    expect(closedState.circuitState).toBe("closed");
-    expect(closedState.failureCount).toBe(0);
-    expect(closedState.circuitOpenUntil).toBeNull();
-    expect(closedState.lastFailureTime).toBeNull();
-    expect(closedState.halfOpenSuccessCount).toBe(0);
+    expect(deleteMock).toHaveBeenCalledWith(1);
+
+    const { health: afterSuccess } = await getEndpointHealthInfo(1);
+    expect(afterSuccess.circuitState).toBe("closed");
+    expect(afterSuccess.failureCount).toBe(0);
+    expect(afterSuccess.circuitOpenUntil).toBeNull();
+    expect(afterSuccess.lastFailureTime).toBeNull();
+    expect(afterSuccess.halfOpenSuccessCount).toBe(0);
 
     expect(await isEndpointCircuitOpen(1)).toBe(false);
 
+    const deleteCallsAfterSuccess = deleteMock.mock.calls.length;
     await resetEndpointCircuit(1);
-    expect(deleteMock).toHaveBeenCalledWith(1);
+    expect(deleteMock.mock.calls.length).toBeGreaterThan(deleteCallsAfterSuccess);
 
     // 说明:recordEndpointFailure 在达到阈值后会触发异步告警(dynamic import + await)。
     // 在 CI/bun 环境下,告警 Promise 可能在下一个测试开始后才完成,从而“借用”后续用例的 module mock,
@@ -120,6 +123,7 @@ describe("endpoint-circuit-breaker", () => {
     vi.resetModules();
 
     const saveMock = vi.fn(async () => {});
+    const deleteMock = vi.fn(async () => {});
 
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
@@ -131,7 +135,7 @@ describe("endpoint-circuit-breaker", () => {
     vi.doMock("@/lib/redis/endpoint-circuit-breaker-state", () => ({
       loadEndpointCircuitState: vi.fn(async () => null),
       saveEndpointCircuitState: saveMock,
-      deleteEndpointCircuitState: vi.fn(async () => {}),
+      deleteEndpointCircuitState: deleteMock,
     }));
 
     const { recordEndpointFailure, recordEndpointSuccess, getEndpointHealthInfo } = await import(
@@ -145,10 +149,170 @@ describe("endpoint-circuit-breaker", () => {
     expect(health.failureCount).toBe(0);
     expect(health.circuitState).toBe("closed");
 
-    const lastState = saveMock.mock.calls[
-      saveMock.mock.calls.length - 1
-    ]?.[1] as SavedEndpointCircuitState;
-    expect(lastState.failureCount).toBe(0);
+    expect(saveMock).toHaveBeenCalledTimes(1);
+    expect(deleteMock).toHaveBeenCalledWith(2);
+  });
+
+  test("getAllEndpointHealthStatusAsync: forceRefresh 时应同步 Redis 中的计数(即使 circuitState 未变化)", async () => {
+    vi.resetModules();
+
+    const endpointId = 42;
+
+    const redisStates = new Map<number, SavedEndpointCircuitState>();
+    const loadManyMock = vi.fn(async (endpointIds: number[]) => {
+      const result = new Map<number, SavedEndpointCircuitState>();
+      for (const id of endpointIds) {
+        const state = redisStates.get(id);
+        if (state) {
+          result.set(id, state);
+        }
+      }
+      return result;
+    });
+
+    vi.doMock("@/lib/logger", () => ({ logger: createLoggerMock() }));
+    vi.doMock("@/lib/redis/endpoint-circuit-breaker-state", () => ({
+      loadEndpointCircuitState: vi.fn(async () => null),
+      loadEndpointCircuitStates: loadManyMock,
+      saveEndpointCircuitState: vi.fn(async () => {}),
+      deleteEndpointCircuitState: vi.fn(async () => {}),
+    }));
+
+    vi.useFakeTimers();
+    vi.setSystemTime(new Date("2026-01-01T00:00:00.000Z"));
+    const t0 = Date.now();
+
+    redisStates.set(endpointId, {
+      failureCount: 1,
+      lastFailureTime: t0 - 1000,
+      circuitState: "closed",
+      circuitOpenUntil: null,
+      halfOpenSuccessCount: 0,
+    });
+
+    const { getAllEndpointHealthStatusAsync } = await import("@/lib/endpoint-circuit-breaker");
+
+    const first = await getAllEndpointHealthStatusAsync([endpointId], { forceRefresh: true });
+    expect(first[endpointId]).toMatchObject({
+      failureCount: 1,
+      lastFailureTime: t0 - 1000,
+      circuitState: "closed",
+      circuitOpenUntil: null,
+      halfOpenSuccessCount: 0,
+    });
+
+    redisStates.set(endpointId, {
+      failureCount: 2,
+      lastFailureTime: t0 + 123,
+      circuitState: "closed",
+      circuitOpenUntil: null,
+      halfOpenSuccessCount: 0,
+    });
+
+    const second = await getAllEndpointHealthStatusAsync([endpointId], { forceRefresh: true });
+    expect(second[endpointId]).toMatchObject({
+      failureCount: 2,
+      lastFailureTime: t0 + 123,
+      circuitState: "closed",
+      circuitOpenUntil: null,
+      halfOpenSuccessCount: 0,
+    });
+
+    expect(loadManyMock).toHaveBeenCalledTimes(2);
+  });
+
+  test("getAllEndpointHealthStatusAsync: 并发请求应复用 in-flight Redis 批量加载", async () => {
+    vi.resetModules();
+
+    const loadManyMock = vi.fn(async (_endpointIds: number[]) => {
+      await new Promise((resolve) => setTimeout(resolve, 10));
+      const result = new Map<number, SavedEndpointCircuitState>();
+      result.set(1, {
+        failureCount: 0,
+        lastFailureTime: null,
+        circuitState: "closed",
+        circuitOpenUntil: null,
+        halfOpenSuccessCount: 0,
+      });
+      result.set(2, {
+        failureCount: 0,
+        lastFailureTime: null,
+        circuitState: "closed",
+        circuitOpenUntil: null,
+        halfOpenSuccessCount: 0,
+      });
+      result.set(3, {
+        failureCount: 0,
+        lastFailureTime: null,
+        circuitState: "closed",
+        circuitOpenUntil: null,
+        halfOpenSuccessCount: 0,
+      });
+      return result;
+    });
+
+    vi.doMock("@/lib/logger", () => ({ logger: createLoggerMock() }));
+    vi.doMock("@/lib/redis/endpoint-circuit-breaker-state", () => ({
+      loadEndpointCircuitState: vi.fn(async () => null),
+      loadEndpointCircuitStates: loadManyMock,
+      saveEndpointCircuitState: vi.fn(async () => {}),
+      deleteEndpointCircuitState: vi.fn(async () => {}),
+    }));
+
+    vi.useFakeTimers();
+    vi.setSystemTime(new Date("2026-01-01T00:00:00.000Z"));
+
+    const { getAllEndpointHealthStatusAsync } = await import("@/lib/endpoint-circuit-breaker");
+
+    const p1 = getAllEndpointHealthStatusAsync([1, 2, 3], { forceRefresh: true });
+    const p2 = getAllEndpointHealthStatusAsync([1, 2, 3], { forceRefresh: true });
+
+    vi.advanceTimersByTime(20);
+    await Promise.all([p1, p2]);
+    expect(loadManyMock).toHaveBeenCalledTimes(1);
+  });
+
+  test("getAllEndpointHealthStatusAsync: cache 超限时应淘汰最早的健康状态,避免内存无限增长", async () => {
+    vi.resetModules();
+
+    process.env.ENDPOINT_CIRCUIT_HEALTH_CACHE_MAX_SIZE = "3";
+
+    const loadManyMock = vi.fn(async (endpointIds: number[]) => {
+      const result = new Map<number, SavedEndpointCircuitState>();
+      for (const endpointId of endpointIds) {
+        result.set(endpointId, {
+          failureCount: 0,
+          lastFailureTime: null,
+          circuitState: "closed",
+          circuitOpenUntil: null,
+          halfOpenSuccessCount: 0,
+        });
+      }
+      return result;
+    });
+
+    vi.doMock("@/lib/logger", () => ({ logger: createLoggerMock() }));
+    vi.doMock("@/lib/redis/endpoint-circuit-breaker-state", () => ({
+      loadEndpointCircuitState: vi.fn(async () => null),
+      loadEndpointCircuitStates: loadManyMock,
+      saveEndpointCircuitState: vi.fn(async () => {}),
+      deleteEndpointCircuitState: vi.fn(async () => {}),
+    }));
+
+    vi.useFakeTimers();
+    vi.setSystemTime(new Date("2026-01-01T00:00:00.000Z"));
+
+    const { getAllEndpointHealthStatusAsync } = await import("@/lib/endpoint-circuit-breaker");
+
+    await getAllEndpointHealthStatusAsync([1, 2, 3], { forceRefresh: true });
+    expect(loadManyMock).toHaveBeenCalledTimes(1);
+
+    await getAllEndpointHealthStatusAsync([4], { forceRefresh: true });
+    expect(loadManyMock).toHaveBeenCalledTimes(2);
+
+    // 1 应已被淘汰;再次访问会触发一次新的 Redis 批量读取
+    await getAllEndpointHealthStatusAsync([1]);
+    expect(loadManyMock).toHaveBeenCalledTimes(3);
   });
 
   test("triggerEndpointCircuitBreakerAlert should call sendCircuitBreakerAlert", async () => {

+ 104 - 27
tests/unit/lib/provider-endpoints/endpoint-selector.test.ts

@@ -27,10 +27,14 @@ describe("provider-endpoints: endpoint-selector", () => {
   test("rankProviderEndpoints 应过滤 disabled/deleted,并按 lastProbeOk/sortOrder/latency/id 排序", async () => {
     vi.resetModules();
     vi.doMock("@/repository", () => ({
+      findEnabledProviderEndpointsByVendorAndType: vi.fn(),
       findProviderEndpointsByVendorAndType: vi.fn(),
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: vi.fn(),
+      getAllEndpointHealthStatusAsync: vi.fn(),
+    }));
+    vi.doMock("@/lib/config/env.schema", () => ({
+      getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
     }));
 
     const { rankProviderEndpoints } = await import("@/lib/provider-endpoints/endpoint-selector");
@@ -91,23 +95,46 @@ describe("provider-endpoints: endpoint-selector", () => {
   test("getPreferredProviderEndpoints 应排除禁用/已删除/显式 exclude/熔断 open 的端点,并返回排序结果", async () => {
     vi.resetModules();
 
+    // findEnabledProviderEndpointsByVendorAndType 语义:只返回 isEnabled=true 且 deletedAt=null 的端点
     const endpoints: ProviderEndpoint[] = [
       makeEndpoint({ id: 1, lastProbeOk: true, sortOrder: 1, lastProbeLatencyMs: 20 }),
       makeEndpoint({ id: 2, lastProbeOk: true, sortOrder: 0, lastProbeLatencyMs: 999 }),
       makeEndpoint({ id: 3, lastProbeOk: null, sortOrder: 0, lastProbeLatencyMs: 10 }),
-      makeEndpoint({ id: 4, isEnabled: false }),
-      makeEndpoint({ id: 5, deletedAt: new Date(1) }),
       makeEndpoint({ id: 6, lastProbeOk: false, sortOrder: 0, lastProbeLatencyMs: 1 }),
     ];
 
     const findMock = vi.fn(async () => endpoints);
-    const isOpenMock = vi.fn(async (endpointId: number) => endpointId === 2);
+    const getAllStatusMock = vi.fn(async (endpointIds: number[]) => {
+      const status: Record<
+        number,
+        {
+          failureCount: number;
+          lastFailureTime: number | null;
+          circuitState: "closed" | "open" | "half-open";
+          circuitOpenUntil: number | null;
+          halfOpenSuccessCount: number;
+        }
+      > = {};
+
+      for (const endpointId of endpointIds) {
+        status[endpointId] = {
+          failureCount: 0,
+          lastFailureTime: null,
+          circuitState: endpointId === 2 ? "open" : "closed",
+          circuitOpenUntil: endpointId === 2 ? Date.now() + 60_000 : null,
+          halfOpenSuccessCount: 0,
+        };
+      }
+
+      return status;
+    });
 
     vi.doMock("@/repository", () => ({
-      findProviderEndpointsByVendorAndType: findMock,
+      findEnabledProviderEndpointsByVendorAndType: findMock,
+      findProviderEndpointsByVendorAndType: vi.fn(async () => []),
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
@@ -124,7 +151,7 @@ describe("provider-endpoints: endpoint-selector", () => {
     });
 
     expect(findMock).toHaveBeenCalledWith(123, "claude");
-    expect(isOpenMock.mock.calls.map((c) => c[0])).toEqual([1, 2, 3]);
+    expect(getAllStatusMock).toHaveBeenCalledWith([1, 2, 3]);
     expect(result.map((e) => e.id)).toEqual([1, 3]);
 
     const best = await pickBestProviderEndpoint({ vendorId: 123, providerType: "claude" });
@@ -134,14 +161,15 @@ describe("provider-endpoints: endpoint-selector", () => {
   test("getPreferredProviderEndpoints 过滤后无候选时返回空数组", async () => {
     vi.resetModules();
 
-    const findMock = vi.fn(async () => [makeEndpoint({ id: 1, isEnabled: false })]);
-    const isOpenMock = vi.fn(async () => false);
+    const findMock = vi.fn(async () => []);
+    const getAllStatusMock = vi.fn(async () => ({}));
 
     vi.doMock("@/repository", () => ({
-      findProviderEndpointsByVendorAndType: findMock,
+      findEnabledProviderEndpointsByVendorAndType: findMock,
+      findProviderEndpointsByVendorAndType: vi.fn(async () => []),
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
@@ -157,7 +185,7 @@ describe("provider-endpoints: endpoint-selector", () => {
     const best = await pickBestProviderEndpoint({ vendorId: 1, providerType: "claude" });
     expect(best).toBeNull();
 
-    expect(isOpenMock).not.toHaveBeenCalled();
+    expect(getAllStatusMock).not.toHaveBeenCalled();
   });
 });
 
@@ -174,14 +202,36 @@ describe("getEndpointFilterStats", () => {
     ];
 
     const findMock = vi.fn(async () => endpoints);
-    // id=2 is circuit open
-    const isOpenMock = vi.fn(async (endpointId: number) => endpointId === 2);
+    const getAllStatusMock = vi.fn(async (endpointIds: number[]) => {
+      const status: Record<
+        number,
+        {
+          failureCount: number;
+          lastFailureTime: number | null;
+          circuitState: "closed" | "open" | "half-open";
+          circuitOpenUntil: number | null;
+          halfOpenSuccessCount: number;
+        }
+      > = {};
+
+      for (const endpointId of endpointIds) {
+        status[endpointId] = {
+          failureCount: 0,
+          lastFailureTime: null,
+          circuitState: endpointId === 2 ? "open" : "closed",
+          circuitOpenUntil: endpointId === 2 ? Date.now() + 60_000 : null,
+          halfOpenSuccessCount: 0,
+        };
+      }
+
+      return status;
+    });
 
     vi.doMock("@/repository", () => ({
       findProviderEndpointsByVendorAndType: findMock,
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
@@ -191,6 +241,7 @@ describe("getEndpointFilterStats", () => {
     const stats = await getEndpointFilterStats({ vendorId: 10, providerType: "claude" });
 
     expect(findMock).toHaveBeenCalledWith(10, "claude");
+    expect(getAllStatusMock).toHaveBeenCalledWith([1, 2, 3]);
     expect(stats).toEqual({
       total: 5, // all endpoints
       enabled: 3, // id=1,2,3 (isEnabled && !deletedAt)
@@ -203,13 +254,13 @@ describe("getEndpointFilterStats", () => {
     vi.resetModules();
 
     const findMock = vi.fn(async () => []);
-    const isOpenMock = vi.fn(async () => false);
+    const getAllStatusMock = vi.fn(async () => ({}));
 
     vi.doMock("@/repository", () => ({
       findProviderEndpointsByVendorAndType: findMock,
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
@@ -224,7 +275,7 @@ describe("getEndpointFilterStats", () => {
       circuitOpen: 0,
       available: 0,
     });
-    expect(isOpenMock).not.toHaveBeenCalled();
+    expect(getAllStatusMock).not.toHaveBeenCalled();
   });
 
   test("should count all enabled endpoints as circuitOpen when all are open", async () => {
@@ -236,13 +287,37 @@ describe("getEndpointFilterStats", () => {
     ];
 
     const findMock = vi.fn(async () => endpoints);
-    const isOpenMock = vi.fn(async () => true);
+    const getAllStatusMock = vi.fn(async (endpointIds: number[]) => {
+      const status: Record<
+        number,
+        {
+          failureCount: number;
+          lastFailureTime: number | null;
+          circuitState: "closed" | "open" | "half-open";
+          circuitOpenUntil: number | null;
+          halfOpenSuccessCount: number;
+        }
+      > = {};
+
+      for (const endpointId of endpointIds) {
+        status[endpointId] = {
+          failureCount: 0,
+          lastFailureTime: null,
+          circuitState: "open",
+          circuitOpenUntil: Date.now() + 60_000,
+          halfOpenSuccessCount: 0,
+        };
+      }
+
+      return status;
+    });
 
     vi.doMock("@/repository", () => ({
+      findEnabledProviderEndpointsByVendorAndType: vi.fn(async () => []),
       findProviderEndpointsByVendorAndType: findMock,
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: true }),
@@ -251,6 +326,7 @@ describe("getEndpointFilterStats", () => {
     const { getEndpointFilterStats } = await import("@/lib/provider-endpoints/endpoint-selector");
     const stats = await getEndpointFilterStats({ vendorId: 1, providerType: "openai-compatible" });
 
+    expect(getAllStatusMock).toHaveBeenCalledWith([1, 2]);
     expect(stats).toEqual({
       total: 2,
       enabled: 2,
@@ -273,13 +349,14 @@ describe("ENABLE_ENDPOINT_CIRCUIT_BREAKER disabled", () => {
     ];
 
     const findMock = vi.fn(async () => endpoints);
-    const isOpenMock = vi.fn(async () => true);
+    const getAllStatusMock = vi.fn(async () => ({}));
 
     vi.doMock("@/repository", () => ({
-      findProviderEndpointsByVendorAndType: findMock,
+      findEnabledProviderEndpointsByVendorAndType: findMock,
+      findProviderEndpointsByVendorAndType: vi.fn(async () => []),
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: false }),
@@ -294,7 +371,7 @@ describe("ENABLE_ENDPOINT_CIRCUIT_BREAKER disabled", () => {
       providerType: "claude",
     });
 
-    expect(isOpenMock).not.toHaveBeenCalled();
+    expect(getAllStatusMock).not.toHaveBeenCalled();
     // All enabled, non-deleted endpoints returned (id=1,2,3), ranked by sortOrder/health
     expect(result.map((e) => e.id)).toEqual([1, 2, 3]);
   });
@@ -310,13 +387,13 @@ describe("ENABLE_ENDPOINT_CIRCUIT_BREAKER disabled", () => {
     ];
 
     const findMock = vi.fn(async () => endpoints);
-    const isOpenMock = vi.fn(async () => true);
+    const getAllStatusMock = vi.fn(async () => ({}));
 
     vi.doMock("@/repository", () => ({
       findProviderEndpointsByVendorAndType: findMock,
     }));
     vi.doMock("@/lib/endpoint-circuit-breaker", () => ({
-      isEndpointCircuitOpen: isOpenMock,
+      getAllEndpointHealthStatusAsync: getAllStatusMock,
     }));
     vi.doMock("@/lib/config/env.schema", () => ({
       getEnvConfig: () => ({ ENABLE_ENDPOINT_CIRCUIT_BREAKER: false }),
@@ -325,7 +402,7 @@ describe("ENABLE_ENDPOINT_CIRCUIT_BREAKER disabled", () => {
     const { getEndpointFilterStats } = await import("@/lib/provider-endpoints/endpoint-selector");
     const stats = await getEndpointFilterStats({ vendorId: 10, providerType: "claude" });
 
-    expect(isOpenMock).not.toHaveBeenCalled();
+    expect(getAllStatusMock).not.toHaveBeenCalled();
     expect(stats).toEqual({
       total: 4,
       enabled: 2, // id=1,2 (isEnabled && !deletedAt)

+ 167 - 0
tests/unit/lib/use-in-view-once.test.tsx

@@ -0,0 +1,167 @@
+import type { ReactNode } from "react";
+import { act } from "react";
+import { createRoot } from "react-dom/client";
+import { afterEach, describe, expect, it, vi } from "vitest";
+
+function render(node: ReactNode) {
+  const container = document.createElement("div");
+  document.body.appendChild(container);
+  const root = createRoot(container);
+
+  act(() => {
+    root.render(node);
+  });
+
+  return {
+    container,
+    unmount: () => {
+      act(() => root.unmount());
+      container.remove();
+    },
+  };
+}
+
+describe("useInViewOnce", () => {
+  const originalNodeEnv = process.env.NODE_ENV;
+  const originalIntersectionObserver = globalThis.IntersectionObserver;
+
+  afterEach(() => {
+    process.env.NODE_ENV = originalNodeEnv;
+    globalThis.IntersectionObserver = originalIntersectionObserver;
+    vi.resetModules();
+  });
+
+  it("在 test 环境下应直接视为可见,并避免创建 IntersectionObserver", async () => {
+    process.env.NODE_ENV = "test";
+
+    const ioCtor = vi.fn(function (this: any) {
+      this.observe = vi.fn();
+      this.unobserve = vi.fn();
+      this.disconnect = vi.fn();
+    });
+    globalThis.IntersectionObserver = ioCtor as any;
+
+    const { useEffect } = await import("react");
+    const { useInViewOnce } = await import("@/lib/hooks/use-in-view-once");
+
+    let lastValue = false;
+
+    function Probe() {
+      const { ref, isInView } = useInViewOnce<HTMLDivElement>();
+      useEffect(() => {
+        lastValue = isInView;
+      }, [isInView]);
+
+      return <div ref={ref} />;
+    }
+
+    const { unmount } = render(<Probe />);
+    await act(async () => {});
+
+    expect(lastValue).toBe(true);
+    expect(ioCtor).not.toHaveBeenCalled();
+
+    unmount();
+  });
+
+  it("应复用共享 observer,并在最后一个 target 解绑后释放资源", async () => {
+    process.env.NODE_ENV = "development";
+
+    type MockEntry = { target: Element; isIntersecting: boolean };
+
+    class MockIntersectionObserver {
+      static instances: MockIntersectionObserver[] = [];
+
+      private readonly callback: (entries: MockEntry[]) => void;
+      readonly observed = new Set<Element>();
+      readonly observe = vi.fn((target: Element) => {
+        this.observed.add(target);
+      });
+      readonly unobserve = vi.fn((target: Element) => {
+        this.observed.delete(target);
+      });
+      readonly disconnect = vi.fn(() => {
+        this.observed.clear();
+      });
+
+      constructor(callback: (entries: MockEntry[]) => void) {
+        this.callback = callback;
+        MockIntersectionObserver.instances.push(this);
+      }
+
+      trigger(target: Element, isIntersecting: boolean) {
+        if (!this.observed.has(target)) return;
+        this.callback([{ target, isIntersecting }]);
+      }
+    }
+
+    globalThis.IntersectionObserver = MockIntersectionObserver as any;
+
+    const { useCallback, useEffect } = await import("react");
+    const { useInViewOnce } = await import("@/lib/hooks/use-in-view-once");
+
+    let node1: Element | null = null;
+    let node2: Element | null = null;
+    let inView1 = false;
+    let inView2 = false;
+
+    function Probe(props: {
+      onNode: (node: Element | null) => void;
+      onView: (value: boolean) => void;
+    }) {
+      const { ref, isInView } = useInViewOnce<HTMLDivElement>();
+      const { onNode, onView } = props;
+      const mergedRef = useCallback(
+        (node: HTMLDivElement | null) => {
+          ref(node);
+          onNode(node);
+        },
+        [onNode, ref]
+      );
+
+      useEffect(() => {
+        onView(isInView);
+      }, [isInView, onView]);
+
+      return <div ref={mergedRef} />;
+    }
+
+    const { unmount } = render(
+      <div>
+        <Probe onNode={(node) => (node1 = node)} onView={(value) => (inView1 = value)} />
+        <Probe onNode={(node) => (node2 = node)} onView={(value) => (inView2 = value)} />
+      </div>
+    );
+    await act(async () => {});
+
+    expect(MockIntersectionObserver.instances).toHaveLength(1);
+    const io = MockIntersectionObserver.instances[0];
+    expect(io.observe).toHaveBeenCalledTimes(2);
+
+    expect(node1).not.toBeNull();
+    expect(node2).not.toBeNull();
+
+    act(() => {
+      io.trigger(node1 as Element, true);
+    });
+    await act(async () => {});
+
+    expect(inView1).toBe(true);
+    expect(io.unobserve).toHaveBeenCalledWith(node1);
+    expect(io.disconnect).not.toHaveBeenCalled();
+    expect(io.observed.has(node1 as Element)).toBe(false);
+    expect(io.observed.has(node2 as Element)).toBe(true);
+
+    act(() => {
+      io.trigger(node2 as Element, true);
+    });
+    await act(async () => {});
+
+    expect(inView2).toBe(true);
+    expect(io.unobserve).toHaveBeenCalledWith(node2);
+    expect(io.disconnect).toHaveBeenCalledTimes(1);
+    expect(io.observed.size).toBe(0);
+
+    unmount();
+  });
+});

+ 14 - 7
tests/unit/repository/provider-endpoint-sync-helper.test.ts

@@ -6,7 +6,8 @@ function createTxMock(selectResults: SelectRow[][]) {
   const queue = [...selectResults];
 
   const selectLimitMock = vi.fn(async () => queue.shift() ?? []);
-  const selectWhereMock = vi.fn(() => ({ limit: selectLimitMock }));
+  const selectOrderByMock = vi.fn(() => ({ limit: selectLimitMock }));
+  const selectWhereMock = vi.fn(() => ({ orderBy: selectOrderByMock, limit: selectLimitMock }));
   const selectFromMock = vi.fn(() => ({ where: selectWhereMock }));
   const selectMock = vi.fn(() => ({ from: selectFromMock }));
 
@@ -221,7 +222,7 @@ describe("syncProviderEndpointOnProviderEdit", () => {
     expect(resetEndpointCircuitMock).not.toHaveBeenCalled();
   });
 
-  test("in-place move unique conflict should fallback to conservative keep-previous behavior", async () => {
+  test("in-place move unique conflict should soft-delete previous endpoint when unreferenced", async () => {
     const oldUrl = "https://old.example.com/v1/messages";
     const newUrl = "https://new.example.com/v1/messages";
     const { syncProviderEndpointOnProviderEdit, updatePayloads, mocks, resetEndpointCircuitMock } =
@@ -250,18 +251,24 @@ describe("syncProviderEndpointOnProviderEdit", () => {
       keepPreviousWhenReferenced: true,
     });
 
-    expect(result).toEqual({ action: "kept-previous-and-kept-next" });
+    expect(result).toEqual({ action: "soft-deleted-previous-and-kept-next" });
     expect(mocks.insertMock).toHaveBeenCalledTimes(1);
-    expect(mocks.updateMock).toHaveBeenCalledTimes(1);
+    expect(mocks.updateMock).toHaveBeenCalledTimes(2);
     expect(updatePayloads[0]).toEqual(
       expect.objectContaining({
         url: newUrl,
       })
     );
+    expect(updatePayloads[1]).toEqual(
+      expect.objectContaining({
+        deletedAt: expect.any(Date),
+        isEnabled: false,
+      })
+    );
     expect(resetEndpointCircuitMock).not.toHaveBeenCalled();
   });
 
-  test("when next endpoint already exists, should keep previous endpoint under conservative policy", async () => {
+  test("when next endpoint already exists, should soft-delete previous endpoint when unreferenced", async () => {
     const oldUrl = "https://old.example.com/v1/messages";
     const newUrl = "https://new.example.com/v1/messages";
     const { syncProviderEndpointOnProviderEdit, mocks, resetEndpointCircuitMock } =
@@ -283,8 +290,8 @@ describe("syncProviderEndpointOnProviderEdit", () => {
       keepPreviousWhenReferenced: true,
     });
 
-    expect(result).toEqual({ action: "kept-previous-and-kept-next" });
-    expect(mocks.updateMock).not.toHaveBeenCalled();
+    expect(result).toEqual({ action: "soft-deleted-previous-and-kept-next" });
+    expect(mocks.updateMock).toHaveBeenCalledTimes(1);
     expect(mocks.insertMock).not.toHaveBeenCalled();
     expect(resetEndpointCircuitMock).not.toHaveBeenCalled();
   });

+ 94 - 0
tests/unit/repository/provider-endpoints-probe-result.test.ts

@@ -0,0 +1,94 @@
+import { describe, expect, test, vi } from "vitest";
+
+describe("provider-endpoints repository - recordProviderEndpointProbeResult", () => {
+  test("endpoint 不存在/已删除时应静默忽略(不写 probe log)", async () => {
+    vi.resetModules();
+
+    const returningMock = vi.fn(async () => []);
+    const whereMock = vi.fn(() => ({ returning: returningMock }));
+    const setMock = vi.fn(() => ({ where: whereMock }));
+    const updateMock = vi.fn(() => ({ set: setMock }));
+
+    const valuesMock = vi.fn(async () => {});
+    const insertMock = vi.fn(() => ({ values: valuesMock }));
+
+    const transactionMock = vi.fn(async (fn: (tx: any) => Promise<void>) => {
+      return fn({ update: updateMock, insert: insertMock });
+    });
+
+    vi.doMock("@/drizzle/db", () => ({
+      db: {
+        transaction: transactionMock,
+      },
+    }));
+
+    const { recordProviderEndpointProbeResult } = await import("@/repository/provider-endpoints");
+
+    await expect(
+      recordProviderEndpointProbeResult({
+        endpointId: 123,
+        source: "scheduled",
+        ok: true,
+        statusCode: 200,
+        latencyMs: 10,
+        errorType: null,
+        errorMessage: null,
+        probedAt: new Date("2026-01-01T00:00:00.000Z"),
+      })
+    ).resolves.toBeUndefined();
+
+    expect(updateMock).toHaveBeenCalledTimes(1);
+    expect(insertMock).not.toHaveBeenCalled();
+    expect(valuesMock).not.toHaveBeenCalled();
+  });
+
+  test("endpoint 存在时应同时更新 snapshot + 写入 probe log", async () => {
+    vi.resetModules();
+
+    const returningMock = vi.fn(async () => [{ id: 123 }]);
+    const whereMock = vi.fn(() => ({ returning: returningMock }));
+    const setMock = vi.fn(() => ({ where: whereMock }));
+    const updateMock = vi.fn(() => ({ set: setMock }));
+
+    const valuesMock = vi.fn(async () => {});
+    const insertMock = vi.fn(() => ({ values: valuesMock }));
+
+    const transactionMock = vi.fn(async (fn: (tx: any) => Promise<void>) => {
+      return fn({ update: updateMock, insert: insertMock });
+    });
+
+    vi.doMock("@/drizzle/db", () => ({
+      db: {
+        transaction: transactionMock,
+      },
+    }));
+
+    const { recordProviderEndpointProbeResult } = await import("@/repository/provider-endpoints");
+
+    await recordProviderEndpointProbeResult({
+      endpointId: 123,
+      source: "manual",
+      ok: false,
+      statusCode: 503,
+      latencyMs: 999,
+      errorType: "http_5xx",
+      errorMessage: "HTTP 503",
+      probedAt: new Date("2026-01-01T00:00:00.000Z"),
+    });
+
+    expect(updateMock).toHaveBeenCalledTimes(1);
+    expect(insertMock).toHaveBeenCalledTimes(1);
+    expect(valuesMock).toHaveBeenCalledTimes(1);
+    expect(valuesMock).toHaveBeenCalledWith(
+      expect.objectContaining({
+        endpointId: 123,
+        source: "manual",
+        ok: false,
+        statusCode: 503,
+        latencyMs: 999,
+        errorType: "http_5xx",
+        errorMessage: "HTTP 503",
+      })
+    );
+  });
+});

+ 142 - 0
tests/unit/repository/statistics-quota-costs-all-time.test.ts

@@ -0,0 +1,142 @@
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
+
+import type { QuotaCostRanges } from "@/repository/statistics";
+
+function concatSqlStringChunks(sqlObject: unknown): string {
+  if (!sqlObject || typeof sqlObject !== "object") return "";
+
+  const maybeSql = sqlObject as { queryChunks?: unknown[] };
+  if (!Array.isArray(maybeSql.queryChunks)) return "";
+
+  return maybeSql.queryChunks
+    .filter((chunk): chunk is string => typeof chunk === "string")
+    .join("");
+}
+
+function createRanges(): QuotaCostRanges {
+  const base = new Date("2026-01-01T00:00:00.000Z");
+  const plus = (ms: number) => new Date(base.getTime() + ms);
+
+  return {
+    range5h: { startTime: base, endTime: plus(5 * 60 * 60 * 1000) },
+    rangeDaily: { startTime: base, endTime: plus(24 * 60 * 60 * 1000) },
+    rangeWeekly: { startTime: base, endTime: plus(7 * 24 * 60 * 60 * 1000) },
+    rangeMonthly: { startTime: base, endTime: plus(30 * 24 * 60 * 60 * 1000) },
+  };
+}
+
+describe("sumUserQuotaCosts & sumKeyQuotaCostsById - all-time query support", () => {
+  beforeEach(() => {
+    vi.resetModules();
+  });
+
+  afterEach(() => {
+    vi.restoreAllMocks();
+  });
+
+  it("sumUserQuotaCosts should treat Infinity as all-time (no created_at cutoff)", async () => {
+    const ranges = createRanges();
+    let capturedAndArgs: unknown[] | undefined;
+    let capturedSelectFields: Record<string, unknown> | undefined;
+
+    vi.doMock("drizzle-orm", async () => {
+      const actual = await vi.importActual<typeof import("drizzle-orm")>("drizzle-orm");
+      return {
+        ...actual,
+        and: (...args: unknown[]) => {
+          capturedAndArgs = args;
+          return (actual as any).and(...args);
+        },
+      };
+    });
+
+    vi.doMock("@/drizzle/db", () => ({
+      db: {
+        select: vi.fn().mockImplementation((fields: Record<string, unknown>) => {
+          capturedSelectFields = fields;
+          return {
+            from: vi.fn().mockReturnValue({
+              where: vi.fn().mockResolvedValue([
+                {
+                  cost5h: "0",
+                  costDaily: "0",
+                  costWeekly: "0",
+                  costMonthly: "0",
+                  costTotal: "0",
+                },
+              ]),
+            }),
+          };
+        }),
+      },
+    }));
+
+    const { sumUserQuotaCosts } = await import("@/repository/statistics");
+    await sumUserQuotaCosts(1, ranges, Infinity);
+
+    expect(capturedAndArgs).toBeDefined();
+    expect(capturedAndArgs?.length).toBe(4);
+
+    expect(capturedSelectFields).toBeDefined();
+    expect(concatSqlStringChunks(capturedSelectFields?.costTotal)).not.toContain("FILTER");
+  });
+
+  it("sumKeyQuotaCostsById should treat Infinity as all-time (no created_at cutoff)", async () => {
+    const ranges = createRanges();
+    let capturedAndArgs: unknown[] | undefined;
+    let capturedSelectFields: Record<string, unknown> | undefined;
+
+    vi.doMock("drizzle-orm", async () => {
+      const actual = await vi.importActual<typeof import("drizzle-orm")>("drizzle-orm");
+      return {
+        ...actual,
+        and: (...args: unknown[]) => {
+          capturedAndArgs = args;
+          return (actual as any).and(...args);
+        },
+      };
+    });
+
+    let selectCallIndex = 0;
+    vi.doMock("@/drizzle/db", () => ({
+      db: {
+        select: vi.fn().mockImplementation((fields: Record<string, unknown>) => {
+          selectCallIndex += 1;
+          const currentCallIndex = selectCallIndex;
+
+          return {
+            from: vi.fn().mockReturnValue({
+              where: vi.fn().mockImplementation(() => {
+                if (currentCallIndex === 1) {
+                  return {
+                    limit: vi.fn().mockResolvedValue([{ key: "test-key-string" }]),
+                  };
+                }
+
+                capturedSelectFields = fields;
+                return Promise.resolve([
+                  {
+                    cost5h: "0",
+                    costDaily: "0",
+                    costWeekly: "0",
+                    costMonthly: "0",
+                    costTotal: "0",
+                  },
+                ]);
+              }),
+            }),
+          };
+        }),
+      },
+    }));
+
+    const { sumKeyQuotaCostsById } = await import("@/repository/statistics");
+    await sumKeyQuotaCostsById(123, ranges, Infinity);
+
+    expect(capturedAndArgs).toBeDefined();
+    expect(capturedAndArgs?.length).toBe(4);
+
+    expect(capturedSelectFields).toBeDefined();
+    expect(concatSqlStringChunks(capturedSelectFields?.costTotal)).not.toContain("FILTER");
+  });
+});

+ 4 - 1
tests/unit/settings/providers/endpoint-latency-sparkline-ui.test.tsx

@@ -89,7 +89,10 @@ describe("EndpointLatencySparkline", () => {
     await flushTicks(5);
 
     expect(container.querySelector('[data-testid="recharts-line"]')).toBeNull();
-    expect(container.querySelector('div[class*="bg-muted/20"]')).not.toBeNull();
+    const placeholder =
+      container.querySelector('div[class*="bg-muted/20"]') ??
+      container.querySelector('div[class*="bg-muted/10"]');
+    expect(placeholder).not.toBeNull();
 
     unmount();
   });

+ 9 - 0
tests/unit/settings/providers/provider-rich-list-item-endpoints.test.tsx

@@ -217,6 +217,15 @@ describe("ProviderRichListItem Endpoint Display", () => {
     const { unmount } = renderWithProviders(
       <ProviderRichListItem
         provider={provider}
+        vendor={{
+          id: 101,
+          websiteDomain: "anthropic.com",
+          displayName: "Anthropic",
+          websiteUrl: "https://anthropic.com",
+          faviconUrl: null,
+          createdAt: new Date("2026-02-01T00:00:00Z"),
+          updatedAt: new Date("2026-02-01T00:00:00Z"),
+        }}
         currentUser={ADMIN_USER}
         enableMultiProviderTypes={true}
       />