ADR 002 Backend DDD and Feature Boundaries
Context
Section titled “Context”This decision is retained as history. ADR 029 replaces its incomplete layer and dependency rules.
Legacy framework folders and controller names do not describe stable Sanmopia business boundaries. Modernization needs ubiquitous language, explicit dependency direction, and feature-sized change units.
Decision
Section titled “Decision”DDD is the backend architecture authority. Source lives under this shape:
src/sanmopia_modernization/ domain/<bounded_context>/features/<feature>/ application/<bounded_context>/features/<feature>/ adapters/<bounded_context>/features/<feature>/ interfaces/- Bounded contexts own vocabulary and invariants.
- A feature slice owns one cohesive use case, not an entire technical layer.
- Domain code has no framework, database, HTTP, or provider dependency.
- Application code coordinates domain contracts and ports.
- Adapters implement persistence and provider ports.
- Interfaces authenticate, authorize, validate contracts, then dispatch.
- CQRS is optional inside a feature. Use separate command/query models only when write invariants and read projections genuinely differ.
- Shared code is promoted only after repeated semantic duplication is proven.
- Tach enforces declared imports and public interfaces.
Frontend Atomic Design is not a backend feature-slice variant. Its boundary is defined by ADR 012.
Implementation Evidence
Section titled “Implementation Evidence”- Tach boundary configuration
- Reservation booking application feature
- Financial lifecycle domain feature
- Settlement Supabase adapter feature
Consequences
Section titled “Consequences”The broad direction is implemented, but not every migrated slice has completed
ubiquitous-language and boundary review. implementation: partial remains
until Tach and naming audits cover the full backend tree.
Revision History
Section titled “Revision History”- 2026-07-13: superseded by ADR 029. The DDD intent remains, but ADR 029 is the authority for layer-first placement, context/feature nesting, dependency direction, ports, and optional feature-local CQRS.