feat: 기능 추가 과정중

This commit is contained in:
donghyeon-ka
2026-07-30 15:58:20 +09:00
parent d3ef801fe6
commit 6c52cdb916
648 changed files with 126325 additions and 6680 deletions
@@ -116,7 +116,7 @@ bootstrap은 page별 orchestration이나 업무 규칙을 소유하지 않는다
| `src/adapters` | HTTP, auth, storage, cache, telemetry 구현 | outbound adapter |
| `src/bootstrap` | runtime config와 구현 조립 | 유일한 composition root |
| `src/contracts` | 여러 계층의 registry가 혼재 | 소유 계층으로 분산 |
| `src/features/reference-feature` | 완전한 제거 가능 수직 예제 | installed contribution과 8단계 제거 gate 유지 |
| `src/features/reference-feature` | 완전한 제거 가능 수직 예제 | installed contribution과 제거 gate 유지 |
현재 구조가 잘 제공하는 기반은 다음과 같다.
@@ -132,10 +132,11 @@ bootstrap은 page별 orchestration이나 업무 규칙을 소유하지 않는다
RP-02 구현으로 다음 경계는 실행 경로에 연결됐다.
- `src/bootstrap/composition-root.js`가 만든 application을 production
- `src/bootstrap/composition-root.ts`가 만든 application을 production
`ApplicationProvider`가 실제 React tree에 주입한다.
- `createApplication`은 session, preference, diagnostics, runtime query
input API만 반환하며 storage, telemetry, release output port를 숨긴다.
- `createApplication`은 session, preference, diagnostics, runtime query와 typed
feature input registry만 반환하며 storage, telemetry, release output port를
숨긴다.
- bootstrap composition 결과는 raw output port를 반환하지 않고
application과 React infrastructure만 반환한다.
- presentation의 direct fetch/browser storage/concrete adapter/TanStack import와
@@ -153,6 +154,16 @@ RP-03 구현으로 HTTP와 server-state 경계도 다음처럼 연결됐다.
정리를 테스트한다.
- HTTP가 자동 network retry를 소유하고 query/mutation adapter의 vendor retry는
비활성화한다.
- reference HTTP operation map은 operation ID마다 route ID, request shape와
성공 model type을 결합한다. runtime schema와 mapper를 통과한 raw executor는
단일 binder에서만 typed executor로 승격되므로 gateway별 응답 cast가 없다.
위 항목은 reference REST vertical의 `COMPOSED` 증거다. auth owner final-request
invariant, auth unavailable fail-close, total deadline, bounded response decoder,
typed Schema/Mapper proof, complete pagination과 mutation concurrency 같은
production hardening delta는
[API contract, Schema, Mapper와 Server State](./api-contract-schema-mapper-and-server-state.md)에
별도 `DESIGNED_NOT_IMPLEMENTED`로 기록한다.
RP-04에서 route 실행 불일치는 닫혔다. route registry와 runtime map은
Data Router tree, codec, surface, title, navigation, chunk/release recovery의
@@ -163,6 +174,12 @@ contract/presentation은 `src/features/reference-feature`가 소유하고, gener
installed catalog만 bootstrap과 router에 노출된다. 제거 gate는 feature와 test를
삭제한 복제본에서 전체 P0 경로를 다시 실행한다.
generic application의 `ApplicationFeatureInputs`는 concrete feature를 import하지
않는 open interface다. 각 feature application API가 module augmentation으로
자신의 literal ID와 input shape를 기여하고, `features.get(id)`는 ID별 정확한
input type을 반환한다. 잘못된 ID/input과 설치 누락은 각각 compile-time negative
fixture와 runtime guard로 닫는다.
RP-06에서 inbound form/page 경계도 실행됐다. `src/presentation/forms`는 Zod
presentation schema, controlled field state, error focus, 422 allowlist,
pending/deduplication과 dirty navigation을 local facade로 감싼다.
@@ -198,7 +215,7 @@ adapter만 교체한다.
| Routing과 navigation | inbound | route input/controller | React Router | 필수 |
| Form submit과 validation 표시 | inbound | command input port 소비 | React form controller | 필수 |
| Server-state query hook | inbound bridge | application input API 소비 | TanStack Query hook | 필수 |
| 외부 push event 처리 | inbound | event input port | WebSocket/SSE listener | 선택 |
| validated external server event | inbound | event input port | SSE/WebSocket listener, Service Worker push handler | 선택 |
| 도메인 API 접근 | outbound | application | Fetch gateway | 필수 |
| 인증 session | outbound | application | 외부 auth owner/SDK | 필수 seam |
| Credential attachment | outbound | transport 또는 auth integration | auth request decorator | 필수 seam |
@@ -396,15 +413,19 @@ Inbound adapter가 해당 type을 application command와 query로 변환한다.
### 8.3 예측 가능한 실패를 typed result로 반환한다
검증 실패, 인증 필요, conflict, network failure처럼 사용자 흐름에
포함되는 실패는 `Result<Value, Failure>`로 반환한다. programmer error와
포함되는 실패는 `Result<Value, Failure = AppFailure>`로 반환한다. programmer error와
불변식 위반을 모두 일반 API 실패로 숨기지는 않는다.
```ts
export type Result<Value, Failure> =
export type Result<Value, Failure = AppFailure> =
| Readonly<{ ok: true; value: Value }>
| Readonly<{ ok: false; error: Failure }>;
```
`AppFailure.kind`는 error registry의 key에서 파생한다. adapter가 받은 외부
오류 code는 이 닫힌 vocabulary로 매핑한 뒤 application 경계를 통과하며,
transport 문맥의 `ApiFailure`는 같은 type을 가리키는 호환 alias다.
### 8.4 Input port를 기술별로 합치지 않는다
`ApplicationService` 한 개에 모든 메서드를 계속 추가하지 않는다.
@@ -885,9 +906,11 @@ capability의 기본 정책, port 또는 안전한 no-op 구현과 composition
| Adapter | 도입 조건 | 기본 상태 |
| --- | --- | --- |
| WebSocket/SSE | 실시간 server event 필요 | opt-in recipe 제공, 미설치 |
| IndexedDB | 큰 offline data 또는 durable queue 필요 | opt-in recipe 제공, 미설치 |
| Service Worker/PWA | offline shell과 installability 필요 | opt-in recipe 제공, 미설치 |
| SSE/WebSocket/bounded polling | active document의 server event 또는 duplex protocol 필요 | common target `DESIGNED_NOT_IMPLEMENTED`, product `NOT_SELECTED` |
| Web Push | inactive browser의 user-visible notification 필요 | target `DESIGNED_NOT_IMPLEMENTED`, product `NOT_SELECTED` |
| IndexedDB/OPFS | offline data, durable queue 또는 large local object 필요 | native reference runtime 제공, 미조립 |
| Cache Storage | 승인된 public HTTP representation offline cache 필요 | native reference runtime 제공, 미조립 |
| Service Worker/PWA | offline shell과 installability 필요 | lifecycle recipe 제공, 미설치 |
| Offline mutation queue | 재연결 후 명령 재처리 필요 | 미설치 recipe |
| Feature flag | remote rollout/kill switch 필요 | opt-in recipe 제공, 미설치 |
| Translation catalog vendor | 원격 catalog·복수 namespace 운영 필요 | 기본 locale facade 뒤에 미설치 |
@@ -896,7 +919,8 @@ capability의 기본 정책, port 또는 안전한 no-op 구현과 composition
| OpenTelemetry | 조직 trace 연계 필요 | opt-in recipe 제공, 미설치 |
| Web Worker | CPU 작업이 main thread를 막음 | opt-in recipe 제공, 미설치 |
| Notification | 사용자 권한 기반 browser notification 필요 | opt-in recipe 제공, 미설치 |
| Clipboard/File/Media | 해당 browser capability 필요 | opt-in recipe 제공, 미설치 |
| File/Blob/picker/download | 해당 file workflow 필요 | native reference runtime 제공, 미조립 |
| Clipboard/Media | 해당 browser capability 필요 | opt-in recipe 제공, 미설치 |
| Image CDN adapter | responsive image transform 필요 | 미설치 recipe |
| Virtualization | 대량 list rendering이 측정상 병목 | opt-in recipe 제공, 미설치 |
| OpenAPI generator | backend 계약에서 client 생성 필요 | opt-in recipe 제공, 미설치 |
@@ -906,11 +930,24 @@ capability의 기본 정책, port 또는 안전한 no-op 구현과 composition
선택 adapter는 “나중에 쓸 수 있으므로” 기본 bundle에 넣지 않는다. 도입
조건, 보안 영향, bundle 비용과 제거 방법이 확인된 경우에만 추가한다.
현재 구현된 공통 catalog, TypeScript contract/fake와 blocking gate는
SSE, WebSocket, Web Push와 bounded polling의 서로 다른 delivery 의미,
inbound/outbound 분리, resume·gap·lifecycle과 현재 상태는
[Realtime events, Web Push, and bounded polling](./realtime-events-web-push-and-bounded-polling.md)을
따른다.
Web Push는 subscription/provider/worker delivery를, 별도 Notification 행은
permission과 user-visible rendering facade를 뜻한다. bounded polling은 inbound
push adapter가 아니라 Query bridge 또는 application orchestrator가 기존 HTTP
operation을 schedule하는 policy다.
현재 구현된 공통 catalog, TypeScript contract/fake, browser-native reference
runtime과 blocking gate는
`docs/architecture/optional-adapter-recipes.md`
`config/recipes/frontend-capability-recipes.json`을 따른다. 이 recipe source를
production에서 직접 import하는 것은 금지하며 선택한 contract만 application
소유 경계로 이동한다.
소유 경계로 이동한다. 실제 API를 호출하는 `referenceRuntime`은 catalog에
`sourceRoots`가 등록된 browser file/IndexedDB/OPFS/Cache/transfer 계열에만
존재한다. realtime target은 아직 `DESIGNED_NOT_IMPLEMENTED`다. 구현된
reference runtime도 dataset/schema/codec/query/policy와 제품 owner가 없으면
bootstrap에 연결하지 않는다.
## 19. 새 outbound adapter 추가 recipe
@@ -1213,8 +1250,8 @@ design-system primitive를 조합하고 controller hook을 통해 application을
| Reference feature | full vertical integration과 complete removal |
TypeScript 전환 후에는 source뿐 아니라 test와 architecture/security
fixture도 typecheck 또는 lint 대상이어야 한다. `.ts/.tsx`가 JS 전용 glob을
우회하지 않도록 한다.
fixture도 typecheck 또는 lint 대상이어야 한다. 모든 실행 fixture를
`.ts/.tsx`로 유지해 확장자별 검사 우회를 허용하지 않는다.
Coverage는 단순 report 생성이 아니라 branch/function/line threshold를
blocking gate로 둔다. 수치만 올리기 위한 구현 세부 테스트보다 port
@@ -1230,13 +1267,13 @@ contract와 실패 분기를 우선한다.
- [ ] `main`은 raw ports 대신 application API를 제공한다.
- [ ] `contracts`는 unrestricted 우회 계층이 아니다.
- [ ] dependency rule과 문서의 source of truth가 하나다.
- [ ] TypeScript와 TSX도 동일한 architecture/security lint를 받는다.
- [x] TypeScript와 TSX도 동일한 architecture/security lint를 받는다.
### 26.2 Runtime composition
- [ ] runtime timeout/retry 설정이 실제 HTTP transport에 반영된다.
- [ ] QueryClient와 feature query bridge가 실제 route에서 동작한다.
- [ ] session UI API와 credential attachment가 분리되어 있다.
- [x] runtime timeout/retry 설정이 실제 HTTP transport에 반영된다.
- [x] QueryClient와 feature query bridge가 실제 route에서 동작한다.
- [x] session UI API와 credential attachment가 분리되어 있다.
- [x] diagnostics와 telemetry가 HTTP/render/storage/cache failure 경로에
연결된다.
- [x] `pagehide`에서 bounded telemetry queue를 flush하고 adapter `dispose`
@@ -1245,8 +1282,9 @@ contract와 실패 분기를 우선한다.
### 26.3 HTTP와 validation
- [ ] path, search, body를 각각 검증하고 직렬화한다.
- [ ] schema가 반환한 normalized data를 실제 request에 사용한다.
- [ ] timeout과 AbortSignal listener가 모든 반환 경로에서 정리된다.
- [x] schema가 반환한 normalized data를 실제 request에 사용한다.
- [x] 생성된 timeout과 AbortSignal listener가 현재 HTTP attempt의 terminal
경로에서 정리된다.
- [ ] retry는 runtime cap, idempotency와 `Retry-After`를 따른다.
- [ ] raw payload와 credential이 failure나 log에 포함되지 않는다.
@@ -1256,7 +1294,7 @@ contract와 실패 분기를 우선한다.
- [x] params/search schema가 실제 navigation에서 실행된다.
- [x] loading/error/chunk/access metadata가 실행 behavior와 연결된다.
- [ ] local, URL, server, session, persisted state가 분류 규칙을 따른다.
- [ ] server state를 별도 global store에 중복 보관하지 않는다.
- [x] reference server state를 별도 global store에 중복 보관하지 않는다.
### 26.5 Reference feature
@@ -1268,7 +1306,7 @@ contract와 실패 분기를 우선한다.
### 26.6 품질
- [ ] source와 test가 strict TypeScript 검사를 받는다.
- [x] source와 test가 strict TypeScript 검사를 받는다.
- [ ] React Hooks와 JSX accessibility lint가 blocking이다.
- [ ] coverage threshold가 blocking이다.
- [ ] MSW integration, component, 3-engine E2E와 axe가 통과한다.
@@ -1298,10 +1336,12 @@ contract와 실패 분기를 우선한다.
### P2: 프로젝트별 선택 capability
WebSocket/SSE, offline/IndexedDB, Service Worker, feature flag, product
SSE/WebSocket, Web Push, bounded polling, offline/IndexedDB, Service Worker, feature flag, product
analytics, vendor error reporting, worker, virtualization, OpenAPI generation,
global store와 cloud visual-review service는 실제 프로젝트 요구와 측정 결과에
따라 추가한다.
GraphQL, Connect/gRPC-Web, Protobuf REST Gateway, global store와 cloud
visual-review service는 실제 프로젝트 요구와 측정 결과에 따라 추가한다.
GraphQL과 browser Protobuf/Gateway의 선택·설치 조건은 VD-26과
VD-27/VD-29/VD-30을 따른다.
P2 adapter를 많이 설치하는 것은 skeleton 완성도의 기준이 아니다.
안전한 경계, 도입 recipe, 테스트 계약과 제거 가능성이 준비되어 있는지가