Skip to content

feat(workflows): add the transactional email log api - #127746

Merged
trunk-io[bot] merged 23 commits into
masterfrom
dmarchuk/transactional-email-log-api
Nov 5, 2026
Merged

trunk-io[bot] merged 23 commits into
masterfrom
dmarchuk/transactional-email-log-api

Conversation

@dmarchuk

@dmarchuk dmarchuk commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • A developer whose password reset never arrived can't look up that send in PostHog.

Changes

  • transactional_email_log/ lists sends, newest first, with search by message ID or recipient and filters by status and email.
  • transactional_email_log/:id/ returns one send with its timeline, subject and person. A status Kafka delivered twice shows once.
  • stats/ counts outcomes per email or sending domain. It groups messages as it reads them, so it uses far less memory.
  • The list picks its page from each send's queued row, so a long period doesn't group every send to show 50. A status filter still reads the whole period, unless a search or a selected email narrows it. A queued row Kafka delivered twice takes one place on a page.
  • results/ counts who did an event after their first send, including recipients with no person profile.
  • People see only sends of workflows they can view. Other workflows return 404.
  • Personal API keys need person:read for the list and one send, because they name recipients. Results also need query:read.
  • The list, stats and results count against the same query limits as insights, and answer 429 when those are full.
  • All four sit behind the transactional email flag.
  • API types are regenerated (mechanical). The list is a reviewed exception in test_pagination_contract.py.

How did you test this code?

  • Deleted a workflow through the API on a local copy: its 19 sends stayed in the list, stats and email page, a member with access to only one other workflow still got not found, and a member denied a workflow still got not found after it was deleted. Sends from code show their template_key. Older sends with no recipient or workflow stay hidden, and no backfill is planned.
  • Called every endpoint on the local stack against real sends and real SES updates (feat(workflows): record recipient, domain, opens and clicks per email #127745). Steps are below.
  • Loaded 100M made-up emails for one team (about 350M rows) into local ClickHouse and used the Log and Metrics tabs in a browser. Timings are below.
  • Not run by hand: the conversion limits and the date bounds. The backend test covers them.
  • Not tested at this size: message_assets and person events. Not tested on a real cluster. Local ClickHouse has 2 threads and 7.2 GB, so the times are a guide.
Steps and edge cases
  • Another project's send returns 404, and results matched a hand count.

  • A demo project's delivery updates were simulated, because its mail catcher sends none.

  • In a browser, a member blocked from a workflow got a 404 for its send, and the list and stats left it out. The workflow's creator keeps access.

  • Searched in a browser on demo data: a real message ID found its send, and an ID older than the log and a random UUID found nothing. The search now reads only the 10 minutes around the time in the ID. Not rerun at 100M.

  • In a browser, the log and Metrics loaded normally with the query limits on. With a 429 forced in the browser, Metrics showed the error and Try again loaded the numbers. A backend test covers the real limiter answering 429. The limit was not reached by hand.

  • Repeated the queued row of the 100 newest sends at 100M emails. Pages 1 and 2 still showed 50 different sends, with the next page flagged correctly, in 0.5s.

  • Inserted a redelivered clicked row in ClickHouse. The email page read "Clicked 2 times" before the fix, and shows one click after it. Three real opens at different times still read "Opened 3 times".

  • Inserted a send for a distinct ID with no person, then captured upgraded_plan with $process_person_profile: false. Results went from 1 converted and 10 revenue to 2 converted and 35 revenue.

  • Compared old and new results queries on the demo data for upgraded_plan with revenue, $pageview over 30 days and uploaded_file over 1 day. All three matched.

  • Called each endpoint with two real personal API keys:

    Key scopes list, one send stats results
    hog_flow:read 403, missing person:read 200 403, missing query:read
    plus person:read, query:read 200 200 200
Timings at 100M emails (browser, with ClickHouse's query log)
Action Before After Rows read after
Log, 7 days 33.5s, or failed 0.03s query, 0.5s in the browser 37,710
Log, 30 days Not run 0.6s in the browser About 37,000
Log, next page, and back 3s (24-hour view) 0.5s 56,142
Log, filter by email, 30 days Not run 0.6s in the browser 300K
Log, status filter, 7 days Not run 17s in the browser 87M
Log, status filter on an email that's 1 in 6 sends Not run 16s in the browser 175M
Log, status filter on a rare email Not run 2.9s query 93M
Search, one recipient, 7 days 1.5s 2.3s query 87M
One email: details Under 10 ms 10 ms 1,024 and up to 82,944
One email: other emails to this person 1.5s 3.5s query 98M
Metrics, 7 days Failed: out of memory 18s and 20s, 1 GB each 82M
Metrics, 30 days Not run 75s and 79s, under 500 MB each 350M

"Before" ran on the old key with older data removed, so 7-day volume matched. Search is slower because it now skips newest-first reading, which took 6s for a rare recipient.

CI report notes
  • Python duplication: query_concurrency.py matches the copy in product_analytics, and ai_observability keeps its own too. Products can't import each other's presentation code, so a shared helper is a separate change.
  • Backend coverage: the uncovered lines are dataclass fields in contracts.py and the two ClickHouse reads in message_assets.py. test_counts_who_converted_within_the_window_after_their_first_send runs both reads, so no new test is added.

Test rationale: New test_transactional_email_log.py guards the sort order, the scopes each route needs, a status delivered twice, a conversion with no person profile, conversions in and out of the window, an open hiding a bounce, cross-project reads, workflows the user can't view and deleted templates.

Release status

  • This change is behind a feature flag and is not available to users

Docs update

  • None.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5

Skills: /improving-drf-endpoints, /writing-clickhouse-queries, /writing-dataclasses, /writing-tests, /writing-pr-descriptions, /writing-plainly

More context for AI agents
  • Session: Claude Code session on a devbox, tested on the local dev stack
  • Decisions: Rendered email, subject and person come from message_assets, which already keeps them and blanks sensitive templates. Kafka can deliver a status twice, so the timeline collapses identical rows.
  • Read closely: products/messaging/backend/services/transactional_email_log.py, the list query and the results queries

🤖 Generated with Claude Code

https://claude.ai/code/session_01BMRf2uGenMximWGgxyo3gr

@dmarchuk
dmarchuk added this pull request to stack #127749 November 2, 2026 19:35
@dmarchuk dmarchuk self-assigned this Nov 2, 2026
@dmarchuk dmarchuk changed the title feat(workflows): add an API for the transactional email log, stats and results feat(workflows): add the transactional email log api Nov 2, 2026

@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 a533b42: 2 Must fix, 3 Should fix.

This is the only automatic review while this pull request is a draft. Comment @posthog review to review new changes sooner. Otherwise, a review of the new changes runs when you mark it ready for review.

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.

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs 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) — 1 new duplicated block (worst 139 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/messaging/backend/presentation/query_concurrency.py:1 products/product_analytics/backend/presentation/query_concurrency.py:1 28 139
✅ 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 — no change

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

Total: 76.91 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.02 MiB · 25 files no change █████████░ 89.5% 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.00 MiB · 623 files no change ██████████ 99.0% of 3.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
3.87 MiB · 1,234 files no change ██████████ 96.5% of 4.01 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
7.57 MiB · 2,924 files no change ████████░░ 77.0% 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.73 MiB · 1,760 files no change ██████████ 95.9% 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
5.99 MiB · 2,257 files no change ██████████ 95.5% of 6.27 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
6.59 MiB · 2,484 files no change ███████░░░ 70.0% of 9.41 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
7.58 MiB · 2,836 files no change ███████░░░ 72.3% of 10.49 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
6.89 MiB · 2,593 files no change ████████░░ 84.8% 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/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
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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
104.9 KiB src/products.tsx
87.3 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.3 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
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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
104.9 KiB src/products.tsx
87.3 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.3 KiB src/lib/utils/eventUsageLogic.ts
28.3 KiB src/lib/constants.tsx
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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.7 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js
110.8 KiB ../packages/quill/packages/primitives/dist/index.js
104.9 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.3 KiB src/lib/api.ts
78.5 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
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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
110.8 KiB ../packages/quill/packages/primitives/dist/index.js
104.9 KiB src/products.tsx
87.3 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.0 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
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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
110.8 KiB ../packages/quill/packages/primitives/dist/index.js
104.9 KiB src/products.tsx
87.3 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.0 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
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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
110.8 KiB ../packages/quill/packages/primitives/dist/index.js
104.9 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.3 KiB src/lib/api.ts
78.5 KiB src/scenes/dashboard/dashboardLogic.tsx
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.0 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
Size File
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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.7 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js
110.8 KiB ../packages/quill/packages/primitives/dist/index.js
104.9 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.3 KiB src/lib/api.ts
78.5 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
358.6 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
321.5 KiB ../node_modules/.pnpm/posthog-js@1.446.0_@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
110.8 KiB ../packages/quill/packages/primitives/dist/index.js
104.9 KiB src/products.tsx
96.1 KiB ../packages/quill/packages/components/dist/index.js
87.3 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.0 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 3.00 MiB no change
shell 2.39 MiB no change
query 56.4 KiB no change
features 355.1 KiB no change

Download the interactive layer graph for this PR.

Posted automatically by check-layers

✅ Toolbar bundle — eager 2.41 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.41 MiB · 19 files no change ████░░░░░░ 42.2% of 5.72 MiB
Deferred (lazy) 2.61 MiB · 42 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
959.7 KiB dist/toolbar/toolbar-app-BDU5YOOJ.css
730.5 KiB dist/toolbar/chunk-chunk-5OFHAOCQ.js
290.5 KiB dist/toolbar/chunk-chunk-JALBDYXT.js
131.8 KiB dist/toolbar/chunk-chunk-FQJO25M6.js
130.4 KiB dist/toolbar/chunk-chunk-ZENU6H74.js
75.7 KiB dist/toolbar/toolbar-app-H3OM5EET.js
69.0 KiB dist/toolbar/chunk-chunk-BFAXZMC5.js
33.8 KiB dist/toolbar/chunk-chunk-KQXUYICT.js
21.7 KiB dist/toolbar/chunk-chunk-VHSKFHI2.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 — 🔺 +13.0 KiB (+0.0%)

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

Total: 982.68 MiB · 🔺 +13.0 KiB (+0.0%)

ℹ️ MCP UI apps size — 35 app(s), 29269.0 KB JS

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

App JS CSS
debug 848.8 KB 220.9 KB
explain-chart 1122.8 KB 220.9 KB
action 771.5 KB 220.9 KB
action-list 839.8 KB 220.9 KB
cohort 770.5 KB 220.9 KB
cohort-list 838.8 KB 220.9 KB
email-template 770.4 KB 220.9 KB
error-details 775.4 KB 220.9 KB
error-issue 772.7 KB 220.9 KB
error-issue-list 841.2 KB 220.9 KB
experiment 836.9 KB 220.9 KB
experiment-list 840.5 KB 220.9 KB
experiment-results 838.7 KB 220.9 KB
feature-flag 839.2 KB 220.9 KB
feature-flag-list 842.9 KB 220.9 KB
feature-flag-testing 773.8 KB 220.9 KB
inline-scan 771.0 KB 220.9 KB
insight-actors 838.3 KB 220.9 KB
llm-costs 835.6 KB 220.9 KB
session-recording 772.8 KB 220.9 KB
survey 772.1 KB 220.9 KB
survey-global-stats 835.6 KB 220.9 KB
survey-list 840.5 KB 220.9 KB
survey-stats 835.6 KB 220.9 KB
trace-span 770.9 KB 220.9 KB
trace-span-list 839.7 KB 220.9 KB
vision-observation-list 838.9 KB 220.9 KB
workflow 770.9 KB 220.9 KB
workflow-list 839.1 KB 220.9 KB
workflow-setup-status 770.6 KB 220.9 KB
query-results 1094.3 KB 220.9 KB
render-ui 1198.7 KB 220.9 KB
visual-review-snapshots 775.4 KB 220.9 KB
workflow-data-suggestions 773.2 KB 220.9 KB
workflow-sending-rules 771.9 KB 220.9 KB
✅ Playwright — all passed

All tests passed.

View test results →

⚠️ Backend coverage — 88.0% of changed backend lines covered — 72 uncovered

🧪 Backend test coverage

Patch coverage — changed backend lines (products + core): ██████████████████░░ 88.0% (551 / 623)

File Patch Uncovered changed lines
products/workflows/backend/services/message_assets.py 30.0% 203–205, 219, 232, 243, 270
products/workflows/backend/facade/api.py 33.3% 230, 241–243
products/workflows/backend/facade/contracts.py 33.3% 38–40, 43–45
products/messaging/backend/facade/contracts.py 39.3% 256–259, 261–264, 266–269, 274–276, 281–282, 284–285, 287, 289, 295–303, 308–310, 312
products/messaging/backend/presentation/query_concurrency.py 81.8% 20–23
products/messaging/backend/services/transactional_email_log.py 92.6% 78–79, 95, 156, 194, 209, 221–223, 270, 298, 328, 409, 451–452
products/messaging/backend/presentation/views/transactional_email_log.py 98.5% 258–259

🤖 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 552548098790097 -n patch-coverage), or the coverage-data block at the end of this comment.

Per-product line coverage (touched products)
Product Coverage Lines
demo ██████████████░░░░░░ 71.2% 1,979 / 2,778
knowledge_writer ███████████████░░░░░ 73.6% 1,045 / 1,419
batch_exports ████████████████░░░░ 82.2% 23,516 / 28,595
engineering_analytics █████████████████░░░ 85.5% 12,322 / 14,415
mcp_analytics █████████████████░░░ 86.3% 5,811 / 6,732
commands █████████████████░░░ 86.8% 1,709 / 1,970
posthog_ai ██████████████████░░ 87.9% 4,305 / 4,897
notebooks ██████████████████░░ 88.8% 15,454 / 17,407
mcp_registry ██████████████████░░ 89.0% 1,596 / 1,794
dashboards ██████████████████░░ 89.4% 8,040 / 8,993
product_tours ██████████████████░░ 89.7% 1,355 / 1,510
warehouse_suggestions ██████████████████░░ 90.1% 3,841 / 4,262
cohorts ██████████████████░░ 90.3% 9,219 / 10,211
signals ██████████████████░░ 90.7% 102,983 / 113,560
canvas ██████████████████░░ 91.2% 8,199 / 8,988
data_warehouse ██████████████████░░ 91.4% 15,919 / 17,422
managed_warehouse ██████████████████░░ 91.4% 12,990 / 14,214
tasks ██████████████████░░ 91.4% 84,253 / 92,160
autoresearch ██████████████████░░ 91.5% 11,717 / 12,805
today ██████████████████░░ 91.5% 3,975 / 4,344
cdp ██████████████████░░ 91.5% 10,510 / 11,481
data_modeling ██████████████████░░ 91.8% 12,082 / 13,159
metrics ██████████████████░░ 91.9% 11,560 / 12,579
streamlit_apps ██████████████████░░ 91.9% 3,139 / 3,415
business_knowledge ██████████████████░░ 92.1% 10,825 / 11,753
wizard ██████████████████░░ 92.2% 7,002 / 7,594
review_hog ██████████████████░░ 92.3% 17,836 / 19,323
conversations ██████████████████░░ 92.3% 31,368 / 33,969
error_tracking ███████████████████░ 92.5% 20,375 / 22,018
early_access_features ███████████████████░ 92.6% 1,339 / 1,446
slack_app ███████████████████░ 92.7% 23,664 / 25,518
alerts_platform ███████████████████░ 92.7% 8,744 / 9,429
notifications ███████████████████░ 92.8% 1,218 / 1,312
stamphog ███████████████████░ 93.0% 10,413 / 11,193
alerts ███████████████████░ 93.1% 11,782 / 12,656
surveys ███████████████████░ 93.3% 7,256 / 7,780
web_analytics ███████████████████░ 93.4% 26,472 / 28,347
workflows ███████████████████░ 93.5% 28,561 / 30,531
approvals ███████████████████░ 93.7% 5,004 / 5,341
marketing_analytics ███████████████████░ 93.8% 22,053 / 23,522
context_layer ███████████████████░ 93.8% 3,984 / 4,247
exports ███████████████████░ 93.9% 4,324 / 4,607
cross_project_dashboards ███████████████████░ 93.9% 858 / 914
mcp_store ███████████████████░ 93.9% 9,197 / 9,793
authorization ███████████████████░ 94.0% 671 / 714
billing_alerts ███████████████████░ 94.0% 2,322 / 2,470
ai_observability ███████████████████░ 94.0% 33,984 / 36,138
messaging ███████████████████░ 94.0% 8,646 / 9,194
customer_analytics ███████████████████░ 94.1% 30,795 / 32,714
replay_vision ███████████████████░ 94.4% 33,353 / 35,345
logs ███████████████████░ 94.4% 19,485 / 20,630
reminders ███████████████████░ 94.8% 782 / 825
experiments ███████████████████░ 94.8% 45,390 / 47,873
actions ███████████████████░ 94.9% 997 / 1,051
warehouse_sources ███████████████████░ 94.9% 136,366 / 143,695
growth ███████████████████░ 95.0% 11,563 / 12,176
endpoints ███████████████████░ 95.0% 9,720 / 10,232
annotations ███████████████████░ 95.1% 1,097 / 1,153
skills ███████████████████░ 95.2% 7,633 / 8,018
access_control ███████████████████░ 95.4% 8,470 / 8,881
data_catalog ███████████████████░ 95.7% 4,715 / 4,928
subscriptions ███████████████████░ 95.7% 14,019 / 14,650
product_analytics ███████████████████░ 95.8% 30,539 / 31,877
feature_flags ███████████████████░ 95.8% 29,679 / 30,975
revenue_analytics ███████████████████░ 95.9% 1,877 / 1,958
data_quality ███████████████████░ 96.0% 8,561 / 8,915
tracing ███████████████████░ 96.5% 4,572 / 4,737
account_audits ███████████████████░ 96.7% 770 / 796
pulse ███████████████████░ 97.3% 2,036 / 2,093
analytics_platform ████████████████████ 98.0% 2,883 / 2,943
groups ████████████████████ 98.2% 1,604 / 1,634

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.

@dmarchuk dmarchuk added the cross-lane-change Allow for cross lane (i.e. django + rust) changes to merge at once label Nov 2, 2026
@dmarchuk
dmarchuk force-pushed the dmarchuk/transactional-email-log-api branch 2 times, most recently from df0e879 to a2c29ad Compare November 3, 2026 12:35
@dmarchuk
dmarchuk force-pushed the dmarchuk/transactional-email-log-api branch from a2c29ad to 0e574c6 Compare November 3, 2026 12:48
@dmarchuk
dmarchuk marked this pull request as ready for review November 3, 2026 14:27
@parameterai

parameterai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Risk: No findings

This delta is the fix for the previously reported deleted-workflow access leak: a reader's explicit deny of a workflow now outlives the workflow's deletion, because blocked_ids also draws from the persisted AccessControl deny rows, not just the still-existing workflow rows. The change strictly tightens access, adds no new surface, and covers the list, stats, and single-send reads.

Sentinel reviewed 1e9df84 · Review settings

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team November 3, 2026 14:28

@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 0e574c6: 2 Must fix, 1 Should fix.

@veria-ai

veria-ai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 3 · PR risk: 0/10

@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 98a441d: 1 Should fix.

This is review round 3 on this pull request. When findings keep coming back in the same code, the approach is usually the problem. Before the next fix, check whether a different design would remove the whole class of findings.

@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 52a80f4: 1 Should fix.

This is review round 4 on this pull request. When findings keep coming back in the same code, the approach is usually the problem. Before the next fix, check whether a different design would remove the whole class of findings.

@dmarchuk
dmarchuk requested a review from a team as a code owner November 4, 2026 01:08
@dmarchuk
dmarchuk force-pushed the dmarchuk/transactional-email-log-api branch from 7c08edf to 6b2c30b Compare November 4, 2026 01:09
@dmarchuk
dmarchuk force-pushed the dmarchuk/transactional-email-log-api branch from 6b2c30b to 5efea7c Compare November 4, 2026 12:02

@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 5efea7c: 2 Should fix.

This is review round 5 on this pull request. When findings keep coming back in the same code, the approach is usually the problem. Before the next fix, check whether a different design would remove the whole class of findings.

@dmarchuk
dmarchuk force-pushed the dmarchuk/transactional-email-log-api branch from 7a98ee8 to 48bcf57 Compare November 4, 2026 19:39
@stamphog
stamphog Bot dismissed their stale review November 4, 2026 19:39

A new stamphog review started for this PR — the fresh verdict replaces this approval.

stamphog[bot]

This comment was marked as outdated.

@stamphog
stamphog Bot dismissed their stale review November 5, 2026 10:25

A new stamphog review started for this PR — the fresh verdict replaces this approval.

stamphog[bot]

This comment was marked as outdated.

Base automatically changed from dmarchuk/email-status-events-writes to master November 5, 2026 10:52
@stamphog
stamphog Bot dismissed their stale review November 5, 2026 10:52

The PR was retargeted to a different base branch, so the approved diff is no longer what was reviewed. Stamphog re-reviews automatically.

@trunk-io

trunk-io Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

😎 This pull request was merged.

@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Nov 5, 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.

The prerequisites gate refused this pull request because it has merge conflicts, so stamphog can't review it in its current state. The other gates (deny-list, size and tier) passed, so the conflicts are the only thing blocking it. To move forward, resolve the conflicts by merging or rebasing onto the base branch and push the result. If you still want a person to look at it in the meantime, ask a human reviewer.

Gate mechanics and policy version
Gate Result
prerequisites ✗ merge conflicts present
deny-list ✓ no deny categories matched
size ✓ 1141L, 14F substantive, 2315L/23F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1d-complex (2315L, 23F, cross-cutting, feat)
stamphog 2.7.0 .stamphog/policy.yml @ unknown · reviewed head b86dd82

@dmarchuk dmarchuk added the stamphog Request AI approval (no full review) label Nov 5, 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.

Approved.

Owning-team authorship supplies assurance for the substantive risky changes; the other team's file contains generated types only. No concrete unresolved reviewer concern or production/security showstopper was established; historical review summaries do not provide actionable findings or current-head assurance.

  • Author wrote 0% of the modified lines and has 24 merged PRs in these paths (familiarity MODERATE).
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 1107L, 10F substantive, 2252L/14F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1d-complex (2252L, 14F, two-areas, feat)
stamphog 2.7.0 .stamphog/policy.yml @ 1e9df84 · reviewed head 1e9df84

@trunk-io

trunk-io Bot commented Nov 5, 2026

Copy link
Copy Markdown

This pull request is queued for merge as part of 127747, which will merge 127746, 127747.

@trunk-io
trunk-io Bot merged commit d141e95 into master Nov 5, 2026
294 checks passed
@trunk-io
trunk-io Bot deleted the dmarchuk/transactional-email-log-api branch November 5, 2026 12:41
@trunk-io

trunk-io Bot commented Nov 5, 2026

Copy link
Copy Markdown

This pull request was merged into master as part of stacked PR 127747.

@deployment-status-posthog

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

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-11-05 13:06 UTC Run
prod-us ✅ Deployed 2026-11-05 13:27 UTC Run
prod-eu ✅ Deployed 2026-11-05 13:29 UTC Run

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

Labels

cross-lane-change Allow for cross lane (i.e. django + rust) changes to merge at once stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant