Skip to content

feat(alerts): capture insight alert destination create/delete events - #71027

Merged
vdekrijger merged 6 commits into
masterfrom
posthog-code/insight-alert-destination-analytics
Jul 15, 2026
Merged

feat(alerts): capture insight alert destination create/delete events#71027
vdekrijger merged 6 commits into
masterfrom
posthog-code/insight-alert-destination-analytics

Conversation

@vdekrijger

Copy link
Copy Markdown
Contributor

Problem

We can't measure adoption of insight-alert messaging destinations by type. When a user adds a Slack, Discord, Microsoft Teams, or webhook destination to an insight alert, it's created as a separate HogFunction after the alert — so neither alert created nor alert updated records which destination type was attached. The only broad proxy, integration created, is generic (it also fires for Linear, Google Ads, etc., which aren't alert destinations at all), so it can't answer "how many Discord/Teams alert destinations were set up?"

This gap surfaced when trying to report on Discord and Microsoft Teams alert-destination adoption — there was simply no signal that tied a destination type to an alert.

Changes

Emit dedicated analytics events from the insight alert notification flow, mirroring the existing logs alert destination created / logs alert destination deleted events:

  • insight alert destination created — one per successfully created destination, tagged with type (slack / discord / microsoft_teams / webhook) and alert_id.
  • insight alert destination deleted — tagged with the type derived from the HogFunction's template_id, and alert_id.

Adds a small notificationTypeFromTemplateId helper next to the existing buildAlertDestination template mapping so the two stay in sync.

How did you test this code?

  • Added a parameterized unit test for notificationTypeFromTemplateId (template → type mapping, plus null/unknown handling). jest products/alerts/frontend/logic/alertNotifications.test.ts passes (17/17).
  • Ran kea-typegen on the changed logic — types generate cleanly.
  • Did not exercise the capture calls in a running app; they follow the same posthog.capture pattern already used elsewhere in this logic file and in the logs equivalent.

This new test catches drift between the destination template_ids written in buildAlertDestination and the type mapping used to label the analytics events — a mismatch would silently mislabel adoption.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Authored by the PostHog Slack app (Claude) from a Slack thread. The task started as a data question about Discord/Microsoft Teams insight-alert-destination adoption; the data showed no measurable signal, and investigation traced this to missing instrumentation rather than zero usage. Chose to mirror the established logs-alert destination events rather than enriching alert created/alert updated, because destinations are created as independent HogFunctions and would not be reliably captured on the alert lifecycle events.

No skills were required (frontend-only kea logic change; no DRF/migration/generated-API-type changes).


Created with PostHog from a Slack thread

Insight alert messaging destinations (Slack, Discord, Microsoft Teams, webhook) are created as separate HogFunctions after the alert, so neither `alert created` nor `alert updated` records which destination type was attached. That left no way to measure adoption of individual destination types.

Emit `insight alert destination created` (one per successfully created destination, tagged with `type`) and `insight alert destination deleted` (tagged with the type derived from the HogFunction template_id), mirroring the existing `logs alert destination created`/`deleted` events.

Adds a `notificationTypeFromTemplateId` helper next to the existing template mapping, with a parameterized test guarding the two against drift.

Generated-By: PostHog Code
Task-Id: e9e87adc-1734-4175-b5e1-b2854d717329
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Bundle size — 🔺 +3.6 KiB (+0.0%)

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

Total: 64.77 MiB · 🔺 +3.6 KiB (+0.0%)

File Size Δ vs base
posthog-app/_parent/products/tracing/frontend/TracingScene.js 102.3 KiB 🔺 +2.4 KiB (+2.4%)

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.22 MiB · 22 files no change ███░░░░░░░ 28.4% of 4.29 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.15 MiB · 2,978 files no change █████████░ 88.1% of 9.25 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/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers 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

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/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.1 KiB ../node_modules/.pnpm/posthog-js@1.401.0/node_modules/posthog-js/dist/rrweb.js
267.7 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
235.5 KiB src/taxonomy/core-filter-definitions-by-group.json
222.7 KiB ../node_modules/.pnpm/posthog-js@1.401.0/node_modules/posthog-js/dist/module.js
164.0 KiB src/queries/validators.js
154.3 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
106.1 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 ../packages/quill/packages/quill/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

Dist folder size — 🔺 +34.0 KiB (+0.0%)

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

Total: 1308.11 MiB · 🔺 +34.0 KiB (+0.0%)

Playwright — all passed

All tests passed.

View test results →

Centralize the notification-type → HogFunction template_id mapping into one TEMPLATE_ID_BY_NOTIFICATION_TYPE map. buildAlertDestination reads it and notificationTypeFromTemplateId inverts it, instead of each hand-listing the same four `template-*` literals.

Generated-By: PostHog Code
Task-Id: e9e87adc-1734-4175-b5e1-b2854d717329
The `insight alert destination deleted` capture fired unconditionally before deleteWithUndo resolved, so it was recorded even when the DELETE request failed (deleteWithUndo swallows errors) and on the undo action — inflating deletion counts.

Move the capture into the deleteWithUndo callback and gate it on the non-undo path, so it only fires after a delete actually lands. The destination type is resolved from the closure up front since the HogFunction is gone from state by the time the callback runs.

Generated-By: PostHog Code
Task-Id: e9e87adc-1734-4175-b5e1-b2854d717329
@trunk-io

trunk-io Bot commented Jul 15, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@vdekrijger
vdekrijger marked this pull request as ready for review July 15, 2026 11:29
@github-actions

github-actions Bot commented Jul 15, 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 411f792 · box box-c6eb0f195dfb · ready in 852s (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 July 15, 2026 11:30
@vdekrijger vdekrijger added the stamphog Request AI approval (no full review) label Jul 15, 2026
@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(alerts): only capture destination de..." | Re-trigger Greptile

Comment thread products/alerts/frontend/logic/alertNotificationLogic.ts Outdated
stamphog[bot]
stamphog Bot previously approved these changes Jul 15, 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.

Frontend-only analytics instrumentation adding posthog.capture calls for insight alert destination create/delete, with parameterized test coverage and a STRONG-familiarity author; not risky territory (no migrations, API contracts, auth, billing, deps, or CI touched).

  • Author wrote 89% of the modified lines and has 0 merged PRs in these paths (familiarity STRONG).
  • greptile-apps[bot] reviewed the current head.
  • Unresolved greptile inline comment: deleting a destination with an unrecognized/legacy template_id still emits the deletion event with type: null, so type-filtered deletion reports will undercount those destinations. Minor analytics-completeness gap, not a correctness or safety issue — fine to address as a fast-follow.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 60L, 2F substantive, 84L/3F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1b-small (84L, 3F, single-area, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ 4f77bdc · reviewed head 01c80d8

@posthog

posthog Bot commented Jul 15, 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.

Addresses a Greptile review finding: the delete path could emit `insight alert destination deleted` with `type: null` when a destination's template_id isn't recognized, which pollutes type-filtered deletion reports. Guard the capture on a known type so the delete path only emits classifiable events, matching the create path which always carries a known type.

Generated-By: PostHog Code
Task-Id: e9e87adc-1734-4175-b5e1-b2854d717329
@vdekrijger
vdekrijger enabled auto-merge (squash) July 15, 2026 11:44
@stamphog
stamphog Bot dismissed their stale review July 15, 2026 11:44

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

stamphog[bot]
stamphog Bot previously approved these changes Jul 15, 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.

Frontend-only analytics instrumentation (posthog.capture calls) with no auth/billing/migration/API surface touched; author is on the owning team with strong familiarity, added tests cover the new mapping helper, and the one substantive reviewer comment (unrecognized template losing type on delete) was already addressed in the diff.

  • Author wrote 89% of the modified lines and has 0 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 63L, 2F substantive, 87L/3F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1b-small (87L, 3F, single-area, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ 79cffa7 · reviewed head 6f33174

…lytics

Generated-By: PostHog Code
Task-Id: e9e87adc-1734-4175-b5e1-b2854d717329
The frontend typecheck gate runs kea-typegen and fails on any drift between generated and committed types. notebookNodeSQLV2Logic's committed inline type block on master was missing the isInterrupting value and the interruptRun/setIsInterrupting actions that the logic already declares, so every PR merging with master (including this one) failed the "types up to date" check.

Regenerate the block to include those entries. The resulting file matches kea-typegen's output exactly (blob 2f2b6c6). No logic change — generated types only.

Generated-By: PostHog Code
Task-Id: e9e87adc-1734-4175-b5e1-b2854d717329
@stamphog
stamphog Bot dismissed their stale review July 15, 2026 12:23

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

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

Additive analytics-only change (new posthog.capture calls for alert destination create/delete) with a shared, tested mapping helper; the one prior reviewer concern (unclassified deletions) is already fixed in the current diff. The unrelated notebookNodeSQLV2Logic.ts hunk is just inline-typegen interface additions matching already-existing implementation, not new behavior.

  • Author wrote 89% of the modified lines and has 0 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 70L, 3F substantive, 94L/4F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1b-small (94L, 4F, two-areas, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ d72a7eb · reviewed head 411f792

@vdekrijger
vdekrijger merged commit d2e96c4 into master Jul 15, 2026
199 checks passed
@vdekrijger
vdekrijger deleted the posthog-code/insight-alert-destination-analytics branch July 15, 2026 13:04
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-15 13:34 UTC Run
prod-us ✅ Deployed 2026-07-15 14:01 UTC Run
prod-eu ✅ Deployed 2026-07-15 14:01 UTC Run

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

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant