Files
zarinpal-analytics-backend/docs/decisions/0001-modular-monolith.md

1.7 KiB

ADR 0001: Capability-oriented modular monolith

  • Status: Accepted
  • Date: 2026-08-20

Context

The backend must support ingestion, merchant identity, deterministic analytics, authenticated APIs, and a later AvalAI integration. The hackathon needs fast delivery, while a production continuation needs explicit boundaries and independent testability. A distributed service architecture would add deployment and consistency costs before traffic or ownership evidence justifies them.

Decision

Build one Go modular monolith organized by business capability. Identity, data foundation, analytics, merchant API, and later AI assistance own their internal models and behavior. Cross-capability calls use explicit package contracts. Lightweight ports/adapters isolate external systems such as PostgreSQL, AvalAI, clocks, and credential/session infrastructure where substitution or deterministic testing provides concrete value.

Runnable concerns such as the HTTP API, importer, migrations, and optional analytics jobs may have separate thin commands under cmd/ while sharing the same internal modules and release artifact lineage.

Consequences

  • One repository, database boundary, and release train keep development and operations simple.
  • Capability boundaries remain visible and can be extracted later if measured scaling or ownership needs justify it.
  • Packages must not bypass module contracts through shared mutable state or an unrestricted generic utils/models layer.
  • Ports are introduced at real external or volatile boundaries, not around every function.
  • This decision does not choose dependency injection, HTTP routing, ORM/database access, or background-job libraries; those remain separate approval decisions.