Skip to content

Workflows first run: Make it yours, send me a test, enable #260

Closed

Description

@Silthus

Map: Map: build the Workflows first run, from template gallery to first send
Spec: Spec: Workflows first run

Cast: Fable 5.1 (UI)

Question

Can a new user make every email of the starter theirs, see each in their own inbox, and turn the workflow on, all from one screen?

Delivers end to end. Spec section "Make it yours" without the AI button and the engagement switch, plus the workflows first run test sent and workflows first run workflow created events. Builds on the tailored template gallery and the first-run sender seam.

  • A gallery card opens Make it yours in the Workflows tab, addressed by a search param with the template id. Back and reload return to it.
  • EmailTemplater with type="native_email" and layout="inline", with the first-run sender as from.
  • Every email, not just the first (Michael, 2026-10-05). Most gallery templates send two to four emails, the welcome sequence included. The screen makes it obvious there are several and makes moving between them easy:
    • a list of the template's emails in flow order, each with its subject and when it goes out relative to the trigger (for example "Right away", "After 3 days");
    • picking one loads it into the editor; edits to every email are kept while switching;
    • the screen says which email is open ("Email 2 of 3") and marks the ones already edited;
    • a template with one email shows no list.
    • Design the layout so the list holds up at 520px. This is the open design question of the slice; record the reasoning and screenshots on the ticket.
  • "Send me a test": the email that is open, as edited, to the signed-in user's email from the first-run sender, through the test invocation endpoint the library test send uses (POST hog_flows/new/invocations with a one-step flow). A "Skipping send:" result shows its reason. Give the skip-reason reader one home if you reuse it from broadcastTestSendLogic. No modal.
  • "Enable and open workflow" with the "Enable workflow" switch, on by default. Off, the button reads "Open workflow".
    • One POST hog_flows/: the seam's sender on every email step, every edited email in its own step, the matched trigger event, status active or draft per the switch.
    • Then it opens the workflow editor and remembers the id as the first-run workflow, in the browser.
    • A rejected create shows the server's message and creates nothing. The button shows a loading state while the request runs.
  • No first-run sender: "Send me a test" and "Enable workflow" are disabled with a reason that links to Channels. "Open workflow" still creates a draft.
  • The side column stacks under the editor in a narrow container. LemonUI only. Copy through /writing-user-facing-copy.

