Skip to main content

PostgreSQL Strategy & Overview

Archive

This was the original rationale document written during the PostgreSQL migration decision. The architecture diagrams and Technology Versions table reference the Spring Boot implementation. The "Why PostgreSQL" requirements table and the Firebase/PostgreSQL responsibility split are the most durable content here; the rest is superseded by MVP Architecture and Database Design.

This page explains why PostgreSQL was chosen as the system of record for the Acctz platform, how it relates to the existing Firebase layer, and the high-level database architecture that supports a multi-tenant accounting product.


Why PostgreSQL

↑ Back to top

The Acctz platform targets the same problem space as QuickBooks, Xero, and Wave -- multi-user, multi-tenant financial data management. That problem has hard requirements that map directly to a relational database:

RequirementWhy It MattersPostgreSQL Capability
Double-entry enforcementEvery journal entry must balance (debits = credits)CHECK constraints, triggers, transactions
Referential integrityAccounts belong to entities, entities belong to orgsForeign keys, CASCADE rules
Multi-tenant isolationUsers must never see another organization's dataRow Level Security (RLS), session variables
Complex reportingP&L, Balance Sheet, Trial Balance, aging reportsSQL joins, GROUP BY, window functions, CTEs
Period lockingClosed periods must be immutableStatus constraints, trigger-enforced immutability
Audit trailEvery change must be traceable for complianceAppend-only tables, REVOKE, trigger guards
Import/exportQBO, OFX, IIF, CSV interchange formatsFITID deduplication, human-readable codes alongside UUIDs
Predictable costHosting cost should not scale with read volumeFixed infrastructure, no per-operation billing

The Firebase Firestore Verdict documents the specific shortcomings of Firestore for this use case. The short version: Firestore is structurally wrong for relational, multi-tenant, aggregation-heavy accounting data.


What Firebase Still Does

↑ Back to top

Firebase is not being abandoned -- its role is being narrowed to what it does well:

ConcernStays in FirebaseMoves to PostgreSQL
Authentication (who are you?)Yes-
Identity tokens (JWT issuance)Yes-
User profile data-Yes (iam.users)
Authorization (roles, permissions)-Yes (iam.roles, iam.role_permissions)
Chart of accounts-Yes (ledger.accounts)
Journal entries-Yes (ledger.journal_entries)
Bank transactions-Yes (banking.bank_transactions)
Audit trail-Yes (audit.audit_log)
Real-time UI sync (future)Possibly (notifications, presence)-

See the Identity Bridge page for the full authentication flow.


Database Architecture at a Glance

↑ Back to top

A single PostgreSQL 18 instance hosts one database (acctz) with four domain schemas:

acctz (database)
├── iam Identity & access management
├── ledger Core double-entry accounting
├── banking Bank feeds, imports, reconciliation
└── audit Immutable compliance log

This schema-per-domain layout was specified in the Architecture Plan and is now implemented via seven Flyway migrations (V1 through V7). Each schema maps to a bounded context in the backend:

SchemaDomainOwner ModuleTables
iamIdentity & AccessIAM service layer6 tables
ledgerCore AccountingLedger service layer9 tables + 2 reference tables
bankingBank Feeds & ReconciliationBanking service layer5 tables
auditComplianceCross-cutting1 table

See the Database Design page for the full ERD and table catalog.


How It Fits Together

↑ Back to top

The overall system flow, from user sign-in through to database query:

Key points:

  • Firebase owns authentication -- the client never sends credentials to Spring Boot
  • PostgreSQL owns authorization -- roles, permissions, and data visibility are enforced by RLS at the database level
  • The bridge is the iam.users table, which maps firebase_uid to a local UUIDv7 id
  • Every query is tenant-scoped -- the SET LOCAL app.current_user_id session variable activates RLS policies on all 16 tenant-scoped tables

Technology Versions

↑ Back to top

ComponentVersionNotes
PostgreSQL17.3 (Alpine)Docker image postgres:18.3-alpine
FlywayManaged by Spring Boot starter7 migrations (V1-V7)
Spring Boot3.xJPA/Hibernate with ddl-auto: validate
Java17+UUIDv7 generator requires java.security.SecureRandom
Firebase AuthLatestJWT verification via Firebase Admin SDK
Docker Composev2Orchestrates PostgreSQL, pgAdmin, app

Further Reading

↑ Back to top