Files
tech-log-frontend/src/features/reference-feature

Reference feature ownership and removal

이 모듈은 제품 도메인이 아니라 새 기능의 수직 경계를 검증하는 제거 가능한 reference implementation이다.

소유 경계

  • domain: 외부 DTO와 React를 모르는 불변 model
  • application: UI가 호출하는 list/get/create input과 gateway 계약
  • adapters: HTTP executor를 gateway로 투영하는 outbound adapter
  • contracts: route/API/query contribution, Zod DTO와 request schema, mapper
  • presentation: route input을 query/form controller로 연결하는 inbound adapter, 독립 form schema/command mapper와 list/detail/form/status page

generic application은 비어 있는 ApplicationFeatureInputs와 typed features.has/get registry만 소유한다. 이 feature의 application API가 module augmentation으로 "reference-feature": ReferenceFeatureInput을 기여하므로 등록되지 않은 ID와 잘못된 input shape는 typecheck에서 거절된다. feature hook은 별도 cast나 runtime shape 확인 없이 정확한 input type을 받는다. 다만 동적 호출로 설치되지 않은 ID가 들어오는 경우를 위해 get의 runtime guard도 유지한다.

예측 가능한 실패는 src/application/result.ts의 공통 Result<Value, Failure = AppFailure>로 반환한다. AppFailure.kindERROR_REGISTRY key에서 파생된 닫힌 vocabulary이며, transport 호환 이름인 ApiFailure는 같은 type의 alias다.

HTTP adapter의 operation map은 operation ID마다 허용된 route ID, request shape와 성공 value type을 함께 묶는다. raw HTTP executor의 성공값은 Zod request/response 검증과 feature mapper를 통과한 뒤 operation별 runtime result guard에서 typed executor로 승격된다. 따라서 gateway 메서드는 개별 응답 cast 없이 정확한 결과를 반환하고, operation/route/request 조합 오류는 typecheck에서 차단된다.

route codec과 URL builder는 src/presentation/routes/route-codecs.ts, route type은 route-contract.ts, React context/provider/hook은 route-input.tsx가 각각 소유한다. reference page는 app-router.tsx를 역참조하지 않고 좁은 useRouteInput 경계만 사용하므로 lazy route와 router 사이의 순환 의존을 만들지 않는다. page는 HTTP client, storage, auth owner, output port나 TanStack API를 직접 import하지 않는다.

설치 지점

  • 직렬화 계약: src/features/installed-feature-contracts.ts
  • component/codec: src/features/installed-feature-runtimes.tsx
  • bootstrap input 조립: src/features/installed-feature-adapters.ts

새 기능도 이 세 지점에 contribution을 합성하되 feature ID를 generic application, router나 HTTP client에 하드코딩하지 않는다.

검증과 제거

corepack pnpm test:reference-feature
corepack pnpm test:sample-removal

첫 명령은 URL filter와 query key/HTTP request의 동일성, schema/mapper, 모든 query/mutation/form 상태와 production composition을 검증한다. 두 번째 명령은 임시 복제본에서 이 source/test 디렉터리를 제거하고 installed catalog를 빈 목록으로 재생성한다. feature 소유 coverage include, risk-policy 행과 test-evidence contribution도 제거한 뒤 typecheck, architecture, registry, unit/integration, coverage, source evidence, home smoke, production build와 source/built fixture ID 잔여 0개를 검사한다. generic feature registry의 성공 경로는 reference와 무관한 unit test가 소유하므로 feature 삭제 후에도 공통 boundary coverage가 유지된다.

CI의 negative type fixture는 잘못된 feature ID/input shape, registry에 없는 failure kind, operation과 route ID의 불일치가 실제로 컴파일 실패하는지도 검증한다. Architecture fixture는 허용 edge뿐 아니라 unresolved import, 금지 계층 edge와 TypeScript 순환 의존을 각각 거절해야 통과한다.