Skip to content

Source truth: - ../truth/decisions/accepted/0032-qbo-first-controlled-cutover.md - ../truth/contracts/company-conversion-run.contract.md - ../truth/contracts/accounting-import-run.contract.md - ../truth/contracts/accounting-import-candidate.contract.md - ../truth/contracts/qbo-conversion-connector.contract.md Last reviewed: 2026-08-01

QBO Controlled-Cutover Fixture Profile

This profile is replacement-scenario infrastructure. It applies when an existing QBO accounting instance is being replaced by BooksPlus. Startup- scenario company creation uses ordinary setup and must not manufacture a QBO connection, capture, qualified package, or CompanyConversionRun.

This page records the Draft provider compatibility, mapping, control-schedule, and live-capture foundation qualified by Step 14, Slices 14B through 14D. It does not add accounting meaning. The accepted QBO controlled-cutover decision and canonical contracts remain authoritative.

Qualified fixtures

The qualified inputs are BooksPlus-owned JSON fixture packages in the bp3 domain-test data. They are representative, non-sensitive, and documentation-derived; they are not raw QuickBooks Online exports, captured API responses, or production company data.

Fixture identity:

  • profile key: qbo-controlled-cutover-fixture;
  • profile version: 2;
  • compatibility identity: qbo-fixture-package-v2;
  • fixture kind: representative_non_production;
  • source form: documentation_derived_fixture_package;
  • declared edition: qbo_us_sandbox;
  • baseline fixture qbo-controlled-cutover-v1.json SHA-256: 3fccb8da9b688ff2cbcdf7e82403ac7e70ca04666fff519af422d8801c483020;
  • chart-complete fixture qbo-controlled-cutover-chart-mapping-v1.json SHA-256: 4ae2c92be0bb364c113328d5af290333e69b215a8698d72f6a8c8a5b9792ac79.

The baseline fixture deliberately exposes a trial-balance account without a matching account fact and therefore proves the missing-source-account blocker. The chart-complete fixture adds that exact account fact and is the successful mapping, control, and approval fixture. Both use the version 2 package contract with explicit control applicability.

AccountingImportRun preserves the exact package bytes, file hash, source system, profile identity, company scope, accepted time, and company currency. The profile also retains the raw JSON text for every supported company, account, trial-balance line, trial-balance report, and object-state fact.

Draft provider support matrix

Concern Qualified in version 2 Not qualified
QBO edition Two US sandbox-shaped representative fixtures Other countries, editions, feature combinations, and production companies
Input form BooksPlus fixture-package JSON with exact payload hash Native QBO files, spreadsheets, arbitrary JSON, raw API envelopes, or Desktop files
Transport Previously staged fixture payload and versioned qbo-live-api-capture-v1 manifest Recurring polling, webhooks, change-data capture, writes, or synchronization
Source company Explicit realmId, repeated selectedRealmId, CompanyInfo subset, and expected realm check Realm discovery, user-company lists, or implicit company choice
Accounting settings Home currency, country, declared edition, minor-version metadata, capture timestamp, and cutover date Fiscal-year, tax, multicurrency, closing-date, or locale behavior not present in the package
Chart facts Account Id, SyncToken, name, optional number, type, optional subtype, active state, currency, and modified time Automatic BooksPlus target selection, chart mutation, or provider account semantics becoming canonical
Opening position One accrual-basis, company-currency trial balance at the selected cutover date, with account identity and exact debit/credit text Cash basis, comparative periods, foreign currency, posting, or a claim that report rows are ledger lines
Cutover controls Explicit applicability, amount, count, source-account ids, and evidence for receivables, payables, inventory, bank, credit card, sales tax, payroll liabilities, and retained earnings/prior income; bank controls include checks, deposits, payments, and transfers Materiality policy, inferred applicability, operational subledger creation, or provider reconciliation becoming ledger truth
Object changes Explicit fixture evidence for changed, inactive, voided, deleted, and merged states Inferring deletion, merge, void, or history from absence or descriptive text
Other QBO objects May be retained later as non-posting control evidence Customer, vendor, item, receivable, payable, banking, payroll, fixed-asset, inventory, or transaction masters

The package field names are a stable BooksPlus compatibility contract, not a claim that raw QBO response casing or envelopes have the same shape. A later captured-response or live connector profile must translate provider responses into this review boundary and earn its own compatibility identity and tests.

Live capture boundary

Slice 14D adds the canonical QBO Conversion Connector Contract and a read-only HTTP client for sandbox or production realm-scoped endpoints. One explicitly confirmed QBO realm is bound to one BooksPlus company before capture. The desktop stores no provider client secret. A separately deployed authorization broker must perform any client-secret-bearing callback, code exchange, token refresh, or revocation and hand BooksPlus a short-lived exact- realm token bundle.

BooksPlus encrypts token bundles and provider responses with the company data- protection service. One restartable extraction checkpoints CompanyInfo, every deterministically paged Account response, and TrialBalance, BalanceSheet, AgedReceivables, AgedPayables, InventoryValuationSummary, and SalesTaxLiability reports at the cutover date. Completed checkpoint bytes are never fetched again during resume. Throttling, timeout, and temporary provider failure preserve in_progress; authentication failure additionally marks the connection reauthorization_required.

Only a complete ordered manifest enters AccountingImportIntakeService under profile qbo-live-api-capture version 1. The manifest contains protected- payload identities, response hashes, lengths, request identities, capture times, and provider request ids, but no token, raw response, customer name, account name, or amount. PostgreSQL and company backup version company-snapshot-v23 / bp3-schema-202608130002 preserve connections, encrypted credentials, interrupted checkpoints, and completed import links.

This capture is not yet a qualified live conversion profile. Slice 14E must translate and compare live response shapes to the version 2 controlled-cutover facts, prove every applicable control, and hold unavailable or inconsistent provider evidence.

Qualified live package

QboLiveCaptureQualificationService reads only a completed extraction after authorizing qbo_conversion_extraction.qualify. It verifies the immutable manifest, checkpoint sequence, protected-response ownership and purpose, authenticated recovery, byte length, and SHA-256 before translation.

A successful translation stages qbo-controlled-cutover-live version 1 with compatibility identity qbo-live-qualified-package-v1. The package uses the same company, account, opening trial-balance, eight-schedule, and object- state fact shape as the fixture profile, so the existing mapping, reconciliation, approval, recovery, and application path re-parses the same immutable payload throughout.

Qualification fails closed. Missing report totals, account/report identity gaps, nonzero controls without applicable accounts, source-control differences, or mismatched date/currency/basis stage no qualified import. The current capture does not include bank outstanding checks, deposits, payments, and transfers; therefore any applicable bank account is a visible qualification blocker. No operator-entered or inferred zero substitutes for missing evidence.

Identity, dates, and normalization

  • realmId identifies the selected QBO company. A mismatch between the package realm, its repeated selection evidence, and the conversion context is a blocking issue.
  • An account source identity is qbo.account/{Id}@{SyncToken}. Missing Id or SyncToken holds the proposal. Repeated identical IDs are visible duplicates; changed values under the same ID are conflicts.
  • A trial-balance control identity includes its date, basis, and exact package SHA-256. It is a control fact, not a source event or posting identity.
  • Package and trial-balance dates must equal the selected cutover date. Timestamps require ISO 8601 offset form. No local-time assumption is made.
  • Decimal source text is retained before invariant-culture parsing. Negative, dual-sided, malformed, or unbalanced values are blocking issues.
  • Account names are normalized only to detect ambiguous mapping proposals. They never select a BooksPlus account automatically.

Chart mapping review

QboChartMappingReviewService version 1 requires one explicit decision for every qualified QBO account:

  • map to one exact active same-company BooksPlus account id;
  • stage one explicitly classified active account for creation; or
  • exclude a non-balance-bearing source account with a reason.

The service does not infer BooksPlus type, normal balance, code, or account identity from QBO account numbers, names, types, or subtypes. A new-account decision supplies those BooksPlus values explicitly and becomes a row in the canonical staged ChartImportBatch. Account creation and its authorization, history, and audit remain owned by chart-import commit and account maintenance. The caller supplies the current mapping-review actor explicitly; chart staging does not reuse the earlier import-intake actor by assumption.

Mapping review uses fingerprint schema qbo-chart-mapping-v1. The lowercase SHA-256 binds company, import run, payload hash, realm, profile version, mapping version, source identities and raw-object hashes, and every normalized decision. Decision order does not affect the fingerprint. An exact replay reuses its existing staged chart batch; changed meaning under an already staged mapping version is a conflict.

The immutable review result records source identity, disposition, exact target account id and version for existing targets, or the staged chart row for a new target. Missing source facts or decisions, duplicate decisions, unknown source accounts, inactive source or target accounts, duplicate targets or codes, balance-bearing exclusions, and chart-import validation errors block dependent conversion work.

The transient review result is not itself accepted conversion state. Slice 14C2A copies its exact mapping identity, version, fingerprint, decisions, dispositions, and staged chart references into the durable CompanyConversionRun before control evaluation. This boundary avoids creating a second mapping or chart workflow.

Conversion controls and approval

Profile version 2 requires every supported control-schedule family to appear exactly once. An applicable schedule supplies its normal balance, exact control amount, record count, source trial-balance account ids, and evidence references. A non-applicable schedule supplies an explicit reason and cannot claim an amount or account. Applicable bank controls explicitly enumerate outstanding checks, deposits, payments, and transfers, including zero counts and amounts.

CompanyConversionWorkflowService compares these schedules to the exact opening trial balance selected by the durable mapping. Control result version conversion-control-v1 contains trial-balance equality, balance-sheet equality, all eight schedule outcomes, outstanding instruments, source and mapping disposition counts and amounts, evidence, and a deterministic fingerprint. Exact equality is required because no accepted materiality policy currently authorizes an immaterial-difference threshold. Blocked evaluations remain durable in mapped; only a result with matched or explicitly not-applicable controls reaches reconciled.

Approval version conversion-approval-v1 binds the BooksPlus company and selected source company, source links and hashes, profile, cutover date and currency, mapping selection, control result and dispositions, and approving actor. The protected approval command requires visible confirmation of that exact fingerprint and source-company identity. It does not commit the chart, create accounts or Source Documents, or post opening balances.

Application and recovery

Application version conversion-application-v1 requires a separate protected apply decision and the same visible approval-fingerprint and source-company confirmation. The run enters durable applying before downstream mutation. Its chart step commits the exact approved staged batch using the applying actor's chart authority. Every resulting account is then bound to its mapping ordinal, source identity, chart row, account id, and account version. Recovery accepts those accounts only when batch-correlated account history proves their origin; matching account codes are insufficient.

The opening step resolves every nonzero trial-balance line through the approved existing-account mapping or the persisted chart results. It calls OpeningBalanceSetupReviewService, which preserves readiness, company- currency, eligible-period, Source Document, authorization, audit, and central posting rules. A run-derived source identifier makes an interrupted posting recoverable. Resume validates the exact posting date, explanation, lines, currency, source evidence, actor, journal entry, Source Document, and posting audit before reusing it.

The aggregate persists each completed step before beginning its successor. Only both durable result sets plus the succeeded apply audit can produce applied. PostgreSQL still enforces at most one applied controlled cutover per company. Company backup version company-snapshot-v23 preserves applying and applied recovery state with company-scoped result constraints.

Dispositions and limitations

Active, complete, company-currency account facts become non-posting mapping proposals. Inactive accounts and ambiguous names are held. Unsupported currency, missing identity, conflicting identity, invalid dates or amounts, voided, deleted, merged, and otherwise unsupported state evidence blocks qualification or dependent conversion work. Changed and exact-duplicate evidence remains visible for review.

Each fixture contains one inactive account and one explicit changed-object fact to exercise review behavior. There is no captured provider event stream that can establish delete or merge completeness. Absence from a fixture therefore has no state meaning.

The provider profile itself remains pure in-memory normalization. It has no repository, workflow, chart, Source Document, period, audit, ledger, network, or provider-client dependency. Mapping review remains non-mutating; only the separately protected conversion application coordinates canonical chart and opening-balance owners.

Provider references used for fixture shape

The representative fields and limitations were checked against Intuit's official documentation for the QuickBooks Online Accounting API, data queries, QuickBooks Online basics, and reports. Live connector behavior was also checked against Intuit's official OAuth 2.0 guidance, query and pagination guidance, and limits and throttles. Provider documentation is evidence for this Draft compatibility record only; it is not BooksPlus accounting truth.