Skip to content

Fix high-concurrency dashboard session stats#988

Merged
ding113 merged 4 commits into
devfrom
fix/high-concurrency-dashboard
Apr 3, 2026
Merged

Fix high-concurrency dashboard session stats#988
ding113 merged 4 commits into
devfrom
fix/high-concurrency-dashboard

Conversation

@ding113

@ding113 ding113 commented Apr 1, 2026

Copy link
Copy Markdown
Owner

Summary

In high-concurrency mode, replace the dashboard's top "Active Sessions" metric with RPM, hide the dashboard live-sessions panel, and hide the active-sessions section on the usage-logs page. Keep the normal-mode session UI unchanged by branching on enableHighConcurrencyMode.

Follow-up to #979 - adapts the dashboard UI to the high-concurrency mode introduced there, where expensive real-time session observability writes are intentionally reduced.

Problem

PR #979 added enableHighConcurrencyMode, but the dashboard and usage-logs pages still rendered session-dependent UI:

  • the top dashboard metric still implied active session counts
  • the dashboard sidebar still fetched and displayed live sessions
  • the usage-logs page still rendered the active-sessions section

In high-concurrency mode those session figures are intentionally incomplete, so the existing UI became misleading and wasted work on queries that should not run.

Solution

Gate the affected UI on enableHighConcurrencyMode:

  • High-concurrency mode
    • show RPM (recentMinuteRequests) as the first dashboard card
    • hide LiveSessionsPanel
    • disable the dashboard active-sessions query
    • hide the usage-logs active-sessions section
  • Normal mode
    • preserve the existing active-sessions metric, live panel, and logs-page section

Changes

  • src/app/[locale]/dashboard/_components/dashboard-bento-sections.tsx
    • pass enableHighConcurrencyMode from system settings into DashboardBento
  • src/app/[locale]/dashboard/_components/bento/dashboard-bento.tsx
    • branch the first metric card between RPM and concurrent sessions
    • only fetch/render live sessions in normal mode
    • restore the shared REFRESH_INTERVAL constant for session polling
    • switch the lower grid from 4 columns to 3 columns in high-concurrency mode
  • src/app/[locale]/dashboard/logs/page.tsx
    • only render UsageLogsActiveSessionsSection in normal mode
    • reuse the already-fetched currencyDisplay when rendering the logs active-sessions section
  • src/app/[locale]/dashboard/logs/_components/usage-logs-sections.tsx
    • keep UsageLogsDataSection request-scoped settings reuse
    • make UsageLogsActiveSessionsSection accept currencyCode directly to avoid an extra settings fetch in normal mode
  • tests/unit/dashboard/dashboard-home-layout.test.tsx
    • cover both high-concurrency and normal-mode dashboard branches
  • tests/unit/dashboard/logs/page.test.tsx
    • cover both high-concurrency and normal-mode logs-page branches
    • add mock isolation and assert the concrete section components rendered by each mode

Local Verification

Targeted regression checks

  • bunx vitest run tests/unit/dashboard/dashboard-home-layout.test.tsx tests/unit/dashboard/logs/page.test.tsx src/app/[locale]/dashboard/logs/_components/usage-logs-sections.test.tsx
    • Result: 3 passed, 9 passed

Full project checks

  • bun run lint
    • Result: exit 0 (10 warnings, 1 info, 0 errors)
  • bun run typecheck
    • Result: exit 0
  • bun run build
    • Result: exit 0
  • bun run test
    • Result: 420 passed | 1 skipped test files, 4199 passed | 3 skipped tests, exit 0

Local browser smoke

Using the repo dev stack at http://127.0.0.1:23000:

  • logged in with local dev admin token cch-dev-admin
  • verified local dev system_settings.enable_high_concurrency_mode = true
  • verified /en/dashboard shows RPM as the first card and no live-sessions panel
  • verified /en/dashboard/logs does not render the active-sessions section

