Skip to content

feat(marketing-analytics): open exact conversion recordings - #110907

Open
jabahamondes wants to merge 21 commits into
masterfrom
codex/marketing-conversion-details
Open

jabahamondes wants to merge 21 commits into
masterfrom
codex/marketing-conversion-details

Conversation

@jabahamondes

@jabahamondes jabahamondes commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Marketing analytics users cannot open recordings of the sessions behind conversion counts in Ad performance or the legacy dashboard.

Changes

  • Click a positive event or action conversion cell to open its conversion recordings.
  • The popup reuses the existing Replay playlist and player without changing shared Replay components.
  • Marketing analytics selects exact conversion session IDs using the table's attribution, filters, period and campaign mappings.
  • Hidden grouping columns remain available for selection without changing saved column preferences.
  • Query errors show a query ID and a retry action.
  • Empty states distinguish missing session IDs from sessions without available recordings.
  • Warehouse goals, ad rows, ad group rows and shared dashboards do not expose this action.
  • Generated API types and dependency metadata are mechanical changes.

The main review risk is preserving conversion timestamps and session IDs together through live and precomputed attribution.
The processor collects session IDs only for this endpoint, leaving ordinary table queries unchanged.

Note

The initial playlist contains recordings from conversion sessions, not all recordings belonging to the same people.
Replay retains its native controls, including “Show all,” which can clear the session filter.

New surface relative to master, so there is no before screenshot.

Conversion recordings with the existing Replay player

Before and after

Before:

flowchart LR
    Cell[Conversion cell] --> Count[Count only]
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class Cell phYellow;
    class Count phGray;
Loading

After:

flowchart LR
    Cell[Conversion cell] --> API[Marketing analytics endpoint]
    API --> Sessions[Conversion session IDs]
    Sessions --> Replay[Existing Replay playlist and player]
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class Cell,Replay phYellow;
    class API phRed;
    class Sessions phGray;
Loading

How did you test this code?

Test rationale: Existing attribution tests cover totals, not the returned conversion session IDs.
Endpoint tests cover event and action goals, live and precomputed attribution, row mappings, pagination, missing IDs and retryable states.
Logic tests cover failed appends; table tests cover hidden row keys and saved columns.
Storybook covers recordings, unavailable recordings, missing IDs, preparation and query errors.

Local checks covered both event schemas, Jest, TypeScript, repository-wide mypy, strict preflight and light/dark visual snapshots.
Browser checks covered the local empty state, fixture-backed Replay rendering and a narrow viewport.
The broader attribution suite encountered four local dictionary permission failures; that regression run is not fully green.
Production-scale query performance and real captured recording playback remain unchecked.

Latest CI checks are pending.
The earlier coverage report predates this recordings revision.

Release status

  • No feature flag controls this change
  • This change is behind a feature flag and is not available to users
  • This change makes a previously flagged feature available to everyone

Flag: marketing-analytics-conversion-recordings.

Automatic notifications

  • Publish to changelog?

Docs update

Updated the existing conversion query documentation for exact session selection, missing recordings, pagination and query IDs.

🤖 Agent context

Autonomy: Human-driven (agent-assisted).
Agent: Codex, GPT-5 family; the exact runtime variant is not exposed.

This independent alternative to #106305 and the #108015 stack replaces the intermediate people list with exact conversion recordings.
The screenshot replaces the superseded people-list screenshot.
Replay examples reuse existing public repository fixtures.

The earlier CodeRabbit pass fixed missing interaction selectors and append-error pagination.
Mandatory campaign IDs for comparison rows were rejected because those rows aggregate campaign/source groups.
That local review predates this recordings revision.

Skills used

writing-ui-components, writing-kea-logics, writing-tests, writing-user-facing-copy, improving-drf-endpoints, writing-clickhouse-queries, writing-code-comments, writing-dataclasses, maintaining-python-tests, reviewing-with-coderabbit, run-posthog, hogli, running-ci-preflight, debugging-ci-failures, placing-product-frontend-code, implementing-mcp-tools, merging-prs, and writing-pr-descriptions.

@jabahamondes jabahamondes self-assigned this Oct 2, 2026
@trunk-io

trunk-io Bot commented Oct 2, 2026

Copy link
Copy Markdown

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

🚨 Trunk lane — universal lane

This PR is assigned to the universal lane. It cannot merge in parallel with other PRs, so it can take longer to merge. Ask dev-ex if you think this is wrong.

⚠️ Complexity (TypeScript) — 2 functions above the limit (max 14)

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.

Function Location Complexity Limit
ConversionRecordingsModal products/marketing_analytics/frontend/ConversionRecordingsModal.tsx:12 14 10
conversionRecordingsRequest products/marketing_analytics/frontend/conversionRecordingsRequest.ts:73 11 10
⚠️ Duplication (Python) — 2 new duplicated blocks (worst 223 tokens)

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.

First copy Second copy Lines Tokens
products/marketing_analytics/backend/hogql_queries/conversion_goal_processor.py:1586 products/marketing_analytics/backend/hogql_queries/conversion_goal_processor.py:1773 40 223
products/marketing_analytics/backend/hogql_queries/conversion_goal_processor.py:856 products/marketing_analytics/backend/hogql_queries/conversion_goal_processor.py:1118 11 73
✅ 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.

⚠️ Bundle size — 🔺 +4.86 MiB (+7.0%)

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

Total: 74.65 MiB · 🔺 +4.86 MiB (+7.0%)

