Skip to content

feat(workflows): show a tailored template gallery on an empty workflows tab - #111816

Closed
Silthus wants to merge 3 commits into
PostHog:masterfrom
Silthus:feat/workflows-first-run-gallery
Closed

Silthus wants to merge 3 commits into
PostHog:masterfrom
Silthus:feat/workflows-first-run-gallery

Conversation

@Silthus

@Silthus Silthus commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Note

Stacked on #111726, which adds starts_on to the global templates. This PR carries that commit. Review the commits after it.

Problem

  • A new team that opens Workflows sees a generic empty state, and "New workflow" drops it into a blank editor.
  • The template gallery exists, but the empty state skips it, and it does not know which templates the project's events can start.

Note

🔵 Merge risk: low (merge-risk rubric)

  • The Workflows tab switches to the gallery for projects with no workflows, and the empty-state gate steps aside, but only with workflows-first-run on.
  • The flag is off by default. Flag off, WorkflowsScene renders WorkflowsTable and the gate decides as before. Logic and render tests cover the switch and the fit rules.

Changes

Kind Files Lines
Production 9 +521 −2
Tests 3 +375 −0
Total 12 +896 −2
  • Behind the new workflows-first-run flag, a project with no workflows sees an email template gallery on the Workflows tab instead of the empty state.
  • Each card shows its cover, its steps, and only what starts it: an event chip, a stretch without an event, or a schedule.
  • Templates the project's events can start come first. "Picked for your data (n)" is the default, "All email templates (n)" sits beside it.
  • One recommended starter leads, highlighted, with a one-line reason above its cover. The welcome sequence wins when the project sends a signup event, otherwise the first ready template.
  • A card that is not ready says "Your app does not send this event yet" under its event chip.
  • "Start playing" is the last card and opens the blank workflow path. A link opens the full template chooser.
  • Picking a card opens the template through the existing createWorkflowFromTemplate path, until the "Make it yours" screen lands.
  • Fit comes from one event_definitions request over every starts_on event. Only definitions with a last_seen_at count, so a planned event does not make a template ready.
  • Schedules count as ready once the project ingested any event.
  • The gate's bypassFeatureFlag hands the tab back to the scene under the flag, so the scene tabs stay reachable. ?empty_state=1 still shows the old screen.
  • New events: workflows first run gallery shown (ready_count, recommended_template_id) and workflows first run template picked (template_id, recommended, ready).
  • Mechanical: a highlighted prop on WorkflowTemplateCard, and the flag constant.
Project Full width 520px scene
Sends signed_up and pageviews signups, full width signups, 520px
Sends only pageviews pageviews, full width pageviews, 520px
Sends no events no events, full width no events, 520px

How did you test this code?