Greptile Summary

This PR adapts the dashboard and usage-logs UI to the high-concurrency mode introduced in #979, ensuring that session-dependent UI elements (which are intentionally degraded in that mode) are hidden and replaced with more meaningful metrics.

Key changes:

  • dashboard-bento.tsx: When enableHighConcurrencyMode is on, the first metric card now shows RPM (recentMinuteRequests) instead of concurrent sessions; the active-sessions React Query is disabled (enabled: isAdmin && !enableHighConcurrencyMode); and LiveSessionsPanel is not rendered. The grid drops from a 4-column to a 3-column layout to fill the space cleanly.
  • dashboard-bento-sections.tsx: Passes enableHighConcurrencyMode from the server-fetched systemSettings into DashboardBento.
  • usage-logs-sections.tsx: Converts UsageLogsActiveSessionsSection from an async component (which fetched its own getSystemSettings()) into a simple synchronous component that receives currencyCode as a prop. UsageLogsDataSection now accepts an optional systemSettings prop as a bypass for the internal cached fetch.
  • logs/page.tsx: Fetches systemSettings once, passes currencyDisplay directly to UsageLogsActiveSessionsSection, conditionally renders it only in normal mode, and forwards the full settings object to UsageLogsDataSection — resolving the duplicate DB-query concern from the previous review thread.
  • Tests: Full test coverage for both modes in two test files, with mock isolation and concrete assertion on which section components are rendered.

Confidence Score: 5/5

  • Safe to merge — changes are well-scoped, well-tested, and the previous double-DB-query concern is fully resolved.
  • All changed paths have unit-test coverage for both high-concurrency and normal modes. No P0 or P1 issues found. The duplicate getSystemSettings call raised in the previous review thread is resolved by this PR: UsageLogsActiveSessionsSection now receives currencyCode as a prop, and UsageLogsDataSection receives the full settings object, so only one DB round-trip is made per request in both modes.
  • No files require special attention.

Important Files Changed

Filename Overview
src/app/[locale]/dashboard/_components/bento/dashboard-bento.tsx Accepts enableHighConcurrencyMode prop to conditionally show RPM vs concurrent-sessions metric, gate the active-sessions query, and hide LiveSessionsPanel; grid switches from 4- to 3-column in HCM.
src/app/[locale]/dashboard/logs/_components/usage-logs-sections.tsx Converts UsageLogsActiveSessionsSection from async (fetching its own settings) to a pure sync component that accepts currencyCode as a prop; UsageLogsDataSection now accepts an optional systemSettings prop to avoid a redundant DB call.
src/app/[locale]/dashboard/logs/page.tsx Fetches systemSettings once, conditionally renders UsageLogsActiveSessionsSection only in normal mode, and passes the settings object down to UsageLogsDataSection, eliminating the duplicate DB query flagged in the previous thread.
tests/unit/dashboard/logs/page.test.tsx New test file covering both HCM and normal mode rendering of UsageLogsPage, using a JSX-tree helper to assert which section components are included in the output.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[DashboardBentoSection / UsageLogsPage\nfetch systemSettings once] --> B{enableHighConcurrencyMode?}

    B -- Yes --> C[DashboardBento\nFirst card: RPM\nSessions query: disabled\nLiveSessionsPanel: hidden\nGrid: 3-column]
    B -- No --> D[DashboardBento\nFirst card: Concurrent Sessions\nSessions query: enabled\nLiveSessionsPanel: shown\nGrid: 4-column]

    A --> E{enableHighConcurrencyMode?}
    E -- Yes --> F[UsageLogsPage\nSkip UsageLogsActiveSessionsSection]
    E -- No --> G[UsageLogsPage\nRender UsageLogsActiveSessionsSection\ncurrencyCode passed as prop]

    F --> H[UsageLogsDataSection\nsystemSettings passed as prop]
    G --> H
Loading