File Size Δ vs base
render-query/src/render-query/render-query.js 23.44 MiB 🔺 +4.68 MiB (+24.9%)
exporter/src/exporter/scenes/ExporterNotebookScene.js 3.83 MiB 🟢 -66.6 KiB (-1.7%)
posthog-app/src/queries/nodes/WebVitals/WebVitals.js 22.1 KiB 🔺 +6.2 KiB (+39.1%)
posthog-app/src/queries/Query/Query.js 15.8 KiB 🔺 +6.2 KiB (+64.8%)
posthog-app/src/scenes/project-homepage/today/TodayReportHoverCardChart.js 16.4 KiB 🔺 +6.2 KiB (+60.8%)
posthog-app/src/scenes/web-analytics/SessionAttributionExplorer/SessionAttributionExplorerScene.js 21.6 KiB 🔺 +6.2 KiB (+40.1%)
posthog-app/_parent/products/posthog_ai/frontend/components/tool/widgets/CreateInsightWidget.js 16.5 KiB 🔺 +6.1 KiB (+59.5%)
posthog-app/_parent/products/posthog_ai/frontend/components/tool/widgets/QueryWidget.js 16.5 KiB 🔺 +6.1 KiB (+59.3%)
posthog-app/_parent/products/autoresearch/frontend/AutoresearchPipelineScene.js 59.4 KiB 🔺 +6.0 KiB (+11.3%)
posthog-app/_parent/products/groups/frontend/pages/Groups.js 18.9 KiB 🔺 +6.0 KiB (+46.8%)
posthog-app/_parent/products/persons/frontend/pages/PersonsScene.js 21.0 KiB 🔺 +6.0 KiB (+40.2%)
posthog-app/src/scenes/activity/explore/SessionsScene.js 19.3 KiB 🔺 +6.0 KiB (+45.2%)
posthog-app/src/scenes/debug/DebugScene.js 34.4 KiB 🔺 +6.0 KiB (+21.2%)
posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyBuilderScene/CustomerJourneyBuilderScene.js 17.0 KiB 🔺 +6.0 KiB (+54.0%)
posthog-app/_parent/products/endpoints/frontend/EndpointsScene.js 43.2 KiB 🔺 +6.0 KiB (+16.1%)
posthog-app/src/scenes/activity/explore/EventsScene.js 18.9 KiB 🔺 +6.0 KiB (+46.4%)
posthog-app/src/scenes/cohorts/Cohort.js 50.0 KiB 🔺 +5.9 KiB (+13.5%)
posthog-app/_parent/products/ai_observability/frontend/tags/AIObservabilityTagScene.js 42.8 KiB 🔺 +5.9 KiB (+16.0%)
posthog-app/_parent/products/signals/frontend/inbox/components/detail/ReportAiPanel.js 19.2 KiB 🔺 +5.9 KiB (+44.6%)
posthog-app/src/layout/panel-layout/navbar/tabs/NavTabChat.js 25.3 KiB 🔺 +5.9 KiB (+30.5%)
posthog-app/_parent/products/ai_observability/frontend/evaluations/EvaluationsScene.js 34.9 KiB 🔺 +5.9 KiB (+20.2%)
posthog-app/_parent/products/ai_observability/frontend/tags/AIObservabilityTagsScene.js 22.7 KiB 🔺 +5.8 KiB (+34.6%)
posthog-app/_parent/products/endpoints/frontend/EndpointScene.js 67.1 KiB 🔺 +5.8 KiB (+9.4%)
posthog-app/_parent/products/posthog_ai/frontend/scenes/TaskTracker/components/EmbeddedTaskComposerImpl.js 16.8 KiB 🔺 +5.7 KiB (+51.8%)
posthog-app/_parent/products/posthog_ai/frontend/scenes/TaskTracker/components/SidePanelRunnerImpl.js 21.6 KiB 🔺 +5.7 KiB (+36.1%)
posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene.js 105.6 KiB 🔺 +5.7 KiB (+5.7%)
posthog-app/_parent/products/business_knowledge/frontend/scenes/playground/BusinessKnowledgePlaygroundScene.js 30.7 KiB 🔺 +5.7 KiB (+22.7%)
posthog-app/src/scenes/dashboard/Dashboard.js 17.1 KiB 🔺 +5.7 KiB (+49.6%)
posthog-app/src/scenes/web-analytics/WebAnalyticsScene.js 259.2 KiB 🔺 +5.7 KiB (+2.2%)
posthog-app/_parent/products/ai_observability/frontend/prompts/LLMPromptScene.js 58.2 KiB 🔺 +5.6 KiB (+10.7%)
posthog-app/_parent/products/replay_vision/frontend/replay_scanners/components/ScannerScoutsTab.js 24.5 KiB 🔺 +5.5 KiB (+29.3%)
posthog-app/_parent/products/posthog_ai/frontend/scenes/TaskTracker/TaskTracker.js 96.8 KiB 🔺 +5.5 KiB (+6.1%)
posthog-app/_parent/products/tasks/frontend/spaces/SpaceScene.js 77.2 KiB 🔺 +5.5 KiB (+7.7%)
posthog-app/_parent/products/actions/frontend/pages/Action.js 16.8 KiB 🔺 +5.4 KiB (+48.1%)
posthog-app/src/scenes/data-management/definition/DefinitionView.js 41.4 KiB 🔺 +5.4 KiB (+14.9%)
posthog-app/src/scenes/project-homepage/today/TodayReportPage.js 24.4 KiB 🔺 +5.4 KiB (+28.3%)
posthog-app/src/scenes/product-tours/ProductTour.js 185.1 KiB 🔺 +5.3 KiB (+3.0%)
posthog-app/src/scenes/marketing-analytics/MarketingAnalyticsScene.js 140.7 KiB 🔺 +5.3 KiB (+3.9%)
posthog-app/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene.js 16.9 KiB 🔺 +5.3 KiB (+45.8%)
posthog-app/_parent/products/ai_observability/frontend/AIObservabilitySessionScene.js 17.2 KiB 🔺 +5.3 KiB (+44.3%)
posthog-app/_parent/products/early_access_features/frontend/EarlyAccessFeature.js 16.2 KiB 🔺 +5.3 KiB (+48.3%)
posthog-app/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene.js 192.6 KiB 🔺 +5.2 KiB (+2.8%)
posthog-app/src/scenes/experiments/SharedMetrics/SharedMetric.js 23.9 KiB 🔺 +5.2 KiB (+28.1%)
posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerAnalyticsAccountScene/CustomerAnalyticsAccountScene.js 61.7 KiB 🔺 +5.2 KiB (+9.3%)
posthog-app/src/scenes/hog-functions/HogFunctionScene.js 60.7 KiB 🔺 +5.1 KiB (+9.3%)
posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner.js 58.8 KiB 🔺 +5.1 KiB (+9.5%)
posthog-app/src/scenes/insights/InsightScene.js 53.8 KiB 🔺 +4.8 KiB (+9.8%)
posthog-app/_parent/products/signals/frontend/inbox/InboxScene.js 485.4 KiB 🔺 +4.6 KiB (+1.0%)
posthog-app/_parent/products/ai_observability/frontend/AIObservabilityScene.js 171.6 KiB 🔺 +4.4 KiB (+2.6%)
posthog-app/src/scenes/surveys/Survey.js 17.4 KiB 🔺 +4.3 KiB (+32.5%)
posthog-app/src/scenes/saved-insights/SavedInsights.js 95.5 KiB 🔺 +4.1 KiB (+4.5%)
posthog-app/src/scenes/feature-flags/FeatureFlag.js 120.2 KiB 🔺 +3.7 KiB (+3.2%)
exporter/src/exporter/scenes/ExporterInsightScene.js 8.6 KiB 🔺 +1.3 KiB (+17.1%)
exporter/src/exporter/scenes/ExporterQueryScene.js 7.5 KiB 🔺 +1.3 KiB (+20.2%)
exporter/src/queries/nodes/WebVitals/WebVitals.js 12.6 KiB 🔺 +1.3 KiB (+11.2%)
exporter/src/queries/Query/Query.js 6.3 KiB 🔺 +1.3 KiB (+25.1%)
posthog-app/src/scenes/experiments/Experiment.js 294.5 KiB 🟢 -1.2 KiB (-0.4%)
posthog-app/src/scenes/notebooks/NotebookScene.js 33.5 KiB 🟢 -1.2 KiB (-3.5%)
exporter/_parent/products/posthog_ai/frontend/components/tool/widgets/CreateInsightWidget.js 6.9 KiB 🔺 +1.2 KiB (+20.8%)
exporter/_parent/products/posthog_ai/frontend/components/tool/widgets/QueryWidget.js 7.0 KiB 🔺 +1.2 KiB (+20.7%)
posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene.js 93.1 KiB 🟢 -1.2 KiB (-1.3%)
posthog-app/_parent/products/groups/frontend/pages/Group.js 34.5 KiB 🟢 -1.2 KiB (-3.3%)
posthog-app/_parent/products/persons/frontend/pages/PersonScene.js 44.0 KiB 🟢 -1.2 KiB (-2.6%)
posthog-app/_parent/products/replay_vision/frontend/observations/ObservationRecording.js 15.0 KiB 🟢 -1.2 KiB (-7.4%)
posthog-app/src/scenes/notebooks/NotebookCanvasScene.js 24.2 KiB 🟢 -1.2 KiB (-4.7%)
posthog-app/src/scenes/notebooks/NotebookPanel/NotebookPanel.js 25.9 KiB 🟢 -1.2 KiB (-4.4%)
posthog-app/src/scenes/session-recordings/detail/SessionRecordingDetail.js 15.3 KiB 🟢 -1.2 KiB (-7.2%)
posthog-app/src/scenes/session-recordings/file-playback/SessionRecordingFilePlaybackScene.js 18.0 KiB 🟢 -1.2 KiB (-6.2%)
posthog-app/src/scenes/session-recordings/kiosk/SessionRecordingsKiosk.js 23.3 KiB 🟢 -1.2 KiB (-4.9%)
posthog-app/src/scenes/session-recordings/player/modal/SessionPlayerModal.js 15.9 KiB 🟢 -1.2 KiB (-7.0%)
posthog-app/src/scenes/session-recordings/playlist/SessionRecordingsPlaylistScene.js 20.3 KiB 🟢 -1.2 KiB (-5.6%)
posthog-app/src/scenes/session-recordings/SessionRecordings.js 14.7 KiB 🟢 -1.2 KiB (-7.5%)
posthog-app/src/scenes/session-recordings/settings/SessionRecordingsSettingsScene.js 15.6 KiB 🟢 -1.2 KiB (-7.1%)
posthog-app/src/scenes/sessions/SessionProfileScene.js 28.2 KiB 🟢 -1.2 KiB (-4.1%)
exporter/src/exporter/scenes/ExporterDashboardScene.js 7.3 KiB 🔺 +1.1 KiB (+17.0%)
posthog-app/src/scenes/max/Max.js 29.0 KiB 🟢 -1.0 KiB (-3.4%)
posthog-app/src/scenes/project-homepage/ai-first/AiFirstHomepage.js 42.4 KiB 🟢 -1.0 KiB (-2.4%)

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

