Skip to content

Last reviewed: 2026-08-01 Accepted decision: - ../decisions/accepted/0032-qbo-first-controlled-cutover.md

Contract: QBO conversion connector

Purpose and boundary

The QBO conversion connector performs one read-only, company-selected capture for the controlled-cutover workflow. It preserves provider responses and feeds them into the canonical AccountingImportRun intake boundary. It does not own mapping, reconciliation, chart maintenance, Source Documents, posting, or conversion application.

The connector applies only to the replacement scenario for an existing QBO instance. Startup-scenario company setup must not require a QBO connection, capture, or qualified conversion package.

The connector is not recurring synchronization. It does not write to QBO.

Authorization handoff and company selection

  • QBO authorization uses the accounting scope and a registered HTTPS callback.
  • A desktop executable must not contain or persist the provider client secret.
  • Authorization-code exchange, refresh, and revocation that require the client secret belong to a separately deployed narrow authorization broker.
  • BooksPlus accepts a short-lived authorization handoff containing the selected QBO realm, access token, current refresh capability when supplied by the broker, and exact expiry metadata. Callback deployment and broker operations are independently deployable; they do not receive accounting authority.
  • The user explicitly selects one BooksPlus company and confirms the exact QBO realm before a connection is persisted. The callback realm, confirmed realm, connection realm, every request path, and staged capture realm must agree exactly. CompanyInfo must be captured from that realm-scoped request; its provider object id is not treated as the realm id.
  • Connection and credential replacement are protected, company-scoped actions. A credential handoff for another realm or BooksPlus company is rejected without provider access or persisted connection state.

Credential protection

  • Access tokens, refresh tokens, authorization codes, client secrets, and broker credentials never appear in ordinary records, logs, audit reasons, exception messages, filenames, source evidence, or import payloads.
  • Provider tokens are encrypted through the canonical company data-protection service and require the company key to be unlocked for use.
  • Ordinary connection state stores only the protected-payload identity, realm, environment, expiry metadata, status, and attribution.
  • Only the latest accepted token bundle may be used. Token rotation is serialized per connection and persists the replacement before it is used.
  • A missing, expired, revoked, or unverifiable token pauses extraction and requires a new broker handoff; it does not discard captured checkpoints.

Extraction and checkpoints

One QboConversionExtraction belongs to one BooksPlus company and one exact connection realm. It records:

  • stable extraction id and request id;
  • deterministic request fingerprint;
  • BooksPlus company, connection, selected realm, environment, cutover date, requested profile, minor version, actor, and correlation context;
  • ordered operation and page checkpoints;
  • each exact provider response length, SHA-256, protected-payload identity, capture time, request identity, and provider request id when supplied;
  • terminal immutable AccountingImportRun identity; and
  • status, created time, and updated time.

The initial read-only operation set is CompanyInfo, all Account query pages, TrialBalance, BalanceSheet, AgedReceivables, AgedPayables, InventoryValuationSummary, and SalesTaxLiability at the explicit cutover date. Account queries use deterministic ascending source identity and explicit pagination. Provider response bytes are protected and checkpointed before the next operation or page begins.

An exact extraction-command replay returns the same extraction. Reusing a request id with changed company, connection, realm, date, profile, or minor version is a conflict. Resume starts after the last durable checkpoint and never refetches or replaces a completed checkpoint. A read-only request whose response was not durably checkpointed may be repeated.

HTTP 429, timeouts, and transient provider failures leave the extraction in_progress and preserve checkpoints. Authentication failure changes the connection to reauthorization_required and preserves the extraction. Invalid realm, malformed response, unsupported response size, changed checkpoint meaning, or provider evidence that cannot be scoped is a visible blocking failure; it does not stage a partial import.

Immutable import handoff

After every required checkpoint is durable, BooksPlus creates one deterministic qbo-live-api-capture-v1 package. It contains metadata and exact response bytes or exact protected-response representations, but no token or secret. Its ordered manifest binds every operation, page, request identity, response hash, length, capture time, and provider request id.

The package is staged only through AccountingImportIntakeService with source system quickbooks_online, profile key qbo-live-api-capture, profile version 1, JSON media type, and the selected BooksPlus company currency. Intake exact replay remains authoritative. The extraction persists the resulting import-run id before becoming completed.

