Skip to content

fix(workflows): move a new broadcast onto its own URL once its draft is saved - #107557

Merged
trunk-io[bot] merged 8 commits into
masterfrom
posthog/broadcasts-draft-url
Sep 28, 2026
Merged

trunk-io[bot] merged 8 commits into
masterfrom
posthog/broadcasts-draft-url

Conversation

@dmarchuk

@dmarchuk dmarchuk commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • The broadcast wizard saves a draft on the first Continue, or when the content step opens, but the page stays on /broadcasts/new until launch.
  • A reload then opens a blank wizard, and the saved draft is left behind as an untitled "New broadcast" in the list.

Changes

  • Once the wizard saves a new draft, it replaces /broadcasts/new with /broadcasts/<id>?step=<current step>.
  • The draft's page loads the saved draft and resumes on that step, then drops step from the URL. Without the parameter, a draft resumes at its first incomplete step, as before.
  • A reload after that reopens the same draft.
  • The URL change remounts the wizard from the saved copy. An email edit still waiting on its autosave holds the move until that save lands, so nothing typed during the create or a Continue save is lost.
  • A launch that creates the draft and then stops also moves to the draft URL. That covers an audience over the batch limit, a failed request, and an edit made elsewhere during the launch.
  • A failed email autosave retries up to 3 times, 2 seconds apart. The page moves to the draft URL once a save lands, and the text on screen is never replaced by an older saved copy.

How did you test this code?

Playwright against a local stack:

Step Master This branch
Continue from the first step URL stays /broadcasts/new URL becomes /broadcasts/<id>, still on the goal step
Reload Blank wizard on the first step, draft orphaned Same draft, resumed at its first incomplete step
Jump straight to the content step URL stays /broadcasts/new URL becomes /broadcasts/<id> on the content step
  • Each wizard created exactly one draft (one POST 201), on master and on this branch.
  • Typing during a slow create: a Playwright route held the draft POST for 6 seconds while the subject was typed on the content step.
    • The commit before this fix: the URL moved, the typed subject vanished, and Postgres stored an empty subject.
    • This branch: the URL moved after the autosave, the subject stayed on screen and survived a reload, and Postgres stored it.
  • The Jest cases cover the create race, a Continue that saves a pending edit, and an edit typed while Continue's save is in flight. Each case fails without its fix. So do the cases for a launch from /broadcasts/new that stops at the audience limit or on an edit conflict, and for an autosave that fails once and then saves.
  • Not tested in the browser: that launch path. Reaching it needs the draft create on the content step to fail first.

create-race-after-reloaded

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

Automatic notifications

  • Publish to changelog?

Docs update

None.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Opus 5.5 (claude-opus-5-5)

  • Skills: /writing-pr-descriptions.
  • CodeRabbit CLI: not signed in, so the PR opened without a local pass.
  • The page remounts on its own URL rather than rewriting history in place, because the wizard logic is keyed by the URL's id.

@dmarchuk dmarchuk self-assigned this Sep 28, 2026
@trunk-io

trunk-io Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

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

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

⚠️ Complexity (TypeScript) — 4 functions above the limit (max 22)

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
launchBroadcast products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1190 22 10
<anonymous> products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:823 17 10
setEmail products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1021 12 10
moveToDraft products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1324 11 10
✅ Duplication (Python) — clean

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

✅ Duplication (TypeScript) — clean

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

⚠️ Comment density — 5% of added code lines are comments (12 of 234)

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

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

Files with the most added comment lines:

File Comment lines Added lines
products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts 12 65

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

⚠️ Bundle size — 🔺 +36.6 KiB (+0.1%)

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

Total: 68.92 MiB · 🔺 +36.6 KiB (+0.1%)

