feat: add removable reference feature vertical slice
This commit is contained in:
@@ -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 품질
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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을
|
||||
|
||||
Reference in New Issue
Block a user