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>
This commit is contained in:
@@ -14,7 +14,8 @@ Then open **http://localhost:8080** (Session 1's placeholder UI) or
|
||||
**http://localhost:8080/portal** (Session 2's Angular portal) — both are
|
||||
reachable side by side through the same proxy, for comparison. That's the
|
||||
only host port published — `legacy-backend` and `case-framework` are
|
||||
deliberately unreachable from the host (see §4 below).
|
||||
deliberately unreachable from the host (only `proxy` publishes a port — see
|
||||
`docker-compose.yml`).
|
||||
|
||||
**Memory:** SQL Server (`legacy-db`) needs roughly 2GB of RAM; budget ~6GB
|
||||
total for Docker/Podman. First start takes a minute or two while SQL Server
|
||||
@@ -32,6 +33,49 @@ seed data (legacy ids 1001–1012, owned ids `REG-2026-0001..0005`).
|
||||
|
||||
## What's built so far
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
browser(["Browser"])
|
||||
browser -->|":8080 · the only published port"| proxy["proxy · nginx"]
|
||||
|
||||
subgraph new_g["NEW — the replacement"]
|
||||
direction TB
|
||||
portal["portal-frontend<br/>Angular"]
|
||||
placeholder["new-frontend<br/>plain HTML"]
|
||||
newapi["new-backend<br/>.NET"]
|
||||
newdb[("new-db<br/>Postgres 16")]
|
||||
newapi --> newdb
|
||||
end
|
||||
|
||||
subgraph legacy_g["LEGACY — being strangled"]
|
||||
direction TB
|
||||
legweb["legacy-frontend<br/>Razor Pages"]
|
||||
legapi["legacy-backend<br/>.NET"]
|
||||
legdb[("legacy-db<br/>SQL Server 2022")]
|
||||
legweb --> legapi --> legdb
|
||||
end
|
||||
|
||||
subgraph cf_g["VENDOR — stays put"]
|
||||
direction TB
|
||||
cf["case-framework<br/>.NET"]
|
||||
cfdb[("case-db<br/>Postgres 16")]
|
||||
cf --> cfdb
|
||||
end
|
||||
|
||||
proxy -->|"/portal/"| portal
|
||||
proxy -->|"/"| placeholder
|
||||
proxy -->|"/api/"| newapi
|
||||
proxy -->|"/legacy"| legweb
|
||||
|
||||
newapi ==>|"seams A + B"| legapi
|
||||
newapi ==>|"seam D"| cf
|
||||
```
|
||||
|
||||
Ten containers; only the proxy publishes a port. The two thick edges are the
|
||||
seams — everything the new system knows about the old one crosses one of them.
|
||||
See [`docs/architecture.md`](docs/architecture.md) for how each seam works, and
|
||||
[`docs/playbook.md`](docs/playbook.md) for applying the pattern to a real system.
|
||||
|
||||
**Session 1 — backend.** Ten containers: three frontends, three backends,
|
||||
three databases, one proxy. `new-frontend` (reachable at `/`) is a
|
||||
deliberately plain, unstyled HTML page (`new-frontend/index.html`) that
|
||||
@@ -76,7 +120,8 @@ cd new && dotnet test tests/Architecture.Tests
|
||||
`legacy-db` is SQL Server 2022; `new-db` and `case-db` are PostgreSQL 16.
|
||||
This isn't decoration — a single shared engine would let an implementer
|
||||
quietly join across schemas or share a `DbContext`, and the seam would
|
||||
evaporate. Two engines force the read ACL to be a real HTTP call (§7.2),
|
||||
evaporate. Two engines force the read ACL to be a real HTTP call
|
||||
([seam A](docs/architecture.md#the-four-seams)),
|
||||
force the take-ownership step ordering in `TakeOwnershipHandler` to be a real
|
||||
constraint rather than a stylistic choice (no distributed transaction is
|
||||
available across them), and make the legacy type vocabulary
|
||||
|
||||
Reference in New Issue
Block a user