Files
strangler-fig-demo/docs/adr/ADR-002-write-through-has-no-business-rules.md
T
ehoandClaude Haiku 4.5 ddec15ccb2 docs(architecture): add diagrams and implementation playbook
Added three new documents with nine Mermaid diagrams to make the strangler
fig strategy visible:

- README: container topology diagram at the start, with the proxy entry point
  and three seams labelled
- docs/architecture.md: five diagrams tracing the exact implementation:
  - The four seams and who holds authority at each boundary
  - How by-id read goes through the resolver, but list-read bypasses it
  - Case lifecycle state machine (the strategy in one picture)
  - Take-ownership sequence with failure windows annotated
  - Write-through error round-trip showing zero validation logic crossed
- docs/playbook.md: how to apply this to a production system:
  - Write-path decision tree (five read/write patterns)
  - Cutover ordering diagram (side-effects-free first, least recoverable last)
  - Seven transferable rules with pointers to the files that demonstrate them
  - Scope diagram of what's proven vs. left as your decisions

Resolved all 13 dangling § citations (to an absent spec doc) by linking to
the actual files or dropping them. Replaced portal-frontend/README.md
boilerplate with accurate content. All diagrams parse and link-check clean.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-01 09:15:39 +02:00

52 lines
2.7 KiB
Markdown

# ADR-002: The write-through translator carries no business rules
## Status
Accepted.
## Context
Seam B lets a user edit a **legacy-owned** case's applicant details (name,
address, contact) from the new portal, without the new system taking
ownership of that case. The legacy system remains the authority on this data
until ownership is explicitly taken ([ADR-003](ADR-003-ownership-is-taken-per-case.md)).
It is tempting, once a translation layer exists between the portal's request
shape and legacy's `PUT /api/aanvragen/{id}/gegevens` shape, to also smuggle
in a validation shortcut or two — "just check the postcode format here too, it
saves a round trip." That temptation is exactly what this ADR forecloses.
## Decision
`New.Infrastructure.Legacy`'s write-through translator (the type backing
`ILegacyCaseGateway.UpdateDetailsAsync`) contains **no business rules**: no
conditionals on request values, no validation beyond null/shape checks, no
derived values, no defaulting. It only:
1. Maps the portal's 9-field request onto legacy's expected shape.
2. Calls `PUT legacy-backend/api/aanvragen/{id}/gegevens`.
3. Maps legacy's response — success, or **every** returned field error via the
`veld`/`code` → portal-field-path table — back into the portal's error
shape, including a generic fallback for any unrecognized legacy code
(logged as a warning, never dropped or guessed at).
If a rule needs to be enforced on this data from the new portal, that is a
signal the capability should be taken into ownership instead, not
patched into the translator.
## Consequences
- The portal cannot offer a better validation experience than legacy already
has for this seam — by design. The `Gevalideerd door het legacy systeem`
notice on the write-through form (`portal-frontend/src/app/case-detail/edit-applicant-details/`)
exists specifically so the user
knows why: this is the honest version of a seamless UI, not a limitation to
hide.
- Rule 11 in Architecture.Tests (no `New.Api` type both constructs a legacy
request DTO and touches a `DbContext`) is only a **partial**, structural
proxy for this constraint — and is already close to vacuous given rule 3
(legacy DTOs are `internal` to `New.Infrastructure.Legacy` with no
`InternalsVisibleTo` grant, so `New.Api` cannot even name them). The
stronger claim this ADR makes — that the translator itself contains no
conditional business logic — is a **code-review rule**, not a
machine-enforced one. We say so here rather than implying test coverage
that does not exist.
- Any future temptation to "just add one small check" in the translator
should instead be read as a signal to take that capability into ownership.