⚠️ Eager graph — 2 over 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.63 MiB · 22 files 🔺 +82 B (+0.0%) █████████░ 88.8% of 1.84 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.72 MiB · 661 files 🔺 +168 B (+0.0%) █████████░ 92.3% of 4.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.59 MiB · 2,409 files 🔺 +168 B (+0.0%) █████████░ 91.0% of 8.34 MiB
🟡 dashboard scene
src/scenes/dashboard/Dashboard.tsx
13.68 MiB · 4,839 files 🔺 +4.01 MiB (+41.4%) ██████████ 101.5% of 13.48 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
7.61 MiB · 2,417 files 🔺 +168 B (+0.0%) █████████░ 88.6% of 8.58 MiB
🟡 events scene
src/scenes/activity/explore/EventsScene.tsx
13.40 MiB · 4,709 files 🔺 +4.12 MiB (+44.3%) ██████████ 106.1% of 12.64 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
12.11 MiB · 4,130 files 🟢 -14.8 KiB (-0.1%) ████████░░ 77.0% of 15.72 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] 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/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.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

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.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/index.tsx
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
854 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.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
100.5 KiB src/lib/api.ts
92.7 KiB src/products.tsx
69.4 KiB src/lib/lemon-ui/icons/icons.tsx
40.1 KiB src/lib/utils/eventUsageLogic.ts
38.7 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
33.9 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
29.0 KiB ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
279.9 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.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
110.1 KiB ../packages/quill/packages/quill/dist/index.js
100.5 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
92.7 KiB src/products.tsx
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
315.5 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
279.9 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.8 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.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
110.1 KiB ../packages/quill/packages/quill/dist/index.js
100.5 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
279.9 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.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
110.1 KiB ../packages/quill/packages/quill/dist/index.js
100.5 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
92.7 KiB src/products.tsx
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
315.5 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
279.9 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.8 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.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
110.1 KiB ../packages/quill/packages/quill/dist/index.js
100.5 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
315.5 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
306.2 KiB ../node_modules/.pnpm/posthog-js@1.435.5_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
279.9 KiB src/taxonomy/core-filter-definitions-by-group.json
220.3 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.8 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.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
110.1 KiB ../packages/quill/packages/quill/dist/index.js
100.5 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js

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

