# Flows (Mermaid)

## A. Card Added → Auto-Promote to METERED
```mermaid
sequenceDiagram
  autonumber
  participant U as User
  participant PL as Stripe Payment Link
  participant ST as Stripe
  participant EV as EventBridge (Partner Bus)
  participant LH as Lambda (stripe_event_handler)
  participant D as DynamoDB (customer_links)
  participant G as API Gateway (Usage Plans)

  U->>PL: Complete checkout (add card / start sub)
  PL->>ST: Create PM / start metered sub
  ST-->>EV: payment_method.attached / setup_intent.succeeded
  EV-->>LH: Invoke with event
  LH->>LH: action = handle_stripe_event(evt)
  alt action.target_plan == "metered"
    LH->>G: move API key FREE_10K -> METERED
    LH->>D: save(plan="metered", usage_plan_id="METERED", metered_subscription_item_id)
  else action.target_plan == "free"
    LH->>G: move API key METERED -> FREE_10K
    LH->>D: save(plan="free", usage_plan_id="FREE_10K")
  end
```

## B. Payment Failed → Demote to FREE
```mermaid
sequenceDiagram
  autonumber
  participant ST as Stripe
  participant EV as EventBridge
  participant LH as Lambda (stripe_event_handler)
  participant D as DynamoDB
  participant G as API Gateway

  ST-->>EV: invoice.payment_failed
  EV-->>LH: Invoke with payload
  LH->>LH: action = handle_stripe_event(evt)
  LH->>G: move key to FREE_10K
  LH->>D: save(plan="free", usage_plan_id="FREE_10K")
```

## C. Hourly Usage Reporting
```mermaid
sequenceDiagram
  autonumber
  participant S as CloudWatch Schedule
  participant UR as Lambda (usage_reporter)
  participant D as DynamoDB
  participant G as API Gateway
  participant ST as Stripe

  S-->>UR: cron(hourly)
  UR->>D: query links plan=="metered" and subscription_item_id set
  loop each link
    UR->>G: GetUsage(usage_plan_id, api_key_id, since, until)
    UR->>UR: delta = used - last_reported (non-negative)
    alt delta > 0
      UR->>ST: report_usage(subscription_item_id, delta, period_end, idempotency_key)
      UR->>D: update checkpoints
    end
  end
```
