Architecture Is the Decisions You Cannot Undo Cheaply
Frameworks come and go; structure is what survives. Our architecture practice is built on domain-driven boundaries, decisions recorded in writing, and systems designed to evolve — because the only wrong architecture is the one that cannot change.
Philosophy
Four Commitments Behind Every System
Before any diagram is drawn, these commitments are already in force. They are the difference between an architecture that photographs well and one that ages well.
Domain-Driven Boundaries
Service and module boundaries follow the business domain — records, events, monitoring, integration — not the org chart of the month. Boundaries that match how the business thinks stay stable while teams reorganize around them.
Modular Monolith First
We start with a well-modularized monolith and extract services only when scale or team topology demands it — with the seam already designed in. Microservices are a solution to an organizational problem, not a badge.
Every Decision Gets an ADR
Architecture Decision Records — the practice introduced by Michael Nygard — capture each significant choice with its context and consequences. A new engineer reads our ADRs and inherits ten years of judgment in an afternoon.
Designed to Evolve
Versioned contracts, parallel-run migrations, strangler-fig replacements. We never bet the platform on a big-bang rewrite — evolution is a feature we engineer on purpose.
System Structure
One Reference Architecture, Four Platforms
Every FiduciaWay platform follows the same layered shape. The names change; the contract discipline does not: each layer only talks to its neighbors, and every hop is authenticated, authorized and traced.
Experience Layer
SSR web apps and native mobile clients — bilingual, RTL-first, WCAG 2.2 AA, rendered close to the user.
API & Gateway Layer
Typed, versioned contracts at the door: gRPC internally, OpenAPI 3.1 externally. Rate limits, quotas and mTLS enforced here — not sprinkled through the codebase.
Domain Services Layer
Business logic in domain-aligned services with explicit ownership. Idempotent handlers, saga-based workflows, and events as the system of record between contexts.
Data & Integrity Layer
PostgreSQL as the default engine of truth, append-only ledgers where history must be provable, and derived stores for read-heavy paths — reconciled continuously.
Platform & Runtime Layer
Kubernetes, infrastructure as code, progressive delivery and observability wired in at birth — the layer that makes the four above operable by humans.
Decisions on Record
Real ADRs, Abridged for the Web
These are actual Architecture Decision Records from our platform, lightly abridged. In the repositories they carry IDs, dates, review threads and status — accepted, superseded, or deliberately reversed.
PostgreSQL as the default system of record
Context —Every new service kept debating its own storage. We needed a default with the fewest regrettable properties and the deepest operational experience on the team.
Decision —PostgreSQL unless a written, ADR-backed exception exists. Anything exotic must prove why relational discipline fails the specific workload.
Event-carried state transfer between contexts
Context —Cross-context reads were coupling services at query time; one slow consumer could stall an entire flow.
Decision —Contexts publish events carrying full state; consumers keep local projections. Coupling moved from runtime to schema, where CI can watch it.
Feature flags gate every release
Context —Long-lived release branches were producing integration debt and Friday-night rollbacks.
Decision —All changes merge to trunk dark, ship disabled, and wake up progressively per environment, cohort and percentage — decoupling deploy from release.
Append-only ledger for Ledger
Context —Auditability required that financial history be provably immutable — no UPDATE, no DELETE, no trust in discipline alone.
Decision —Hash-chained append-only records with Merkle proofs; corrections are new compensating entries, never rewrites. Auditors verify without asking us.
Quality Attributes
The Numbers Architecture Must Defend
These are not marketing figures — they are SLOs with error budgets, reviewed weekly, and every architectural change is evaluated against them in writing.
availability, customer-facing critical paths
yearly error budget per SLO — spent in public
API latency, server-side, per region
data loss objective on systems of record
recovery objective for a full region loss
Documented Trade-offs
Where We Chose Boring — and Why It Won
Good architecture is the art of paying for the problems you want. These are the trades we consciously made — each one has a full ADR behind it.
Structure —Modular monolith before microservices
Distribution is a tax you pay in latency, debugging and operational surface. We pay it only when team and scale economics genuinely demand it.
Consistency —Strong consistency for records, eventual for views
Balances and ledgers get serializable transactions; dashboards and projections tolerate staleness measured in seconds. One rule per data class, written down.
Integration —Typed contracts over REST-and-hope
Contracts compiled into CI turn integration drift into a red build at the author’s desk — not an incident at the client’s.
Build vs Buy —Buy plumbing, build the domain
Message brokers and databases are commodities with deep ecosystems; our competitive ground is records, events and workflow logic. We spend engineering where it compounds.