|
|
|
@@ -33,13 +33,13 @@
|
|
|
|
|
|
|
|
|
|
특히 다음은 선행 해결이 필요하다.
|
|
|
|
|
|
|
|
|
|
1. React 화면이 호출할 application input API와 런타임 주입 경계
|
|
|
|
|
2. TanStack Query를 사용하는 표준 query/mutation inbound adapter
|
|
|
|
|
3. TypeScript 전환 전에 TS 파일까지 검사하도록 만드는 도구 안전망
|
|
|
|
|
4. path/query/body projection과 runtime timeout/retry가 정확히 연결된 HTTP 계층
|
|
|
|
|
5. 선언과 실행이 일치하는 typed route 계약
|
|
|
|
|
6. 전체를 제거할 수 있는 실제 reference feature
|
|
|
|
|
7. 폼, 페이지 템플릿, 확장된 디자인 시스템과 컴포넌트 워크벤치
|
|
|
|
|
RP-01~RP-03에서 TypeScript 도구 안전망, application runtime 주입,
|
|
|
|
|
query/mutation inbound adapter와 HTTP 실행 계약은 구현됐다. 현재 선행 해결
|
|
|
|
|
대상은 다음과 같다.
|
|
|
|
|
|
|
|
|
|
1. 선언과 실행이 일치하는 typed route 계약
|
|
|
|
|
2. 전체를 제거할 수 있는 실제 reference feature
|
|
|
|
|
3. 폼, 페이지 템플릿, 확장된 디자인 시스템과 컴포넌트 워크벤치
|
|
|
|
|
|
|
|
|
|
따라서 현재 상태를 “프론트 공통부가 모두 구현됐다”고 표현하면 범위가 과장된다.
|
|
|
|
|
더 정확한 표현은 다음과 같다.
|
|
|
|
@@ -63,13 +63,13 @@
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
| 부트·런타임 설정 | 준비됨 | `src/bootstrap`, runtime schema, release 검사 | 현 상태 유지, TS 전환 시 동일 게이트 유지 |
|
|
|
|
|
| 계층 의존 방향 | 부분 준비 | `.dependency-cruiser.cjs`, `src/application/ports` | inbound/outbound 명명과 `contracts` 소유권까지 집행 |
|
|
|
|
|
| application facade | 부분 준비 | `create-application.js`는 있으나 `main.jsx`에서 우회 | UI에는 input API만 주입 |
|
|
|
|
|
| HTTP client | 부분 준비 | timeout, abort, retry, auth, envelope, Zod가 존재 | path/query, parsed body, runtime 설정, 정리 로직 보완 |
|
|
|
|
|
| retry | 부분 준비 | safe/keyed 요청 정책 존재 | retry 소유자 단일화, 설정 연결, telemetry |
|
|
|
|
|
| application facade | 준비됨 | typed input/output catalog, provider, production composition test | feature input use case를 contribution으로 확장 |
|
|
|
|
|
| HTTP client | 준비됨 | path/search/body projection, runtime timeout/retry, abort/cleanup test | feature gateway 뒤에서 사용 |
|
|
|
|
|
| retry | 준비됨 | HTTP 단일 소유, runtime max attempts, Query retry off | RP-09에서 telemetry 연결 |
|
|
|
|
|
| 오류 모델 | 부분 준비 | error registry와 normalization 존재 | typed discriminated union과 계층별 mapper |
|
|
|
|
|
| 검증 | 부분 준비 | runtime/API Zod 존재 | route/form/domain 경계를 분리하고 실제 parse 결과 사용 |
|
|
|
|
|
| 검증 | 부분 준비 | runtime/API Zod parse 결과를 실제 request에 사용 | route/form/domain 경계를 추가 |
|
|
|
|
|
| 인증 연동 | 준비됨/프로젝트 선택 | opaque auth owner와 demo seam 존재 | 인증 방식별 recipe; 기본 token 저장소는 추가하지 않음 |
|
|
|
|
|
| 서버 상태 | 미제공에 가까운 부분 준비 | QueryClientProvider와 cache port는 존재 | query/mutation hook과 화면 reference flow |
|
|
|
|
|
| 서버 상태 | 부분 준비 | 제한된 query/mutation bridge와 lifecycle test | RP-05 reference route에서 실제 feature 연결 |
|
|
|
|
|
| 클라이언트 상태 | 부분 준비 | local state, theme context, session external store | 상태 소유권 표와 typed external-store 예제 |
|
|
|
|
|
| 범용 global store | 프로젝트 선택 | 별도 라이브러리 없음 | 필요 조건에 따라 Zustand/Redux Toolkit/state machine 선택 |
|
|
|
|
|
| 라우팅 | 부분 준비 | lazy route, access hint, registry 존재 | typed runtime map, codec, recovery, metadata 집행 |
|
|
|
|
@@ -82,7 +82,7 @@
|
|
|
|
|
| 국제화 | 미제공 | 한국어 문자열·locale이 하드코딩 | typed message/formatter/locale/RTL 경계 |
|
|
|
|
|
| logging/diagnostics | 미제공 | telemetry port는 있으나 logger 없음 | redaction이 적용된 diagnostics/logging 경계 |
|
|
|
|
|
| telemetry | 부분 준비 | registry, queue, redaction 존재 | HTTP·boot·cache·storage·route 사건에 실제 연결 |
|
|
|
|
|
| 비동기 상태 불변식 | 부분 준비 | 공통 model/surface는 있으나 일부 모순 상태를 허용 | query/mutation 상태 조합과 action latch를 닫음 |
|
|
|
|
|
| 비동기 상태 불변식 | 준비됨 | 배타적 typed overlay, stale latch, 실제 retry/conflict action | reference 화면에서 전체 상태 전시 |
|
|
|
|
|
| 단위·통합·E2E | 준비됨 | Vitest, RTL, MSW, Playwright 3엔진 | TS 테스트 검사, 실제 bootstrap 통합, 위험 시나리오 보강 |
|
|
|
|
|
| UI 회귀 검증 | 미제공 | axe/reflow는 있으나 visual baseline 없음 | Storybook 또는 동급 workshop과 시각 회귀 |
|
|
|
|
|
| 샘플 제거 | 부분 준비 | fixture 제거 테스트 존재 | sample domain/registry/runtime 전체 제거 검증 |
|
|
|
|
@@ -94,13 +94,12 @@
|
|
|
|
|
|
|
|
|
|
### 5.1 P0: 기능 개발을 막는 항목
|
|
|
|
|
|
|
|
|
|
#### application 계층이 런타임에서 우회된다
|
|
|
|
|
#### RP-02에서 application 런타임 우회 해결
|
|
|
|
|
|
|
|
|
|
`src/bootstrap/composition-root.js`는 application을 생성하지만
|
|
|
|
|
`src/bootstrap/main.jsx`는 이를 라우터에 주입하지 않는다. UI에는 auth, storage,
|
|
|
|
|
telemetry 같은 raw outbound dependency와 concrete QueryClient가 전달된다.
|
|
|
|
|
`src/application/create-application.js`도 use case 중심 input API보다 outbound
|
|
|
|
|
capability를 다시 노출하는 형태다.
|
|
|
|
|
`src/bootstrap/composition-root.js`가 만든 typed application input API는
|
|
|
|
|
production `ApplicationProvider`에 주입된다. raw auth, storage, telemetry와
|
|
|
|
|
release port는 closure 안에 남고 UI는 session, preference, diagnostics와 runtime
|
|
|
|
|
query만 사용한다.
|
|
|
|
|
|
|
|
|
|
목표 상태:
|
|
|
|
|
|
|
|
|
@@ -110,12 +109,13 @@ capability를 다시 노출하는 형태다.
|
|
|
|
|
- bootstrap만 concrete outbound adapter를 알고 조합한다.
|
|
|
|
|
- 실제 bootstrap부터 reference page까지 연결한 통합 테스트가 있다.
|
|
|
|
|
|
|
|
|
|
#### 서버 상태 라이브러리는 마운트됐지만 사용할 수 없다
|
|
|
|
|
#### RP-03에서 표준 서버 상태 bridge 구현
|
|
|
|
|
|
|
|
|
|
`QueryClientProvider`는 존재하지만 저장소의 제품 코드에서 `useQuery`와
|
|
|
|
|
`useMutation`을 사용하지 않는다. 동시에 presentation의 `@tanstack/**` import는
|
|
|
|
|
금지돼 있다. 현재 `QueryCachePort`는 명령형 read/write/invalidate만 제공하여
|
|
|
|
|
React 구독, 요청 상태, cancellation, optimistic update를 대신할 수 없다.
|
|
|
|
|
`src/presentation/adapters/query` 한 경계만 `@tanstack/**`를 import한다.
|
|
|
|
|
`useApplicationQuery`와 `useApplicationMutation`은 application result를 React
|
|
|
|
|
lifecycle에 연결하며 cancellation, stale failure, duplicate submit, optimistic
|
|
|
|
|
rollback, conflict resolution과 invalidation을 검증한다. 다른 presentation
|
|
|
|
|
경로의 직접 TanStack import는 negative fixture가 거절한다.
|
|
|
|
|
|
|
|
|
|
목표 상태:
|
|
|
|
|
|
|
|
|
@@ -128,7 +128,7 @@ React 구독, 요청 상태, cancellation, optimistic update를 대신할 수
|
|
|
|
|
- loading, empty, refreshing, stale, offline, error, conflict, optimistic rollback을
|
|
|
|
|
reference feature에서 보여 준다.
|
|
|
|
|
|
|
|
|
|
#### TypeScript 전환 전에 검사 도구가 TS를 인식해야 한다
|
|
|
|
|
#### RP-01에서 TypeScript 검사 도구 안전망 구현
|
|
|
|
|
|
|
|
|
|
현재 source는 모두 JS/JSX이고 `strict + allowJs + checkJs`를 사용한다. 이는 좋은
|
|
|
|
|
중간 안전망이지만 다음 도구는 TS migration을 그대로 따라가지 못한다.
|
|
|
|
@@ -143,18 +143,14 @@ TypeScript 전환은
|
|
|
|
|
[TypeScript의 JavaScript migration 가이드](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html)
|
|
|
|
|
처럼 점진적으로 진행하되, 이 저장소에서는 tooling glob과 CI를 먼저 고쳐야 한다.
|
|
|
|
|
|
|
|
|
|
#### HTTP 계약에 선언과 실행의 차이가 있다
|
|
|
|
|
#### RP-03에서 HTTP 선언과 실행의 차이 해결
|
|
|
|
|
|
|
|
|
|
현재 HTTP 계층은 공통화 수준이 높지만 다음 정확성 문제가 남아 있다.
|
|
|
|
|
|
|
|
|
|
- runtime config의 `REQUEST_TIMEOUT_MS`, `MAX_RETRY_ATTEMPTS`가 client 생성에
|
|
|
|
|
전달되지 않는다.
|
|
|
|
|
- operation path에 path parameter와 search parameter를 투영하는 표준 builder가
|
|
|
|
|
없다.
|
|
|
|
|
- sample filter는 cache key에만 반영되고 실제 요청 URL에는 반영되지 않는다.
|
|
|
|
|
- Zod의 parsed/transformed request body 대신 원본 body를 전송한다.
|
|
|
|
|
- request validation의 조기 반환 경로에서 timeout/listener 정리가 늦어진다.
|
|
|
|
|
- HTTP failure, retry, recovery가 telemetry 사건과 이어지지 않는다.
|
|
|
|
|
HTTP request builder는 path segment escaping, canonical optional/array search,
|
|
|
|
|
Zod default/trim 결과의 실제 query/body 전송을 담당한다. runtime timeout과
|
|
|
|
|
0/1/N max retry가 client factory에 주입되고 caller abort와 timeout을 다른 typed
|
|
|
|
|
failure로 투영한다. validation 조기 반환은 fetch/timer 0회이며 success, schema
|
|
|
|
|
failure, abort, timeout과 exhausted retry는 scheduler/listener cleanup을
|
|
|
|
|
검증한다. HTTP 사건의 semantic telemetry 연결은 RP-09 범위다.
|
|
|
|
|
|
|
|
|
|
client를 거대한 범용 함수로 계속 확장하지 말고 transport, request builder, auth,
|
|
|
|
|
timeout, retry, decoder, mapper 책임을 분리해야 한다. application에는 범용 HTTP
|
|
|
|
|