File Size Δ vs base
posthog-app/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgePlaygroundScene.js 26.2 KiB 🔺 +26.2 KiB (new)
render-query/src/render-query/render-query.js 20.25 MiB 🟢 -19.2 KiB (-0.1%)
posthog-app/_parent/products/workflows/frontend/Workflows/WorkflowScene.js 50.7 KiB 🔺 +11.2 KiB (+28.4%)
posthog-app/_parent/products/workflows/frontend/TemplateLibrary/MessageTemplate.js 30.8 KiB 🔺 +5.6 KiB (+22.2%)
posthog-app/_parent/products/signals/frontend/inbox/InboxScene.js 467.4 KiB 🔺 +1016 B (+0.2%)

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.57 MiB · 22 files 🔺 +1.3 KiB (+0.1%) █████████░ 85.4% 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.56 MiB · 629 files 🟢 -21.8 KiB (-0.6%) █████████░ 88.4% of 4.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.37 MiB · 2,330 files 🟢 -19.0 KiB (-0.3%) █████████░ 88.3% of 8.34 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

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
301.8 KiB ../node_modules/.pnpm/posthog-js@1.434.14_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
267.6 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.4 KiB src/lib/api.ts
88.4 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
28.4 KiB src/scenes/scenes.ts
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
301.8 KiB ../node_modules/.pnpm/posthog-js@1.434.14_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
271.7 KiB src/taxonomy/core-filter-definitions-by-group.json
267.6 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
100.4 KiB src/lib/api.ts
98.5 KiB ../packages/quill/packages/quill/dist/index.js
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
88.4 KiB src/products.tsx

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.38 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.38 MiB · 19 files 🔺 +1.4 KiB (+0.1%) ████░░░░░░ 41.5% of 5.72 MiB
Deferred (lazy) 2.10 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
798.3 KiB dist/toolbar/toolbar-app-QRKUYVPZ.css
650.9 KiB dist/toolbar/chunk-chunk-ZLZUDQLU.js
483.6 KiB dist/toolbar/chunk-chunk-6JFSEK3E.js
138.3 KiB dist/toolbar/chunk-chunk-SL4WBWFJ.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
75.2 KiB dist/toolbar/toolbar-app-BCYDYBUD.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-4NNH3FVO.js
21.0 KiB dist/toolbar/chunk-chunk-GRXIOXBW.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 — 🔺 +289.4 KiB (+0.0%)

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

Total: 945.70 MiB · 🔺 +289.4 KiB (+0.0%)

✅ Playwright — all passed

All tests passed.

View test results →

@greptile-apps

greptile-apps Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Retrigger

[Medium risk] Adds URL navigation when a new broadcast draft is saved.

The PR is not yet safe to merge because a failed email autosave can leave a newly created draft on /broadcasts/new.

Reviews (2) · Last reviewed commit: "fix(workflows): keep an email edit made ..."

Comment thread products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts
Comment thread products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts Outdated
Comment thread products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

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

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

After a new broadcast draft is saved, the wizard replaces the URL with the saved broadcast URL and current step when no email edit is pending. Email autosaves and Continue also trigger this URL update after saving. The wizard tracks email-edit generations so an older save does not clear the pending state of a newer edit. Launch error and audience-limit paths also trigger the URL update. During draft hydration, the wizard resumes at a valid step from the URL and removes that parameter while preserving other search and hash parameters. If the URL has no valid step, the wizard resumes at the first incomplete step or review.

Priority: ⬇️ Low

Merge Risk: 🟡 Moderate · up to 4c3d2

After a launch conflict, reloading can open a new broadcast wizard instead of the saved draft. Update the URL on that path before merging.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 4c3d2

The change is confined to how the broadcast wizard moves to and restores an already saved draft. No new server endpoint or permission is evident. The main remaining uncertainty is how repeated creation requests are handled.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The changed reachability is a browser URL and wizard restoration path for broadcasts in the current project, rather than a newly defined production API entrypoint. Server-side authorization was not independently established.

Trust Boundaries and Controls

  • observed — The URL-supplied step is checked against known wizard steps before restoration. Draft loading remains scoped by the current project ID; the inspected change does not replace that project context with a URL-supplied one.

Resilience and Maintainability Implications

  • observed — Autosave conflict handling and edit-generation checks limit stale writes and premature remounts in the inspected paths; the tests include edits made during creation and while a Continue save is in flight.
🚥 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 problem, user-visible changes, testing evidence and limitations, release status, docs status, and agent involvement. The agen…
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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

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

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Update the URL after launch creates a draft. · broadcastWizardLogic.ts:1198

products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1198
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update the URL after launch creates a draft.

If launchBroadcast creates a draft and a later preview, schedule, or activation request fails, the page remains at /broadcasts/new. A reload then starts a new wizard instead of reopening the saved draft. Call showSavedDraftUrl after storing the draft, before the later requests.


ℹ️ Review info
⚙️ Run configuration

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

Review profile: QUIET

Plan: Enterprise

Run ID: 5f8c70d1-66c9-45ad-95bf-bdb165720435

📥 Commits

Reviewing files that changed from the base of the PR and between 1006ba5 and a28c61b.

📒 Files selected for processing (1)
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

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

@trunk-io

trunk-io Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

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: 1


ℹ️ Review info
⚙️ Run configuration

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

Review profile: QUIET

Plan: Enterprise

Run ID: 480f8f49-dbb6-45b1-9f3f-5aafeffe26d6

📥 Commits

Reviewing files that changed from the base of the PR and between a28c61b and a0d10bb.

📒 Files selected for processing (2)
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

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

Comment thread products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

@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: dade2698-a918-42c5-b00c-0e29584f6681

📥 Commits

Reviewing files that changed from the base of the PR and between a0d10bb and a8bd188.

📒 Files selected for processing (2)
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

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

Comment thread products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts Outdated

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

🧹 Nitpick comments (1)
products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts (1)

199-199: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Test the Continue race on the route-mounted wizard.

Arrange the test so an email edit is pending before continueStep() while the route is still /broadcasts/new. Do not reset the route after the saved-draft transition. Assert that the route remains /broadcasts/new until the later edit saves.

The current test keeps using the original logic after manually pushing /broadcasts/new. Its final route assertion can pass even if navigation occurs before the later save.


ℹ️ Review info
⚙️ Run configuration

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

Review profile: QUIET

Plan: Enterprise

Run ID: 1cfe8ad5-e69b-4ce8-b703-f05d8299cc45

📥 Commits

Reviewing files that changed from the base of the PR and between a8bd188 and da78dd0.

📒 Files selected for processing (2)
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

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

@dmarchuk
dmarchuk marked this pull request as ready for review September 28, 2026 11:20
@dmarchuk dmarchuk added the stamphog Request AI approval (no full review) label Sep 28, 2026
@github-actions

