# QuickBooks Invoice Creation

## Objective

Turn app transactions into QuickBooks invoices with the right customer, items, and tax.

Server-side creation of an invoice in the connected accounting company from an app transaction, with the external reference stored.

## 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. Resolve the customer before building the invoice: look up the stored external reference first, then attempt a deliberate match, and create a new customer only when neither finds anything.
2. Require an explicit mapping from each app product or charge to an income item and a tax code in the connected company. Do not guess a default account, because the wrong account is an accounting error someone has to unwind by hand later.
3. Compute totals as exact decimals under one defined rounding rule, and reconcile the app's total against the total the provider returns before marking the transaction synced.
4. Store the returned invoice identifier and its version against the app transaction and use them for every later read or update. Xero Invoice Sync solves the same problem for a different ledger, so keep customer matching, queueing, and reconciliation in one shared path and vary only the provider adapter.
5. Run the whole exchange server-side under the workspace's stored credentials, refreshing an expired token before the call and prompting for re-authorization when the refresh fails. Never place accounting credentials anywhere the browser can read them.

## 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 app records for the same real customer must not produce two ledger customers. Match deliberately, and when the match is ambiguous surface it rather than creating a second entry an accountant has to merge.
- An item or tax code made inactive in the accounting system is rejected on use. Validate the saved mapping against the company's current lists before sending, and name the stale mapping to the operator.
- Rounding differences of one cent per line become real discrepancies at volume. Apply rounding at one defined point and refuse to post an invoice whose total does not match the app's.
- The provider rejects an update that carries an outdated version of the object. Re-read the invoice, reapply the change, and retry once rather than forcing the write through.
- A closed accounting period refuses a posting outright. Report that to the operator as a period problem with a suggested date, not as a generic sync failure.
- Without the stored invoice reference, a retried job creates a second invoice for the same transaction. Write the reference in the same transaction that marks the app record as sent.
- Payments, credits, and voids applied inside the accounting system must flow back to the app, or the app will keep showing an invoice as outstanding long after it was paid.
- When the provider is unavailable the app transaction must still complete. Queue the invoice, show it as pending, and never block a customer-facing action on an accounting write.

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

- [ ] Each app transaction produces exactly one invoice, even when the creation job is retried.
- [ ] Customers are matched before creation, and ambiguous matches are surfaced rather than duplicated.
- [ ] Every synced product or charge has an explicit income item and tax code mapping, validated against the company's current lists.
- [ ] Invoice totals reconcile exactly with the app's totals, with rounding applied at one defined point.
- [ ] Version conflicts and closed-period rejections produce specific, actionable operator messages.
- [ ] Credentials refresh server-side and are never exposed to the browser.
- [ ] A provider outage leaves invoices queued and visible as pending without failing the originating transaction.
- [ ] 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.
