From bebe4feccfd445eb6d05454e8bc110bdb532b58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=89=E9=91=AB=E5=8D=87?= Date: Thu, 11 Jun 2026 14:57:27 +0800 Subject: [PATCH] =?UTF-8?q?chore(leaderboard):=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=8E=92=E8=A1=8C=E6=A6=9C=E5=BD=93=E5=A4=A9=E5=BF=AB=E7=85=A7?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E9=97=B4=E9=9A=94=E9=BB=98=E8=AE=A4=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=B8=BA=E5=8D=8A=E5=A4=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADMIN_LEADERBOARD_TODAY_TTL_SECONDS 默认值 300s -> 43200s, 当天数据约每半天重算一次;调度器 tick、凌晨定稿与手动“刷新当天”不变。 Co-Authored-By: Claude Fable 5 --- offline-backend-20260512/backend/CLAUDE.md | 2 +- .../backend/app/gateway/routers/admin_users.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline-backend-20260512/backend/CLAUDE.md b/offline-backend-20260512/backend/CLAUDE.md index e9c96f9c..695d6884 100644 --- a/offline-backend-20260512/backend/CLAUDE.md +++ b/offline-backend-20260512/backend/CLAUDE.md @@ -256,7 +256,7 @@ Proxied through nginx: `/api/langgraph/*` → LangGraph, all other `/api/*` → ### Admin Leaderboard Snapshots (`/api/admin/users/leaderboard*`) -The admin 用户排行榜 is served from **precomputed per-day snapshots** in `admin_leaderboard_daily_stats` (keyed by `(stat_date, settings_hash)`), not by aggregating raw rows on every request. A background scheduler inside the Gateway (`_leaderboard_snapshot_scheduler_loop` in `app/gateway/app.py`, singleton file-locked) ticks every `ADMIN_LEADERBOARD_BACKGROUND_INTERVAL_SECONDS` (default 300s): it prewarms recent days, then builds any `queued`/`error`/stale-`running` day. `GET /leaderboard` merges the per-day snapshots for the requested range. **Today** is rebuilt whenever its snapshot is older than `ADMIN_LEADERBOARD_TODAY_TTL_SECONDS` (default 300s); a past day, once `ready`, is treated as fresh forever. +The admin 用户排行榜 is served from **precomputed per-day snapshots** in `admin_leaderboard_daily_stats` (keyed by `(stat_date, settings_hash)`), not by aggregating raw rows on every request. A background scheduler inside the Gateway (`_leaderboard_snapshot_scheduler_loop` in `app/gateway/app.py`, singleton file-locked) ticks every `ADMIN_LEADERBOARD_BACKGROUND_INTERVAL_SECONDS` (default 300s): it prewarms recent days, then builds any `queued`/`error`/stale-`running` day. `GET /leaderboard` merges the per-day snapshots for the requested range. **Today** is rebuilt whenever its snapshot is older than `ADMIN_LEADERBOARD_TODAY_TTL_SECONDS` (default 43200s = half a day, so the leaderboard refreshes ~twice daily); a past day, once `ready`, is treated as fresh forever. Two on-demand/automatic refresh paths layer on top: - **Manual "刷新当天"** — `POST /leaderboard/refresh-today` force-rebuilds *today's* snapshot **synchronously** (bounded by the same semaphore/timeout the scheduler uses), then returns the merged range. Lets an admin pull the latest real-time records into the stats without waiting for the TTL. Frontend: a "刷新当天" button on `AdminUserLeaderboardPage` → `useRefreshTodayLeaderboard` (`core/admin/hooks.ts`), which primes + invalidates the `["admin-activity","leaderboard"]` query. diff --git a/offline-backend-20260512/backend/app/gateway/routers/admin_users.py b/offline-backend-20260512/backend/app/gateway/routers/admin_users.py index 8d6b5711..c5419444 100644 --- a/offline-backend-20260512/backend/app/gateway/routers/admin_users.py +++ b/offline-backend-20260512/backend/app/gateway/routers/admin_users.py @@ -82,7 +82,7 @@ _LEADERBOARD_DAILY_SNAPSHOT_LIMIT = max( ) _LEADERBOARD_TODAY_TTL_SECONDS = max( 30.0, - float(os.getenv("ADMIN_LEADERBOARD_TODAY_TTL_SECONDS", "300")), + float(os.getenv("ADMIN_LEADERBOARD_TODAY_TTL_SECONDS", "43200")), ) _LEADERBOARD_QUERY_TIMEOUT_MS = max( 500,