# Metered Pricing Implementation - Simple Approach

## Summary
Migrating from deprecated `usage_records` API to Stripe's new Meters API with the absolute minimum changes. No new environment variables, no database changes, no backward compatibility complexity.

## What's Changing

### 1. API Version Pinning Removal
**Files affected:** 6 CLI files
**Change:** Delete `stripe.api_version = "2024-06-20"`
**Impact:** Uses latest Stripe API version

### 2. Product Setup Changes
**File:** `src/augint_billing_lib/cli/products/setup.py`
**Change:**
- Create a meter first during product setup
- Pass meter ID to price creation

```python
# New: Create meter during setup
meter = stripe.billing.Meter.create(
    display_name="API Usage",
    event_name="api_usage",  # Hardcoded event name
    default_aggregation={"formula": "sum"}
)

# Modified: Pass meter to price
price = create_metered_price_with_tiers(
    product_id=product.id,
    currency="usd",
    tiers=tiers,
    meter_id=meter.id  # New parameter
)
```

### 3. Usage Reporting Changes
**File:** `src/augint_billing_lib/adapters/stripe.py`
**Change:** Switch from `usage_records` to `MeterEvent`

```python
def report_usage(self, subscription_item_id, units, timestamp, idempotency_key):
    # Get customer from subscription (2 API calls)
    sub_item = stripe.SubscriptionItem.retrieve(subscription_item_id)
    subscription = stripe.Subscription.retrieve(sub_item.subscription)

    # Report to meter instead of usage_records
    return stripe.billing.MeterEvent.create(
        event_name="api_usage",  # Hardcoded - we only have one meter
        payload={
            "stripe_customer_id": subscription.customer,
            "value": str(units)
        },
        timestamp=timestamp,
        idempotency_key=idempotency_key
    )
```

## What's NOT Changing

### Database
- **No changes to DynamoDB schema**
- Keep `metered_subscription_item_id` field (still needed to find customer)
- No new fields added

### Environment Variables
- **No new environment variables**
- Existing variables unchanged

### Service Layer
- **No changes to BillingService**
- Still calls `stripe.report_usage()` with same parameters
- Interface remains identical

### Lambda Handlers
- **No changes needed**
- Same inputs/outputs
- Same error handling

## Architecture Comparison

### Old Flow
```
Lambda → Service → StripeAdapter → subscription_items/usage_records API
                        ↓
                Needs subscription_item_id
```

### New Flow
```
Lambda → Service → StripeAdapter → Get Customer → MeterEvent API
                        ↓                ↓
                subscription_item_id → customer_id → meter event
```

## Implementation Details

### Why This Approach?
1. **Minimal changes** - Only touches 3 core areas
2. **No config drift** - Hardcoded event name prevents misconfiguration
3. **No migration needed** - Works alongside existing system
4. **Simple rollback** - Just revert the library version

### Trade-offs
- **Extra API call** - Need to fetch customer from subscription item (acceptable for simplicity)
- **Hardcoded event name** - Not configurable (we only have one use case)
- **Meter per environment** - Each environment gets its own meter (cleaner separation)

## Testing Plan

1. **Unit Tests**: Mock the new `MeterEvent.create()` calls
2. **Integration Tests**: Create test meter in Stripe test mode
3. **Staging**: Full end-to-end test with real meter
4. **Production**: Deploy after staging validation

## Rollout Plan

### Phase 1: Library Update (This PR)
- Remove API version pinning
- Update usage reporting method
- Update CLI setup command

### Phase 2: Create Meters (Manual)
```bash
# Run once per environment
ai-billing products setup staging   # Creates meter automatically
ai-billing products setup production # Creates meter automatically
```

### Phase 3: Deploy
- Deploy new library version to Lambda
- Monitor CloudWatch for errors
- Verify usage reporting in Stripe dashboard

## Monitoring

### Key Metrics
- Meter event creation success rate
- API call latency (now 2 calls instead of 1)
- Stripe API errors

### Alerts
- Failed meter event creation
- Customer lookup failures
- Rate limiting (1000/sec limit)

## FAQ

**Q: Why not store meter ID in environment?**
A: The meter is tied to the price in Stripe. We only have one meter per environment, hardcoded as "api_usage".

**Q: What about backward compatibility?**
A: Clean slate approach. Old library versions continue working with usage_records.

**Q: Why keep subscription_item_id?**
A: Still needed to find the customer ID for meter events.

**Q: What if we need multiple meters later?**
A: Can add configuration then. For now, YAGNI (You Aren't Gonna Need It).

## Summary for Infra Team

**What you need to do:** Nothing initially. Just deploy the new library version when ready.

**What stays the same:** Database, environment variables, Lambda handlers, monitoring.

**What changes:** Under the hood, usage is reported via meter events instead of usage records.

**Risk level:** Low - minimal changes, easy rollback, fully tested in staging first.
