تخطَّ إلى المحتوى

ADR Examples

هذا المحتوى غير متوفر بلغتك بعد.

Illustrative only. The ADR page states the rules; these are the judgement calls the rules cannot make for you.

A load-bearing decision fits on one screen. Note that the Consequences line reframes the whole thing — that sentence is what stops someone “simplifying” it two years later.

# 0003. Split the writable and read-only database contexts
Status: Accepted
State: Current
Date: 2026-05-27
Scope: Persistence. Applies to every data path in the API.
Enforcement: ErpReadDbContext.SaveChanges throws; a startup check aborts
the API if the ERP database is not attached READ_ONLY.
## Context
We read route, customer and salesman data from the client's ERP database and
own our own planning data. One DbContext over both makes an accidental write
to the ERP a normal-looking line of code — no reviewer would catch it, and the
client's system of record is the blast radius.
## Decision
We will run two contexts. `AppDbContext` is writable and owns the RoutePlanner
schema. `ErpReadDbContext` is read-only over ERP views.
## Rules
- Do not merge the two contexts.
- `ErpReadDbContext` exposes no public `DbSet<T>` and runs `NoTracking`.
- EF migrations target `AppDbContext` only.
## Consequences
Two contexts to register and two connection strings to configure. Queries
spanning both must be composed in memory. The type split is a data safety
feature, not a style preference.

The field is only worth having if it is true on the merging branch.

Enforcement line Verdict
ErpReadDbContext.SaveChanges throws; startup aborts if the ERP DB is not READ_ONLY Good. Both checks exist in code; the rule cannot be broken silently.
A folder-scan unit test walks the Endpoints/ tree and fails the build — where no such test was ever written Bad. Reads as enforced; is not. The convention drifts and nobody notices.
Review-only Good. Honest. A reviewer knows to look, and nobody assumes a machine is watching.

If you write an Enforcement line describing work you intend to do, the ADR is not ready to merge — the check merges with it.

Two legal shapes. Both leave the original Decision text intact, so the history stays readable.

Prepended banner — corrects the record after acceptance:

# 0022. Cluster affinity as a compactness force
> **Amended 2026-07-09.** Decision §4 described cluster affinity as the
> *primary* compactness force. It is secondary — the backbone term dominates.
> The weight of 3.0 stated below was recalibrated to 10.0 in ADR-0024.
Status: Accepted
...

Appended section — sharpens without reversing:

## Amendment — 2026-07-05: one use case per folder
This sharpens, and does not reverse, the original decision. It retires the
clause "a slice may contain related endpoints": one slice is now exactly one
folder containing exactly one `*Endpoint.cs`.
Enforcement: Review-only.

Supersede instead when the decision is genuinely reversed — a new ADR, Supersedes: 0020, 0021 at the top of the new one, and a banner on the old ones pointing forward.

/docs/adr/README.md. Without it, the only way to learn that three ADRs are dead is to open all of them.

# Architecture Decision Records
| # | Title | Status | State | Scope |
|---|-------|--------|-------|-------|
| 0001 | Aspire for local orchestration | Accepted | Current | Local dev |
| 0002 | ERP is read-only | Accepted | Current | Persistence |
| 0003 | Dual DbContext split | Accepted | Current | Persistence |
| 0012 | Customer grouping engine | Superseded by 0025 | — | Territory |
| 0020 | Circuity travel model | Superseded by 0025 | — | Territory |
| 0025 | OSRM replaces circuity | Accepted | Current | Territory |

A real run from one of our repos — twelve ADRs in three weeks on a single solver:

ADR What it did Should have been
0014 Adopted an external solver dependency ADR — a dependency is a boundary
0015 Chose the solver formulation ADR — a seam
0016 Chose the assignment algorithm ADR — a seam
0022 Set a weight to 3.0 Design doc — a number
0024 Retuned the same weight to 10.0 Design doc — the same number
0026 Promoted the weight to a per-scenario slider, “fixes the slow-solve regression” Design doc, and a bug fix is never an ADR
0025 Deleted the objective term, making the slider inert ADR — reversal, correctly superseding 0020 and 0021

Three of the twelve were decisions. The rest were calibration, and turned the ADR folder into a changelog — which meant an agent told to “read the ADRs” got tuning history instead of a decision record. The right home already existed in the same repo: a living design doc plus a calibration-findings file.

Back to Architecture Decision Records.

👤 المسؤول: Wahid Bitar🗓 آخر مراجعة: 2026-07-25

Read this page in English