# Xero Invoice Sync

## Objective

Keep Xero invoices, contacts, and payment state aligned with what the app believes.

Alignment between app transactions and invoices in the connected accounting organisation, covering contacts, tax rates, and payment status.

## 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. Make the operator choose the organisation explicitly when connecting and store that choice, because one login commonly reaches several organisations and the first one returned is not necessarily the right one.
2. Resolve the contact before the invoice, matching on a stored external reference first and creating a contact only when nothing matches with confidence.
3. Read tax rates and account codes from the connected organisation rather than assuming any standard set, and revalidate a saved mapping before each send.
4. Treat approval as the boundary of ownership. The app may create and amend a draft, but once an invoice is approved or paid the ledger owns it; do not let the app rewrite an approved invoice.
5. Pull payment, credit note, and void status back onto the app record so the app's view of what is outstanding matches the ledger's. QuickBooks Invoice Creation is the sibling for a different ledger; share the matching and queueing path rather than writing a second one.

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

- One login can reach several organisations. If the connection does not pin one, invoices eventually land in the wrong company's books, which is not something an accountant can undo quickly.
- Matching contacts on name alone joins unrelated businesses. Match on a stored reference, and treat a near match as something to confirm rather than something to assume.
- An invoice moves through draft, submitted, approved, paid, voided, and credited, and most of those transitions are one-way. Model the whole lifecycle rather than a paid flag.
- Tax treatment and currency rules belong to the organisation's configuration, not to the app. Send the codes the organisation defines and let it compute what it computes.
- Once an invoice is approved, editing it from the app either fails or corrupts a filed return. After approval the app raises a credit note or a new invoice; it does not rewrite the original.
- Access tokens for this kind of connection expire quickly and the refresh token may itself rotate on use. Persist the new refresh token atomically, because losing it forces the operator to reconnect by hand.
- Rate limits are enforced per organisation and per application. Queue sends and back off when refused, and never place an accounting call inside a user-facing request.
- When the ledger is unreachable, show the invoice as pending with the reason and the time of the last attempt. A silent failure is discovered at the end of the quarter.

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

- [ ] The connected organisation is chosen explicitly at setup and every request is scoped to it.
- [ ] Contacts are matched by stored reference before any new contact is created.
- [ ] Draft, approved, paid, voided, and credited invoices are each represented distinctly in the app.
- [ ] Approved invoices are read-only from the app, and corrections are made by credit note or new invoice.
- [ ] Token refresh, including a rotating refresh token, survives a restart with no operator action.
- [ ] Payment and credit status flows back so the app's outstanding balance matches the ledger's.
- [ ] Rate-limited and unreachable states are visible with a reason and a last-attempt time.
- [ ] 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.