github-actions Bot commented Sep 28, 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 8802378 · box box-cedf8aca423a · ready in 631s (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 September 28, 2026 11:20
@greptile-apps

greptile-apps Bot commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff

These findings sit on lines the diff does not cover, so they could not be posted inline. Each one leaves this list once its file changes.

  • P1 Autosave failure blocks draft navigation products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1063 ▶

    If the draft is created but the email autosave fails with a network or server error, this handler leaves emailEditPending true. That prevents the move off /broadcasts/new, so reloading opens a blank wizard and leaves the saved draft behind. Clear or recover the pending state on autosave failure while preserving the unsaved edit.

@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 — escalated to a human reviewer.

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

The fix correctly moves the URL off /broadcasts/new once a draft saves via ensureDraft, setEmail, and Continue, with tests covering the associated races. But CodeRabbit flagged (Major) that launchBroadcast's early-failure paths — e.g. the audience-over-limit return, which sends the user back to the recipients step to fix filters — still leave the page on /broadcasts/new after the draft is created, reproducing the exact orphaned-draft-on-reload bug this PR is meant to fix. That comment is unaddressed in the current diff (launchBroadcast never calls the new showSavedDraftUrl action), and an unaddressed valid bot concern should not be auto-approved.

  • Author wrote 100% of the modified lines and has 3 merged PRs in these paths (familiarity STRONG).
  • coderabbitai[bot] reviewed the current head.
  • CodeRabbit's Major comment on broadcastWizardLogic.ts (near launchBroadcast) — call showSavedDraftUrl after the draft is created in launchBroadcast, before the later blast-radius/schedule requests — is not addressed in the current diff, leaving a code path where a mid-launch failure (e.g. audience over the batch limit) orphans the draft on reload, the same bug class this PR fixes elsewhere.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 68L, 1F substantive, 190L/2F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1c-medium (190L, 2F, single-area, fix)
stamphog 2.2.0 .stamphog/policy.yml @ da78dd0 · reviewed head da78dd0

@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Sep 28, 2026
@github-actions
github-actions Bot requested a deployment to preview-pr-107557 September 28, 2026 11:52 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

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

Review profile: QUIET

Plan: Enterprise

Run ID: b7cf2d1c-96e5-4267-a7e7-a7c93516866f

📥 Commits

Reviewing files that changed from the base of the PR and between da78dd0 and 4c3d2f5.

📒 Files selected for processing (2)
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

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

Comment thread products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts

@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 — escalated to a human reviewer.

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

Greptile flagged a still-unaddressed P1 concern (autosave failure leaves emailEditPending true, so the wizard never moves off /broadcasts/new and the draft is orphaned on reload) — I traced the current code and this failure path still doesn't clear the pending flag or retry the URL move, so the bot's concern reads as valid and unresolved in the current diff.

  • Author wrote 100% of the modified lines and has 3 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot].
  • Greptile (independent bot reviewer) raised a P1 'Autosave failure blocks draft navigation' concern that appears unresolved in the current head: the setEmail autosave's catch block only clears cache.emailEditPending for EditedElsewhereError, not for generic/network failures, so a transient save error can still leave a newly created draft stuck on /broadcasts/new and orphaned on reload — the exact bug class this PR is meant to fix, just narrowed to one edge case.
  • This is not a regression versus master (master orphans drafts in more cases), but the unresolved bot concern should be addressed or explicitly rebutted before merge.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 72L, 1F substantive, 238L/2F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1c-medium (238L, 2F, single-area, fix)
stamphog 2.2.0 .stamphog/policy.yml @ 8b547a8 · reviewed head 8b547a8

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

Frontend state/routing fix for the broadcast wizard, not risky territory (no auth, billing, migration, API contract, dependency, or CI surface); author is on the owning team with STRONG familiarity (100% of touched lines, 3 days ago) and added extensive new tests covering the race conditions. The diff shows the prior CodeRabbit "update URL after launch" concern and the Greptile autosave-blocking concern were both addressed with new showSavedDraftUrl calls and a retry mechanism; no active human reviewer, hold comment, or in-progress (👀) review is present.

  • Author wrote 100% of the modified lines and has 3 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot].
  • If the email autosave keeps failing past the 3 retries, emailEditPending is never cleared and the wizard stays on /broadcasts/new indefinitely — same as pre-existing behavior, not a regression, and explicitly called out as untested-in-browser in the PR description.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 85L, 1F substantive, 274L/2F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1c-medium (274L, 2F, single-area, fix)
stamphog 2.2.0 .stamphog/policy.yml @ 8802378 · reviewed head 8802378

@trunk-io
trunk-io Bot merged commit e1fcc28 into master Sep 28, 2026
253 checks passed
@trunk-io
trunk-io Bot deleted the posthog/broadcasts-draft-url branch September 28, 2026 14:41
@deployment-status-posthog

deployment-status-posthog Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-09-28 15:20 UTC Run
prod-us ✅ Deployed 2026-09-28 15:41 UTC Run
prod-eu ✅ Deployed 2026-09-28 15:41 UTC Run

This branch was successfully deployed

1 active deployment
preview-pr-107557 — 88023786 Deployed Sep 28, 2026 by github-actions[bot]
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