Skip to content

feat(insights): Conversion Journeys config matrix + leg empty states (NPPD-1742)#371

Merged
kmwilkerson merged 3 commits into
feat/insights-rsmfrom
nppd-1742-insights-conversion-journeys-empty-states-config-matrix
Jun 20, 2026
Merged

feat(insights): Conversion Journeys config matrix + leg empty states (NPPD-1742)#371
kmwilkerson merged 3 commits into
feat/insights-rsmfrom
nppd-1742-insights-conversion-journeys-empty-states-config-matrix

Conversation

@kmwilkerson

@kmwilkerson kmwilkerson commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What & why

Applies the empty-state pattern (NPPD-1694) to the Conversion Journeys tab, scoped (per NPPD-1742) to the parts with no upstream dependency: the configuration matrix (which legs render) and the subscription / donation conversion legs. The registration leg is left exactly as-is — its treatment needs hub-side registration counts and is tracked in NPPD-1743.

Behavior

Config matrix — each conversion-endpoint leg renders only when that stream is configured:

  • Subscription leg ⟺ an active non-donation subscription exists.
  • Donation leg ⟺ active donors exist.
  • Unconfigured → visibility: 'hidden' (reason: 'not_configured') → the component omits the whole cell (registrations-only publishers see just the registration + cross-upsell cells, never zero funnels). No BQ query is issued for a hidden leg.

Per-leg states (configured legs) — funnel-shaped, since these are funnels not scorecards:

  • Zero entries → swap the funnel for an in-cell no_opportunity note (nothing to draw).
  • Entries but zero conversions → keep the funnel (the drop-off is the signal) + a no_conversions annotation, {N} = prior-stage base.
  • Otherwise → the normal funnel.

Testing

  • PHP: Test_Conversion_Metric 79/79, Test_Conversion_REST_Controller 15/15. New: leg hidden-when-unconfigured (+ asserts no query issued), visibility stamping; existing leg tests updated for the new config-gate precondition.
  • JS: full suite 76 suites / 588 pass, incl. the matrix (all 4 combinations) and per-leg states in PerJourneyConversionFunnelsSection.test.tsx.
  • PHPCS + ESLint clean, tsc clean for the conversion files.
  • Smoke-tested in fixture mode: default (all legs), conversion_registrations_only (both conversion legs omitted), and empty (funnel-shaped no_opportunity in both configured legs). The .test.tsx NPPD-1683 caveat applies but is fixed, so these run in CI.

kmwilkerson and others added 3 commits June 19, 2026 17:02
…PPD-1742)

Apply the empty-state pattern to the Conversion Journeys subscription and
donation legs. A per-leg visibility gate hides a conversion endpoint when the
publisher doesn't run that reader-revenue stream (config matrix); configured-
but-quiet legs get funnel-shaped no_opportunity / no_conversions treatments.
The registration leg is left as-is (NPPD-1743).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…PPD-1742)

Code-review follow-up: the subscription/donation no_conversions note fired on
conversion===0 alone, so a leg with registered readers but zero prior-stage
base (e.g. no prompt shown) rendered "{0} saw a prompt, but none converted"
next to a funnel showing readers entering — self-contradicting, and counter to
the ticket's "prior stage HAS a base" definition. Guard on priorStage > 0; that
case now falls through to the normal funnel. Adds an edge-case test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…D-1742)

PHPCS (workspace-root standard, stricter than the plugin lint) flagged the
$donation_leg_configured property's @var-only docblock as missing a short
description. Add one.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kmwilkerson kmwilkerson marked this pull request as ready for review June 20, 2026 00:52
@kmwilkerson kmwilkerson requested a review from a team as a code owner June 20, 2026 00:52
@kmwilkerson kmwilkerson merged commit f07616e into feat/insights-rsm Jun 20, 2026
7 checks passed
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