Skip to content

Last reviewed: 2026-08-13 Accepted decision: - ../../decisions/accepted/0031-company-scoped-postgresql-backup-and-atomic-restore.md

Contract: Company backup snapshot

Purpose

This contract defines the versioned ownership catalog and restore behavior for one BooksPlus company stored in a shared PostgreSQL schema.

Snapshot identity

The current catalog version is company-snapshot-v23.

The current application-schema version is bp3-schema-202608130002.

A snapshot carries:

  • backup, company, format, application-schema, and catalog versions;
  • the exact company-owned relational projection;
  • the exact managed-evidence component;
  • the exact company key-envelope component;
  • referenced immutable shared definitions; and
  • a manifest of every component identity, length, and cryptographic digest.

An implementation must compare the live schema with this catalog. An uncataloged persisted relation or an unexpected ownership path blocks backup creation and restore.

Current relation catalog

Direct company-owned state

Rows are selected by their company_id, except company, which is selected by its stable id. security_audit_event includes only rows whose company_id equals the backup company.

  • company
  • account
  • account_history
  • account_role_assignment
  • accounting_correction
  • accounting_event_relationship
  • accounting_import_accepted_candidate
  • accounting_import_run
  • banking_and_finance_fact
  • chart_import_batch
  • close_approval
  • close_check_snapshot
  • close_report_pack
  • close_reopen
  • close_run
  • close_run_number_sequence
  • close_waiver
  • company_conversion_run
  • company_conversion_control_result
  • company_conversion_approval
  • company_conversion_application
  • company_protection_key_envelope
  • dolibarr_account_crosswalk_mapping
  • dolibarr_mapping_set_selection
  • dolibarr_role_projection
  • financial_period
  • finance_account_reconciliation_result
  • finance_statement_match_result
  • finance_sales_tax_remittance_match
  • finance_settlement_allocation
  • fiscal_calendar_profile
  • journal_entry
  • journal_entry_number_sequence
  • information_return_payer_profile
  • information_return_payer_profile_protected_tin
  • information_return_support_run
  • inventory_accounting_fact
  • inventory_ppv_allocation
  • inventory_ppv_reconciliation_result
  • inventory_valuation_snapshot
  • information_return_draft
  • information_return_filing_submission
  • information_return_recipient_statement
  • payee_profile_protected_tin
  • payee_tax_profile
  • protected_payload_envelope
  • qbo_connection
  • qbo_conversion_extraction
  • purchasing_and_payables_fact
  • purchasing_grni_settlement_allocation
  • purchasing_prepayment_recognition_allocation
  • report_run
  • report_run_number_sequence
  • security_audit_event
  • sales_tax_capability_profile
  • sales_tax_result
  • sales_tax_return_control
  • sales_tax_return_control_number_sequence
  • sales_tax_remittance
  • sales_tax_remittance_number_sequence
  • sensitive_source_document_artifact
  • setup_acknowledgement
  • starter_chart_installation_review
  • source_document
  • summary_accounting_batch
  • summary_accounting_batch_number_sequence
  • worker_classification_record

Company-owned child state

Rows are selected only through the declared parent path:

Relation Company-owning parent path
accounting_import_payload accounting_import_run
chart_import_row chart_import_batch
chart_import_issue chart_import_batch
company_conversion_import_link company_conversion_run
company_conversion_mapping_decision company_conversion_run
company_conversion_status_change company_conversion_run
company_conversion_control_check company_conversion_control_result
company_conversion_application_step company_conversion_application
company_conversion_application_account company_conversion_application
qbo_conversion_extraction_checkpoint qbo_conversion_extraction
close_check_source_reference close_check_snapshot
close_report_pack_evidence close_report_pack
close_report_pack_report_run close_report_pack
close_reopen_evidence close_reopen
financial_period_state_change financial_period
finance_account_reconciliation_line finance_account_reconciliation_result
journal_entry_line journal_entry
report_snapshot report_run
report_snapshot_line report_snapshot through report_run
report_snapshot_source_contribution report_snapshot through report_run
sales_tax_profile_evidence sales_tax_capability_profile
sales_tax_jurisdiction_summary sales_tax_result
sales_tax_return_inclusion sales_tax_return_control
sales_tax_reconciliation_snapshot sales_tax_return_control
sales_tax_external_filing_evidence sales_tax_return_control
sales_tax_return_status_history sales_tax_return_control
sales_tax_external_payment_evidence sales_tax_remittance
sales_tax_remittance_status_history sales_tax_remittance
information_return_support_line information_return_support_run
summary_accounting_validation_issue summary_accounting_batch
summary_accounting_evidence_link summary_accounting_batch
summary_accounting_prepared_entry_preview summary_accounting_batch
summary_accounting_prepared_entry_preview_line summary_accounting_prepared_entry_preview through summary_accounting_batch
summary_accounting_posting_result_link summary_accounting_batch

