Skip to content

RFC 001: Architecture Evolution & Legacy Migration

Early iterations of the enterprise system relied on direct-SQL database queries and shared database schemas to integrate with legacy enterprise resource planning (ERP) systems. This tight database coupling introduced significant architectural challenges:

  • Schema Fragility: Changes in the legacy ERP database structures instantly broke our application queries.
  • Zero Isolation: Direct SQL queries bypassed standard business domain validations, leading to transaction and data integrity errors.
  • Scaling Inhibitions: It was impossible to decompose domains into standalone services because every library was database-dependent on the central ERP database.

2. Design Decision: Bounded Context Adapters

Section titled “2. Design Decision: Bounded Context Adapters”

To resolve these tight database couplings, we executed a complete migration to a clean, domain-driven, adapter-based architecture:

graph TD
    subgraph New Architecture
        WMS[WMS Domain Controller] -->|Shared Protocol| Interface[Python LedgerProtocol]
        Interface -->|In-Process IPC| Local[LocalLedgerAdapter]
        Interface -->|Network Proxy| Nats[NatsLedgerAdapter]
        Local --> Finance[Finance Domain Core]
        Nats --> Service[Decomposed Finance Service]
    end
    
    subgraph Legacy Architecture
        OldApp[Old Application] -->|Direct Raw SQL| SQL[(Legacy Database)]
    end

Rather than direct data queries, modules are restricted to a Bounded Context:

  1. Plain String References: Documents represent entities from other domains using plain string IDs (e.g. StockEntry.supplier_id as a plain UUID string) rather than database-level Foreign Keys.
  2. Shared Protocols: Interactions between domains are mediated exclusively by stateless, Python-native Interfaces (Protocols) registered in the shared libs/m_protocols directory.
  3. Local vs. Out-of-Process Adapters: Local environments call the provider modules directly in memory, while production environments proxy calls via modular NATS adapters over the network.

We migrated all legacy database schemas to modern, class-based DocType definitions using SQLAlchemy on PostgreSQL:

  • Explicit Mapping: Legacy tables and unstructured columns were explicitly mapped into declarative Python models inheriting from BaseDocType.
  • Database Autonomy: Decoupled tables were given clean, primary indexes and automated migration routines (m migrate sync), allowing them to run on distinct, isolated PostgreSQL database nodes in Enterprise Mode.
  • Idempotency & Auditing: Every transaction is recorded using immutable double-entry ledger postings, completely eliminating un-audited direct database edits.