The live capture is source evidence for the existing controlled-cutover path. It does not claim that every captured provider report has been qualified into a conversion control. Slice 14E must qualify the live-package translation and surface unavailable or inconsistent controls as blockers before approval.

Qualified live conversion handoff

Qualification is a separate protected read-and-translation action over one completed extraction. It must:

  • resolve the exact same-company live-capture manifest and extraction;
  • verify the complete ordered operation and page sequence;
  • authenticate every protected response and recheck its company, extraction, purpose, request identity, byte length, and SHA-256 checkpoint binding;
  • translate company, Account, trial-balance, and independent report evidence into one deterministic qbo-live-qualified-package-v1 package;
  • stage that package only through AccountingImportIntakeService under source system quickbooks_online, profile qbo-controlled-cutover-live, version 1, and the selected company currency; and
  • return exact intake replay for the same qualified bytes.

The qualified-live package uses the version 2 controlled-cutover fact shape and control taxonomy. Its source form remains distinguishable from the representative fixture profile. Qualification does not overwrite or expose the protected provider responses.

Every applicable control requires independent captured evidence and exact agreement with its selected opening trial-balance accounts. A nonzero report without applicable captured accounts, a missing account-level report identity, an unavailable report total, or any difference is blocking. Absence of an applicable account may support explicit non-applicability only when the complete paged Account capture and corresponding report are consistent with zero.

An applicable bank control additionally requires explicit outstanding checks, deposits, payments, and transfers. The initial live capture does not contain those four facts; therefore a capture with an applicable bank account remains blocked and no qualified conversion import is staged. The operator must obtain a later versioned capture/profile that supplies that evidence rather than infer or enter zero through the translator.

Qualification has no durable aggregate of its own. The protected capture is the source evidence, and the exact-replay AccountingImportRun is the immutable qualified result. Existing import, conversion, backup, restore, audit, period, Source Document, chart, and posting authorities remain unchanged.

Authorization and audit

Protected actions:

  • qbo_connection.connect;
  • qbo_connection.replace_credential;
  • qbo_conversion_extraction.start;
  • qbo_conversion_extraction.qualify; and
  • qbo_connection.disconnect.

Every action resolves actor and BooksPlus company before connection or extraction lookup. Succeeded, denied, failed, replayed, paused, and disconnected outcomes emit value-free audit evidence. Audit may retain company, actor, connection or extraction id, realm, environment, operation name, result, machine identity, correlation id, and provider request id. It must not retain tokens, authorization codes, raw provider responses, customer names, account names, amounts, or other payload values.

Starting extraction also invokes the separately protected accounting_import_run.stage action only when the complete package is handed off. Connector authority never implies import, conversion, chart, or posting authority.

Persistence, backup, and isolation

  • Connection state, extraction state, and checkpoints are company-owned and persistent. Credential and response payloads use protected company payloads.
  • Database constraints bind connection, extraction, checkpoint, protected payload, import run, and audit identities to the same company.
  • Concurrent resume serializes per extraction. Completed extraction state and its import-run link are immutable. Ordinary behavior does not delete capture history.
  • Company backup and restore preserve connections, encrypted credential and response payloads, interrupted checkpoints, completed import links, and company-scoped constraints. Restored credentials remain encrypted and usable only after the restored company key is unlocked.
  • No lookup may expose whether another company has a realm, connection, extraction, checkpoint, credential, or import run.

Explicit exclusions

This contract does not authorize:

  • a provider client secret in BooksPlus desktop code or storage;
  • implementation or hosting of the authorization broker or callback;
  • recurring polling, webhooks, change-data capture, or bidirectional sync;
  • writes to QBO;
  • full-history or operational-subledger conversion;
  • inference of accounting meaning from provider fields;
  • direct chart mutation, Source Document creation, or ledger posting; or
  • Dolibarr, IRIS A2A, professional-access, or support-access work.
  • company-conversion-run.contract.md
  • accounting-import-run.contract.md
  • security/company-data-encryption-contract.md
  • security/audit-event-contract.md
  • security/company-backup-snapshot.contract.md
  • ../decisions/accepted/0032-qbo-first-controlled-cutover.md