Test seams. A kea logic test with the API mocked at the HTTP layer: the create payload for both switch states (with edits to more than one email kept across switching), the test invocation and its skip reason, the no-sender state, and a rejected create. Storybook stories for each state, rendered and screenshotted at full width and 520px (the editor loads from Unlayer's CDN, so render with network access).

Write scope. The first-run folder under products/workflows/frontend/, the Workflows tab routing in products/workflows/frontend/WorkflowsScene.tsx or its scene logic, and the skip-reason helper if it moves out of products/workflows/frontend/Broadcasts/broadcastTestSendLogic.ts. Tests and stories.
Overlap: frontend/src/scenes/hog-functions/email-templater/ is edited by #237 (PostHog#111695) and PostHog#111370 from #221. Use EmailTemplater as it is. emailTemplaterLogic has no key, so mount one templater on this screen only.

Acceptance criteria

  • A card opens Make it yours with the template's first email in the editor, and reload returns to it.
  • A template with several emails lists them in flow order with their timing; switching keeps edits; the create payload carries every edited email.
  • "Send me a test" delivers the edited email to the signed-in user against a local stack; a skipped send shows its reason.
  • "Enable and open workflow" creates an active workflow with every edited email, the seam's sender on every email step and the matched trigger event, then opens it. With the switch off it creates a draft.
  • With no first-run sender, test and enable are disabled with a reason, and "Open workflow" creates a draft.
  • Screenshots of each state at full width and 520px are on this ticket.

How to build (map #253)

  • /implement + /tdd red-green-refactor, outside-in, at the seams named above. The frontend mocks the API at the HTTP layer. Mock only what is external: the LLM and the PostHog analytics client.
  • Repo skills apply where the diff touches their area: /writing-tests, /improving-drf-endpoints, /writing-ui-components, /writing-kea-logics, /adopting-generated-api-types, /placing-product-frontend-code, /writing-user-facing-copy, /writing-code-comments.
  • Branch from upstream/master, push to the fork, open a draft PR on PostHog/posthog against master. A stacked PR carries its parent's commits and a "Stacked on" note.
  • Then /qa-swarm. Shipped means a draft PR it handed off. Never mark ready, enqueue or merge.
  • Public repo: state sender rules as product rules. Fixture addresses use example.com. The prototype is throwaway: read it for behavior, never copy or cherry-pick it.

Activity

  1. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Amended by the conductor (Michael, 2026-10-05, origin https://posthog.slack.com/archives/C06GG249PR6/p1791188180453239): Make it yours covers every email of a multi-email template, not only the first. Most gallery templates have two to four emails, the welcome sequence included.

  2. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Conductor note from the gallery slice (#258): gallery cards are not limited to people with Editor access, as the old empty state was not. Make it yours must handle a viewer cleanly: disable "Enable and open workflow" and "Send me a test" with a reason when the user cannot create workflows, rather than letting the create fail.

  3. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Runtime: Claude Code background agent (conductor thread on devbox-michaelr-3)
    Worker: impl-260, Claude Fable 5.1 (ambiguous UI design: multi-email navigation, AI panel beside the editor)
    Worktree: /home/coder/.t3/worktrees/posthog/fr-260, branch feat/workflows-first-run-make-it-yours: the gallery branch (PostHog#111816) merged with the sender seam branch (PostHog#112003) at 188a54c9e8f
    Review: one cross-family review (Codex adversarial-review), per the map's updated rule
    Cap: 4 hours from 16:24 UTC
    CodeRabbit slot: 1 of 3

  4. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Worker transcript: /tmp/claude-1001/-home-coder--t3-worktrees-posthog-t3code-1d6de0ea/6f4018e1-a32c-4b89-bae8-f0ca1d7056a8/tasks/a55c9348ea51b55d5.output. Deadline wake set for 20:31 UTC.

  5. self-assigned this
    on Oct 5, 2026
  6. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Claimed by conductor worker impl-260 (Claude Code background agent, Fable 5.1).

  7. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Layout decision: the multi-email list

    Draft PR: PostHog#112053 (head 9777b8c10d38c, stacked on PostHog#111816 and PostHog#112003).

    Decision. The email list is a vertical list of rows (number, subject, timing, an "Edited" tag), not tabs or a segmented control above the editor. It sits at the top of the side column beside the editor, above "Send me a test" and "Enable and open workflow". Below a 56rem container width (a container query on the screen, not a viewport breakpoint) the grid collapses to one column in this order: list, "Email n of m", editor, actions. A template with one email shows no list and no counter.

    Why rows and not tabs. Subjects are long ("Reminder to complete your onboarding") and every email needs its timing beside it. At 520px a tab row of three such labels either truncates the subjects to nothing or wraps into a shape that no longer reads as tabs. Rows keep subject and timing legible at every width, and at 520px they take about 40px each, so three emails cost one line of editor height. The list also stays visible while the editor scrolls, which matters once #261 opens PostHog AI beside the screen and takes another 512px.

    Why the side column and not above the editor at full width. The actions already live in a side column (spec), and the list belongs with them: both say "where am I and what happens next". Putting the list above the editor at full width would push the editor down for every template and leave the side column half empty.

    Why the editor remounts per email (key={openEmail.id}). The templater exports the canvas with a 500ms debounce. With one mounted instance, a click on another email inside that window would land email 1's body on email 2. Remounting makes that impossible; the cost is a canvas reload per switch. Known gap: a canvas edit made in the last 500ms before switching is lost (the field edits are not).

    Open email as a selector. firstRunMakeItYoursLogic.values.openEmail (subject, timing, the edited EmailTemplate, edited) and openEmailPosition are what #261 should read.

    State Full width 520px scene
    Two emails, sandbox sender
    Three emails
    One email, no list
    No sender
    Viewer access
    Test send skipped
    Create rejected

    Screenshots are rendered from the Storybook stories headless with the Unlayer editor loaded from its CDN, and live on the fork branch assets/fr-260-make-it-yours because hogli pr:upload-image refused this account.

  8. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Resolution

    PR: PostHog#112053 (draft), head a8c22c7ee3f83, branch Silthus:feat/workflows-first-run-make-it-yours, stacked on PostHog#111816 and PostHog#112003. The map's review rule applied: one Codex adversarial review instead of qa-swarm.

    Proof

    • Red before green at the logic seam, products/workflows/frontend/firstRun/firstRunMakeItYoursLogic.test.ts (API mocked at the HTTP layer): flow order and timing; edits kept across switching; create payload for both switch states with the sender on every email step and the matched trigger event; test invocation payload and skip reason; no sender; rejected create; viewer access; and, after the review, a switch, test send or create while the templater holds an unexported canvas edit. Red runs: each case failed first with "is not a function" or the stale value; green on the implementation, 35 tests in the folder.
    • firstRunGalleryLogic.test.ts now asserts a pick routes to /workflows?template=<id>. findTestSendSkipReason moved to Workflows/hogflows/ with its test.
    • Final tree gate: typescript:check clean, pnpm --filter=@posthog/frontend fix clean, Jest for firstRun, Broadcasts and the moved test (19 suites) green, pre-push hogli ci:preflight --strict 0 failures.
    • Storybook: WorkflowsFirstRunMakeItYours.stories.tsx, one story per state plus a narrow one, with play functions for the skipped send and the rejected create. Screenshots at full width and the 552px viewport (520px scene) are in the layout comment above and refreshed after the review fixes on assets/fr-260-make-it-yours at 30c41d699543c.
    • Browser check (scripted Playwright against Storybook with the Unlayer editor from its CDN): typed into email 1's subject, switched to email 2, back: the edit stayed, the "Edited" tag showed, each canvas showed its own email.

    Review findings (Codex adversarial review, GPT-6.1 Sol)

    1. High, fixed. A canvas edit in the 500ms before switching, sending or creating was lost or stale, because the templater exports with a debounce and the keyed editor unmounted at once. Fix: openEmail, sendTest and createWorkflow wait while the mounted templater reports a pending export (its cache.pendingDesignEdit), then act. Three logic tests cover it.
    2. Medium, fixed. The editor offered sender controls the payload overrode. Fix: the editor runs as type="native_email_template", which hides From and To; the sender shows under the "Enable workflow" switch. This deviates from the ticket's type="native_email" line, which was written before the conflict was visible.

    CodeRabbit: skipped, the CLI is signed out in this sandbox and no person was available.

    Calls made

    • Email list as rows in the side column, stacking above the editor under 56rem of container width (reasoning in the comment above).
    • Editor remounts per email, so an export can never land on the wrong email.
    • openEmail and openEmailPosition are the selectors for Workflows first run: Change with PostHog AI edits the email in place #261.
    • Both loaders catch their own errors so the screen shows them in place without the generic failure toast.
    • workflows first run workflow created carries template_id and enabled; engagement_events waits for the slice that adds the switch.
    • No sender: "Enable workflow" is off and disabled, "Open workflow" creates a draft; a viewer sees both buttons disabled with the access reason.
    • The create uses the generated hogFlowsCreate; the test send keeps api.hogFlows.createTestInvocation because the generated invocation function has no response type.

    Gaps and follow-ups

    • Not run against a local stack (none in this sandbox), so the real test send and an active create against the backend are unverified. Acceptance criterion 3 needs that check in review.
    • hogli pr:upload-image refused this account, so screenshots live on a fork branch. The PR assignee could not be set from the fork either.
    • Fork CI needs Michael's approval (recorded gap on the map).
    • Draft PR, not marked ready.
  9. Silthus commented on Oct 5, 2026

    @Silthus
    OwnerAuthor

    Shipped as draft PostHog#112053 (head a8c22c7). Closing per the map's resolution rule.

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions