# Account Upgrade Feature Design

**Date:** 2025-12-10
**Status:** Approved
**Branch:** feature/account-management

## Problem

Users cannot upgrade their subscription tier from within the app. The subscription page (`/dashboard/subscription`) only shows current tier info and links to Stripe's billing portal for payment management. Contextual upgrade prompts (on Leads, Stats, etc.) link to the subscription page, but it doesn't provide upgrade functionality.

## Solution

Add an upgrade section to the subscription page with a feature comparison table and "Upgrade" buttons that initiate Stripe Checkout for mid-subscription tier changes.

## Design

### 1. Subscription Page Enhancement

**Location:** `/dashboard/subscription` (existing page)

**New section:** "Upgrade Your Plan" appears below the "Current Subscription" card.

**Contents:**

- Feature comparison table (extracted from `public/landing/index.html`)
- Current tier highlighted
- Lower tiers grayed out (no downgrade in MVP)
- "Upgrade to X" buttons on tiers above current
- Professional tier users see "You're on the highest tier" message

**User flow:**

```
Starter user → sees Growth/Enhanced/Professional with "Upgrade" buttons
Growth user  → sees Enhanced/Professional with "Upgrade" buttons
Professional → upgrade section hidden or shows "highest tier" message
```

### 2. Stripe Checkout for Upgrades

**New endpoint:** `POST /api/checkout/upgrade`

**Request:**

```typescript
{
  targetTier: 'growth' | 'enhanced' | 'professional';
}
```

**Response:**

```typescript
{
  checkoutUrl: string;
}
```

**Implementation:**

- Validate user is authenticated and has a dealer account
- Validate targetTier is higher than current tier
- Create Stripe Checkout session with:
  - `customer`: dealer's existing `stripeCustomerId`
  - `mode`: 'subscription'
  - `line_items`: target tier's price ID
  - `subscription_data.metadata`: `{ upgrade: true, previousTier }`
- Return checkout URL for frontend redirect

Stripe handles proration automatically (credits remaining time on current plan).

### 3. Webhook Integration

**Existing handler:** `customer.subscription.updated` in `/api/webhooks/stripe/route.ts`

**Required change:** After updating `dealer.subscriptionTier`, call the existing tier handlers:

```typescript
// Detect tier change direction
if (tierRank(newTier) > tierRank(oldTier)) {
  await handleTierUpgrade(dealer.id, newTier);
} else if (tierRank(newTier) < tierRank(oldTier)) {
  await handleTierDowngrade(dealer.id, newTier);
}
```

The `handleTierUpgrade()` and `handleTierDowngrade()` functions already exist in `lib/tier-handlers.ts` but aren't currently called from the webhook.

### 4. Contextual Prompts (No Changes Needed)

Existing upgrade prompts in these locations already link to `/dashboard/subscription`:

- Leads page (`/dashboard/leads`)
- Stats page (`/dashboard/stats`)
- Performance Metrics widget

Once the subscription page has upgrade functionality, these prompts will work end-to-end.

## Components

### New Files

- `components/subscription/PlanComparison.tsx` - Feature comparison table
- `components/subscription/UpgradeCard.tsx` - Individual tier card with upgrade button
- `app/api/checkout/upgrade/route.ts` - Upgrade checkout endpoint

### Modified Files

- `app/dashboard/subscription/page.tsx` - Add upgrade section
- `app/api/webhooks/stripe/route.ts` - Call tier handlers on subscription update

## Feature Comparison Data

Extract from `public/landing/index.html`. Features by tier:

| Feature                       | Starter | Growth | Enhanced | Professional |
| ----------------------------- | ------- | ------ | -------- | ------------ |
| Set-up & Hosting              | ✓       | ✓      | ✓        | ✓            |
| AMSOIL Content Updates        | ✓       | ✓      | ✓        | ✓            |
| Dealer Information Editor     | ✓       | ✓      | ✓        | ✓            |
| Auto transfer links to AMSOIL | ✓       | ✓      | ✓        | ✓            |
| Core SEO & AI features        | ✓       | ✓      | ✓        | ✓            |
| Lead generation form          | -       | ✓      | ✓        | ✓            |
| Social Profile Linking        | -       | ✓      | ✓        | ✓            |
| Custom Domain Option          | -       | ✓      | ✓        | ✓            |
| Featured content editor       | -       | -      | ✓        | ✓            |
| Advanced SEO & AI             | -       | -      | ✓        | ✓            |
| Performance Dashboard         | -       | -      | ✓        | ✓            |
| Optimized local content       | -       | -      | -        | ✓            |
| Content section editor        | -       | -      | -        | ✓            |
| Content publishing            | -       | -      | -        | ✓            |

## Out of Scope (MVP)

- Downgrade flow (users contact support)
- Annual/monthly billing toggle (use current billing cycle)
- Upgrade confirmation modal (Stripe Checkout handles this)
- Email notifications on upgrade (future enhancement)

## Security Considerations

- Validate targetTier is actually higher than current tier
- Use existing `stripeCustomerId` - don't accept customer ID from frontend
- Verify dealer ownership matches authenticated user
- Rate limit the upgrade endpoint

## Testing

- Test upgrade from each tier to each higher tier
- Verify proration works correctly
- Verify webhook updates tier in database
- Verify tier handlers are called (blog nav item appears for Professional)
- Test with test dealer accounts (`test-starter@claude.dev`, etc.)