✅ Toolbar bundle — eager 2.20 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.20 MiB · 19 files 🔺 +168 B (+0.0%) ████░░░░░░ 38.4% of 5.72 MiB
Deferred (lazy) 2.11 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
835.7 KiB dist/toolbar/toolbar-app-Z2QN6LUJ.css
657.6 KiB dist/toolbar/chunk-chunk-ICCNHLTE.js
259.4 KiB dist/toolbar/chunk-chunk-7JWMBALG.js
138.2 KiB dist/toolbar/chunk-chunk-NO7LY7Z5.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
75.2 KiB dist/toolbar/toolbar-app-4JNR2EDC.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-RTVMQWBO.js
21.0 KiB dist/toolbar/chunk-chunk-RB2MZCGP.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

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

⚠️ Dist folder size — 🔺 +27.62 MiB (+2.9%)

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

Total: 988.05 MiB · 🔺 +27.62 MiB (+2.9%)

ℹ️ MCP UI apps size — 33 app(s), 17633.6 KB JS

Built size of each MCP UI app (main.js + styles.css).

App JS CSS
debug 597.9 KB 199.4 KB
action 454.1 KB 199.4 KB
action-list 564.2 KB 199.4 KB
cohort 453.1 KB 199.4 KB
cohort-list 563.2 KB 199.4 KB
email-template 452.9 KB 199.4 KB
error-details 469.6 KB 199.4 KB
error-issue 454.5 KB 199.4 KB
error-issue-list 564.8 KB 199.4 KB
experiment 561.3 KB 199.4 KB
experiment-list 564.9 KB 199.4 KB
experiment-results 566.3 KB 199.4 KB
feature-flag 566.8 KB 199.4 KB
feature-flag-list 570.5 KB 199.4 KB
feature-flag-testing 457.3 KB 199.4 KB
inline-scan 453.6 KB 199.4 KB
insight-actors 562.3 KB 199.4 KB
invite-email-preview 452.3 KB 199.4 KB
llm-costs 559.3 KB 199.4 KB
session-recording 455.3 KB 199.4 KB
survey 454.7 KB 199.4 KB
survey-global-stats 561.9 KB 199.4 KB
survey-list 564.9 KB 199.4 KB
survey-stats 561.9 KB 199.4 KB
trace-span 453.5 KB 199.4 KB
trace-span-list 564.1 KB 199.4 KB
vision-observation-list 563.3 KB 199.4 KB
workflow 453.4 KB 199.4 KB
workflow-list 563.5 KB 199.4 KB
loops-review 457.8 KB 199.4 KB
query-results 774.3 KB 199.4 KB
render-ui 858.4 KB 199.4 KB
visual-review-snapshots 457.9 KB 199.4 KB
✅ Playwright — all passed

All tests passed.

View test results →

⚠️ Backend coverage — 99.0% of changed backend lines covered — 2 uncovered

🧪 Backend test coverage

Patch coverage — changed backend lines (products + core): ████████████████████ 99.0% (266 / 268)

File Patch Uncovered changed lines
products/marketing_analytics/backend/hogql_queries/conversion_goal_processor.py 90.5% 861–862

🤖 Agents: add a test only if an uncovered line exposes a realistic regression that existing tests miss. Otherwise explain why no new test is needed under "How did you test this code?". Gap list: the patch-coverage artifact on this run (gh run download 108499851927066 -n patch-coverage), or the coverage-data block at the end of this comment.

Per-product line coverage (touched products)
Product Coverage Lines
platform_features ██░░░░░░░░░░░░░░░░░░ 12.1% 7 / 58
demo ███████████░░░░░░░░░ 53.4% 1,445 / 2,707
data_tools ████████████░░░░░░░░ 61.2% 90 / 147
warehouse_sources_queue ██████████████░░░░░░ 68.2% 1,868 / 2,740
ai_gateway ███████████████░░░░░ 75.0% 9 / 12
aeo ███████████████░░░░░ 76.3% 617 / 809
batch_exports ████████████████░░░░ 81.3% 21,581 / 26,561
apm █████████████████░░░ 84.1% 1,306 / 1,553
cdp ██████████████████░░ 88.3% 4,559 / 5,164
ml_inference ██████████████████░░ 88.8% 539 / 607
mcp_analytics ██████████████████░░ 89.2% 5,038 / 5,651
product_tours ██████████████████░░ 89.3% 1,340 / 1,500
dashboards ██████████████████░░ 89.6% 6,924 / 7,727
notebooks ██████████████████░░ 90.2% 15,514 / 17,207
signals ██████████████████░░ 90.4% 60,184 / 66,556
cohorts ██████████████████░░ 90.5% 8,534 / 9,434
data_warehouse ██████████████████░░ 90.6% 14,375 / 15,860
streamlit_apps ██████████████████░░ 90.8% 2,679 / 2,951
managed_warehouse ██████████████████░░ 91.0% 10,252 / 11,263
data_modeling ██████████████████░░ 91.2% 10,562 / 11,584
tasks ██████████████████░░ 91.3% 79,747 / 87,308
exports ██████████████████░░ 91.7% 9,684 / 10,566
business_knowledge ██████████████████░░ 92.0% 8,472 / 9,208
engineering_analytics ██████████████████░░ 92.2% 11,497 / 12,475
ai_training ██████████████████░░ 92.2% 356 / 386
today ██████████████████░░ 92.3% 999 / 1,082
webmcp ███████████████████░ 92.5% 248 / 268
early_access_features ███████████████████░ 92.6% 1,339 / 1,446
conversations ███████████████████░ 92.6% 29,225 / 31,559
visual_review ███████████████████░ 92.7% 10,000 / 10,785
managed_migrations ███████████████████░ 92.7% 1,581 / 1,705
stamphog ███████████████████░ 92.8% 8,109 / 8,742
canvas ███████████████████░ 92.9% 7,155 / 7,703
approvals ███████████████████░ 93.0% 3,974 / 4,271
mcp_registry ███████████████████░ 93.1% 1,670 / 1,794
notifications ███████████████████░ 93.2% 1,144 / 1,228
error_tracking ███████████████████░ 93.3% 16,389 / 17,573
surveys ███████████████████░ 93.4% 6,644 / 7,113
autoresearch ███████████████████░ 93.6% 8,955 / 9,572
slack_app ███████████████████░ 93.7% 14,611 / 15,600
context_layer ███████████████████░ 93.8% 3,415 / 3,639
web_analytics ███████████████████░ 93.9% 23,763 / 25,313
billing_alerts ███████████████████░ 94.1% 2,094 / 2,226
mcp_store ███████████████████░ 94.3% 8,959 / 9,501
wizard ███████████████████░ 94.7% 6,150 / 6,496
workflows ███████████████████░ 94.7% 15,227 / 16,072
reminders ███████████████████░ 94.8% 760 / 802
alerts ███████████████████░ 94.9% 10,038 / 10,575
ai_observability ███████████████████░ 94.9% 26,288 / 27,689
review_hog ███████████████████░ 95.0% 11,750 / 12,362
annotations ███████████████████░ 95.1% 817 / 859
customer_analytics ███████████████████░ 95.2% 26,116 / 27,428
legal_documents ███████████████████░ 95.2% 2,311 / 2,427
marketing_analytics ███████████████████░ 95.3% 19,716 / 20,681
endpoints ███████████████████░ 95.3% 9,345 / 9,801
posthog_ai ███████████████████░ 95.4% 2,530 / 2,653
actions ███████████████████░ 95.5% 756 / 792
logs ███████████████████░ 95.5% 15,456 / 16,188
experiments ███████████████████░ 95.5% 33,219 / 34,767
data_catalog ███████████████████░ 95.6% 4,402 / 4,606
tracing ███████████████████░ 95.6% 3,536 / 3,699
replay_vision ███████████████████░ 95.6% 29,389 / 30,727
growth ███████████████████░ 95.7% 11,381 / 11,888
skills ███████████████████░ 95.8% 6,972 / 7,274
messaging ███████████████████░ 95.9% 3,834 / 3,999
product_analytics ███████████████████░ 96.0% 28,521 / 29,696
revenue_analytics ███████████████████░ 96.4% 1,889 / 1,959
user_interviews ███████████████████░ 96.5% 2,870 / 2,974
feature_flags ███████████████████░ 96.6% 27,119 / 28,060
access_control ███████████████████░ 96.7% 7,739 / 8,007
warehouse_sources ███████████████████░ 97.3% 475,513 / 488,633
data_quality ████████████████████ 97.5% 7,701 / 7,895
links ████████████████████ 97.9% 234 / 239
metrics ████████████████████ 98.0% 4,265 / 4,351
security ████████████████████ 98.0% 1,304 / 1,330
analytics_platform ████████████████████ 98.3% 2,784 / 2,833
pulse ████████████████████ 98.5% 2,046 / 2,078
live_debugger ████████████████████ 99.2% 626 / 631
field_notes ████████████████████ 99.4% 172 / 173

Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.

@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Retrigger

[Medium risk] Adds a new feature to show people behind conversion cells in marketing analytics.

The PR does not appear safe to merge while two previously reported drill-down failures remain.

Reviews (2) · Last reviewed commit: "chore: sync generated inputs before conv..."

