-
-
Notifications
You must be signed in to change notification settings - Fork 187
feat(my-usage): cache statistics and timezone fixes #623
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b0f6f89
3a66813
a6b972d
bc8f0d2
30e1681
72ab4fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -299,9 +299,9 @@ export function LeaderboardView({ isAdmin }: LeaderboardViewProps) { | |
| { | ||
| header: t("columns.totalTokens"), | ||
| className: "text-right", | ||
| cell: (row) => formatTokenAmount((row as ProviderCacheHitRateEntry).totalTokens), | ||
| sortKey: "totalTokens", | ||
| getValue: (row) => (row as ProviderCacheHitRateEntry).totalTokens, | ||
| cell: (row) => formatTokenAmount((row as ProviderCacheHitRateEntry).totalInputTokens), | ||
| sortKey: "totalInputTokens", | ||
| getValue: (row) => (row as ProviderCacheHitRateEntry).totalInputTokens, | ||
| }, | ||
|
Comment on lines
299
to
305
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's examine the specific file and lines
cat -n src/app/[locale]/dashboard/leaderboard/_components/leaderboard-view.tsx | sed -n '295,310p'Repository: ding113/claude-code-hub Length of output: 774 🏁 Script executed: # Find and check the i18n message files for the columns.totalTokens key
fd -type f -name "*.json" -path "*/messages/*" | head -20Repository: ding113/claude-code-hub Length of output: 237 🏁 Script executed: # Search for columns.totalTokens in i18n files
rg "totalTokens" -t json src/Repository: ding113/claude-code-hub Length of output: 49 🏁 Script executed: # Find all message/i18n JSON files
find . -type f -name "*.json" -path "*messages*" | head -20Repository: ding113/claude-code-hub Length of output: 705 🏁 Script executed: # Search for totalTokens more broadly, not just in src/
rg "totalTokens" --type jsonRepository: ding113/claude-code-hub Length of output: 1600 🏁 Script executed: # Check what changed in the PR by looking at git diff for i18n files
git diff --name-only | grep -i messagesRepository: ding113/claude-code-hub Length of output: 49 🏁 Script executed: # Check the structure of dashboard.json files, specifically looking for columns key
rg -A 2 -B 2 "columns" messages/en/dashboard.json | head -50Repository: ding113/claude-code-hub Length of output: 1045 🏁 Script executed: # Let's look at the actual JSON structure around totalTokens in dashboard files
python3 << 'EOF'
import json
import glob
for file in glob.glob("messages/*/dashboard.json"):
try:
with open(file, 'r', encoding='utf-8') as f:
data = json.load(f)
# Check if 'columns' key exists
if 'columns' in data:
print(f"\n=== {file} ===")
print("columns keys:", list(data['columns'].keys()))
if 'totalTokens' in data['columns']:
print(f"columns.totalTokens = {data['columns']['totalTokens']}")
# Also check leaderboard section
if 'leaderboard' in data and isinstance(data['leaderboard'], dict):
if 'columns' in data['leaderboard']:
print(f"\n=== {file} (leaderboard.columns) ===")
print("leaderboard.columns keys:", list(data['leaderboard']['columns'].keys())[:10])
if 'totalTokens' in data['leaderboard']['columns']:
print(f"leaderboard.columns.totalTokens = {data['leaderboard']['columns']['totalTokens']}")
except Exception as e:
print(f"Error reading {file}: {e}")
EOFRepository: ding113/claude-code-hub Length of output: 153 🏁 Script executed: # Extract just the leaderboard section from one dashboard file
jq '.leaderboard' messages/en/dashboard.json 2>/dev/null | head -100Repository: ding113/claude-code-hub Length of output: 2567 🏁 Script executed: # Search for both totalTokens and totalInputTokens in the message files
rg "totalInputTokens" messages/Repository: ding113/claude-code-hub Length of output: 49 🏁 Script executed: # Check the exact structure - look for where columns.totalTokens is defined
rg -B 5 "totalTokens" messages/en/dashboard.json | grep -E "(leaderboard|columns|totalTokens)" | head -20Repository: ding113/claude-code-hub Length of output: 140 列标题与实际数据语义不匹配,需要更新国际化 key 逻辑变更正确:将 但存在 UX 问题:第 300 行的列标题使用 需修复:
否则用户会误解为该列显示全部 Token。 🤖 Prompt for AI Agents |
||
| ]; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
date-fns-tz fromZonedTime undefined timezone behavior💡 Result:
Short answer: fromZonedTime has a known implementation issue — it reads date parts with getHours()/getFullYear() (local-time getters) and then builds a UTC Date from those parts, so the result is only correct if the environment's system time zone is UTC. That makes conversions wrong when your system TZ ≠ UTC (including cases where you pass undefined/omit a timeZone). See the GitHub issue describing the problem and the library docs for the intended behavior. [1][2]
What to do:
Sources:
[1] GitHub issue describing the fromZonedTime bug.
[2] date-fns-tz README / docs (function descriptions: fromZonedTime, toZonedTime, formatInTimeZone).
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 1184
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 772
🏁 Script executed:
# Check imports and overall structure head -n 50 src/actions/my-usage.tsRepository: ding113/claude-code-hub
Length of output: 1963
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 367
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 954
🏁 Script executed:
# Check env.schema for TZ configuration fd env.schema -t fRepository: ding113/claude-code-hub
Length of output: 95
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 547
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 878
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 94
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 762
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
Repository: ding113/claude-code-hub
Length of output: 548
fromZonedTime存在已知 Bug,会导致时区转换错误。date-fns-tz中的fromZonedTime函数存在实现缺陷:它使用本地时间的 getter 方法(getHours()、getFullYear()等)而非正确的 UTC 转换,只在系统时区为 UTC 时才能正常工作。即使配置了TZ: "Asia/Shanghai",如果部署环境的系统时区不是 UTC,该函数返回的时间戳仍会错误。这会导致getMyUsageLogs和getMyStatsSummary返回的日期范围查询结果不准确。改用
zonedTimeToUtc或其他库提供的安全函数替代fromZonedTime。🤖 Prompt for AI Agents