Company security configuration requiring review

  • security_actor_role_assignment

Captured assignments are not automatically activated. Before replacement, the restore workflow presents current and captured assignments for an explicit protected role_permission.change review. Only approved assignments are applied in the replacement transaction. Existing assignments remain current unless the review explicitly changes them; recovery into an absent company activates none by default.

Embedded immutable shared definitions

These relations are not replaced wholesale. Only definitions referenced by the company snapshot are embedded and reconciled under ADR 0031:

  • information_return_rule_set
  • security_actor
  • security_role
  • security_permission
  • security_role_permission

Actor references include actors named by company records and company-scoped audit events, not only actors with a current role assignment.

Installation state excluded from company backup

  • booksplus_schema_migration
  • company-null rows of security_audit_event

The migration ledger is used to establish the application-schema version but is never restored from a company backup.

Logical component projections

Physical co-location does not collapse required backup components:

  • company_protection_key_envelope is projected into the company-key-envelope component and omitted from the ordinary relational component;
  • for protected_payload_envelope rows owned by a sensitive W-9 artifact, the encrypted artifact bytes and their encryption/integrity material are projected into the managed-evidence component while the owning relational identities remain in the relational projection;
  • other protected payloads, including protected taxpayer identifiers, QBO token bundles, and exact QBO response checkpoints, remain in the company relational projection; and
  • sensitive_source_document_artifact metadata binds the managed-evidence component back to its Source Document and protected-payload identity.

The capture and restore implementation must prove that every logical row and artifact is represented exactly once and that the components reconstruct all required database constraints.

Shared-definition reconciliation

  • Existing shared definitions are never overwritten.
  • Existing information-return rule versions require exact content equality.
  • Existing role identities require compatible role name and exact permission membership.
  • Existing protected-action permission names must match the embedded identity.
  • Existing actor identities require compatible stable actor id, actor type, and mapped external identity when present. Existing status and login mapping remain current.
  • Missing shared roles, permissions, and role-permission memberships may be inserted exactly.
  • Missing actors are inserted disabled and without a login or operating-system mapping. Their historical display name and actor type are retained.
  • Captured actor-role assignments remain inactive unless explicitly approved through protected role-permission review.
  • Any incompatible shared identity blocks restore before mutation.

Restore rules

  • The target company UUID must equal the backup company UUID or be absent.
  • An absent company is created with the captured UUID; identity is never remapped.
  • Replacement runs only in exclusive BooksPlus maintenance mode under the company-scoped restore lock.
  • All validation completes in staging before the replacement transaction.
  • The recovery secret must authenticate both the container and company key envelope.
  • Company-owned state is replaced atomically.
  • Company audit events are merged append-only by immutable event id.
  • Other-company and installation state is unchanged.
  • Failure leaves pre-restore company state unchanged and emits value-free protected-action audit evidence where the current audit store is available.

Schema evolution

Every persistence migration must:

  1. update this catalog for every relation or ownership-path change;
  2. increment the catalog version when snapshot representation or restore behavior changes;
  3. add schema-to-catalog conformance tests; and
  4. add capture and restore tests for the changed state.

The initial implementation supports only exact schema and catalog versions.

Reporting owns report_run and its number sequence directly by company. Immutable report snapshots, normalized lines, and source contributions are company-owned children reached through their ReportRun. Restore replaces this aggregate in dependency order and preserves the run-to-succeeded-audit link.

The Sales Tax Accounting and Remittance Contract makes capability profiles, tax results, jurisdiction summaries, return controls and inclusions, reconciliation snapshots, filing and payment evidence links, remittances, Finance remittance matches, number sequences, histories, and audit links company-owned backup state. Catalog version company-snapshot-v23 includes the capability-profile, Sales-result, return-control, reconciliation, filing- evidence, remittance, external-payment-evidence, Finance-match, numbering, and history relations introduced through Slices 15B0T3 and 15B0T4.

Acceptance criteria

  • Every current persisted relation is classified.
  • Backup creation fails when the live schema contains an uncataloged relation.
  • Capture observes one repeatable-read company snapshot.
  • Other-company rows and company-null audit events are absent.
  • Referenced shared definitions are complete and conflicts block restore.
  • Missing actors cannot receive access merely because a backup was restored.
  • No captured actor-role assignment becomes active without explicit protected review.
  • Managed evidence and the company key envelope are present exactly once.
  • Container and company-key recovery validation completes before mutation.
  • Failed restore leaves replaceable company state unchanged; only the permitted append-only failed-restore audit evidence may be added.
  • Successful restore changes only the target company and merges audit evidence append-only.