Add subscription upgrade/change/cancel UX and account self-delete (#75) (#76)
Deploy Beta / unit-tests (push) Successful in 10s
Unit Tests / test (push) Successful in 11s
Deploy Beta / deploy-beta (push) Successful in 1m55s

## Summary
- Closes [#75](#75)
- Companion for [chat_backend#34](ai_ml_operations/chat_backend#34) (self-delete API)
- Account Billing: Upgrade / Change plan / Cancel CTAs (Stripe portal–first), plan picker when multiple public selectable plans exist, cancel confirmation with period-end messaging, complimentary users get no fake cancel
- Usage card Upgrade scrolls/focuses Billing; analytics for upgrade/change/cancel intents
- Danger Zone: email-confirmed `DELETE /user/` then logout → `/signin/`

## Test plan
- [ ] `npm test -- --watchAll=false --testPathPattern='BillingSection|DeleteAccountSection'`
- [ ] Paid Stripe user: Upgrade / Change plan / Cancel → portal (or checkout for higher selectable plan)
- [ ] Cancel confirm shows period-end access copy; scheduled cancel notice when `cancel_at_period_end`
- [ ] Backer/admin: complimentary message, no Cancel/Upgrade
- [ ] Delete account: confirm email → soft-delete → signed out at `/signin/`Reviewed-on: #76
This commit was merged in pull request #76.
This commit is contained in:
2026-08-01 12:24:10 -07:00
parent 5a847b64cc
commit 19698658b1
9 changed files with 936 additions and 66 deletions
+11 -1
View File
@@ -20,7 +20,11 @@ const queue: QueuedCall[] = [];
* | Conversation Created | New chat id assigned over WS |
* | Message Sent | User submits prompt (no content) |
* | ToS Acknowledged | POST acknowledge_tos succeeds |
* | Billing Portal Opened | When #33 portal CTA ships |
* | Billing Portal Opened | Account manage / portal CTAs |
* | Subscription Upgrade Started | Upgrade intent (#75) |
* | Plan Change Started | Change-plan intent (#75) |
* | Subscription Cancel Started | Cancel intent (#75) |
* | Account Delete Started / Success / Failed | Self-delete (#34 companion) |
*/
export const AnalyticsEvents = {
LOGIN_SUCCESS: 'Login Success',
@@ -36,6 +40,12 @@ export const AnalyticsEvents = {
MESSAGE_SENT: 'Message Sent',
TOS_ACKNOWLEDGED: 'ToS Acknowledged',
BILLING_PORTAL_OPENED: 'Billing Portal Opened',
SUBSCRIPTION_UPGRADE_STARTED: 'Subscription Upgrade Started',
PLAN_CHANGE_STARTED: 'Plan Change Started',
SUBSCRIPTION_CANCEL_STARTED: 'Subscription Cancel Started',
ACCOUNT_DELETE_STARTED: 'Account Delete Started',
ACCOUNT_DELETE_SUCCESS: 'Account Delete Success',
ACCOUNT_DELETE_FAILED: 'Account Delete Failed',
} as const;
export type AnalyticsEventName = (typeof AnalyticsEvents)[keyof typeof AnalyticsEvents];