feat: add removable reference feature vertical slice

This commit is contained in:
donghyeon-ka
2026-07-26 14:56:34 +09:00
parent 980981bc86
commit c11be43f20
87 changed files with 1881 additions and 1114 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ Automated axe checks do not establish WCAG conformance. A human reviewer must
review all six route records in `artifacts/tests/a11y-manual/` against one
release candidate and sign them. The required scope is derived from the route
registry: `APP_HOME`, `EXAMPLES_UI`, `EXAMPLES_STATES`, `EXAMPLES_AUTH`,
`SAMPLE_RESOURCE_LIST`, and `NOT_FOUND`. Copy the template fields exactly; the
`REFERENCE_RESOURCE_LIST`, and `NOT_FOUND`. Copy the template fields exactly; the
gate rejects blank identity/timestamp/signature fields, pending verdicts,
mismatched release IDs, or missing routes.
@@ -33,14 +33,13 @@
특히 다음은 선행 해결이 필요하다.
RP-01~RP-04에서 TypeScript 도구 안전망, application runtime 주입,
RP-01~RP-05에서 TypeScript 도구 안전망, application runtime 주입,
query/mutation inbound adapter, HTTP 실행 계약과 executable route/release
recovery 계약 구현됐다. 현재 선행 해결
recovery 계약, 제거 가능한 reference 수직 슬라이스는 구현됐다. 현재 선행 해결
대상은 다음과 같다.
1. 전체를 제거할 수 있는 실제 reference feature
2. 폼, 페이지 템플릿, 확장된 디자인 시스템과 컴포넌트 워크벤치
3. 국제화, diagnostics, optional adapter recipe와 심화 품질 게이트
1. 폼, 페이지 템플릿, 확장된 디자인 시스템과 컴포넌트 워크벤치
2. 국제화, diagnostics, optional adapter recipe와 심화 품질 게이트
따라서 현재 상태를 “프론트 공통부가 모두 구현됐다”고 표현하면 범위가 과장된다.
더 정확한 표현은 다음과 같다.
@@ -70,7 +69,7 @@ recovery 계약은 구현됐다. 현재 선행 해결
| 오류 모델 | 부분 준비 | error registry와 normalization 존재 | typed discriminated union과 계층별 mapper |
| 검증 | 부분 준비 | runtime/API Zod parse 결과를 실제 request에 사용 | route/form/domain 경계를 추가 |
| 인증 연동 | 준비됨/프로젝트 선택 | opaque auth owner와 demo seam 존재 | 인증 방식별 recipe; 기본 token 저장소는 추가하지 않음 |
| 서버 상태 | 부분 준비 | 제한된 query/mutation bridge와 lifecycle test | RP-05 reference route에서 실제 feature 연결 |
| 서버 상태 | 준비 | reference route의 query/mutation, cancellation, stale, optimistic/conflict/rollback | feature별 query contribution recipe 유지 |
| 클라이언트 상태 | 부분 준비 | local state, theme context, session external store | 상태 소유권 표와 typed external-store 예제 |
| 범용 global store | 프로젝트 선택 | 별도 라이브러리 없음 | 필요 조건에 따라 Zustand/Redux Toolkit/state machine 선택 |
| 라우팅 | 준비됨 | Data Router, typed runtime map, codec, metadata consumer, bounded chunk recovery | reference feature route와 release E2E로 사용 범위 확장 |
@@ -86,7 +85,7 @@ recovery 계약은 구현됐다. 현재 선행 해결
| 비동기 상태 불변식 | 준비됨 | 배타적 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 전체 제거 검증 |
| 샘플 제거 | 준비 | feature/catalog/test 제거 후 type/architecture/registry/test/home/build 8단계 검증 | 새 contribution도 같은 제거 gate에 포함 |
| registry·compatibility 집행 | 부분 준비 | registry와 gate는 있으나 실제 before/after 및 orphan 검사가 제한적 | type/reference/orphan/diff/migration을 자동 검증 |
| 공급망 검사 | 부분 준비 | lockfile·문서·gate는 있으나 실제 transitive 취약점/license/SBOM 깊이가 부족 | pinned scanner와 policy exception/증적 연결 |
| realtime·offline·file 등 | 프로젝트 선택 | 현재 없음 | port/adapter recipe와 선택 기준 제공 |
@@ -159,8 +158,8 @@ timeout, retry, decoder, mapper 책임을 분리해야 한다. application에는
#### RP-04에서 route registry를 실행 계약으로 전환
`src/contracts/routes.js` 직렬화 가능한
`src/contracts/route-runtime-contract.js` 기준으로
platform route 계약과 `src/features/installed-feature-contracts.js` 직렬화
가능한 contribution을 기준으로
`src/presentation/routes/app-router.tsx`가 Data Router route object와
navigation을 생성한다. `route-runtime.tsx`는 lazy component의 실행 map만
소유하며 contract/runtime 누락과 orphan은 TypeScript negative fixture와 registry
@@ -179,16 +178,18 @@ gate가 모두 거절한다.
연결하고, no-store manifest 재조회와 build/release 쌍별 1회 reload를
production application input까지 연결한다.
#### reference feature가 완전히 제거되지 않는다
#### RP-05에서 제거 가능한 reference feature 구현
현재 sample removal gate는 `src/sample/contract-fixture`만 삭제한다. sample API
operation, schema, mapper, domain model, query key는 다른 production 경로에 남는다.
반면 화면에 노출된 `/sample/resources`는 실제 query 수직 흐름을 실행하지 않는다.
`src/features/reference-feature`가 domain, application input, outbound gateway,
DTO/schema, mapper, route/API/query contract, query/mutation controller와 page를
한 소유 경계에 둔다. production composition은 generic feature input catalog를
통해 이 input을 주입하며 UI는 HTTP나 output port를 직접 보지 않는다.
reference feature는 domain, application input/output, schemas, operation,
mapper, query controller, pages, tests를 한 소유 경계 아래 모아야 한다. 해당 모듈과
registry contribution을 제거한 뒤 typecheck, architecture, test, build가 모두
통과해야 “제거 가능”으로 판정한다.
`test:sample-removal`은 임시 복제본에서 feature source/tests를 삭제하고 installed
contract/runtime/adapter catalog를 빈 목록으로 재생성한다. 그 뒤 typecheck,
architecture, registry, unit/integration, home smoke, build와 fixture ID 잔여
0개를 검사한다. 설치 모드에서는 MSW를 사용한 bootstrap → router → application
→ HTTP → schema → mapper → query cache → page 수직 테스트가 실행된다.
#### 비동기·복구 상태의 불변식이 닫혀 있지 않다
@@ -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/sample` | 제거 가능 예제 일부 | 완전한 removable reference feature |
| `src/features/reference-feature` | 완전한 제거 가능 수직 예제 | installed contribution과 8단계 제거 gate 유지 |
현재 구조가 잘 제공하는 기반은 다음과 같다.
@@ -154,15 +154,14 @@ RP-03 구현으로 HTTP와 server-state 경계도 다음처럼 연결됐다.
- HTTP가 자동 network retry를 소유하고 query/mutation adapter의 vendor retry는
비활성화한다.
RP-04에서 첫 번째 실행 불일치는 닫혔다. route registry와 runtime map은
RP-04에서 route 실행 불일치는 닫혔다. route registry와 runtime map은
Data Router tree, codec, surface, title, navigation, chunk/release recovery의
단일 조립 입력이며 registry/type/build 검증이 누락과 orphan을 거절한다.
후속 브랜치에서 닫아야 할 실행 불일치는 다음과 같다.
1. 제거 테스트는 `src/sample/contract-fixture`만 제거하며, sample API
operation, Zod schema, mapper, domain model과 query key는 다른 경로에
남는다.
RP-05에서 두 번째 불일치도 닫혔다. feature별 domain/application/adapter/
contract/presentation은 `src/features/reference-feature`가 소유하고, generic
installed catalog만 bootstrap과 router에 노출된다. 제거 gate는 feature와 test를
삭제한 복제본에서 전체 P0 경로를 다시 실행한다.
이 문서의 목표 구조는 기존 기반을 폐기하는 것이 아니라 이러한
불일치를 제거하는 것이다.
@@ -1222,11 +1221,11 @@ contract와 실패 분기를 우선한다.
### 26.5 Reference feature
- [ ] route부터 API mapper와 화면까지 완전한 수직 경로가 실행된다.
- [ ] list/create 등 최소 query와 mutation 예제가 있다.
- [ ] loading/empty/error/refresh/conflict 상태가 있다.
- [ ] reference feature 전체 삭제 후 typecheck/test/build가 통과한다.
- [ ] built asset에 reference operation, schema, mapper가 남지 않는다.
- [x] route부터 API mapper와 화면까지 완전한 수직 경로가 실행된다.
- [x] list/create 등 최소 query와 mutation 예제가 있다.
- [x] loading/empty/error/refresh/conflict 상태가 있다.
- [x] reference feature 전체 삭제 후 typecheck/architecture/registry/test/home/build가 통과한다.
- [x] 제거 모드 built asset에 reference operation, schema, mapper가 남지 않는다.
### 26.6 품질
+3 -2
View File
@@ -44,12 +44,13 @@ flowchart LR
The current executable route tree is mounted only after runtime configuration
and release-manifest coherence pass. It receives the composed query client,
credential-opaque session port, storage port, telemetry port, and immutable
build ID. Visible starter pages do not depend on the removable sample fixture.
build ID. Generic starter pages do not depend on the removable reference
feature.
This describes the current starter composition, not the completed target. The
capability review found that raw outbound capabilities still reach the React
tree, the composed application facade is not yet its entry point, and several
route, HTTP, recovery, telemetry, and sample-removal contracts are only
route, HTTP, recovery, telemetry, and reference-feature removal contracts are only
partially connected. Use the following documents for the evidence and migration
plan:
@@ -23,8 +23,8 @@ RP-04 이후 현재 구현에는 다음 장점이 있다.
- route heading focus와 비동기/render error boundary가 있다.
- redirect loop와 chunk recovery가 bounded production call graph에 연결돼 있다.
`src/contracts/routes.js`, `src/contracts/route-runtime-contract.js`,
`src/presentation/routes/route-runtime.tsx`의 완전성은 TypeScript와 registry
platform route 계약, `src/features/installed-feature-contracts.js`,
`src/features/installed-feature-runtimes.tsx`의 완전성은 TypeScript와 registry
negative fixture가 함께 검사한다. params/search codec, loading/error surface,
access, title, navigation, chunk ID는
`src/presentation/routes/app-router.tsx`에서 모두 소비된다. built Vite
+13 -11
View File
@@ -11,7 +11,8 @@ primitives, and state surfaces remain reusable.
validated config + coherent release manifest
-> concrete adapters
-> QueryClientProvider
-> BrowserRouter
-> ApplicationProvider
-> RouterProvider
-> ThemeProvider
-> SessionProvider
-> AppShell
@@ -31,7 +32,7 @@ remain stable in the shell.
| `EXAMPLES_UI` | `/examples/ui` | public | interactive primitives and tokens |
| `EXAMPLES_STATES` | `/examples/states` | public | async and access state matrix |
| `EXAMPLES_AUTH` | `/examples/auth` | public | session integration controls |
| `SAMPLE_RESOURCE_LIST` | `/sample/resources` | integration-defined | protected integration seam |
| `REFERENCE_RESOURCE_LIST` | `/examples/reference-resources` | integration-defined | removable vertical slice |
| `NOT_FOUND` | `*` | public | safe navigation recovery |
Navigation labels and order come from `ROUTE_REGISTRY`; the sidebar does not
@@ -54,24 +55,25 @@ An external owner implements `readState`, `subscribe`, `beginSignIn`,
## Extending the starter
The steps below describe the current extension path. The platform review found
that several route metadata fields and the composed application facade are not
yet connected end to end. New platform work should follow
The steps below describe the current extension path. New platform work should follow
[routing, page templates, and reusable patterns](./routing-pages-and-patterns.md)
and the
[TypeScript, state, and data-flow target](./typescript-state-and-data-flow.md)
rather than adding another independent route or data-loading convention.
1. Register the route path, access hint, title, chunk, loading surface, error
surface, and optional navigation metadata in `src/contracts/routes.js`.
2. Add a lazy page in `src/presentation/` and render it through `RouteSurface`.
3. Use application ports or use cases; do not import concrete adapters.
1. Add a serializable contribution under the feature ownership boundary and
install it through `src/features/installed-feature-contracts.js`.
2. Add the lazy component and route codecs through
`src/features/installed-feature-runtimes.tsx`.
3. Compose feature application inputs and outbound gateways only through
`src/features/installed-feature-adapters.ts`.
4. Use the semantic tokens, UI primitives, and state surfaces before adding a
project-specific variant.
5. Add component behavior, all-engine E2E, automated axe, and signed manual
route evidence.
6. Run `test:sample-removal` to prove the visible starter still builds without
`src/sample/contract-fixture`.
6. Run `test:sample-removal` to prove the generic starter typechecks, passes
architecture/registry/tests/home smoke, and builds without the complete
reference feature.
Theme preference is the public `COLOR_SCHEME` storage contract. Authentication
tokens and other secrets remain forbidden storage keys.
+3 -2
View File
@@ -37,8 +37,9 @@ Arbitrary-value policy:
- user-controlled or runtime-composed class strings are forbidden
- class variants must be selected from a closed static map
The removable sample may demonstrate tokens, but production starter modules do
not import from `src/sample/contract-fixture`.
The removable reference feature may demonstrate tokens, but generic production
starter modules do not import its domain, application, adapter, or presentation
implementation.
This file documents the currently implemented token and primitive baseline.
The [design-system platform contract](./design-system-platform.md) defines the
@@ -446,6 +446,14 @@ tests/support/query/
helper는 production default를 복사하지 않는다. production factory를 호출하고
필요한 시간·retry만 test override로 주입한다.
RP-05의 executable reference matrix는
`tests/features/reference-feature`에 모여 있다. 설치 모드에서는 URL codec과
query key/HTTP search의 동일성, DTO 차단, loading/success/empty/terminal,
refreshing/stale, pending/duplicate/optimistic/conflict/rollback과 MSW production
composition을 검증한다. 제거 모드는 feature source/tests와 installed
contract/runtime/adapter contribution을 제거한 복제본에서 P0 gate와 built asset
잔여 0개를 다시 검증한다.
## 8. Form 테스트
Form test는 field primitive, form controller, application command mapping을