Skip to content

Accounting Modes

Daniel Hokanson edited this page Aug 30, 2026 · 2 revisions

Forge is built for shops that already keep their books somewhere — and for shops that don't. Which of those you are changes how a large part of the app behaves, so it is worth understanding before you install.

Canonical reference: docs/architecture.md (§ Standalone vs Integrated Mode) and the accounting suite plan under docs/delivery/complete/accounting-suite/.

The ⚡ ACCOUNTING BOUNDARY marker

Throughout the specs, a marks a feature that behaves differently depending on this setting. If you are reading a doc and see it, that section has two answers.

Integrated mode — an accounting provider is connected

QuickBooks Online is the default and primary provider; Xero, FreshBooks, Sage, NetSuite, Wave and Zoho implement the same interface.

  • Invoices, payments, AR, financial reports, vendor records and tax calculations are owned by the accounting system.
  • Forge reads that financial data through the provider's API and caches it locally; the financial screens become read-only views.
  • Quotes and sales orders still live in Forge, syncing outward to the provider's estimate and sales-order documents.
  • Shipping triggers invoice creation in the accounting system.

This is the mode most shops start in: keep the accountant happy, get better operational tooling on top.

Standalone mode — no provider connected

Forge manages invoices, payments, AR aging, customer statements, basic P&L and sales tax itself, in its own Postgres tables, with full CRUD through the UI.

Native double-entry GL (CAP-ACCT-FULLGL)

Beyond the lightweight built-in books there is a native double-entry general ledger — posting engine, sub-ledgers, statements, period close, FX, payroll and bank reconciliation — so a shop can keep a real book of record inside Forge rather than in QuickBooks.

Two things to know about it:

  • It is off by default and gated on data, not just a toggle. The capability cannot be enabled for a book until that book's opening balances are loaded — a posted conversion journal must exist, verified by a tie-out. This is deliberate: a ledger that starts from nothing is worse than no ledger. Disabling is ungated.
  • Posting is inline and transactional. The operational command and its journal entry commit or roll back together, in one transaction. A posting failure fails the operation immediately and visibly. Nothing posts asynchronously behind your back, and posted entries are immutable — enforced both by a SaveChanges interceptor and by database triggers.

A scheduled reconciliation sweeper left-joins should-have-posted documents against journal entries and alerts on orphans, which is also the mechanism for catching up a document backlog that predates enabling the GL.

Switching modes

  • On connect: existing local financial data is offered for sync — merge or archive.
  • On disconnect: the last-synced accounting data becomes the local baseline.

Mode is a per-install admin setting, resolved at runtime by AccountingServiceFactory from system settings. The mutual exclusion between built-in books and an external provider is enforced declaratively through Capability Gating rather than by branching logic scattered through the codebase.

Clone this wiki locally