Comment thread products/marketing_analytics/frontend/conversionPeopleLogic.ts Outdated
@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⛔ Files ignored due to path filters (4)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • products/marketing_analytics/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.zod.ts is excluded by !**/generated/**
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 161625f2-705a-45eb-9692-0d54b4a71a8d

📥 Commits

Reviewing files that changed from the base of the PR and between 0d86a22 and fc77a21.

⛔ Files ignored due to path filters (4)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • products/marketing_analytics/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.zod.ts is excluded by !**/generated/**

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a feature-flagged flow that lets eligible Marketing Analytics conversion cells open a modal with attributed session recordings. The backend carries session IDs through attribution queries and exposes a paginated endpoint with row matching and precompute handling. The frontend prepares hidden row-key columns, builds requests from supported table rows, and displays loading, preparation, error, and empty states.

Priority: ⬇️ Low

Merge Risk: 🟡 Moderate · up to 0d86a

Some conversion cells may open recordings from a different campaign row or show more sessions than the displayed count represents. Resolve these row-matching discrepancies before merging.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 0d86a

The new recording lookup uses project-scoped requests, declares read-access requirements, and reuses the existing recording viewer. No introduced access-control bypass was established, but downstream authorization and some cancellation behavior were not fully verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated exposure is project-level conversion-session discovery followed by recording browsing. Row selection narrows the lookup but is not an authorization boundary; declared scopes and inherited access-control and membership policies are the relevant controls. This path does not itself establish cross-project access.

Security Findings and Attack Paths

  • inferred — A possible stale-page disclosure across teams was not established. Although the conversion loader key contains the request rather than the team, the table requires team-qualified selection identity and the inspected team-switch action performs full navigation, destroying the old page context. This counterevidence rejects the proposed ordinary team-switch attack path, without proving every lifecycle scenario safe.

Trust Boundaries and Controls

  • observed — The inherited ordinary permission chain includes authentication, API-scope enforcement, access-control policy, and team or organization membership. The lookup preserves team/user execution context, and the modal sends returned identifiers as caller-owned playlist filters. Permission-policy internals and independent downstream recording authorization were not fully hydrated.

Resilience and Maintainability Implications

  • observed — The new preparing path inherits an existing warming mechanism with an atomic team/query debounce, a per-team budget, and short enqueue-failure backoff. Its background task has expiry and execution limits and calls to_query rather than executing or caching a privileged result. These controls bound repeated requests and preserve separation between warming authority and user-visible query results; underlying materialization cleanup was not fully inspected.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description is complete and aligned with the template. It explains the user problem, visible changes, feature-flag status, screenshots, testing rationale, known limitations, documentation updates,…
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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

@jabahamondes
jabahamondes marked this pull request as ready for review October 2, 2026 14:46
@parameterai

parameterai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Risk: No findings

This delta replaces the conversion-people endpoint with a conversion-recordings endpoint that returns attributed conversion session IDs (optionally computed in the conversion preaggregate via a new include_session_ids flag), rendered through the existing team-scoped session recordings playlist. All attacker-controlled inputs (group, source, campaign_id, and the now free-text after cursor) reach ClickHouse only as ast.Constant bound parameters, and the endpoint keeps team scoping with marketing_analytics:read + session_recording:read scopes. No new security issues found.

Sentinel reviewed 0d86a22 · Review settings

@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 14:47 In progress
@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

🦔 Hogbox preview · ✅ ready

▶ Open the preview

🔑 Login test@posthog.com / 12345678 (demo data)
🧩 Running this PR's backend and frontend, on the PostHog :master base
🔗 Link stable across rebuilds — a re-push swaps the box underneath, the URL stays
🔒 Access tailnet only (PostHog VPN)
🛠️ Admin inspect & debug state in hogland
💤 Idle sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen

commit fc77a21 · box box-849551fb8edc · ready in 645s (push → usable) · build log · rebuilds on every push, torn down on close

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team October 2, 2026 14:47
@jabahamondes
jabahamondes removed the request for review from a team October 2, 2026 14:48
@jabahamondes jabahamondes added the reviewhog ($$$) Reviews pull requests before humans do label Oct 2, 2026
@posthog

posthog Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

🦔 PostHog Review reviewed this pull request

Found 1 must fix, 5 should fix, 1 consider.

Published 7 findings (view the review).

Resolved comments: 1 fixed, 2 declined, 1 already settled, 2 left for you

@trunk-io

trunk-io Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

Failed Test Failure Summary Logs
Scenes/Code review Default play-test The test failed because a logic component was not mounted when accessed, and there were unhandled network requests intercepted by the mock service... Logs ↗︎
compareTopLevelSections() reports a modifiers change when the current query overrides the team default A TypeError occurred because the code attempted to access the 'add' property of an undefined object. Logs ↗︎

View Full Report ↗︎ ⋅ Docs

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 6699962c-17b8-4184-808d-b5d43cb50b35

📥 Commits

Reviewing files that changed from the base of the PR and between d6a0180 and 01f58d1.

⛔ Files ignored due to path filters (4)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • products/marketing_analytics/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.zod.ts is excluded by !**/generated/**
📒 Files selected for processing (15)
  • .github/new-events-schema-targets.txt
  • docs/internal/web-analytics-query-serving.md
  • frontend/src/lib/constants.tsx
  • frontend/src/scenes/web-analytics/tabs/marketing-analytics/frontend/components/MarketingAnalyticsTable/MarketingAnalyticsTable.tsx
  • products/marketing_analytics/backend/api.py
  • products/marketing_analytics/backend/services/conversion_people.py
  • products/marketing_analytics/backend/services/test_conversion_people.py
  • products/marketing_analytics/frontend/ConversionPeopleModal.stories.tsx
  • products/marketing_analytics/frontend/ConversionPeopleModal.tsx
  • products/marketing_analytics/frontend/conversionPeopleLogic.test.ts
  • products/marketing_analytics/frontend/conversionPeopleLogic.ts
  • products/marketing_analytics/frontend/conversionPeopleRequest.ts
  • products/marketing_analytics/mcp/tools.yaml
  • products/marketing_analytics/package.json
  • services/mcp/src/api/generated.ts

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment thread products/marketing_analytics/backend/services/conversion_people.py Outdated
@posthog

posthog Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏

@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

Found 1 must fix, 5 should fix, 1 consider.

Comment thread products/marketing_analytics/frontend/ConversionPeopleModal.tsx Outdated
Comment thread products/marketing_analytics/backend/services/conversion_people.py Outdated
Comment thread products/marketing_analytics/backend/services/conversion_people.py Outdated
Comment thread products/marketing_analytics/backend/services/conversion_people.py Outdated
Comment thread products/marketing_analytics/backend/api.py Outdated
@posthog posthog Bot removed the reviewhog ($$$) Reviews pull requests before humans do label Oct 2, 2026
Add ph-no-capture to the person link so autocapture and session replay do not record person emails or names, matching PersonDisplay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 8e12072e-c799-4fd9-850e-a3f898a44a44
@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 15:25 In progress
…rsion people

The people query read the warehouse identity column only from schema_map and fell back to the default distinct_id column. A goal that sets its required top-level distinct_id_field without repeating it in schema_map then failed or joined on the wrong column. Fall back to the goal's top-level field and cover it with a warehouse goal test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 8e12072e-c799-4fd9-850e-a3f898a44a44
@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 15:30 In progress
The cell lookup searched only saved conversion goals, so cells of an applied but unsaved goal had no people action. Look up the query's draft goal first, matching the backend's goal order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 8e12072e-c799-4fd9-850e-a3f898a44a44
@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 15:33 In progress
…eople

The conversion people query joined persons on an equality only, so HogQL deduplicated every person in the team before the join. Add a persons.id IN filter to the join, which PersonsTable moves into its deduplication subquery, following the ActorsQueryRunner pattern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 8e12072e-c799-4fd9-850e-a3f898a44a44
@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 15:36 In progress
The conversion people query embeds the full table query, which groups by high-cardinality campaign dimensions, but ran with the default settings that disable GROUP BY spilling. Pass the marketing spill threshold, as the table runner does, and cover the people path in the query settings test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 661927ce-d6cd-4e17-a95a-422ae618ceda
@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 15:48 In progress
DRF CharField trims surrounding whitespace by default, but the people query compares the row keys to table values exactly. A row whose campaign or source keeps a surrounding space then selected the trimmed row's people, or no people. Keep whitespace on group, source_name and campaign_id, and cover a padded row key in the endpoint test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 99c34c7b-5148-4293-a7de-60534d47e149
@github-actions
github-actions Bot requested a deployment to preview-pr-110907 October 2, 2026 15:57 In progress

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

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (2)
products/marketing_analytics/backend/services/conversion_people.py-159-170 (1)

159-170: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Materialize the shared conversions query.

query is rendered in two independent subqueries: the outer FROM source and the persons.id IN subquery. The conversion query includes conversion work and may join person_distinct_ids, so a reachable people lookup can repeat that work. Create an ast.CTE with materialized=True, attach it to people.ctes, and reference its name in both positions. Keep the persons.id IN predicate because PersonsTable promotes it based on the left-side persons.id.

products/marketing_analytics/backend/api.py-1128-1143 (1)

1128-1143: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Allow offsets beyond 10,000 for conversion-people pagination.

conversionPeopleLogic uses the accumulated result count as the next offset. When a cell has more than 10,000 people, the next load-more request can use an offset above the serializer maximum and fail validation. This limits browsing only for unusually large cells. Users can still search or browse earlier pages, so this is a minor, recoverable workflow limitation rather than a major failure.

Raise the serializer maximum, or remove this request-specific cap if the paginator and API do not define a lower maximum.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 939601e7-0a75-40d6-addf-1e2665348898

📥 Commits

Reviewing files that changed from the base of the PR and between 01f58d1 and 7857b35.

⛔ Files ignored due to path filters (4)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • products/marketing_analytics/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.zod.ts is excluded by !**/generated/**
📒 Files selected for processing (6)
  • frontend/src/scenes/web-analytics/tabs/marketing-analytics/frontend/components/MarketingAnalyticsTable/MarketingAnalyticsTable.tsx
  • products/marketing_analytics/backend/api.py
  • products/marketing_analytics/backend/hogql_queries/test_query_settings.py
  • products/marketing_analytics/backend/services/conversion_people.py
  • products/marketing_analytics/backend/services/test_conversion_people.py
  • products/marketing_analytics/frontend/ConversionPeopleModal.tsx

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

@jabahamondes jabahamondes added the stamphog Request AI approval (no full review) label Oct 2, 2026
@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Oct 2, 2026

@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 yet — waiting on the conditions below.

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

Stamphog can't approve this pull request automatically because two gates refused it. The deny-list gate matched the deps_toolchain category, most likely from the pnpm-lock.yaml and products/marketing_analytics/package.json changes, which add kea-loaders and kea-test-utils. The tier gate classified it as T2-never, a cross-cutting feature spanning 22 files and 1,945 lines across backend, frontend, generated code, and MCP tooling. The size gate itself passed.

Please ask a human reviewer to look at it. To make it easier to review, you could move the dependency and lockfile changes into their own pull request, and split the backend endpoint from the frontend modal.

  • 👍 on the PR from greptile-apps[bot].
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✗ matches: deps_toolchain
size ✓ 785L, 12F substantive, 1945L/22F incl. docs/generated/snapshots — within ceiling
tier ✗ classified as T2-never: T2-never (1945L, 22F, cross-cutting, feat)
stamphog 2.3.1 .stamphog/policy.yml @ unknown · reviewed head d27cb16

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 14b13c24-f8e0-46b6-a151-a41ecab295c9

📥 Commits

Reviewing files that changed from the base of the PR and between 7857b35 and d27cb16.

⛔ Files ignored due to path filters (4)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • products/marketing_analytics/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.zod.ts is excluded by !**/generated/**
📒 Files selected for processing (14)
  • docs/internal/web-analytics-query-serving.md
  • frontend/src/lib/constants.tsx
  • frontend/src/scenes/web-analytics/tabs/marketing-analytics/frontend/components/MarketingAnalyticsTable/MarketingAnalyticsTable.tsx
  • frontend/src/scenes/web-analytics/tabs/marketing-analytics/frontend/logic/marketingAnalyticsTableLogic.ts
  • products/marketing_analytics/backend/api.py
  • products/marketing_analytics/backend/hogql_queries/test_query_settings.py
  • products/marketing_analytics/backend/services/conversion_people.py
  • products/marketing_analytics/backend/services/test_conversion_people.py
  • products/marketing_analytics/frontend/ConversionPeopleModal.stories.tsx
  • products/marketing_analytics/frontend/conversionPeopleLogic.test.ts
  • products/marketing_analytics/frontend/conversionPeopleLogic.ts
  • products/marketing_analytics/frontend/conversionPeopleRequest.test.ts
  • products/marketing_analytics/frontend/conversionPeopleRequest.ts
  • services/mcp/src/api/generated.ts

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

default="", allow_blank=True, trim_whitespace=False, help_text="The displayed row source."
)
campaign_id = serializers.CharField(
required=False,

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🔎 Supported by static analysis

🏁 Script executed:

sed -n 36,80p products/marketing_analytics/backend/services/conversion_people.py
sed -n 17,33p products/marketing_analytics/frontend/conversionPeopleRequest.ts
sed -n 65,99p products/marketing_analytics/frontend/conversionPeopleRequest.ts
sed -n 1115,1145p products/marketing_analytics/backend/api.py

Repository: PostHog/posthog

Length of output: 6258


Match the missing-ID comparison row exactly.

In comparison mode, the table must aggregate rows across campaign IDs before the people lookup. If a non-comparison row can omit campaign_id, the current query can also match every ID for the same group and source. Preserve comparison behavior, but ensure non-comparison requests include the selected row's ID, including when the ID is null or empty. Add a test covering both row types.

@jabahamondes jabahamondes changed the title feat(marketing-analytics): show people behind conversion cells feat(marketing-analytics): open exact conversion recordings Oct 2, 2026

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: PostHog/posthog/.coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 5bb226eb-7d1b-46e6-b29c-5260afbf7099

📥 Commits

Reviewing files that changed from the base of the PR and between d27cb16 and 0d86a22.

⛔ Files ignored due to path filters (4)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • products/marketing_analytics/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.ts is excluded by !**/generated/**
  • products/marketing_analytics/frontend/generated/api.zod.ts is excluded by !**/generated/**
📒 Files selected for processing (18)
  • .github/new-events-schema-targets.txt
  • docs/internal/web-analytics-query-serving.md
  • frontend/src/lib/constants.tsx
  • frontend/src/scenes/web-analytics/tabs/marketing-analytics/frontend/components/MarketingAnalyticsTable/MarketingAnalyticsTable.tsx
  • frontend/src/scenes/web-analytics/tabs/marketing-analytics/frontend/logic/marketingAnalyticsTableLogic.ts
  • products/marketing_analytics/backend/api.py
  • products/marketing_analytics/backend/hogql_queries/conversion_goal_processor.py
  • products/marketing_analytics/backend/hogql_queries/test_query_settings.py
  • products/marketing_analytics/backend/services/conversion_recordings.py
  • products/marketing_analytics/backend/services/test_conversion_recordings.py
  • products/marketing_analytics/frontend/ConversionRecordingsModal.stories.tsx
  • products/marketing_analytics/frontend/ConversionRecordingsModal.tsx
  • products/marketing_analytics/frontend/conversionRecordingsLogic.test.ts
  • products/marketing_analytics/frontend/conversionRecordingsLogic.ts
  • products/marketing_analytics/frontend/conversionRecordingsRequest.test.ts
  • products/marketing_analytics/frontend/conversionRecordingsRequest.ts
  • products/marketing_analytics/mcp/tools.yaml
  • services/mcp/src/api/generated.ts

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

ast.Field(chain=["person_id"]),
ast.Field(chain=["conversion_timestamp"]),
ast.Field(chain=["conversion_math_value"]),
*([ast.Field(chain=["session_id"])] if self.include_session_ids else []),

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.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use the same conversion identity for the table and session lookup.

If two precomputed conversions share a person, timestamp, math value, and tracked dimensions but have different session IDs, the table query collapses them into one row. The session lookup keeps both because include_session_ids adds session_id to the distinct-row identity. A conversion cell can therefore show one conversion while its drill-down returns two sessions. Keep the deduplication identity consistent across both queries, or use an event identity that distinguishes genuine conversions in both paths.

@hosthog

hosthog Bot commented Oct 2, 2026

Copy link
Copy Markdown

HostHog preview — posthog-desktop-web

Latest build (fc77a21): https://54ecbf75a88a4b55ba937d13430bdfaa.hosthog.dev

Employee-gated; every push gets a fresh URL whose content never changes. All previews stop serving when the PR closes.

@posthog

posthog Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

👋 Visual changes detected for this PR.

Review and approve in PostHog Visual Review

If these changes are unexpected, they may be caused by a flaky test or a broken snapshot on master. Don't approve — rerun the job or wait for a fix.

Install the Visual Review Chrome extension to see visual review results at the top of your pull requests.

This branch was successfully deployed

1 active deployment
preview-pr-110907 — fc77a21e Deployed Oct 2, 2026 by github-actions[bot]
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