Test seams:

  • firstRunGalleryLogic.test.ts drives the gallery logic with templates and event definitions mocked at the HTTP layer.
    • Six project shapes check fit, matched event, recommendation, order and filter. They cover alias preference, a planned (never seen) signup event, and schedules ready from ingested_event alone.
    • One case checks that the gallery asks for every starts_on event in a single request.
    • The analytics cases check both events and that each kind of pick opens its template.
    • Two cases check the error banner state and its retry for each lookup.
  • WorkflowsFirstRunTab.test.tsx renders the tab and checks that a project without workflows gets the gallery and one with a workflow gets the table.
  • WorkflowsFirstRun.stories.tsx renders the whole app at /workflows for the three projects and a 520px scene. The screenshots above come from those stories in a headless browser.
  • No existing test covered this logic, because it is new. A kea logic test is the cheapest level that sees the HTTP requests and the selectors together.
  • Proof on the ticket: red, green.
  • Not checked: a real backend round trip, and the flag-off scene in a browser.

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. The flag is off.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5. Review panel: GPT-6.1 Sol and Claude Opus 5.5.

  • Slice of the Workflows first run map (Silthus/posthog#253), ticket Silthus/posthog#258. Built test-first.
  • Skills: tdd, qa-swarm, merge-risk, /placing-product-frontend-code, /writing-kea-logics, /writing-ui-components, /writing-tests, /writing-user-facing-copy, /writing-code-comments, /writing-pr-descriptions, /reviewing-with-coderabbit.
  • CodeRabbit CLI: skipped, because the CLI was signed out and no person was available to sign in. The remote CodeRabbit review only commented on the parent PR's template files.
  • Four review rounds. Round 1 found that planned event definitions counted as seen, now fixed. Rounds 2 to 4 tightened copy, tests and a type name.
  • Calls a reviewer may redirect: the reason sits above the cover rather than in the footer; the gallery loads the templates list itself rather than reusing workflowTemplatesLogic.
  • The screenshots live on a fork branch, because the PR asset upload lacked permission for this account.
  • Duplicate search: gh pr list --search "workflows first run gallery" found nothing related.

🤖 Generated with Claude Code

@trunk-io

trunk-io Bot commented Oct 5, 2026

Copy link
Copy Markdown

Merging to master in this repository is managed by Trunk.

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

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

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

We couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting @coderabbitai full review.

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds starts_on metadata to workflow-template API responses and configures global templates with event, no-event, schedule, or null start conditions. It adds frontend logic to assess template readiness, rank recommendations, and track gallery interactions. A feature-flagged first-run tab displays the gallery and its template cards. API and frontend tests cover metadata, readiness, recommendations, and selection.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to 6fefa

The gallery can recommend a template that users cannot activate, and its onboarding and schedule guidance is inaccurate. Other templates remain available, so the impact is bounded; fix these issues before expanding the feature.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 6fefa

The gallery reuses the existing draft editor rather than executing workflows directly. Risk is bounded, but an email template’s audience changes outside the gallery flag, so disabling the gallery does not fully roll back that change.

Retained concerns

  • Low · security · observed: The full PR broadens the onboarding email template’s default audience by removing its person-email predicate while retaining the messaging/campaigns URL filter. This executable template change is outside the gallery flag: disabling the gallery does not restore the former predicate. Selection still produces a draft requiring configuration and explicit persistence or activation, so this is a bounded audience-control and rollback concern, not verified unauthorized sending.
Security review details

Security Blast Radius

  • inferred — The shared onboarding template change is available across projects that consume global templates, but its execution exposure is through subsequently configured and enabled project workflows. The removed predicate broadens eligible events; it does not establish immediate sending or an update to every existing workflow.

Trust Boundaries and Controls

  • observed — Gallery template and event-definition requests include the current project ID. The event-definition implementation applies project filtering, and existing test source asserts denial of another team’s definitions. The public template endpoint exposes global repository templates rather than project event data.

Resilience and Maintainability Implications

  • observed — Template selection does not create a runnable workflow by itself. New template-derived workflows load as drafts, and automatic saving skips workflows whose ID is new. This limits the consequences of repeated selection or interrupted gallery navigation before explicit persistence.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description is self-contained and covers the user problem, visible changes, screenshots, test coverage and gaps, release status, and agent context. The release status uses checkboxes instead of th…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Note

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

🟡 Other comments (2)
products/workflows/backend/templates/onboarding_started_but_not_completed_template.json-4-8 (1)

4-8: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

starts_on.detail says /onboarding, but the trigger filters on messaging/campaigns.

The card shows "on /onboarding". The trigger at lines 37-40 and lines 131-134 matches $current_url icontains "messaging/campaigns". If a user picks this template, the workflow starts on a different page than the card says. Make the two agree. Either change the trigger value to /onboarding, or change detail to describe the real filter.

products/workflows/backend/templates/trial-ending-reminder.json-4-8 (1)

4-8: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the unsupported three-day detail.

The first-run card displays “ends in 3 days” beside $pageview. This workflow waits 12 days after its trigger, then sends an email described as a two-day reminder. The card’s timing conflicts with the configured sequence.

Suggested fix
-        "detail": "ends in 3 days"
+        "detail": ""

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: d2252ca5-4264-402c-952f-5581cf12cf94
📥 Commits

Reviewing files that changed from the base of the PR and between f2f45d6 and c9411de.

⛔ Files ignored due to path filters (1)
  • products/workflows/frontend/generated/api.schemas.ts is excluded by !**/generated/**
📒 Files selected for processing (31)
  • frontend/src/lib/constants.tsx
  • products/workflows/backend/presentation/views/hog_flow_template.py
  • products/workflows/backend/templates/announce_a_new_feature_template.json
  • products/workflows/backend/templates/celebrate-milestone.json
  • products/workflows/backend/templates/feature-adoption-tips.json
  • products/workflows/backend/templates/heavy-usage-detected.json
  • products/workflows/backend/templates/high-intent-notification.json
  • products/workflows/backend/templates/negative-survey-response.json
  • products/workflows/backend/templates/onboarding_started_but_not_completed_template.json
  • products/workflows/backend/templates/re-engagement-workflow.json
  • products/workflows/backend/templates/repeated-failure-alert.json
  • products/workflows/backend/templates/support-ticket-notification.json
  • products/workflows/backend/templates/ticket-unresolved-alert.json
  • products/workflows/backend/templates/trial-ending-reminder.json
  • products/workflows/backend/templates/trial_started_upgrade_nudge_template.json
  • products/workflows/backend/templates/unlocking_advanced_features.json
  • products/workflows/backend/templates/unused-features-education.json
  • products/workflows/backend/templates/user-stuck-onboarding.json
  • products/workflows/backend/templates/user-upgrade-webhook.json
  • products/workflows/backend/templates/welcome_email_sequence_template.json
  • products/workflows/backend/tests/api/test_hog_flow_template.py
  • products/workflows/frontend/Workflows/templates/WorkflowTemplateCard.tsx
  • products/workflows/frontend/WorkflowsScene.tsx
  • products/workflows/frontend/emptyState/workflowsEmptyState.tsx
  • products/workflows/frontend/firstRun/GalleryTemplateCard.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRun.stories.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunGallery.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunTab.tsx
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.test.ts
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.ts
  • services/mcp/src/api/generated.ts

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

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

🟡 Other comments (1)
products/workflows/frontend/firstRun/TemplateStartsOnLine.tsx-25-25 (1)

25-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard against an empty events list on non-schedule templates.

startsOn.events[0] is undefined when an event or no_event template has an empty events array and no matchedEvent. EventChip then receives undefined, and PropertyKeyInfo renders an empty chip. The API type does not forbid this shape. Only schedule is documented as empty. Render the chip only when an event name exists.

Proposed fix
-            <EventChip event={matchedEvent ?? startsOn.events[0]} />
+            {(matchedEvent ?? startsOn.events[0]) && <EventChip event={(matchedEvent ?? startsOn.events[0])!} />}
🧹 Nitpick comments (1)
products/workflows/frontend/firstRun/firstRunGalleryLogic.ts (1)

257-266: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Gallery-shown analytics can fire on a failed or repeated load.

loadSeenEventsSuccess fires workflows first run gallery shown each time it runs. A retry through loadEmailTemplates re-triggers the chain, so the event is captured again for the same visit. Also, loadSeenEvents runs with an empty list when there are no templates, and the event still fires with ready_count: 0. Both cases skew funnel counts.

Capture the event once per mount, for example with a flag reducer or a guard on the first success.


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: 89c80bef-3bb9-40ce-9ed8-2fda13cae006
📥 Commits

Reviewing files that changed from the base of the PR and between c9411de and 630331b.

📒 Files selected for processing (7)
  • products/workflows/frontend/firstRun/GalleryTemplateCard.tsx
  • products/workflows/frontend/firstRun/TemplateStartsOnLine.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRun.stories.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunGallery.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunTab.test.tsx
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.test.ts
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.ts

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

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

🟡 Other comments (1)
products/workflows/frontend/firstRun/WorkflowsFirstRunGallery.tsx-96-96 (1)

96-96: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Describe schedule templates accurately.

When no project events have arrived, schedule templates are not ready either. They do not start on the events named in this subtitle. Use wording that covers both event-based and schedule templates. As per coding guidelines, “Use the names users see, and stay consistent across every surface.”

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: b4b35d06-82c1-4e8e-973e-66c9ec1ee312
📥 Commits

Reviewing files that changed from the base of the PR and between 630331b and 11f275a.

📒 Files selected for processing (5)
  • products/workflows/frontend/firstRun/WorkflowsFirstRun.stories.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunGallery.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunTab.tsx
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.test.ts
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.ts
💤 Files with no reviewable changes (1)
  • products/workflows/frontend/firstRun/WorkflowsFirstRun.stories.tsx

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

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

🟡 Minor · Keep this template out of the ready gallery until its workflow… · re-engagement-workflow.json:4-8

products/workflows/backend/templates/re-engagement-workflow.json:4-8
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep this template out of the ready gallery until its workflow is runnable.

When $pageview has been observed, this new metadata puts the template in “Picked for your data.” Picking it opens the template editor, but activating the saved draft fails because its event trigger has empty filters. If the trigger alone is fixed, the 14-day condition still matches TRUE and routes to exit_node, so the email is skipped. Remove this metadata until the trigger and activity check are valid.

Suggested fix
-    "starts_on": {
-        "kind": "no_event",
-        "events": ["$pageview"],
-        "detail": "for 14 days"
-    },

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: d559fd78-0b5c-4903-9f8b-fec3f92144b1
📥 Commits

Reviewing files that changed from the base of the PR and between 11f275a and 6fefaff.

📒 Files selected for processing (3)
  • products/workflows/frontend/firstRun/GalleryTemplateCard.tsx
  • products/workflows/frontend/firstRun/WorkflowsFirstRunGallery.tsx
  • products/workflows/frontend/firstRun/firstRunGalleryLogic.test.ts

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

@Silthus

Silthus commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Note

🤖 GPT-6.1 Sol responding on behalf of Michael

Replaced by the draft fork PR #329 in its native fork stack. @meikelmosby will start migrating the stack from the fork into PostHog/posthog for upstream review and CI. Closing this master-targeted copy to keep the handoff clear.

@Silthus Silthus closed this Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant