sub2api/backend/internal/handler/admin/usage_query_cache_test.go
DaydreamCoding bf24b61139 perf(usage): 优化 /admin/usage 打开速度与刷新响应
根因:页面 mount 并发 6 个请求,其中 5 个在原始 usage_logs 上 live 聚合,
且有 1 个重复 getModelStats。优化(不引入预聚合):

前端
- UsageView 经 :model-options 下传 model 列表,移除 UsageFilters 重复的
  getModelStats(mount 请求 6→5,少一次 usage_logs 全表 GROUP BY model)
- 刷新/换筛选保留旧模型数据(invalidateModelStatsCache 只失效标记不清空数据),
  图表不再闪空,刷新期间页面保持可交互

后端
- GetStatsWithFilters 4 条聚合 errgroup 并行(仅 *sql.DB 连接池路径,ent.Tx
  顺序回退以保事务内不并发),endpoint 明细 best-effort;抑制取消级联噪声日志
- /admin/usage/stats 复用 dashboard 的 newSnapshotCache 30s 处理器层缓存,按
  filters+窗口为 key;前端手动刷新带 nocache=1 强制回源(刷新=最新)

注:自合并提交 4c8396c 迁移而来,仅取"列表打开速度与刷新响应"部分;原提交的
"审计查看弹窗大 body 渲染"改动(AuditLogModal / audit-log-format / 审计 i18n)
依赖尚未迁移的审计功能(d8389ade),本次已排除。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 18:56:08 +08:00

29 lines
812 B
Go

package admin
import (
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/pkg/usagestats"
"github.com/stretchr/testify/require"
)
func TestUsageStatsCacheKey_StableAndDistinct(t *testing.T) {
start := time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)
end := time.Date(2026, 5, 31, 0, 0, 0, 0, time.UTC)
base := usagestats.UsageLogFilters{StartTime: &start, EndTime: &end, Model: "claude-3"}
k1 := usageStatsCacheKey(base)
k2 := usageStatsCacheKey(base)
require.NotEmpty(t, k1)
require.Equal(t, k1, k2, "same filters must produce same key")
other := base
other.Model = "gpt-4o"
require.NotEqual(t, k1, usageStatsCacheKey(other), "different model must change key")
withUser := base
withUser.UserID = 7
require.NotEqual(t, k1, usageStatsCacheKey(withUser), "different user must change key")
}