Skip to content

Add post-subscription onboarding activation - #204

Closed
paulocastellano wants to merge 115 commits into
mainfrom
feature/post-subscription-onboarding
Closed

Add post-subscription onboarding activation#204
paulocastellano wants to merge 115 commits into
mainfrom
feature/post-subscription-onboarding

Conversation

@paulocastellano

@paulocastellano paulocastellano commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Renames the pre-Stripe ICP flow to Welcome (/welcome/{persona|goals|referral-source}); Stripe checkout starts from the referral step — no social-connect gate before checkout.
  • Replaces the $1 first-month coupon with a Stripe Checkout trial (CASHIER_TRIAL_DAYS, clamped to Stripe's 48h minimum) plus optional promotion codes (CASHIER_ALLOW_PROMOTION_CODES).
  • Adds a single-page post-Stripe activation checklist at /onboarding (connect MCP agent → connect social → create first post; draft counts). MCP is skippable per-step; social + first post are required. Residual banner in the sidebar (desktop) and pinned strip (mobile) link back to /onboarding.
  • Members of accounts without an active subscription land on a dedicated /welcome/subscription-required screen (polls until the owner subscribes) instead of walking a flow they can never finish.
  • /billing/processing sends owners to /onboarding; purchase tracking only fires with a Stripe-verified conversion, so foreign or invented session ids never fire the pixel, and each checkout session is consumed once per account.
  • Workspace MCP settings page (Claude/ChatGPT first-class, advanced clients in accordions); API/MCP access aligned on hasAppAccess so no-card trial activation works.
  • Legacy /onboarding/* URLs redirect to their welcome equivalents.
  • Existing accounts that already have app access are backfilled as dismissed (data migration mirroring hasAppAccess) so they never see activation; unpaid / pre-checkout accounts keep a clean slate and enter the checklist after they subscribe.

Deploy

  1. Deploy and run migrations (schema + data backfill).
  2. The data migration stamps onboarding_dismissed_at only for accounts that already have app access (active/past_due/grace subscription, plus generic trial when card is not required). Unpaid signups are left alone so a later conversion still sees onboarding.

Test plan

  • Backend suite: welcome funnel, checkout trial/promo config, processing session verification, onboarding resolve/sync/skip/complete, residual share + query-cost guards, observer broadcast guards, backfill migration (incl. unpaid left alone), middleware redirects
  • Browser tests (Pest + Playwright, CI e2e shards): welcome walkthrough up to the enabled checkout CTA, onboarding skip clearing the residual banner, mobile residual, member landing on the subscription-required screen
  • Manual smoke: real Stripe checkout → processing → onboarding → connect MCP (Claude/ChatGPT) → first post → continue

paulocastellano and others added 30 commits July 24, 2026 12:59
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent polling analytics noise, short-circuit completed onboarding status, and align subscribe copy across locales.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten welcome persona/goals/referral screens, slim goal options, redesign residual onboarding in the sidebar footer, and merge workspace/user menus into one header dropdown with notifications at the top.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Update .env.example to clarify trial days and promotion code settings.
- Replace FirstMonthCheckoutDiscount with ConfigureSubscriptionCheckout for better handling of subscription checkouts.
- Ensure trial days are validated when card is not required during signup.
- Introduce support for promotion codes in the checkout process.
- Remove deprecated FirstMonthCheckoutDiscount class and its associated tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace polling with Echo broadcasts, keep shared residual reads pure, and DRY welcome/platform/MCP surfaces for a cleaner activation path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fill the English fallback gaps left after the activation i18n prune, including welcome_anonymous and sidebar onboarding labels.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Mirror Changelogfy’s connect/disconnect MCP UI under workspace settings, share settings tabs via a composable, and pin Outros/account links in the sidebar menus.

Co-authored-by: Cursor <cursoragent@cursor.com>
Match onboarding/settings card chrome: border-2, shadow-2xs, bold type, and bordered icon tiles.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
AccordionItem’s default border-b was zeroing the bottom edge when combined with card borders.

Co-authored-by: Cursor <cursoragent@cursor.com>
Hosted clients use config settings URLs with connect buttons; keep accordion config paste for other MCP apps.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
cursoragent and others added 20 commits August 4, 2026 00:20
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
Ignore Passport keys under storage/passport, keep SELF_HOSTED defaulted
to true, require personal-access tokens on REST, and avoid minting a
second checkout after a completed Stripe session. Align MCP revoke with
createPost access, keep analytics fail-open, and cover the regressions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove API_KEY_EXPIRATION_DAYS. Users can leave the date empty for a
never-expiring personal access token, or pick a date (end of day).

Co-authored-by: Cursor <cursoragent@cursor.com>
Add end-of-day storage and today-allowed cases for each entry point.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the changed-files DIFF_BASE shortcut and run Pint, Prettier, and
ESLint over the whole tree. Format the frontend to match, and leave
import sorting to Prettier so the two tools stop fighting.

Co-authored-by: Cursor <cursoragent@cursor.com>
…der for PlanSeeder

- Added 'workspace_settings' entry to sidebar translations for multiple languages.
- Updated DatabaseSeeder to always call PlanSeeder, removing the conditional check for self-hosted configuration.
… McpSettingsController

- Consolidated token revocation logic into a new method for user-specific client revocation.
- Updated McpSettingsController to utilize the new revocation method, simplifying the disconnect process.
- Removed redundant code and improved readability in both classes.
…ocesses

- Replaced direct access token revocation logic with calls to RevokeWorkspaceApiKeys for improved clarity and maintainability.
- Updated RemoveMember action to utilize the new revocation method for user-specific workspace API keys.
- Simplified role update logic in WorkspaceInviteController to ensure proper revocation unless the user is an admin.
- Updated multiple controllers to replace Symfony Response with InertiaResponse for consistency in response types.
- Adjusted method signatures to reflect the new response type, enhancing clarity and maintainability.
- Ensured proper handling of HTTP status codes across various abort conditions.
- Updated .env.example and compose.prod.yaml to include instructions for setting up Passport OAuth keys using environment variables for multi-node deployments.
- Removed the previous logic for storing Passport keys in a dedicated directory from the entrypoint script, now preferring environment variables for key management.
- Ensured that the entrypoint script generates keys only if the environment variables are not set, enhancing flexibility in deployment configurations.
- Simplified the event capture logic in PostHogService to utilize the new deduplication methods in SendEvent.
- Removed the NetworkUniqueViolation class and integrated its functionality into NetworkAlreadyConnectedException for better clarity.
- Updated various controllers to streamline onboarding and social account handling, ensuring proper checks for account status.
- Enhanced tests for SendEvent to cover deduplication and cache interactions, improving reliability and maintainability.
- Updated onboarding status handling to streamline MCP connection checks and ensure proper state management.
- Refactored billing controller methods to simplify session handling and remove unnecessary request validation.
- Removed obsolete request classes for acknowledging checkout purchases and skipping onboarding steps, consolidating logic for clarity.
- Improved access token management by refining the conditions for MCP OAuth grants and ensuring proper user permissions.
- Cleaned up social account observer logic to enhance uniqueness checks and onboarding status broadcasts.
@paulocastellano

Copy link
Copy Markdown
Contributor Author

I will split this pull request into smaller bundles.

paulocastellano added a commit that referenced this pull request Aug 6, 2026
Drop team_collaboration, automate_api, and track_performance so the goals step stays at nine choices.

Co-authored-by: Cursor <cursoragent@cursor.com>
paulocastellano added a commit that referenced this pull request Aug 6, 2026
…een (#243)

* Rename pre-subscription onboarding funnel to Welcome.

Move the ICP steps to /welcome, drop the social-connect checkout gate, hold unpaid members on a subscription-required screen, and keep legacy /onboarding URLs working until the post-subscription checklist lands.

Closes #237

Co-authored-by: Cursor <cursoragent@cursor.com>

* Drop legacy /onboarding ICP URL aliases.

Unfinished users re-enter Welcome via EnsureAccountReady on next login; /onboarding stays free for the post-subscription checklist.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Simplify Welcome PostHog event names.

Use welcome.persona/goals/referral and drop the unused checkout case — begin checkout stays on the frontend as checkout.started / begin_checkout.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Slim welcome goal options to match the #204 set.

Drop team_collaboration, automate_api, and track_performance so the goals step stays at nine choices.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Split Welcome AI goals into TryPost AI and MCP assistants.

Rewrite ai_content for in-app generation and add use_mcp so Claude/ChatGPT/Cursor intent is captured separately across locales.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Harden Welcome goals gate and drop dead checkout UI.

Treat removed goal values as incomplete so mid-funnel users re-select, remove the unused canCheckout branch, and fix the pt-BR welcome progress label.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add password visibility toggle to the login form.

Match the register eye control so users can reveal their password while signing in.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Point the sidebar community link to Discord.

Replace the X stay-updated entry with Join Discord and the trypost.it/discord invite.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Rename the sidebar Discord link to Discord community.

Softer label that matches the other support nav items.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix broken Turkish Discord community translation.

An unescaped apostrophe left a parse error in lang/tr/sidebar.php.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants