Skip to content

fix(mcp): keep the KPI comparison window stable so it can be cached - #131279

Merged
trunk-io[bot] merged 3 commits into
masterfrom
lucas/mcp-kpi-cache-window
Nov 7, 2026
Merged

trunk-io[bot] merged 3 commits into
masterfrom
lucas/mcp-kpi-cache-window

Conversation

@lucasheriques

@lucasheriques lucasheriques commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • Returning to the MCP analytics dashboard tab is slow every time, even with nothing new to load.
  • The KPI and Users tiles widen the date range to compare against the previous period, and that wider window started at the current millisecond.
  • So every load sent new filters, and the server recomputed both queries: 5 to 12 seconds each in one measured session. Every other tile came back from cache in about 300ms.

Changes

  • The comparison window now opens on a whole minute, so loads within the same minute are answered from cache.
  • The previous period stays within a minute of the selected period's length. Rounding to a whole bucket would have skewed every delta by up to a bucket.

How did you test this code?

Test rationale: new cases in the logic's filter-wiring tests. Two loads in the same minute send identical KPI and Users windows (-7d, -24h, -90d). For -7d and -90d just after midnight, the previous period matches the selected one to within a minute. A 14:00 to 14:30 custom range keeps its 13:30 start. The first case fails on master.

  • Not checked: real cache hit rates, which only production shows.

Release status

  • No feature flag controls this change

Docs update

  • None.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, claude-opus-5-5

Skills: /writing-tests, /writing-code-comments, /writing-pr-descriptions

More context for AI agents
  • Decisions: the rounding is scoped to MCP analytics. Error tracking also uses buildComparisonWindow, but its owners should opt in themselves.
  • Follow-ups: the dashboard also refetches every tile when its tab remounts. Keeping its last result across tab switches is a separate change.

@lucasheriques lucasheriques self-assigned this Nov 6, 2026
@trunk-io

trunk-io Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@stamphog
stamphog Bot requested a review from a team November 6, 2026 22:10
@parameterai

parameterai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Risk: No findings

This increment only moves two explanatory comment lines between adjacent test cases in mcpDashboardOverviewLogic.test.ts; no production code changes. Nothing in it introduces or alters any security-relevant surface.

Sentinel reviewed d3011b9 · Review settings

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

✅ Trunk lane — non-backend lane (fe:product:mcp_analytics)

This PR is assigned to the non-backend lane (fe:product:mcp_analytics). It does not run backend Python tests and may merge in parallel with PRs in other lanes.

✅ Complexity (TypeScript) — clean

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

✅ Duplication (Python) — clean

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

🚨 Comment density — 15% of added code lines are comments (9 of 59)

This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.

Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.

Files with the most added comment lines:

File Comment lines Added lines
products/mcp_analytics/frontend/mcpDashboardOverviewLogic.test.ts 6 49
products/mcp_analytics/frontend/mcpDashboardOverviewLogic.ts 3 10

This check does not block merging. It updates on every push and clears when the share drops.

✅ Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 77.40 MiB · no change

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

✅ Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.03 MiB · 25 files no change █████████░ 90.1% of 1.14 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
3.01 MiB · 625 files no change ██████████ 99.2% of 3.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
3.83 MiB · 1,228 files no change ██████████ 95.6% of 4.01 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
7.61 MiB · 2,941 files no change ████████░░ 77.4% of 9.84 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
4.70 MiB · 1,756 files no change ██████████ 95.3% of 4.93 MiB
AI-first home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
6.00 MiB · 2,265 files no change ██████████ 95.7% of 6.27 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
6.69 MiB · 2,519 files no change ███████░░░ 71.0% of 9.41 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
7.71 MiB · 2,884 files no change ███████░░░ 73.5% of 10.49 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
6.91 MiB · 2,605 files no change █████████░ 85.0% of 8.13 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 products/product_analytics/frontend/insights/activityDescriptions stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/zod/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/logic/billing/billingLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/ProductEmptyState/productSetupPreloadLogic.ts stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/kea-test-utils/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/product_analytics/frontend/insights/activityDescriptions stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/panel-layout/ProjectTree/menus/SessionReplayMenuItems.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/navigation/projectNoticeLogic.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/navigation/ImpersonationNotice/ImpersonationNotice.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/cohorts/cohortSavedToast.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/wizard/frontend/runs/WizardRunDetailsDrawer.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayShell.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayContextPanelFloating.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodaySidePanel.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayTopBar.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/todayRailItems.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/subscriptions/frontend/components/Subscriptions/exportNudge/exportNudgeLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/billing/paymentEntryLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/conversations/frontend/components/SidePanel/sidepanelTicketsLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/zod/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/authentication/auth/loginLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/authentication/shared/passkeyLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/cohorts/CohortFilters/constants.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/persons/frontend/logics/personsLogic.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/surveys/constants.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/re2js/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/react-markdown/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/Command/Command.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 packages/quill/packages/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/marked/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/frimousse/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/validators.js stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/web-analytics-validators.js stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/re2js/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/debug/HogDebug.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/QueryEditor/QueryEditor.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 packages/quill/packages/charts/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/RecordingsWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/api/primitives.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/scenes/notebooks/Notebook/notebookLogic.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/marked/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/frimousse/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/web-analytics-validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/re2js/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/nodes/InsightViz/InsightViz.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/nodes/DataVisualization/DataVisualization.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/nodes/WebOverview/WebOverview.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/debug/HogDebug.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/QueryEditor/QueryEditor.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/marked/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/frimousse/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/scenes/web-analytics/LiveMetricsDashboard/LiveWebAnalyticsMetrics.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 products/product_analytics/frontend/insights/trends/WorldMap/countryVectors.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/queries/validators.js stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/re2js/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/scenes/debug/HogDebug.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/queries/QueryEditor/QueryEditor.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/marked/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 src/scenes/settings/SettingsMap.tsx stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 @jspm/core/nodelibs/browser/fs stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/re2js/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/d3/src/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.7 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
4.0 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.9 KiB src/lib/utils/bootTiming.ts
1.7 KiB src/index.tsx
1.7 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.2 KiB src/RootErrorBoundary.tsx
1.1 KiB src/lib/utils/deferredAppContext.ts
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
105.7 KiB src/products.tsx
87.4 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
28.4 KiB src/lib/constants.tsx
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
105.7 KiB src/products.tsx
87.4 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
32.5 KiB src/lib/utils/eventUsageLogic.ts
28.4 KiB src/lib/constants.tsx
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
115.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js
111.3 KiB ../packages/quill/packages/primitives/dist/index.js
105.7 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.4 KiB src/lib/api.ts
79.0 KiB src/scenes/dashboard/dashboardLogic.tsx
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.3 KiB ../packages/quill/packages/primitives/dist/index.js
105.7 KiB src/products.tsx
87.4 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.5 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.3 KiB ../packages/quill/packages/primitives/dist/index.js
105.7 KiB src/products.tsx
87.4 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.5 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
41.7 KiB src/scenes/hog-functions/sub-templates/sub-templates.ts
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.3 KiB ../packages/quill/packages/primitives/dist/index.js
105.7 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.4 KiB src/lib/api.ts
79.0 KiB src/scenes/dashboard/dashboardLogic.tsx
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.5 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
115.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js
111.3 KiB ../packages/quill/packages/primitives/dist/index.js
105.7 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.4 KiB src/lib/api.ts
79.0 KiB src/scenes/dashboard/dashboardLogic.tsx
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
359.8 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
321.1 KiB ../node_modules/.pnpm/posthog-js@1.447.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.3 KiB ../packages/quill/packages/primitives/dist/index.js
105.7 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.4 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.5 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

✅ Frontend layers — no new upward imports, 0 removed

Static imports from a lower frontend layer into a higher one (layers, lowest first: kernel, shell, query, features). Compared with the base branch, so an import that a PR also adds to layer-baseline.txt still shows here. Sizes are the source bytes on the eager path of every logged-in page.

Layer Eager source bytes Δ vs base
kernel 2.97 MiB no change
shell 2.36 MiB no change
query 56.2 KiB no change
features 273.8 KiB no change

Download the interactive layer graph for this PR.

Posted automatically by check-layers

✅ Toolbar bundle — eager 2.43 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.43 MiB · 19 files no change ████░░░░░░ 42.4% of 5.72 MiB
Deferred (lazy) 2.64 MiB · 44 files no change n/a — loads on demand
Loader dist/toolbar.js 1.2 KiB no change █░░░░░░░░░ 6.0% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
967.6 KiB dist/toolbar/toolbar-app-KA76SQM3.css
732.1 KiB dist/toolbar/chunk-chunk-V3AZE3AY.js
290.5 KiB dist/toolbar/chunk-chunk-CBC3BDP6.js
137.0 KiB dist/toolbar/chunk-chunk-MQIOXZW3.js
131.8 KiB dist/toolbar/chunk-chunk-FQJO25M6.js
75.7 KiB dist/toolbar/toolbar-app-SUK4QCK4.js
69.0 KiB dist/toolbar/chunk-chunk-BFAXZMC5.js
33.8 KiB dist/toolbar/chunk-chunk-6EBAJOMK.js
21.9 KiB dist/toolbar/chunk-chunk-ADKYKTIU.js
6.8 KiB dist/toolbar/chunk-chunk-RVLGRPCH.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

✅ Dist folder size — 🔺 +1.0 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 990.70 MiB · 🔺 +1.0 KiB (+0.0%)

✅ Playwright — all passed

All tests passed.

View test results →

@posthog posthog 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.

PostHog Review · Standard · reviewed d948725: 1 Should fix.

See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.

if (!wholeBuckets) {
return window
}
return { ...window, dateFrom: startOfBucket(dayjs(window.dateFrom).tz(timezone), interval).toISOString() }

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.

P2 · Preserve current totals when rounding short custom ranges

With the flag enabled, a custom 14:00–14:30 range uses the day interval. Rounding the doubled start from 13:30 to midnight makes both loaders count morning events as current, since currentStartBucket is also midnight. This changes current KPI totals, not just previous-period deltas. Skip rounding for fixed ranges or prevent expansion into the current bucket.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 1cddd62: the window now rounds only when the rounded start stays before the selected period's first bucket, so a sub-bucket range like 14:00 to 14:30 keeps its 13:30 start. A new test covers that range.

@stamphog stamphog 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.

Not approved — this change needs a human reviewer.

Re-add the stamphog label to request another review once you have addressed this.

The current code confirms @PostHog's unresolved concern about incorrect totals for short custom ranges. Address that inline finding and request another review from @PostHog/mcp-analytics before re-requesting.

  • Author wrote 0% of the modified lines and has 47 merged PRs in these paths (familiarity MODERATE).
  • PostHog Review (Standard) reviewed the current head: 1 finding, posted on the PR.
  • posthog[bot] reviewed the current head.
  • @PostHog on products/mcp_analytics/frontend/mcpDashboardOverviewLogic.ts: The short custom-range concern remains unfixed. For a same-day 14:00–14:30 selection, getDefaultInterval returns day; kpiComparisonWindow rounds the doubled start from 13:30 to midnight while currentStartBucket remains midnight. Both loaders therefore include earlier same-day events in current totals. Skip rounding for fixed ranges or prevent expansion into the current bucket, and add a regression test before re-requesting.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 42L, 2F substantive, 77L/3F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1b-small (77L, 3F, two-areas, fix)
stamphog 2.7.0 .stamphog/policy.yml @ d948725 · reviewed head d948725

@stamphog stamphog 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.

Not approved — this change needs a human reviewer.

Re-add the stamphog label to request another review once you have addressed this.

@PostHog's substantive concern about short custom ranges remains present in the current code. Address that comment in products/mcp_analytics/frontend/mcpDashboardOverviewLogic.ts by preventing expansion into the current bucket or skipping rounding for fixed ranges, then re-request review.

  • Author wrote 0% of the modified lines and has 34 merged PRs in these paths (familiarity MODERATE).
  • @PostHog on products/mcp_analytics/frontend/mcpDashboardOverviewLogic.ts: The short fixed-range concern remains unfixed. A 14:00–14:30 custom range defaults to day buckets; kpiComparisonWindow rounds its doubled start from 13:30 to midnight, while both loaders classify events from midnight as current. Morning events therefore inflate current totals. The rounding has no fixed-range exception.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 24L, 1F substantive, 46L/2F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1b-small (46L, 2F, single-area, fix)
stamphog 2.7.0 .stamphog/policy.yml @ a2976ca · reviewed head a2976ca

stamphog[bot]

This comment was marked as outdated.

The KPI and Users tiles query a doubled comparison window whose start was
computed to the current millisecond, so every dashboard load sent new
filters and the server recomputed both queries (5-12s each when
measured), while every other tile came back from cache in ~300ms.
Returning to the dashboard tab paid that cost each time.

The window now opens on the start of its bucket, so repeat loads hit the
cache. The prior period's oldest bucket becomes whole, which can raise the
prior-period values (and so the deltas) by part of one bucket. A window
shorter than one bucket keeps its start, so events before the selected
start never count as current.

Tests: jest products/mcp_analytics/frontend 746 passed. New cases: two
loads 71s apart send identical KPI and Users windows (-7d, -24h, -90d);
a 14:00-14:30 custom range keeps its 13:30 start. Both fail on master.
@lucasheriques
lucasheriques force-pushed the lucas/mcp-kpi-cache-window branch from 1cddd62 to 604e8ca Compare November 6, 2026 23:39
@stamphog
stamphog Bot dismissed their stale review November 6, 2026 23:39

New commits were pushed — dismissing the stamphog approval from an earlier head. Re-add the trigger label to request a fresh review.

stamphog[bot]

This comment was marked as outdated.

Rounding the window to a whole bucket made the previous period up to a
bucket longer than the selected one: with day buckets just after
midnight, flat traffic read as about -12% on the Sessions, Tool calls and
Users deltas. Rounding to the minute keeps one cache key per minute and
the two periods within a minute of each other.

Tests: jest products/mcp_analytics/frontend 748 passed. New case: for -7d
and -90d at 00:59, the previous period matches the selected one to within
a minute (fails with bucket rounding: 23h longer).
@stamphog
stamphog Bot dismissed their stale review November 6, 2026 23:51

New commits were pushed — dismissing the stamphog approval from an earlier head. Re-add the trigger label to request a fresh review.

stamphog[bot]

This comment was marked as outdated.

@stamphog
stamphog Bot dismissed their stale review November 7, 2026 00:25

New commits were pushed — dismissing the stamphog approval from an earlier head. Re-add the trigger label to request a fresh review.

@stamphog stamphog 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.

Approved.

Contained frontend query-window fix with regression tests; the older review concern about expanding short custom ranges to midnight is addressed by minute-level rounding. No current-head review is provided, but this change does not require independent assurance.

  • Author wrote 0% of the modified lines and has 34 merged PRs in these paths (familiarity MODERATE).
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 23L, 1F substantive, 80L/2F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1b-small (80L, 2F, single-area, fix)
stamphog 2.7.0 .stamphog/policy.yml @ d3011b9 · reviewed head d3011b9

@trunk-io
trunk-io Bot merged commit 30f4100 into master Nov 7, 2026
230 of 231 checks passed
@trunk-io
trunk-io Bot deleted the lucas/mcp-kpi-cache-window branch November 7, 2026 17:00
@deployment-status-posthog

deployment-status-posthog Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-11-07 17:22 UTC Run
prod-us ✅ Deployed 2026-11-07 17:36 UTC Run
prod-eu ✅ Deployed 2026-11-07 17:32 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant