업무 언어·불변식·모듈러 모놀리스·ADR로 시작하는 진화형 아키텍처
요구를 불변식과 진화 가능한 경계로 바꾼다.
상태: 출간 후보 웹교정쇄 · 자동 QA 통과 · 도메인 아키텍트 감수 대기 · 25개 장
업무 언어·불변식·모듈러 모놀리스·ADR로 시작하는 진화형 아키텍처
기준일: 2026-08-14 · 상태: 출간 후보 웹교정쇄 · 자동 QA 후 사람 현장 감수 대기
FieldPass의 예약·배정·결제·정산 규칙을 코드 경계와 의사결정 기록으로 바꾼다. 대상 독자는 CRUD는 만들 수 있지만 요구 변경 때 어디를 고쳐야 할지 흔들리는 개발자와 설계 리뷰를 맡기 시작한 리드다. 기능을 따라 입력하는 데서 끝내지 않고 결정의 전제, 실패, 증거와 rollback을 한 세트로 남긴다. 숫자·한도·가격·UI는 영구 사실이 아니며 실습 직전 공식 문서를 다시 확인한다.
FieldPass는 방문 예약, 기사 배정, 사진, 결제와 정산을 가진 합성 B2B 서비스다. 여섯 권이 같은 tenant-demo, res-demo-101, run-demo-001을 사용한다. 따라서 도메인 결정이 API, telemetry, infrastructure, event와 edge에서 같은 의미인지 비교할 수 있다.
npm run test로 여섯 위험 fixture를 실행한다.npm run build로 원고와 SVG를 재생성한다.lab/public/index.html을 열어 입력·판정·증거·원복을 같은 화면에 기록한다.- 실제 cloud·domain 적용은 소유자 승인, 비용 상한과 별도 staging에서만 한다.
cd fieldpass-platform
npm run qa
npm start
먼저 version 9로 의도한 실패와 Problem Details를 확인하고 새 process에서 version 1로 성공·Outbox 대사를 실행한다. 실제 cloud·domain 변경은 소유자 승인과 비용 상한이 있는 staging에서만 한다.

const command = {
commandId: 'cmd-demo-001', tenantId: 'tenant-demo',
reservationId: 'res-demo-101', expectedVersion: 3
};
reservation -> dispatch : ReservationConfirmed v2
billing -> reservation : PaymentAuthorized v1
settlement <- billing : CapturedPayment v1
상태: accepted
맥락: 예약과 기사 배정의 변경 주기가 다르다.
결정: 같은 배포 안의 별도 모듈과 내부 이벤트를 사용한다.
결과: 네트워크 실패 없이 계약을 먼저 검증한다.
node --test test/platform-lab.test.mjs
첫 회의에서 서비스 이름을 정하지 않는다. 고객의 “기사가 확정되면 같은 시간에 다른 예약을 받을 수 없다”는 문장을 주체, trigger, 항상 참이어야 할 결과와 위반 비용으로 나눈다. fieldpass-platform/src/domain.mjs의 Reservation.confirm이 이 문장을 어느 부분까지 지키고 어느 부분은 기사 일정 context에 남겼는지 표시한다.
npm test -- --test-name-pattern="version|tenant|commandId"로 경쟁·격리·중복을 먼저 실패시킨다. Aggregate를 크게 만들어 한 transaction으로 묶는 안과 예약·기사 context를 분리하고 saga·대사를 두는 안을 ADR로 비교한다. traffic, 충돌률, 팀 소유권과 복구 시간이 분리 trigger에 도달하지 않았다면 modular monolith를 유지한다.
최종 산출물은 용어 사전, 상태 전이표, context map, public module API, event schema와 ADR이다. 코드와 문서의 용어가 다르면 완료가 아니다. 장애 뒤 새 불변식과 architecture fitness test가 추가되는지도 확인한다.
목차
- 1장. 시니어 설계는 그림보다 결정이다
- 2장. 사용자 여정을 업무 사건으로 번역한다
- 3장. 용어 사전은 코드와 계약이다
- 4장. 불변식을 먼저 쓴다
- 5장. 명령과 조회를 구분한다
- 6장. Aggregate의 크기를 경쟁으로 정한다
- 7장. 값 객체로 잘못된 상태를 없앤다
- 8장. 상태 기계로 전이를 제한한다
- 9장. Bounded Context를 언어 변화에서 찾는다
- 10장. Context Map으로 관계를 명시한다
- 11장. 모듈러 모놀리스로 계약을 검증한다
- 12장. Application Service는 흐름을 조정한다
- 13장. Port와 Adapter로 변동을 격리한다
- 14장. Domain Event는 이미 일어난 사실이다
- 15장. Policy로 여러 Aggregate 판단을 분리한다
- 16장. 일관성 수준을 업무 비용으로 선택한다
- 17장. Saga와 보상은 삭제가 아니다
- 18장. 읽기 모델은 재구축 가능해야 한다
- 19장. ADR로 맥락과 만료를 남긴다
- 20장. Architecture Fitness Function을 만든다
- 21장. 분리의 증거를 수집한다
- 22장. Legacy를 Strangler 방식으로 옮긴다
- 23장. 설계 리뷰를 위협이 아닌 실험으로 만든다
- 24장. 도메인 Incident를 모델 개선으로 연결한다
- 25장. 최종 캡스톤과 출간 게이트