Reviews (4): Last reviewed commit: "refactor: polish high-concurrency dashbo..." | Re-trigger Greptile

@coderabbitai

coderabbitai Bot commented Apr 1, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

引入并传播系统设置开关 enableHighConcurrencyMode;启用时禁用活跃会话轮询并隐藏实时会话面板,同时将仪表板并发度量切换为每分钟请求数(RPM);相关日志页面与单元测试同步支持两种渲染模式。

Changes

Cohort / File(s) Summary
Dashboard Bento 组件
src/app/[locale]/dashboard/_components/bento/dashboard-bento.tsx
新增组件 prop enableHighConcurrencyMode: boolean;将 active-sessions 查询的 enabled 条件改为 isAdmin && !enableHighConcurrencyMode(在高并发模式下禁用轮询);根据该开关切换 admin 指标卡的标题/数值/比较项,并在高并发模式下不渲染 LiveSessionsPanel
Dashboard Sections 传递开关
src/app/[locale]/dashboard/_components/dashboard-bento-sections.tsx
systemSettings.enableHighConcurrencyMode 读取并将 enableHighConcurrencyMode 传递给 DashboardBento
使用日志组件与页面
src/app/[locale]/dashboard/logs/_components/usage-logs-sections.tsx, src/app/[locale]/dashboard/logs/page.tsx
UsageLogsDataSection 增加可选 `systemSettings?: Pick<SystemSettings, "billingModelSource"
测试
tests/unit/dashboard/dashboard-home-layout.test.tsx, tests/unit/dashboard/logs/page.test.tsx
更新/新增单元测试以覆盖两种模式:高并发模式断言显示 RPM、无 live-sessions 面板且不触发会话轮询;非高并发模式断言标准布局并包含 Active Sessions 面板与轮询调用。

预估代码审查工作量

🎯 3 (中等) | ⏱️ ~20 分钟

可能相关的 PR

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确总结了主要变化:在高并发模式下修复仪表板会话统计相关功能。
Description check ✅ Passed PR description详细描述了高并发模式下的Dashboard UI调整,包括问题、解决方案、具体改动和本地验证结果,与代码变更完全相关。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/high-concurrency-dashboard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added bug Something isn't working area:UI area:statistics size/M Medium PR (< 500 lines) labels Apr 1, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a 'High Concurrency Mode' to the dashboard, which optimizes the UI by hiding live session panels and switching metrics from concurrent sessions to Requests Per Minute (RPM) when enabled. The changes include updates to the Bento dashboard components, usage logs sections, and corresponding unit tests. Feedback suggests restoring the REFRESH_INTERVAL constant to avoid magic numbers and implementing request-level caching for system settings to prevent redundant database queries.

Comment thread src/app/[locale]/dashboard/_components/bento/dashboard-bento.tsx
Comment thread src/app/[locale]/dashboard/_components/bento/dashboard-bento.tsx Outdated
Comment thread src/app/[locale]/dashboard/logs/page.tsx
@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

Comment thread src/app/[locale]/dashboard/logs/page.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/`[locale]/dashboard/logs/page.test.tsx:
- Around line 1-2: The test file page.test.tsx under
src/app/[locale]/dashboard/logs is placed outside the project testing
conventions; either move this unit test into the tests/unit/ directory (e.g.,
tests/unit/dashboard/logs/page.test.tsx) or convert it to a source-adjacent test
that matches the src/**/*.test.ts convention (rename/move to
src/app/[locale]/dashboard/logs/page.test.ts) so it follows the rule for
**/*.test.{ts,tsx}; update any import paths accordingly (references:
page.test.tsx, imports like Children/isValidElement/ReactNode and vitest
fixtures describe/expect/it/vi) to ensure test runner discovers it under the
chosen convention.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3e05b930-7c0d-4a36-b35d-6b48f334808b

📥 Commits

Reviewing files that changed from the base of the PR and between b4192bb and caefca7.

📒 Files selected for processing (6)
  • src/app/[locale]/dashboard/_components/bento/dashboard-bento.tsx
  • src/app/[locale]/dashboard/_components/dashboard-bento-sections.tsx
  • src/app/[locale]/dashboard/logs/_components/usage-logs-sections.tsx
  • src/app/[locale]/dashboard/logs/page.test.tsx
  • src/app/[locale]/dashboard/logs/page.tsx
  • tests/unit/dashboard/dashboard-home-layout.test.tsx

Comment thread tests/unit/dashboard/logs/page.test.tsx Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

No significant issues identified in this PR.

PR Size: M

  • Lines changed: 201
  • Files changed: 6

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate
  • Code clarity - Good

Automated review by Codex AI

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Identified PR #988 (“Fix high-concurrency dashboard session stats”)
  • Calculated PR size as M (201 lines changed across 6 files) and applied label size/M
  • Completed a 6‑perspective diff-scoped review and submitted the “No significant issues” review summary via gh pr review

@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/unit/dashboard/logs/page.test.tsx (1)

37-84: 建议增加测试隔离性

当前每个测试都重复动态导入页面模块,且没有在测试之间重置 mock 状态。虽然由于每个测试都显式设置了 mockResolvedValue,当前代码能正常工作,但建议添加 beforeEach 来重置 mock,提高测试隔离性和可维护性。

此外,通过计算子元素数量来验证渲染结果的方式较为脆弱——如果页面结构变化(如添加包装元素),测试会失败。可考虑使用更稳定的断言方式。

建议的改进方案
+import { beforeEach } from "vitest";
+
+let UsageLogsPage: typeof import("@/app/[locale]/dashboard/logs/page").default;
+
+beforeEach(async () => {
+  vi.resetAllMocks();
+  vi.resetModules();
+  const module = await import("@/app/[locale]/dashboard/logs/page");
+  UsageLogsPage = module.default;
+});

 describe("UsageLogsPage", () => {
   it("only renders the logs data section in high concurrency mode", async () => {
     authMocks.getSession.mockResolvedValue({
       user: {
         id: 7,
         role: "admin",
       },
     });
     systemConfigMocks.getSystemSettings.mockResolvedValue({
       enableHighConcurrencyMode: true,
     });

-    const { default: UsageLogsPage } = await import("@/app/[locale]/dashboard/logs/page");
     const element = await UsageLogsPage({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/dashboard/logs/page.test.tsx` around lines 37 - 84, Add test
isolation and replace the brittle child-count assertion: add a beforeEach that
calls jest.resetAllMocks() (or authMocks.getSession.mockReset() and
systemConfigMocks.getSystemSettings.mockReset()) before each test, then keep the
dynamic import of UsageLogsPage but change the final assertions to check for the
presence or absence of specific child components instead of Children.toArray
length — e.g., inspect element.props.children and assert that a child with
type.name or displayName matching "ActiveSessions" exists when
enableHighConcurrencyMode is false and is absent when true, and likewise assert
the presence of the logs section component (e.g., type.name "LogsData") in both
modes; use authMocks.getSession and systemConfigMocks.getSystemSettings to set
up each scenario.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/unit/dashboard/logs/page.test.tsx`:
- Around line 37-84: Add test isolation and replace the brittle child-count
assertion: add a beforeEach that calls jest.resetAllMocks() (or
authMocks.getSession.mockReset() and
systemConfigMocks.getSystemSettings.mockReset()) before each test, then keep the
dynamic import of UsageLogsPage but change the final assertions to check for the
presence or absence of specific child components instead of Children.toArray
length — e.g., inspect element.props.children and assert that a child with
type.name or displayName matching "ActiveSessions" exists when
enableHighConcurrencyMode is false and is absent when true, and likewise assert
the presence of the logs section component (e.g., type.name "LogsData") in both
modes; use authMocks.getSession and systemConfigMocks.getSystemSettings to set
up each scenario.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c3c59e3-4220-45c7-a53c-eb851ad98b3e

📥 Commits

Reviewing files that changed from the base of the PR and between caefca7 and 1d1219f.

📒 Files selected for processing (1)
  • tests/unit/dashboard/logs/page.test.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 072aed3c2d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/app/[locale]/dashboard/logs/page.tsx
@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/unit/dashboard/logs/page.test.tsx (1)

38-47: 建议补上 systemSettings 透传断言,锁定本次 PR 的关键契约。

当前只校验了“组件是否出现”,但还未验证 UsageLogsDataSection 是否拿到 systemSettings。建议同时断言 getSystemSettings 调用次数,增强对回归(例如重复读取或漏传 props)的防护。

参考修改
+const usageLogsDataSectionSpy = vi.fn();

 function MockUsageLogsDataSection() {
+  usageLogsDataSectionSpy(arguments[0]);
   return null;
 }

 MockUsageLogsDataSection.displayName = "UsageLogsDataSection";

 beforeEach(() => {
   vi.clearAllMocks();
+  usageLogsDataSectionSpy.mockClear();
 });

@@
     expect(getChildComponentNames(element)).toEqual(["UsageLogsDataSection"]);
+    expect(systemConfigMocks.getSystemSettings).toHaveBeenCalledTimes(1);
+    expect(usageLogsDataSectionSpy).toHaveBeenCalledWith(
+      expect.objectContaining({
+        systemSettings: expect.objectContaining({
+          enableHighConcurrencyMode: true,
+        }),
+      }),
+    );
   });

@@
     expect(getChildComponentNames(element)).toEqual([
       "UsageLogsActiveSessionsSection",
       "UsageLogsDataSection",
     ]);
+    expect(systemConfigMocks.getSystemSettings).toHaveBeenCalledTimes(1);
+    expect(usageLogsDataSectionSpy).toHaveBeenCalledWith(
+      expect.objectContaining({
+        systemSettings: expect.objectContaining({
+          enableHighConcurrencyMode: false,
+        }),
+      }),
+    );
   });

Also applies to: 96-97, 120-123

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/dashboard/logs/page.test.tsx` around lines 38 - 47, Add assertions
to verify systemSettings is forwarded: update the mocked UsageLogsDataSection
(MockUsageLogsDataSection) and relevant tests to assert that getSystemSettings
was called the expected number of times and that UsageLogsDataSection received
the systemSettings prop (or that the mock was invoked with a props object
containing systemSettings). Locate mocks for
UsageLogsDataSection/UsageLogsActiveSessionsSection and the getSystemSettings
spy in the test file and add assertions for call count and prop presence to lock
the contract and prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/unit/dashboard/logs/page.test.tsx`:
- Around line 38-47: Add assertions to verify systemSettings is forwarded:
update the mocked UsageLogsDataSection (MockUsageLogsDataSection) and relevant
tests to assert that getSystemSettings was called the expected number of times
and that UsageLogsDataSection received the systemSettings prop (or that the mock
was invoked with a props object containing systemSettings). Locate mocks for
UsageLogsDataSection/UsageLogsActiveSessionsSection and the getSystemSettings
spy in the test file and add assertions for call count and prop presence to lock
the contract and prevent regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1ab55b69-4987-45ca-a8b7-fe0e9eb7bf98

📥 Commits

Reviewing files that changed from the base of the PR and between 1d1219f and 072aed3.

📒 Files selected for processing (1)
  • tests/unit/dashboard/logs/page.test.tsx

@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

@ding113
ding113 merged commit de62b49 into dev Apr 3, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Claude Code Hub Roadmap Apr 3, 2026
@github-actions github-actions Bot mentioned this pull request Apr 3, 2026
@ding113
ding113 deleted the fix/high-concurrency-dashboard branch May 13, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:statistics area:UI bug Something isn't working size/M Medium PR (< 500 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant