# Subscription Workflow Plan

## Overview

End-to-end subscription management workflow for stores on the platform.

---

## 1. Store Subscribes to a Tier

### 1.1 New Store Registration Flow

```
Store Registration → Select Tier → Trial Period → Payment Setup → Active Subscription
```

**Steps:**
1. Store creates account (existing flow)
2. During onboarding, store selects a tier:
   - Show tier comparison cards (Essential, Professional, Business, Enterprise)
   - Highlight features and limits for each tier
   - Default to 14-day trial on selected tier
3. Create `StoreSubscription` record with:
   - `tier` = selected tier code
   - `status` = "trial"
   - `trial_ends_at` = now + 14 days
   - `period_start` / `period_end` set for trial period
4. Before trial ends, prompt store to add payment method
5. On payment method added → Create Stripe subscription → Status becomes "active"

### 1.2 Database Changes Required

**Add FK relationship to `subscription_tiers`:**
```python
# StoreSubscription - Add proper FK
tier_id = Column(Integer, ForeignKey("subscription_tiers.id"), nullable=True)
tier_code = Column(String(20), nullable=False)  # Keep for backwards compat

# Relationship
tier_obj = relationship("SubscriptionTier", backref="subscriptions")
```

**Migration:**
1. Add `tier_id` column (nullable initially)
2. Populate `tier_id` from existing `tier` code values
3. Add FK constraint

### 1.3 API Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/v1/store/subscription/tiers` | GET | List available tiers for selection |
| `/api/v1/store/subscription/select-tier` | POST | Select tier during onboarding |
| `/api/v1/store/subscription/setup-payment` | POST | Create Stripe checkout for payment |

---

## 2. Admin Views Subscription on Store Page

### 2.1 Store Detail Page Enhancement

**Location:** `/admin/stores/{store_id}`

**New Subscription Card:**
```
┌─────────────────────────────────────────────────────────────┐
│ Subscription                                          [Edit] │
├─────────────────────────────────────────────────────────────┤
│ Tier: Professional                    Status: Active        │
│ Price: €99/month                      Since: Jan 15, 2025   │
│ Next Billing: Feb 15, 2025                                  │
├─────────────────────────────────────────────────────────────┤
│ Usage This Period                                           │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐         │
│ │ Orders       │ │ Products     │ │ Team Members │         │
│ │ 234 / 500    │ │ 156 / ∞      │ │ 2 / 3        │         │
│ │ ████████░░   │ │ ████████████ │ │ ██████░░░░   │         │
│ └──────────────┘ └──────────────┘ └──────────────┘         │
├─────────────────────────────────────────────────────────────┤
│ Add-ons: Custom Domain (mydomain.com), 5 Email Addresses    │
└─────────────────────────────────────────────────────────────┘
```

### 2.2 Files to Modify

- `app/templates/admin/store-detail.html` - Add subscription card
- `static/admin/js/store-detail.js` - Load subscription data
- `app/api/v1/admin/stores.py` - Include subscription in store response

### 2.3 Admin Quick Actions

From the store page, admin can:
- **Change Tier** - Upgrade/downgrade store
- **Override Limits** - Set custom limits (enterprise deals)
- **Extend Trial** - Give more trial days
- **Cancel Subscription** - With reason
- **Manage Add-ons** - Add/remove add-ons

---

## 3. Tier Upgrade/Downgrade

### 3.1 Admin-Initiated Change

**Location:** Admin store page → Subscription card → [Edit] button

**Modal: Change Subscription Tier**
```
┌─────────────────────────────────────────────────────────┐
│ Change Subscription Tier                            [X] │
├─────────────────────────────────────────────────────────┤
│ Current: Professional (€99/month)                       │
│                                                         │
│ New Tier:                                               │
│ ○ Essential (€49/month)     - Downgrade                │
│ ● Business (€199/month)     - Upgrade                  │
│ ○ Enterprise (Custom)       - Contact required         │
│                                                         │
│ When to apply:                                          │
│ ○ Immediately (prorate current period)                 │
│ ● At next billing cycle (Feb 15, 2025)                 │
│                                                         │
│ [ ] Notify store by email                              │
│                                                         │
│                    [Cancel]  [Apply Change]             │
└─────────────────────────────────────────────────────────┘
```

### 3.2 Store-Initiated Change

**Location:** Store dashboard → Billing page → [Change Plan]

**Flow:**
1. Store clicks "Change Plan" on billing page
2. Shows tier comparison with current tier highlighted
3. Store selects new tier
4. For upgrades:
   - Show prorated amount for immediate change
   - Or option to change at next billing
   - Redirect to Stripe checkout if needed
5. For downgrades:
   - Always schedule for next billing cycle
   - Show what features they'll lose
   - Confirmation required

### 3.3 API Endpoints

| Endpoint | Method | Actor | Description |
|----------|--------|-------|-------------|
| `/api/v1/admin/subscriptions/{store_id}/change-tier` | POST | Admin | Change store's tier |
| `/api/v1/store/billing/change-tier` | POST | Store | Request tier change |
| `/api/v1/store/billing/preview-change` | POST | Store | Preview proration |

### 3.4 Stripe Integration

**Upgrade (Immediate):**
```python
stripe.Subscription.modify(
    subscription_id,
    items=[{"price": new_price_id}],
    proration_behavior="create_prorations"
)
```

**Downgrade (Scheduled):**
```python
stripe.Subscription.modify(
    subscription_id,
    items=[{"price": new_price_id}],
    proration_behavior="none",
    billing_cycle_anchor="unchanged"
)
# Store scheduled change in our DB
```

---

## 4. Add-ons Upselling

### 4.1 Where Add-ons Are Displayed

#### A. Store Billing Page
```
/store/{code}/billing

┌─────────────────────────────────────────────────────────────┐
│ Available Add-ons                                           │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────┐ ┌─────────────────────┐            │
│ │ 🌐 Custom Domain    │ │ 📧 Email Package    │            │
│ │ €15/year            │ │ From €5/month       │            │
│ │ Use your own domain │ │ 5, 10, or 25 emails │            │
│ │ [Add to Plan]       │ │ [Add to Plan]       │            │
│ └─────────────────────┘ └─────────────────────┘            │
│                                                             │
│ ┌─────────────────────┐ ┌─────────────────────┐            │
│ │ 🔒 Premium SSL      │ │ 💾 Extra Storage    │            │
│ │ €49/year            │ │ €5/month per 10GB   │            │
│ │ EV certificate      │ │ More product images │            │
│ │ [Add to Plan]       │ │ [Add to Plan]       │            │
│ └─────────────────────┘ └─────────────────────┘            │
└─────────────────────────────────────────────────────────────┘
```

#### B. Contextual Upsells

**When store hits a limit:**
```
┌─────────────────────────────────────────────────────────┐
│ ⚠️ You've reached your order limit for this month      │
│                                                         │
│ Upgrade to Professional to get 500 orders/month        │
│                            [Upgrade Now]  [Dismiss]     │
└─────────────────────────────────────────────────────────┘
```

**In settings when configuring domain:**
```
┌─────────────────────────────────────────────────────────┐
│ 🌐 Custom Domain                                        │
│                                                         │
│ Your shop is available at: myshop.platform.com         │
│                                                         │
│ Want to use your own domain like www.myshop.com?       │
│ Add the Custom Domain add-on for just €15/year         │
│                                                         │
│ [Add Custom Domain]                                     │
└─────────────────────────────────────────────────────────┘
```

#### C. Upgrade Prompts in Tier Comparison

When showing tier comparison, highlight what add-ons come included:
- Professional: Includes 1 custom domain
- Business: Includes custom domain + 5 email addresses
- Enterprise: All add-ons included

### 4.2 Add-on Purchase Flow

```
Store clicks [Add to Plan]
    ↓
Modal: Configure Add-on
    - Domain: Enter domain name, check availability
    - Email: Select package (5/10/25)
    ↓
Create Stripe checkout session for add-on price
    ↓
On success: Create StoreAddOn record
    ↓
Provision add-on (domain registration, email setup)
```

### 4.3 Add-on Management

**Store can view/manage in Billing page:**
```
┌─────────────────────────────────────────────────────────────┐
│ Your Add-ons                                                │
├─────────────────────────────────────────────────────────────┤
│ Custom Domain    myshop.com       €15/year    [Manage]      │
│ Email Package    5 addresses      €5/month    [Manage]      │
│                                                             │
│ Next billing: Feb 15, 2025                                  │
└─────────────────────────────────────────────────────────────┘
```

### 4.4 Database: `store_addons` Table

```python
class StoreAddOn(Base):
    id = Column(Integer, primary_key=True)
    store_id = Column(Integer, ForeignKey("stores.id"))
    addon_product_id = Column(Integer, ForeignKey("addon_products.id"))

    # Config (e.g., domain name, email count)
    config = Column(JSON, nullable=True)

    # Stripe
    stripe_subscription_item_id = Column(String(100))

    # Status
    status = Column(String(20))  # active, cancelled, pending_setup
    provisioned_at = Column(DateTime)

    # Billing
    quantity = Column(Integer, default=1)

    created_at = Column(DateTime)
    cancelled_at = Column(DateTime, nullable=True)
```

---

## 5. Implementation Phases

**Last Updated:** December 31, 2025

### Phase 1: Database & Core (COMPLETED)
- [x] Add `tier_id` FK to StoreSubscription
- [x] Create migration with data backfill
- [x] Update subscription service to use tier relationship
- [x] Update admin subscription endpoints
- [x] **NEW:** Add Feature model with 30 features across 8 categories
- [x] **NEW:** Create FeatureService with caching for tier-based feature checking
- [x] **NEW:** Add UsageService for limit tracking and upgrade recommendations

### Phase 2: Admin Store Page (PARTIALLY COMPLETE)
- [x] Add subscription card to store detail page
- [x] Show usage meters (orders, products, team)
- [ ] Add "Edit Subscription" modal
- [ ] Implement tier change API (admin)
- [x] **NEW:** Add Admin Features page (`/admin/features`)
- [x] **NEW:** Admin features API (list, update, toggle)

### Phase 3: Store Billing Page (COMPLETED)
- [x] Create `/store/{code}/billing` page
- [x] Show current plan and usage
- [x] Add tier comparison/change UI
- [x] Implement tier change API (store)
- [x] Add Stripe checkout integration for upgrades
- [x] **NEW:** Add feature gate macros for templates
- [x] **NEW:** Add Alpine.js feature store
- [x] **NEW:** Add Alpine.js upgrade prompts store
- [x] **FIX:** Resolved 89 JS architecture violations (JS-005 through JS-009)

### Phase 4: Add-ons (COMPLETED)
- [x] Seed add-on products in database
- [x] Add "Available Add-ons" section to billing page
- [x] Implement add-on purchase flow
- [x] Create StoreAddOn management (via billing page)
- [x] Add contextual upsell prompts
- [x] **FIX:** Fix Stripe webhook to create StoreAddOn records

### Phase 5: Polish & Testing (IN PROGRESS)
- [ ] Email notifications for tier changes
- [x] Webhook handling for Stripe events
- [x] Usage limit enforcement updates
- [ ] End-to-end testing (manual testing required)
- [x] Documentation (feature-gating-system.md created)

### Phase 6: Remaining Work (NEW)
- [ ] Admin tier change modal (upgrade/downgrade stores)
- [ ] Admin subscription override UI (custom limits for enterprise)
- [ ] Trial extension from admin panel
- [ ] Email notifications for tier changes
- [ ] Email notifications for approaching limits
- [ ] Grace period handling for failed payments
- [ ] Integration tests for full billing workflow
- [ ] Stripe test mode checkout verification

---

## 6. Files Created/Modified

**Last Updated:** December 31, 2025

### New Files (Created)
| File | Purpose | Status |
|------|---------|--------|
| `app/templates/store/billing.html` | Store billing page | DONE |
| `static/store/js/billing.js` | Billing page JS | DONE |
| `app/api/v1/store/billing.py` | Store billing endpoints | DONE |
| `models/database/feature.py` | Feature & StoreFeatureOverride models | DONE |
| `app/services/feature_service.py` | Feature access control service | DONE |
| `app/services/usage_service.py` | Usage tracking & limits service | DONE |
| `app/core/feature_gate.py` | @require_feature decorator & dependency | DONE |
| `app/api/v1/store/features.py` | Store features API | DONE |
| `app/api/v1/store/usage.py` | Store usage API | DONE |
| `app/api/v1/admin/features.py` | Admin features API | DONE |
| `app/templates/admin/features.html` | Admin features management page | DONE |
| `app/templates/shared/macros/feature_gate.html` | Jinja2 feature gate macros | DONE |
| `static/shared/js/feature-store.js` | Alpine.js feature store | DONE |
| `static/shared/js/upgrade-prompts.js` | Alpine.js upgrade prompts | DONE |
| `alembic/versions/n2c3d4e5f6a7_add_features_table.py` | Features migration | DONE |
| `docs/implementation/feature-gating-system.md` | Feature gating documentation | DONE |

### Modified Files
| File | Changes | Status |
|------|---------|--------|
| `models/database/subscription.py` | Add tier_id FK | DONE |
| `models/database/__init__.py` | Export Feature models | DONE |
| `app/templates/admin/store-detail.html` | Add subscription card | DONE |
| `static/admin/js/store-detail.js` | Load subscription data | DONE |
| `app/api/v1/admin/stores.py` | Include subscription in response | DONE |
| `app/api/v1/admin/__init__.py` | Register features router | DONE |
| `app/api/v1/store/__init__.py` | Register features/usage routers | DONE |
| `app/services/subscription_service.py` | Tier change logic | DONE |
| `app/templates/store/partials/sidebar.html` | Add Billing link | DONE |
| `app/templates/store/base.html` | Load feature/upgrade stores | DONE |
| `app/templates/store/dashboard.html` | Add tier badge & usage bars | DONE |
| `app/handlers/stripe_webhook.py` | Create StoreAddOn on purchase | DONE |
| `app/routes/admin_pages.py` | Add features page route | DONE |
| `static/shared/js/api-client.js` | Add postFormData() & getBlob() | DONE |

### Architecture Fixes (48 files)
| Rule | Files Fixed | Description |
|------|-------------|-------------|
| JS-003 | billing.js | Rename billingData→storeBilling |
| JS-005 | 15 files | Add init guards |
| JS-006 | 39 files | Add try/catch to async init |
| JS-008 | 5 files | Use apiClient not fetch |
| JS-009 | 30 files | Use Utils.showToast |
| TPL-009 | validate_architecture.py | Check store templates too |

---

## 7. API Summary

### Admin APIs
```
GET  /admin/stores/{id}                      # Includes subscription
POST /admin/subscriptions/{store_id}/change-tier
POST /admin/subscriptions/{store_id}/override-limits
POST /admin/subscriptions/{store_id}/extend-trial
POST /admin/subscriptions/{store_id}/cancel
```

### Store APIs
```
GET  /store/billing/subscription            # Current subscription
GET  /store/billing/tiers                   # Available tiers
POST /store/billing/preview-change          # Preview tier change
POST /store/billing/change-tier             # Request tier change
POST /store/billing/checkout                # Stripe checkout session

GET  /store/billing/addons                  # Available add-ons
GET  /store/billing/my-addons               # Store's add-ons
POST /store/billing/addons/purchase         # Purchase add-on
DELETE /store/billing/addons/{id}           # Cancel add-on
```

---

## 8. Questions to Resolve

1. **Trial without payment method?**
   - Allow full trial without card, or require card upfront?

2. **Downgrade handling:**
   - What happens if store has more products than new tier allows?
   - Block downgrade, or just prevent new products?

3. **Enterprise tier:**
   - Self-service or contact sales only?
   - Custom pricing in UI or hidden?

4. **Add-on provisioning:**
   - Domain: Use reseller API or manual process?
   - Email: Integrate with email provider or manual?

5. **Grace period:**
   - How long after payment failure before suspension?
   - What gets disabled first?
