Files
web_sport/docs/adr/0002-modular-monolith-not-microservices.md
T

1.6 KiB

ADR-0002: Modular monolith, not microservices

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

Context

The system will eventually need order processing, inventory, payments, search and notifications. That list reads like a microservice diagram, and the temptation is to start there. But on day one there is no traffic, no team boundary and no independent scaling requirement — only the cost of distributed transactions, network failure modes and per-service CI.

Decision

One NestJS process, internally partitioned into modules that own their tables exclusively. Cross-module access happens two ways only: a synchronous call to the other module's public/ service when an answer is needed now, or a domain event when something merely needs to react.

Four modules — inventory, orders, payments, search — are marked EXTRACTION CANDIDATE and additionally forbidden from sharing transactions with the rest of the monolith.

Consequences

A single deploy, a single database, real foreign keys and real transactions — which is exactly what an order/inventory/payment flow wants. Extraction stays possible because the boundaries are enforced now, while they are cheap to enforce.

The risk is boundary erosion: one "quick" cross-module join and the seam is gone. This is why the rule is an ESLint error rather than a paragraph in a wiki.

Alternatives considered

Microservices from day one — rejected as premature: it buys independent scaling nobody needs and pays in distributed-transaction complexity that a checkout flow can least afford. A single unstructured application — rejected: retrofitting boundaries after the fact is the expensive path.