@@ -67,7 +67,7 @@ Strangler Fig story into something a recruiter can *see* in ten seconds.
6767| 0 | Foundations: repo, docs, ADRs, docker-compose skeleton, CI | ** done** |
6868| 1 | Legacy core: GnuCOBOL batch + fixed-width data (containerized) | ** done** |
6969| 2 | The bridge (ACL): C# service wrapping COBOL, first modern endpoint | ** done** |
70- | 3 | Microservices behind the YARP gateway | ** in progress (3a: gateway, 3b: accounts + strangler switch)** |
70+ | 3 | Microservices behind the YARP gateway | ** in progress (3a: gateway, 3b: accounts + strangler switch, 3c: customers )** |
7171| 4 | Event-driven + real-time React/SignalR dashboard | planned |
7272| 5 | CI/CD hardening, observability, tests, polish | planned |
7373
@@ -80,8 +80,46 @@ Phase 3b delivered the modern side of the swap and the Strangler switch
8080itself — see below. The shared ` Account ` model, ` FixedWidthAccountParser ` ,
8181and the legacy-file path resolver moved out of the Bridge into
8282` CobraBridge.Domain ` so AccountsService could reuse them instead of
83- duplicating them. Phases 3c–d (transactions, customers microservices) are
84- not built yet.
83+ duplicating them.
84+
85+ Phase 3c delivered CustomersService — see "Migration vs. net-new" below.
86+ Phase 3d (transactions microservice) is not built yet.
87+
88+ ## Migration vs. net-new
89+
90+ Not every capability behind the gateway is a Strangler migration of
91+ something COBOL already did. CobraBridge deliberately has both kinds, side
92+ by side, because that's what real modernization looks like:
93+
94+ ```
95+ Migrated (Strangler): /api/accounts
96+ COBOL already does this -> Bridge parses it live, AccountsService holds a
97+ migrated copy in Postgres, AccountsSource picks which one answers. The
98+ point is the *swap* being invisible to the client.
99+
100+ Net-new (no legacy equivalent): /api/customers
101+ COBOL never had this -> CustomersService is the only and original source.
102+ There is nothing to migrate, nothing to strangle, no AccountsSource-style
103+ switch — just one backend behind the gateway, like any other service
104+ would be in a system built from scratch.
105+ ```
106+
107+ Conflating the two would misrepresent both: claiming ` /api/customers ` was
108+ "migrated" would invent a legacy capability that never existed, and treating
109+ ` /api/accounts ` as plain net-new work would hide the actual hard part — the
110+ anti-corruption layer and the live cutover. The gateway config says so
111+ explicitly (see ` customers-svc ` cluster comments in
112+ ` src/CobraBridge.Gateway/appsettings.json ` ).
113+
114+ ## Database-per-service (Phase 3b/3c)
115+
116+ AccountsService and CustomersService each own their own PostgreSQL
117+ database — ` cobrabridge_accounts ` and ` cobrabridge_customers ` — on one
118+ shared Postgres server (see [ ADR-0006] ( adr/0006-database-per-service.md ) ).
119+ Neither service ever queries the other's database; the gateway/HTTP
120+ boundary is the only sanctioned integration point. ` postgres/init/*.sql `
121+ creates the second database the first time the data volume initializes
122+ (` POSTGRES_DB ` only creates one).
85123
86124## The Strangler switch (Phase 3b)
87125
@@ -122,18 +160,21 @@ for the full walkthrough.
122160```
123161cobrabridge/
124162├── README.md
125- ├── docker-compose.yml # orchestrates the whole system locally
163+ ├── docker-compose.yml # orchestrates the whole system locally
164+ ├── postgres/init/ # one-time DB-per-service creation scripts
126165├── docs/
127- │ ├── architecture.md # this file
128- │ └── adr/ # architecture decision records
129- ├── legacy-core/ # the COBOL "mainframe" (Phase 1, runs today)
130- ├── src/ # .NET solution (gateway, services, bridge)
131- │ ├── CobraBridge.Domain/ # shared Account model, legacy parser, path resolver
132- │ ├── CobraBridge.Domain.Tests/ # parser + path resolver tests
133- │ ├── CobraBridge.Bridge/ # anti-corruption layer (Phase 2, done)
134- │ ├── CobraBridge.AccountsService/ # modern accounts API (Phase 3b, Postgres-backed)
135- │ ├── CobraBridge.AccountsService.Tests/ # mapper, seeder, endpoint, legacy/modern equivalence tests
136- │ ├── CobraBridge.Gateway/ # YARP API gateway + Strangler switch (Phase 3a/3b)
137- │ └── CobraBridge.Gateway.Tests/ # health, routing, and switch tests for the gateway
166+ │ ├── architecture.md # this file
167+ │ └── adr/ # architecture decision records
168+ ├── legacy-core/ # the COBOL "mainframe" (Phase 1, runs today)
169+ ├── src/ # .NET solution (gateway, services, bridge)
170+ │ ├── CobraBridge.Domain/ # shared Account model, legacy parser, path resolver
171+ │ ├── CobraBridge.Domain.Tests/ # parser + path resolver tests
172+ │ ├── CobraBridge.Bridge/ # anti-corruption layer (Phase 2, done)
173+ │ ├── CobraBridge.AccountsService/ # modern accounts API (Phase 3b, migrated, Postgres-backed)
174+ │ ├── CobraBridge.AccountsService.Tests/ # mapper, seeder, endpoint, legacy/modern equivalence tests
175+ │ ├── CobraBridge.CustomersService/ # customer/KYC API (Phase 3c, net-new, Postgres-backed)
176+ │ ├── CobraBridge.CustomersService.Tests/ # mapper, seeder, endpoint, KYC-filter tests
177+ │ ├── CobraBridge.Gateway/ # YARP API gateway + Strangler switch (Phase 3a/3b/3c)
178+ │ └── CobraBridge.Gateway.Tests/ # health, routing, and switch tests for the gateway
138179└── .github/workflows/ci.yml # build + test pipeline
139180```
0 commit comments