Skip to content

Cu 86exkh107 step 5 instrumentation activation funnel trial to paid navid shad#56

Merged
navidshad merged 3 commits into
devfrom
CU-86exkh107_Step-5-Instrumentation-activation-funnel-trial-to-paid_Navid-Shad
Jul 10, 2026
Merged

Cu 86exkh107 step 5 instrumentation activation funnel trial to paid navid shad#56
navidshad merged 3 commits into
devfrom
CU-86exkh107_Step-5-Instrumentation-activation-funnel-trial-to-paid_Navid-Shad

Conversation

@navidshad

@navidshad navidshad commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

This PR enhances analytics tracking by wiring the account_created, first-save, and pricing-page events, and enriches Stripe lifecycle events with additional data. It also fixes an issue where the pricing-page_viewed tracking was aborted if Mixpanel had no token, preventing subscription page mount failures. Additionally, the .playwright-mcp directory has been added to .gitignore.

🔗 Related Tasks

#86exkh107 - Improve analytics tracking for account creation, first save, pricing page, and Stripe lifecycle events; fix subscription page mount issue related to pricing page tracking

📝 Additional Details

  • The fix ensures that Mixpanel event tracking does not block the subscription page rendering when no token is present.
  • Enrichment of Stripe lifecycle events provides better insight into customer actions.
  • Ignoring .playwright-mcp directory helps keep test artifacts out of version control.

📜 Commit List

  • 71cf5e0 fix: guard pricing-page_viewed track so a token-less Mixpanel can't abort the subscription page mount #86exkh107
  • 5f49c7c feat: wire account_created, first-save & pricing-page analytics + enrich Stripe lifecycle events #86exkh107
  • bf81701 add .playwright-mcp dir into gitignore

navidshad and others added 2 commits July 5, 2026 12:42
…ich Stripe lifecycle events #86exkh107

Close the Step 5 instrumentation gaps against the metrics framework
(codebridger/subturtle-docs). Adds the activation-funnel and trial-to-paid
events that were still missing, using the canonical [object]_[action]
naming convention:

- account_created (server-truth) on the new-user branch of both Google
  OAuth paths; props signup_provider, oauth_timezone, referrer.
- phrase_saved_first-time (server-truth) on a user's first-ever phrase in
  createPhrase; props source_platform, language_pair.
- pricing-page_viewed (client) on the subscription page with from_surface,
  threaded from the cap/limit banner entry points.
- Enrich the Stripe lifecycle events: trial_started +currency;
  subscription_started +currency +subscription_id; subscription_canceled
  +tier +lifetime_value_cents (summed from payment records) +cancel_reason.

Out of scope (per decisions): extension_installed (extension repo) and
fluent_waitlist_signed_up (no dashboard trigger yet). Mixpanel funnels and
the L1 Forgot-rate aggregate are defined for build-out once these deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@navidshad

Copy link
Copy Markdown
Contributor Author

@navidshad navidshad added the review Claude Routine will take this and review the PR label Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Automated PR Review

Primary Task: Step 5 — Instrumentation (activation funnel + trial-to-paid)


Task alignment

Activation funnel

  • account_created — wired on both Google OAuth paths (/google/code-login and /google/access-token-login) with signup_provider, oauth_timezone, referrer
  • phrase_saved_first-time — wired in createPhrase at the single server-truth point; priorPhraseCount === 0 guard is correct; source_platform and language_pair props populated
  • ⚠️ extension_installed — deferred to the extension repo (explicitly noted in the commit body; acceptable)
  • starter_ai_credits_exhausted — listed in the task spec with account_id, days_since_window_start props; not in the diff and not mentioned as deferred in either the PR description or the commit body
  • starter_save_cap_hit — same as above
  • weekly_active aggregate — this is a derived Mixpanel metric (not a new event), so no code change is strictly required, but the task acceptance criterion ("Both funnels wired and filterable") implies at least a verification step

Trial-to-paid funnel

  • pricing-page_viewed — fired in subscription.vue::onMounted with from_surface; all five cap-hit entry points (FeatureLocked, TextChatCounter, VoiceCapBanner, LimitationModal, UsageCapBanner) now thread ?from=cap-hit-banner
  • trial_started — enriched with currency
  • subscription_started — enriched with currency and subscription_id
  • subscription_canceled — enriched with tier, lifetime_value_cents (summed from payment records, best-effort), cancel_reason
  • ⚠️ fluent_waitlist_signed_up — explicitly deferred (no dashboard trigger yet; acceptable)

Out-of-code items (Mixpanel config / aggregate queries)
The task's acceptance criterion includes an L1 Forgot-rate aggregate query and two Mixpanel funnel definitions. These require no code changes, but the PR doesn't confirm or document that they'll be handled separately — worth a one-liner in the PR description.


Commit messages

⚠️ add .playwright-mcp dir into gitignore — missing the Conventional Commits type prefix. Per CLAUDE.md the type prefix drives the release log and must always be present. Should be:

chore: add .playwright-mcp to .gitignore

The bare message won't affect the version bump for this PR (the feat: commit dominates), but it will appear unlabelled in the generated changelog.

feat: wire account_created, first-save & pricing-page analytics + enrich Stripe lifecycle events #86exkh107 — correct type, descriptive, task ID present.


Convention check

server/src/modules/phrase_bundle/functions.ts:17–24 ⚠️
Multi-line JSDoc block on sourcePlatformFromUrl. CLAUDE.md says "Never write multi-paragraph docstrings or multi-line comment blocks — one short line max." The function name is self-documenting; the // Unknown/absent hosts collapse to 'other' behaviour is the only non-obvious bit and could be a single inline comment inside the function body.

.gitignore ⚠️
Missing newline at end of file (\ No newline at end of file in the diff). Minor, but the surrounding lines already have a trailing newline and most editors / git clients expect it.

Event naming
phrase_saved_first-time and pricing-page_viewed follow the [object]_[action] + -inside-a-part convention documented in server/src/utils/analytics.ts (which cites docs/metrics/event-naming.md). The divergence from the task doc's underscored spelling is intentional and correct.

Architecture and test coverage
Server-fired events go through trackServerEvent; frontend events use the ANALYTICS_EVENTS registry — both registries kept in sync. stripe.adapter.test.ts and createPhrase.test.ts cover the new branching logic with clear arrange/act/assert structure.

subscription.vue
Comment block on the PRICING_PAGE_VIEWED tracking call justifies the non-obvious need for an explicit event (auto page-view can't carry attribution) — this is the "WHY" type comment CLAUDE.md permits.


Verdict

REQUEST CHANGES

Two events from the task spec — starter_ai_credits_exhausted and starter_save_cap_hit — are neither implemented nor marked as deferred. Please either add them or explicitly note in the PR description why they're out of scope for this PR. Also fix the bare commit message (add .playwright-mcp dir into gitignorechore: …) and the missing newline in .gitignore. The multi-line JSDoc on sourcePlatformFromUrl should be collapsed to a single inline comment per CLAUDE.md.


Generated by Claude Code

@navidshad navidshad removed the review Claude Routine will take this and review the PR label Jul 8, 2026 — with Claude
…bort the subscription page mount #86exkh107

When NUXT_PUBLIC_MIXPANEL_PROJECT_TOKEN is unset (CI/e2e), the Mixpanel
plugin skips init and analytic.track() throws on the uninitialised
instance. Fired at the top of onMounted, that aborted the mount before
fetchPlans(), so the plan cards never rendered (Playwright
subscription-ui "four plan cards" failed). Wrap the analytics call in
try/catch — instrumentation is best-effort and must never break the page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@navidshad navidshad added the review Claude Routine will take this and review the PR label Jul 10, 2026
@navidshad navidshad removed the review Claude Routine will take this and review the PR label Jul 10, 2026 — with Claude
@navidshad navidshad merged commit 13c6cf5 into dev Jul 10, 2026
6 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0-dev.5 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@navidshad navidshad deleted the CU-86exkh107_Step-5-Instrumentation-activation-funnel-trial-to-paid_Navid-Shad branch July 10, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant