You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds a trial banner to the owner-facing banner stack and the
surrounding plumbing:
- Schema: License.trialEnd, License.hasPaymentMethod, Org.trialUsedAt
(durable flag that survives license deactivation). Two migrations.
- servicePing persists trialEnd / hasPaymentMethod and flips
Org.trialUsedAt on first trial sync.
- Trial banner (owner, dismissible, priority 25): title uses
formatDistance ("Your trial ends in 10 days"); copy + action branch
on hasPaymentMethod. With-PM variant links to /settings/license;
no-PM variant opens the Stripe portal via a new
OpenBillingPortalButton (LoadingButton + createPortalSession).
- currentPlanCard gains a "Trial ends on" fallback column for the
trial-without-PM case (where nextRenewalAt is null).
- activationCodeCard accepts isTrialEligible and flips its checkout
button from "Purchase a license" to "Start a free trial" when the
org hasn't trialed yet, passing requestTrial through to the checkout
endpoint.
- Types mirror the new lighthouse fields (trialEnd, hasPaymentMethod)
and the checkout request additions (installId, requestTrial).
Side-trips to Stripe (portal, checkout) now append ?refresh=true so
the license resyncs on return; trial-checkout also appends
?trial_used=true so Org.trialUsedAt flips immediately (closes the UX
gap between checkout completion and activation-code entry). page.tsx
handles both params, preserves any other query params, and redirects
to a clean URL.
Also: fetchWithRetry now only retries 5xx, 408, and 429 — 4xx errors
(e.g. TRIAL_ALREADY_USED at 409) propagate immediately instead of
retrying pointlessly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments