# Credit Balance

## Objective

Track account credit as a ledger and apply it automatically to future charges.

An append-only record of credits granted and consumed, with a derived balance that is applied to invoices and explained on them.

## 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. Store credit as an immutable ledger of entries with a reason, amount, currency and source. Derive the balance from the ledger; do not keep a mutable number as the truth.
2. Correct mistakes by writing a reversing entry, never by editing or deleting a past one. The history is the accounting record.
3. Apply available credit to invoices automatically and show the applied amount and remaining balance as invoice lines.
4. Define, in writing, whether credit expires, whether it is refundable to a payment method, and whether it moves between workspaces. Undecided rules become support decisions made under pressure.
5. Do NOT let credit push a balance below zero. Reserve the amount when a charge begins so two concurrent charges cannot spend the same credit.

## 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

- Two invoices finalising at the same moment must not both consume the last of the balance. Claim credit atomically before charging.
- Credit is denominated in a currency. Do not apply a credit in one currency to an invoice in another; hold separate balances.
- Refunding a charge that was partly paid with credit must return the credit portion as credit and the money portion as money.
- Expiring credit must be a ledger entry too, so the balance history stays reconcilable after the expiry runs.
- If credit exceeds the invoice total, the invoice is fully covered and the remainder carries forward — the charge must not be attempted for a negative amount.
- Where the billing provider holds its own customer balance, pick one system as authoritative and reconcile the other. Two independent balances will diverge.

## 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

- [ ] Balance is computed from an append-only ledger, and no code path edits or deletes an existing entry.
- [ ] Concurrent charges cannot spend the same credit twice.
- [ ] Balances are held and applied per currency, never converted implicitly.
- [ ] Invoices show the credit applied and the balance remaining after application.
- [ ] Expiry, refundability and transferability rules are defined and enforced consistently.
- [ ] Every balance change, including expiry and reversal, is traceable to a ledger entry with a reason.
- [ ] 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.
