Accounting system architecture
Accounting system architecture: the decisions that matter
The architecture of an accounting system comes down to 4 choices: entity is the unit of books; tenant groups entities, maintained balance summary plus immutable lines, gap-free numbering allocated inside the issuing transaction and FX rates as scaled integers, no guessing when a rate is missing. Each is explained below with the alternatives that were rejected and what you accept by choosing it.
Last checked
Entity is the unit of books; tenant groups entities
Situation: Groups run several legal entities with different currencies, calendars and charts, and auditors review each separately.
Choice: Every financial row carries entity_id and RLS grants entity-level roles; consolidation is a derived snapshot over closed entity periods, never a shared ledger.
- Rejected: One ledger with a company dimension: simpler but cannot close or audit entities independently.
- Rejected: Database per entity: strong isolation but cross-entity reporting needs ETL.
- Consequence: Intercompany needs mirrored journals and an elimination step.
- Consequence: Charts are mapped to a group chart for roll-up.
Maintained balance summary plus immutable lines
Situation: Summing millions of journal lines per report is slow and unpredictable.
Choice: Update an (entity, account, period) summary in the posting transaction and prove it nightly against the lines; reports read the summary.
- Rejected: Compute every report from lines: always right, too slow at scale.
- Rejected: Materialized views refreshed on a schedule: stale during the day.
- Consequence: Posting writes a few more rows.
- Consequence: Integrity job is mandatory.
Gap-free numbering allocated inside the issuing transaction
Situation: Tax authorities in many countries require sequential invoice numbers with no gaps.
Choice: Allocate numbers from a per-series counter row locked in the same transaction that issues the invoice; voids consume numbers and stay visible.
- Rejected: Database sequences: can leave gaps on rollback.
- Rejected: Application-generated random ids: not sequential.
- Consequence: Issuance serialises per series, acceptable at invoicing volumes.
- Consequence: Void and credit-note flows must exist.
FX rates as scaled integers, no guessing when a rate is missing
Situation: Float rates and silent fallbacks produce unexplainable rounding and wrong revaluation.
Choice: Store rates as integers scaled by 1e8, store transaction and functional amounts on every line, and block postings when a rate is missing.
- Rejected: Numeric columns: exact but invites unit confusion.
- Rejected: Use the last known rate: hides a data gap.
- Consequence: Rate load is a critical daily job with an alert.
- Consequence: Rounding differences are posted to an explicit rounding account.
How the data is indexed
Indexes are chosen from the questions the app asks most often. Each line below names a table and the question its main index answers.
- entities: (org_id, parent_entity_id) — consolidation tree traversal.
- gl_accounts: unique (entity_id, code) — account codes unique per entity.
- journals: unique (entity_id, journal_no) — gap-free journal numbering per entity.
- journal_lines: (entity_id, account_id, posting_date) — ledger and trial balance scans.
- fiscal_periods: unique (entity_id, starts_on) — one period per start date per entity.
- vendors: (entity_id, name) — vendor lookup and duplicate detection.
- bills: unique (vendor_id, invoice_number) — duplicate vendor invoices are rejected.
- invoices: unique (entity_id, series, invoice_no) — sequential gap-free numbering per series.
What Forge64 provides underneath
Forge64 matches your description to one of 25 reference architectures, writes the plan and data model into the project, generates the app, and runs a quality gate over the code before you see it. Each app gets its own Postgres database and sign-in with no per-user fee. Hosting on Forge Cloud and Forge Payments are rolling out.
This is a reference design for the category, not a promise that every item is generated today. Built-ins such as background jobs, file uploads and search are rolling out; email sent from your app is coming soon, so anything here that needs it is something you add yourself for now.
FAQ
- What is the most important architecture decision for an accounting system?
- Entity is the unit of books; tenant groups entities. Every financial row carries entity_id and RLS grants entity-level roles; consolidation is a derived snapshot over closed entity periods, never a shared ledger.
- Do I have to make these decisions myself?
- No. Forge AI plans them from your description and writes the decisions into the project as architecture records you can read and change.
- What do the alternatives cost me?
- For example, for "Maintained balance summary plus immutable lines": Compute every report from lines: always right, too slow at scale. Materialized views refreshed on a schedule: stale during the day.
Build your app with Forge64
One prompt to a running app with auth, database, hosting and payments. Start free, no credit card required.
Start building for free