MVP-Friendly, Future-State-Compatible Backend Architecture Plan
This document describes a scalable, privacy-first backend architecture designed for:
- A React Native client
- Financial data (P&L, reconciliation, auditability)
- PostgreSQL
- Bank-feed imports and on-demand polling
- An MVP that can evolve cleanly into microservices (Plan B)
This is intentionally modular, not microservices-first, and avoids early distributed-system complexity.
Architectural Principles
- Modular-first, service-ready boundaries
- Single transactional system of record
- Append-only financial data
- Strong tenant isolation
- Explicit auditability
- Async-ready without mandatory eventing
- Clear ownership of data per domain
High-Level Topology
- React Native Client
- Backend-for-Frontend (BFF) / API Edge
- Core Accounting Backend (single deployable initially)
- PostgreSQL (schema-per-domain)
- Optional async workers (same codebase initially)
Layered Backend Architecture (Logical Layers)
1. API / Edge Layer (BFF)
- Authentication (OIDC / OAuth2)
- Tenant resolution
- Authorization (RBAC)
- Request validation
- Rate limiting
- Response shaping for mobile clients
- Optional GraphQL or REST
- Correlation ID injection
2. Application / Orchestration Layer
- Use-case coordination
- Job orchestration (imports, polling)
- Transaction boundary management
- Calls into domain services
- No business rules
- No persistence logic
3. Domain Layer (Service-Ready Modules)
Each module owns:
- Its business rules
- Its write model
- Its database schema
Banking / Ingestion Domain
- Bank connection management
- Provider adapters
- One-time imports
- On-demand polling
- Raw transaction ingestion
- Import job lifecycle
Transaction Domain
- Normalized transactions
- Deduplication logic
- Pending vs posted handling
- Source attribution
Classification Domain
- Chart of Accounts (flat for MVP)
- Classification rules
- Manual overrides
- Uncategorized handling
Ledger Domain
- Immutable ledger entries
- Double-entry enforcement
- Posting rules
- Period awareness
Reconciliation Domain
- Account balances
- Cleared vs uncleared
- Reconciliation periods
- Period close and lock
Reporting Domain
- P&L generation
- Cross-account aggregation
- Statement generation
- Drill-down read models
Audit Domain
- Append-only audit log
- Change tracking
- Access history
- Compliance evidence
4. Persistence Layer
- PostgreSQL
- Schema-per-domain (e.g. ledger., banking.)
- Single writer per table
- No cross-domain foreign keys
- Views or read models for cross-domain reads
- Flyway migrations per schema
5. Async & Integration Layer (MVP-safe)
- Job tables (import_job)
- Outbox table (event-shaped records)
- In-process dispatch initially
- Kafka-compatible later without refactor
6. Security & Privacy Layer
- Tenant isolation enforced at service layer
- Field-level encryption for sensitive data
- No PII in logs
- Immutable audit trails
- Admin override with reason codes
7. Observability & Ops Layer
- Structured logging
- Correlation IDs
- Metrics per domain
- Health checks
- Data completeness checks
MVP Scope Summary
Included:
- Bank ingestion
- Transaction normalization
- Ledger posting
- Reconciliation
- P&L and statements
- Audit trail
Explicitly excluded (Phase 2+):
- Accruals
- Budgeting
- Tax automation
- Multi-entity consolidation
- Event-driven microservices
Evolution Path (Plan B)
- Extract domains into services as needed
- Promote outbox to Kafka
- Split Postgres by schema ownership
- Add read replicas and materialized views
- Preserve API contracts at BFF
Non-Negotiables
- Ledger is append-only
- Corrections are new entries
- Periods are lockable
- Every report number is traceable
- Database is the system of record