AP-010: Modular by design¶
Everything we build has an owner, a boundary, and a contract.
This principle draws from domain-driven design, bounded contexts, data mesh, and service-oriented architecture — without mandating any single methodology. The practical intent is simple: every system, module, data construct, and UI surface must have a clear business owner, a clear technical owner, a clear boundary, and a clear contract with everything it touches.
This is more suggestive than prescriptive at this stage. The pattern is established here; the specifics are for the engineering team to define and own.
Systems and modules¶
Each system domain maps to a business domain and has a named owning team. No module reaches directly into another module's data store — it calls the contract. Contracts take the form of API schemas, Kafka topic schemas, or documented query interfaces.
Breaking a contract requires coordinating with every consumer. It is not a unilateral decision.
Operational Postgres database¶
The operational Postgres database follows the same ownership principle. Tables and schemas are owned by the domain that writes to them.
What modular ownership means for Postgres reads: The boundary is about writes and contracts, not about blocking reads. A domain that explicitly exposes a read-only view for cross-domain consumption is providing a database contract — equivalent to an API contract. Consumers read from the published view, not from base tables. The owning domain is free to refactor internals as long as the view contract is stable.
Three valid cross-domain read patterns, in order of preference per AP-001 (KISS):
-
Published database view — the owning domain defines a view (e.g.
accounts.balance_readable) in its own schema, scoped to the columns the consuming domain needs. The consuming Lambda reads the view using the owning domain's_readonlyPostgres credential. No service hop. No latency overhead. Preferred for synchronous on-path reads where simplicity matters (e.g. balance checks before payment execution). -
HTTP API — the owning domain exposes a Lambda-backed endpoint. Required when the read involves business logic (e.g. a derived calculation, a gate decision), when the owning domain needs to log the access, or when the call is across a trust boundary (external callers, public API).
-
CDC / EventBridge — the consuming domain maintains a local cache populated from domain events. Required for asynchronous, eventually-consistent read patterns (e.g. AML rule evaluation, analytics, snapshot denormalisation).
What is not permitted: - Reading from another domain's base tables without a published view contract (implicit dependency, no governance). - One domain writing into another domain's schema under any circumstances — always through the owning domain's published write path.
The modular ownership logic is the same as Snowflake; the specific schema design is for the engineering team to define.
Snowflake data products¶
Data products live in schemas within domain databases. A domain database contains all schemas owned by that domain. Teams own their schema — they define it, version it, and are accountable for its stability.
Joins across schemas and databases are permitted and expected. What is not permitted is one domain writing into another domain's schema without going through that domain's contract.
The domain database structure follows the business domain model:
DATABASE: customer -- BD01 / SD02
DATABASE: payments -- BD06 / SD04
DATABASE: aml -- BD07 / SD03
SCHEMA: fraud
SCHEMA: aml
SCHEMA: cases
SCHEMA: reporting
DATABASE: credit -- BD05 / SD05
DATABASE: risk -- BD08 / SD06
DATABASE: platform -- BD09 / SD07
SCHEMA: audit
SCHEMA: governance
Schemas within each database are owned and defined by the responsible engineering team.
Snowflake's schema-based RBAC makes ownership enforceable, not just conventional.
Frontend¶
The frontend is modular by design. Features, sections, and navigation items can be enabled, disabled, or restricted at the role or configuration level without code changes. This supports the dual-mode pattern (ADR-004) and makes it straightforward to gate features by jurisdiction, product tier, customer segment, or build status.
Ownership is explicit¶
Every database, schema, API endpoint, Kafka topic, and UI module has a named business owner and a named technical owner. If something has no owner it does not ship.
Relationship to other principles¶
| Principle | Relationship |
|---|---|
| AP-001 KISS | Boundaries should be obvious, not elaborate. |
| AP-002 Data governance | Explicit ownership is the mechanism that makes data governance real. |
| AP-003 Compliance by design | Regulatory perimeters map to domain boundaries. |
| AP-007 Evolution by design | A well-bounded module can be replaced without touching its neighbours. |