Skip to content

Progressive Decomposition: Modular Adapters & Decentralized Metadata

This document defines the architectural strategy for decoupling domain libraries and regional services using the Adapter Pattern, Dependency Injection, and Hierarchical Metadata Aggregation.

The goal is to transition from a monolithic codebase to a modular “Plug-and-Play” architecture where any library can be deployed either internally (same process) or as a standalone microservice (remote process).

The foundation of the system. It contains Python Protocols (interfaces) and DTOs.

  • Modules only depend on protocols, never on each other.
  • Example: LedgerProtocol defines how to post entries, but not who performs the action.

A dedicated library for “Out-of-Process” adapters.

  • Purpose: Provides implementations of protocols that proxy calls over the network (e.g., via NATS RPC).
  • Decoupling: These adapters only depend on protocols and communication logic. They can be imported into the main application without pulling in the target domain’s full source code and dependencies.

2. Regional Services (m-india, m-nigeria, etc.)

Section titled “2. Regional Services (m-india, m-nigeria, etc.)”

Regional libraries are treated as “Localization & Compliance” providers. They follow the same modular pattern as core domains.

Mode Deployment Communication
Indie (Monolith) In-process Regional library is installed locally; direct function calls via Local Adapters.
Enterprise (SOA) Remote Service Regional library runs in its own process (possibly in a different geographical region for data residency). Communication via NATS Adapters.
  • Compliance Isolation: Run m-china or m-india on local geography servers to satisfy data residency laws (PIPL/GDPR).
  • Specialized Scaling: Scale region-specific logic independently during local peaks.

The application bootstrap uses Dependency Injection (DI) to wire the system based on the environment.

mode = os.environ.get("M_MODE", "indie")
if mode == "enterprise":
# 1. Import lightweight adapter (no domain dependency)
from m_adapters.finance.ledger import NatsLedgerAdapter
# 2. Inject it into the dependent module
container.wms.ledger.override(NatsLedgerAdapter(bus=container.event_bus()))
else:
# 1. Import full domain logic
from finance.adapters.local_ledger import LocalLedgerAdapter
# 2. Inject it
container.wms.ledger.override(LocalLedgerAdapter())

Aggregation is hierarchical. It does not happen centrally in business-m; instead, it happens at the Domain Owner level.

Domain Owner Responsibilities
WMS Owns Warehouse DocTypes (Stock, Inventory). Aggregates WMS-specific regional data (e.g., Indian HSN codes).
Finance Owns Fiscal DocTypes (Ledger, Invoices). Aggregates Finance-specific regional data (e.g., GST/VAT/TDS).
People Owns HR DocTypes (Employee, Payroll). Aggregates People-specific regional data (e.g., PAN, Social Security).

Regional libraries are “plugins” that emit metadata aimed at specific domain owners.

  1. Contribution: m-india broadcasts metadata for its fields (e.g., gst_no for Supplier). It specifically targets the Finance domain.
  2. Aggregation: The Finance Service (Domain Owner) listens for this broadcast and incorporates the m-india fields into its own MetadataDecoratorRegistry.
  3. Baking: The Finance Service “bakes” these fields into its schemas/models. It is the only service that needs to know how to validate or store these specific regional fields.

business-m is not an aggregator of regional fields; it is an Aggregator of Domain Schemas.

  1. Request: When a user opens a Supplier form, business-m asks the Finance service for the Supplier schema.
  2. Response: Finance returns its Augmented Schema (Base Fields + Indian Regional Fields already merged).
  3. Rendering: business-m renders the form. It remains completely unaware that the GSTIN field came from m-india; it simply renders what the Finance domain owner provided.

All modules (wms, finance, m-india) are installed in the same process. Aggregation occurs in memory at startup via local registries.

Domains run as independent services. Regional services broadcast their contributions over NATS. Domain Owners subscribe to these and manage their local augmented state.


[!IMPORTANT] This “Hierarchical Aggregation” ensures that wms, finance, and people remain modular and self-contained. They manage their own regional complexity, keeping the business-m gateway clean and focused on composition.