# Stripe Customer and Subscription Sync

## Objective

Keep local billing state matching Stripe as subscriptions, invoices, and plans change.

A verified event pipeline that projects Stripe customer, subscription, and invoice state onto the app's own access records, with reconciliation for anything the pipeline missed.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Define one local projection of billing state per account: which plan, which status, which period it runs to, and whether access is currently allowed. Every entitlement check in the app reads that projection and nothing else.
2. Verify every incoming event as genuinely from the provider before acting on it, and record its identifier so a replay is recognised and ignored. Providers retry on any non-success response, so handlers must be safe to run repeatedly.
3. Store a timestamp or version with the projection and refuse to apply an event that is older than what has already been written. Events arrive out of order, and a stale cancellation overwriting a fresh renewal locks a paying customer out.
4. Build a reconciliation pass that reads current state from the provider for a given account and repairs the projection, and make it runnable for one account or for all of them. Every event pipeline eventually misses something.
5. First-payment checkout flow is owned by the Stripe Checkout brief. This brief owns everything after: renewals, plan changes, invoices, and access revocation. One event handler, in this brief, and the checkout brief defers to it.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Verified provider events are the authority over local guesses, but they do not arrive in order. Apply them by their own sequence or timestamp rather than by arrival, or a late event will undo a newer one.
- The same event will be delivered more than once. Persist processed event identifiers and make each handler produce the same result on the second run as on the first, including the ones that create invoices or send email.
- A billing customer must resolve to exactly one tenant. If an event arrives for a customer nobody owns, park it for an operator to look at rather than attaching it to a plausible-looking account.
- Trials, paused subscriptions, scheduled plan changes, cancellations that take effect at period end, and past-due delinquency are all distinct states with different access consequences. Cancelled-but-still-paid-until must keep access; past-due must not silently keep it forever.
- Drift will happen. Provide a repair or backfill path that can rebuild an account's projection from the provider's current state, and log what it changed so an operator can see what the pipeline missed.
- A handler that fails partway through must not leave the projection half-updated. Write the change atomically, and if the event cannot be processed, return a failure so the provider retries rather than swallowing it.
- When the provider is unreachable, existing access must continue on the last known projection rather than being revoked. Never treat an inability to check as evidence of non-payment.
- Downgrades and revocations affect what the user can see and do. Decide what happens to data over the new plan's limits, and tell the user before it becomes unreachable.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Every entitlement check in the app reads a single local billing projection.
- [ ] Unverified events are rejected and duplicate deliveries produce no repeated side effects.
- [ ] Out-of-order events cannot overwrite newer state.
- [ ] Trials, pauses, scheduled changes, cancellations, and delinquency each map to a defined access outcome.
- [ ] A reconciliation pass repairs an account's projection from provider state and reports what it corrected.
- [ ] Events for an unmapped customer are quarantined for review rather than guessed at.
- [ ] A provider outage preserves existing access rather than revoking it.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
