diff --git a/docs/architecture/layers.md b/docs/architecture/layers.md index 56a2c3f..2734d97 100644 --- a/docs/architecture/layers.md +++ b/docs/architecture/layers.md @@ -44,6 +44,36 @@ registries today, and the two collaborator types `query-cache` reads from `cross-context-invalidation`. Both lists are frozen — a new edge of either kind fails the gate. +## 어댑터 그룹의 공개 경계 + +각 어댑터 그룹의 공개 표면은 그 그룹의 `index.ts`다. 그룹 바깥 +(`bootstrap`, `features`, `presentation`)은 배럴만 import한다. +`adapter-groups-are-reached-through-their-barrel` 규칙이 이를 강제하고, +`tests/fixtures/architecture/dependency-graph/barrel`이 거부와 허용을 +각각 고정한다 — 규칙을 지우면 그 회귀 검사가 먼저 깨진다. + +두 가지 예외가 있고 둘 다 의도된 것이다. + +- **그룹 내부 파일끼리**는 파일 경로로 직접 import한다. 배럴은 바깥을 위한 + 문이지 내부 규율이 아니다. +- **어댑터 → 커널(`platform/**`)** 간선도 파일 경로를 유지한다. 커널은 + 런타임 합성물이 아니라 프리미티브이고, `check:adapter-inventory`가 네 + 소비자에게 `platform/abortable-operation.ts`로 해석되는 specifier를 + 직접 요구한다. 커널 배럴(`platform/index.ts`)은 bootstrap과 테스트를 + 위한 것이다. + +`storage`는 최상위 배럴이 `indexeddb/`·`opfs/` 서브배럴을 재수출하지 +않는다. 두 런타임이 각자 독립적으로 제거 가능하고 +(`test:browser-file-storage-removal`), 그래서 각 서브배럴이 곧 경계다. +규칙의 도착점 정규식이 1단계 중첩 `index.ts`를 배럴로 인정하는 이유가 +이것이다. + +`service-worker/index.ts`는 `tsconfig.service-worker.json`의 `exclude`에 +들어 있다. 그 설정이 그룹 폴더를 통째로 WebWorker lib로 컴파일하면서 페이지 +realm 파일만 빼는 구조라, 배럴이 그 파일을 다시 끌어들이면 워커 타입체크가 +`document`를 찾지 못한다. 배럴의 타입 커버리지는 `tsconfig.app.json`이 +담당하고, 워커 진입점은 배럴을 쓰지 않는다. + `bootstrap` contains composition only. Business rules and page-specific orchestration belong to domain/application. diff --git a/docs/reviews/adapters/README.md b/docs/reviews/adapters/README.md index 3a35e1a..1c70e9b 100644 --- a/docs/reviews/adapters/README.md +++ b/docs/reviews/adapters/README.md @@ -133,3 +133,15 @@ listener/timer 정리, first-terminal-owner, late rejection 관찰, late native - cleanup 실패를 observation만 남기고 success로 바꾸지 않는다. - schema/database version을 downgrade하거나 broad prefix/root/database 전체 삭제를 rollback으로 사용하지 않는다. - SSE↔WebSocket, Connect↔gRPC-Web↔REST를 장애 중 자동 전환하지 않는다. + +## 테스트의 어댑터 import + +`tests/` 아래 어댑터 import는 배럴로 일괄 이관하지 않는다. `check:architecture`는 +`src`만 스캔하므로 강제되지 않고, 단위 테스트의 상당수가 배럴에 없는 내부 +심볼을 의도적으로 겨눈다. + +어떤 테스트 파일을 **다른 이유로** 수정하거나 분할할 때, 그 파일이 쓰는 +심볼이 해당 그룹 배럴에 있으면 그 파일 안에서만 배럴 경로로 바꾼다. +배럴에 없는 심볼이면 깊은 경로를 유지한다. 배럴에 추가하고 싶으면 그 심볼이 +공개 표면임을 먼저 논증한다 — 테스트 편의로 배럴을 키우면 배럴이 경계가 +아니라 재수출 덤프가 된다.