Files
xiaobaifupan/docs/governance/adr/0001-modular-monolith.md
T

2.4 KiB

ADR 0001: Govern as a Modular Monolith

Status: Accepted

Date: 2026-07-29

Context

The application is deployed on a LAN NAS as one Docker container with a Python HTTP process, SQLite, a build-free browser client, scheduled refresh work, external market providers, and LLM features. Product breadth has grown, while routing, persistence, frontend state, and CSS remain concentrated in a few large files.

The system may later become internet-facing, gain more features, replace SQLite, or move jobs to workers. It does not currently have load or team boundaries that justify distributed services.

Decision

Retain one deployable application and introduce strict internal modules, ports, adapters, feature registries, data contracts, repository contracts, and regression gates.

The deployment remains:

one image + one application process + one persistent data volume + port 8765

Internal code moves toward:

delivery -> application services -> ports -> infrastructure

Compatibility facades permit incremental migration. No feature is rewritten solely to match the target directory structure.

Consequences

Positive

  • Current NAS deployment stays simple.
  • Refactoring can proceed in reversible stages.
  • Feature ownership and account boundaries become visible.
  • Data, database, LLM, and job adapters can be replaced later.
  • A measured hotspot can be extracted without first untangling business logic.

Costs

  • The transition temporarily contains old and new entrypoints.
  • Boundary tests and registries require ongoing maintenance.
  • A single process remains a capacity and fault-isolation limit until infrastructure is deliberately extracted.

Rejected Alternatives

Immediate microservices

Rejected because they add network contracts, service discovery, deployment coordination, distributed tracing, and failure modes before load requires them.

Full framework rewrite

Rejected because replacing the HTTP and frontend frameworks while moving boundaries would combine structural and behavioral risk.

Continue patching flat modules

Rejected because current file size, direct provider creation, global page state, and CSS override layers already make regressions difficult to isolate.

Revisit Conditions

Reconsider service extraction when one module has independently measured scaling needs, requires a separate availability boundary, or needs an independent release lifecycle.