30 KiB
title, source_type, status, branch, parent_branch, related_projects, governing_docs, tags, created, target_merge, status_label, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, contract_packet_sha256, imports
| title | source_type | status | branch | parent_branch | related_projects | governing_docs | tags | created | target_merge | status_label | id | kind | project | work_item | inherits | refines | overrides | depends_on | contract_packet | contract_packet_sha256 | imports | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| branch / feature-routing-navigation-guard-contract | branch-note | raw | feature-routing-navigation-guard-contract |
|
|
|
2026-07-18 | in-progress | BR-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-009 | project-work-item | ca-skeleton-frontend-operational-contract | WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-009 |
|
|
1 | fc5b09275d9cfe6bccc3c7f28c67ca370f6921a9afe79f114398b7761ef660f9 |
|
branch: feature-routing-navigation-guard-contract
Layer:
raw/branch-notes/— 단일 브랜치의 TODO·결정·진행 기록. 머지/종료 후 verified 결과는/ingest로wiki/projects/에 추출한다.
부모 (필수)
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
1 - 패킷 스키마:
contract_packet: 1 - 완료 조건: registry route·param validation·404·redirect-loop·session UX test가 통과한다
상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-ROUTING-001@1 |
routing default는 React Router Declarative Mode다 | Work Item 완료 조건에 적용 | raw/project-notes/ca-skeleton-frontend-operational-contract |
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-AUTH-BOUNDARY-001@1 |
auth lifecycle은 외부 owner가 소유하고 skeleton은 AuthSessionPort만 소비한다 | Work Item 완료 조건에 적용 | raw/project-notes/ca-skeleton-frontend-operational-contract |
브랜치 지역 결정
기존 branch-local 결정은 아래
## Decision Evidence Map / 결정-근거 매핑의 D-row가 소유하며 이 packet에서 복제하지 않는다.
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|
선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|
목표
이 브랜치는 project-wide 계약 FE-OC-005("route ID/path/params/access/loading/error owner는 route registry 하나여야 함")를 구현 착수 가능한 명세로 내린다. 즉 route 메타데이터의 단일 소유 registry(FE-REG-ROUTE, src/contracts/routes.js)를 정의하고, raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008(React Router Declarative Mode를 라우팅 default로 채택, conditional-default)을 이 registry 위에서 구현한다. 부수적으로 FE-OC-010(session state를 소비하되 token lifecycle을 소유하지 않음), FE-OC-015(route error/loading surface 소유를 render boundary와 중복하지 않고 reload loop 금지), FE-OC-024(sample route는 제거 가능한 fixture)에 기여한다. 아직 frontend repository가 없으므로 본 노트의 모든 구현 주장은 planned 등급이다.
- 이슈: (없음 — repository 미생성)
- PR: (없음)
범위
포함 범위
FE-REG-ROUTEroute registry를 단일 SSOT로 정의:routeId/path/paramsSchema/searchSchema/access/loadingSurface/errorSurface/chunkId필드(§5.2 minimum schema) — 등급planned- React Router Declarative Mode 라우팅(
FE-D008):<Routes>/<Route>컴포넌트 트리 + nested<Outlet/>합성 — 등급planned - route
access분류 enum{public, session-required, integration-defined}(§5.2) — 등급planned - navigation guard(=UX hint):
session-requiredroute가AuthSessionPortstate를 소비, redirect loop 차단(bounded hop) — 등급planned - unknown route →
NOT_FOUND(*, public) surface, API 요청 없이 처리(§9.3) — 등급planned - route param/search runtime validation 진입점: registry가 schema 참조를 선언(검증 엔진은 위임) — 등급
planned - route별
loadingSurface/errorSurfaceowner 선언(render boundary와 owner 중복 금지) — 등급planned - sample route fixtures(
APP_HOME,SAMPLE_RESOURCE_LIST,NOT_FOUND)(§5.2 initial rows) — 등급planned
제외 범위
의도적으로 제외 — 다른 owner 브랜치 또는 외부 소유.
- token lifecycle(code exchange·refresh·rotation·logout·revocation): 외부 auth owner + raw/branch-notes/feature-frontend-auth-session-integration-contract
FE-OC-010소유. 본 브랜치는AuthSessionPortstate를 소비만. - backend authorization 결정(최종 권한 판단): backend 소유. guard는 이를 대체하지 않음.
- failure 정규화 taxonomy(
401→AUTH_REQUIRED,404→NOT_FOUND,RENDER_FAILURE등): raw/branch-notes/feature-frontend-error-classification-boundary-contractFE-OC-008소유. - runtime schema 검증 엔진(Zod): raw/branch-notes/feature-runtime-schema-validation-contract
FE-OC-007소유. 본 registry는 schema 참조만 선언. - React error boundary taxonomy + reload-loop guard 구현: raw/branch-notes/feature-frontend-render-recovery-boundary-contract
FE-OC-015소유. 본 registry는 route별 surface owner 선언만. - lazy chunk ID ↔ release manifest 매핑 생성: raw/branch-notes/feature-frontend-release-cache-rollback-contract
FE-OC-016소유. route registry는 생성된chunkId값만 보유. - 8-registry cross-cutting governance(single-owner·compatibility): raw/branch-notes/feature-frontend-contract-registry-governance
FE-OC-022소유.
근거 (필수, 최소 1개+)
| Source | 정당화하는 결정 |
|---|---|
raw/official-docs/react-router-official REACT-ROUTER-C1·REACT-ROUTER-C4 |
D1 — <Routes>/<Route>로 URL segment를 UI에 결합하는 선언적 route 구성 + "Declarative Mode"가 파일 기반 Framework Mode와 별개로 존재(client-only Vite SPA 적합) |
raw/official-docs/react-router-official REACT-ROUTER-C2 |
D2·D8 — nested route + <Outlet/> 합성(레이아웃 아래 보호된 자식 route 중첩) |
raw/official-docs/react-router-official REACT-ROUTER-C3 |
D4 — Link/NavLink 활성 스타일링. navigation guard(라우트 접근 제어)는 증명하지 않음(§Usage Boundaries) → guard 결정은 hub project decision + D4 web 조사로 근거화 |
| reactrouter.com/start/declarative/navigating (2026-07-19 web 조사, 미아카이브) | D4 mechanism — Declarative Mode의 useNavigate programmatic navigation(로그인/로그아웃 등 비상호작용 redirect) 근거. RR-NAV-WEB-C1(§구현 가이드 3 인용) |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-OC-005 (§5.1 owner map, §5.2 route registry schema) |
D2·D3·D6·D8 — route registry 단일 소유, access enum, NOT_FOUND, surface owner |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008 (§9.3 route behavior, §7.8 auth boundary, §13.2 route guard≠authorization) |
D1·D4·D5·D7 — routing default, guard=UX hint, param validation, redirect loop 차단 |
미아카이브 web 근거(
RR-NAV-WEB-C1)는 wiki 승격 전wiki-source-summarizer로raw/official-docs/에 정식 아카이브 필요(React Router 공식 doc의 §메모가 "loader/redirect 패턴 별도 자료 추가 필요"로 이미 flag).
TODO
FE-REG-ROUTEroute registry 모듈(routeId/path/paramsSchema/searchSchema/access/loadingSurface/errorSurface/chunkId) — 등급:planned- registry로부터 Declarative Mode router 구성(
<Routes>/<Route>/<Outlet>) — 등급:planned - access 분류 + navigation guard(UX hint,
AuthSessionPort소비) — 등급:planned - param/search validation 진입점(schema 참조 선언; Zod 검증은 위임) — 등급:
planned NOT_FOUNDroute + redirect-loop guard(automatic redirect ≤ 1, 동일 pair 반복 금지) — 등급:planned- route
loadingSurface/errorSurfaceowner 선언(boundary 중복 금지) — 등급:planned - 테스트: registry snapshot · param validation · 404 no-API · redirect-loop · session UX — 등급:
planned
진행 중 메모
REACT-ROUTER-C3이 guard를 증명하지 않는다는 점이 이 브랜치의 핵심 함정이다. guard 결정은 hub project decision(§7.8/§9.3/§13.2)으로, guard 메커니즘은useNavigateweb 조사(RR-NAV-WEB-C1)로 근거화하고, 구체 컴포넌트 설계는UNSUPPORTED_IMPL_DECISION으로 남긴다.- Declarative Mode에는 built-in loader/redirect가 없으므로 param validation과 guard가 모두 component 계층 구현이 된다(§구현 가이드 3·4).
결정 사항
대안과 근거를 함께 기록. 상세 근거 매핑은 아래 Decision Evidence Map.
- 2026-07-19: 라우팅은 React Router Declarative Mode를 default로 채택 / 이유: client-only Vite SPA는 SSR·file-based convention·route-level loader가 없어 선언적
<Routes>/<Route>트리로 충분 / 검토한 대안: data router mode(route 객체 + loader/action), framework mode(파일 기반 컨벤션+SSR) / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-D008,raw/official-docs/react-router-official.md#REACT-ROUTER-C1·#REACT-ROUTER-C4 - 2026-07-19: route ID/path/params/access/loading/error를 단일 route registry(
FE-REG-ROUTE)가 소유 / 이유: rename·rollback 영향 범위를 한 곳에서 계산, component literal route path로 인한 분산 방지 / 검토한 대안: 파일 기반/컴포넌트 인라인 route 정의 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-OC-005(§5.1·§5.2) - 2026-07-19: route
access는{public, session-required, integration-defined}3-값 enum / 이유: 접근 정책을 registry 필드로 고정해 component 분기 제거 / 검토한 대안: booleanrequiresAuth, role 배열 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-OC-005(§5.2 access field) - 2026-07-19: navigation guard는 UX hint일 뿐 authorization이 아니고 backend authorization이 최종 판단 / 이유: client guard는 우회 가능하므로 보안 경계로 삼지 않음(§13.2) / 검토한 대안: client-side 강제(백엔드 authz 없이 route로 접근 통제) / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract
FE-D008(§7.8·§9.3·§13.2); guard mechanism은RR-NAV-WEB-C1(useNavigate) - 2026-07-19: route param/search는 application 호출 전 runtime validation, registry가 schema 참조 선언·검증 엔진은 위임 / 이유: 잘못된 URL 입력을 경계에서 차단하되 Zod 채택은 별도 owner 결정 / 검토한 대안: validation 생략(신뢰) / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract
FE-D008(§9.3),FE-D007(Zod) - 2026-07-19: unknown route → API 없이 not-found surface,
NOT_FOUND(*, public)를 registry에 포함 / 이유: 존재하지 않는 route에 불필요한 네트워크 요청 금지 / 검토한 대안: 서버 라우팅 위임 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-D008(§9.3·§8.2·§5.2) - 2026-07-19: redirect loop 차단 — navigation attempt당 automatic auth redirect ≤ 1, 동일 source→target pair 반복 금지 / 이유: guard redirect가 무한 루프가 되지 않도록 hop 제한 / 검토한 대안: 무제한 redirect / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract
FE-D008(§9.3·§7.8·§10.2;FE-GATE-008e2e invariant) - 2026-07-19: route별
loadingSurface/errorSurfaceowner를 registry가 선언, route error element와 React error boundary owner 중복 금지 / 이유: 같은 실패를 두 소유자가 처리하는 모호성 제거(§9.3·§10.1) / 검토한 대안: boundary만으로 처리 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-OC-005(§5.2·§9.3·§10.1)
결정-근거 매핑
Decision ID는 본 branch-note 안에서 안정적.Supporting Claims의FE-D###·§n은 hub project 문서 기준.
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|---|
| D1 | React Router Declarative Mode를 라우팅 default로 채택 (FE-OC-005 구현 기반) |
Declarative Mode 유지: client-only Vite SPA에 loader·SSR·file-based convention 요구가 없을 때. 대안(data router/framework mode)은 route-level data loading·SSR이 product requirement가 될 때 전환 | raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008; raw/official-docs/react-router-official.md#REACT-ROUTER-C1, #REACT-ROUTER-C4 |
official-doc + conditional-default | Declarative Mode에는 built-in loader/redirect가 없어 guard·validation을 component 계층에서 구현해야 함(D4·D5 impl 위험) |
| D2 | route ID/path/params/access/loading/error를 단일 route registry(FE-REG-ROUTE)가 소유 — component 내 literal route path 금지 |
항상 registry 경유: route 메타데이터가 rename·compatibility 추적 대상일 때(=본 skeleton). literal 경로는 §0.4 throwaway single-route prototype에서만 허용 | raw/project-notes/ca-skeleton-frontend-operational-contract FE-OC-005 (§5.1 owner map, §5.2 schema) |
project-decision | registry field 확장(신규 access class 등)은 FE-REG-ROUTE 변경 프로토콜(§5.10) 필요 |
| D3 | route access = {public, session-required, integration-defined} 3-값 enum |
이 3-값으로 고정. 새 access class는 FE-REG-ROUTE schema 변경 절차를 거칠 때만 추가 |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-OC-005 (§5.2 access field) |
project-decision | integration-defined semantics는 auth owner 결정에 의존(§7.8) |
| D4 | navigation guard는 UX hint일 뿐 authorization 아님; backend authorization이 최종 판단; session-required route는 AuthSessionPort state를 소비 |
guard=advisory 유지: backend가 authz를 강제하는 한. client-only 강제(백엔드 authz 부재)가 필요하면 별도 결정 필요(현재 근거 없음 → UNSUPPORTED) | raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008 (§7.8·§9.3·§13.2); RR-NAV-WEB-C1(useNavigate); raw/official-docs/react-router-official.md#REACT-ROUTER-C3(guard 미증명 — UX 링크 스타일만) |
project-decision | guard 우회 시 backend authz가 유일 방어선 — client guard를 보안 경계로 오인 금지 |
| D5 | route param·search를 application 호출 전 runtime validation; registry가 paramsSchema/searchSchema 참조 선언, 검증 엔진(Zod)은 위임 |
dynamic param/search 존재 시 validation(conditional field). static route는 schema 없음 | raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008 (§9.3), FE-D007(Zod, §5.2 conditional field) |
project-decision (delegated) | Zod 통합 형태(route wrapper vs effect)는 Declarative Mode에 loader가 없어 impl 미정 |
| D6 | unknown route → API 없이 not-found surface; NOT_FOUND(*, public) route를 registry에 포함 |
catch-all * route 상시 존재. API 응답 404는 별도 정규화(NOT_FOUND kind)로 error-classification branch 소유 |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008 (§9.3·§8.2, §5.2 NOT_FOUND row) |
project-decision | route-level 404 UX와 API 404 UX 일관성은 FE-OC-008와 조율 필요 |
| D7 | redirect loop 차단: navigation attempt당 automatic auth redirect ≤ 1, 동일 source→target pair 반복 금지 | 첫 guard redirect 1회 허용; 두 번째 동일 redirect → terminal auth-required/error surface(§7.8 second-401 terminal, §10.2 guard-record-then-act와 동형) |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-D008 (§9.3·§7.8·§10.2; FE-GATE-008 e2e invariant) |
project-decision | hop-count 상수·guard 자료구조는 문서 미명세 → UNSUPPORTED_IMPL_DECISION(§구현 가이드 5) |
| D8 | route registry가 route별 loadingSurface·errorSurface owner 선언; route error element와 React error boundary owner 중복 금지 |
route-level errorSurface는 lazy-chunk/route render 실패 소유; expected operational 실패는 normal async state로 반환(throw 금지) |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-OC-005 (§5.2·§9.3·§10.1) |
project-decision | boundary taxonomy는 FE-OC-015(render-recovery) 소유 — surface owner token 어휘 정합 필요 |
구현 가이드
모든 세부는
planned(frontend repository 미생성). 경로는 hub §4.6 planned directory blueprint + §5.1 registry owner map에서 도출된 anchor.
1. FE-REG-ROUTE route registry 모듈
Trace: D2 (
FE-OC-005,FE-REG-ROUTE) — hub §5.1(src/contracts/routes.js소유) + §5.2(minimum schema)에서 도출. D6·D8의 필드(NOT_FOUNDrow,loadingSurface/errorSurface)도 이 모듈이 담는다.
- UNSUPPORTED_IMPL_DECISION: 모듈의 JS 형태(frozen descriptor 배열 vs factory 함수) — 문서 미명세. trade-off: snapshot 테스트 용이성을 위해
Object.freeze된 route descriptor 배열 +routeId조회 헬퍼로 채택(임의 선택).- UNSUPPORTED_IMPL_DECISION: 3개 seed row 외 실제 route naming — 문서는
APP_HOME/SAMPLE_RESOURCE_LIST/NOT_FOUND만 제시. trade-off: 신규 route는UPPER_SNAKE_CASE규칙만 따르고 product route는 sample 제거 후 추가.
필드(§5.2 그대로, planned):
| Field | Required | Rule (hub §5.2) |
|---|---|---|
routeId |
yes | stable UPPER_SNAKE_CASE; rename은 breaking |
path |
yes | 중앙 literal; component 내부 literal 금지 |
paramsSchema |
conditional | dynamic param 있으면 runtime validation(D5) |
searchSchema |
conditional | query string을 application input으로 넘기기 전 validation(D5) |
access |
yes | public | session-required | integration-defined(D3) |
loadingSurface |
yes | route-level fallback owner(D8) |
errorSurface |
yes | route-level error owner(D8) |
chunkId |
generated | release manifest와 매핑(생성값만 보유; 매핑은 out-of-scope) |
Initial planned rows(§5.2): APP_HOME(/, public), SAMPLE_RESOURCE_LIST(/sample/resources, integration-defined), NOT_FOUND(*, public, no API retry).
2. Declarative Mode router 구성
Trace: D1 (
FE-D008,REACT-ROUTER-C1·C2·C4) — registry rows를<Routes>/<Route>트리로 렌더, nested route는<Outlet/>로 합성. router는 boot order 9단계(§4.5)에서 생성. anchor:src/presentation/app/,src/presentation/routes/(§4.6).
- UNSUPPORTED_IMPL_DECISION:
<BrowserRouter>컴포넌트 vs 다른 history 구성 — 문서 미명세. trade-off: Declarative Mode 표준인<BrowserRouter>+ registry 기반<Route>생성 함수 채택. base path는VITE_ROUTER_BASE_PATH(§5.4, default/) 소비.- UNSUPPORTED_IMPL_DECISION: registry→route-element 생성 함수 이름/시그니처 — 임의. trace 가능한 단일 함수로 두어 registry가 유일 SSOT임을 보장.
절차(planned): (1) registry 로드(§4.5 step 5) → (2) 각 row를 <Route path element access>로 매핑 → (3) 레이아웃 route는 <Outlet/>로 자식 중첩(REACT-ROUTER-C2) → (4) NOT_FOUND catch-all *는 마지막 → (5) <BrowserRouter basename=VITE_ROUTER_BASE_PATH>로 mount(§4.5 step 10).
3. Access 분류 + navigation guard (UX hint)
Trace: D3·D4 —
session-requiredroute는 raw/branch-notes/feature-frontend-auth-session-integration-contractFE-OC-010의AuthSessionPortstate를 application facade 경유로 소비(§7.8). guard가 미인증 시 auth-required surface 렌더 또는 programmatic redirect. guard≠authorization(§13.2). redirect 메커니즘 근거는RR-NAV-WEB-C1.
- UNSUPPORTED_IMPL_DECISION: guard를 컴포넌트 wrapper vs route element로 구현, 그리고
<Navigate>element vsuseNavigateeffect 중 무엇 — 문서상useNavigate만 근거 확보(RR-NAV-WEB-C1),<Navigate>는 미검증. trade-off: 우선 route wrapper +useNavigate(doc-grounded)로 구현하고<Navigate>채택은 별도 검증 전 보류.- UNSUPPORTED_IMPL_DECISION: guard 컴포넌트/훅 명명 및
integration-definedaccess의 정확한 소비 형태 — auth owner 결정에 의존. trade-off:integration-defined는 auth adapter가 접근 가부를 반환할 때까지 loading surface 유지.
RR-NAV-WEB-C1 (web 인용, reactrouter.com/start/declarative/navigating, 2026-07-19):
"This hook allows the programmer to navigate the user to a new page without the user interacting." 문서 예시 용례: "Logging them out after inactivity" — 즉 비상호작용 상황의 programmatic redirect가
useNavigate의 정당한 용도이며, guard redirect가 이에 해당.
access별 동작(planned): public=무조건 렌더 / session-required=session 있으면 렌더, 없으면 auth-required surface + (선택) 1회 redirect(D7) / integration-defined=auth adapter 판정까지 loading, 판정 후 렌더 or auth-required.
4. Param/Search validation 진입점
Trace: D5 (
FE-D008§9.3, §5.2 conditional field) — registry의paramsSchema/searchSchema는 참조만 담고, 실제 Zod 검증 엔진은 raw/branch-notes/feature-runtime-schema-validation-contractFE-OC-007가 소유. 검증은 application use case 호출 전에 수행.
- UNSUPPORTED_IMPL_DECISION: Declarative Mode에는 loader가 없어 검증을 어디서 실행할지(route-entry 훅 vs 컴포넌트 mount effect) 문서 미명세. trade-off: route-entry 훅에서 schema 참조를 조회→검증→실패 시 not-found/route error surface로 분기(임의 선택, loader 부재 대응).
- UNSUPPORTED_IMPL_DECISION: 검증 실패를
NOT_FOUND로 볼지VALIDATION_REJECTED로 볼지 — 정규화는FE-OC-008소유. trace: 잘못된 route param은 존재하지 않는 리소스로 보아 not-found surface가 default(§9.3 "unknown route" 연장), 최종 kind 매핑은 error-classification과 조율.
5. NOT_FOUND + redirect-loop 방지
Trace: D6·D7 (
FE-D008§9.3·§8.2·§7.8·§10.2,FE-GATE-008e2e invariant) —NOT_FOUNDcatch-all은 API 요청 없이 not-found surface. guard redirect는 navigation attempt당 ≤ 1이고 동일 source→target pair 반복 금지.
- UNSUPPORTED_IMPL_DECISION: source→target pair를 기록하는 guard 자료구조/키 형태와 max hop 상수 — 문서 미명세. trade-off: §10.2
CHUNK_RELOAD_GUARD패턴을 차용해(fromRouteId,toRouteId)키의 per-navigation guard를 두고 두 번째 동일 pair에서 redirect 중단(임의 설계, 문서 패턴 동형).
절차(planned): 첫 미인증 진입 → guard 기록 후 auth-required target으로 1회 redirect → 복귀 후 여전히 미인증이고 동일 pair면 redirect 대신 terminal auth-required surface(§7.8 second-401 terminal과 동형). unknown path → 즉시 NOT_FOUND surface, network 0건.
6. Loading/Error surface owner 선언
Trace: D8 (
FE-OC-005§5.2·§9.3·§10.1) — registry가 route별loadingSurface/errorSurfaceowner token을 선언. route error element와 React error boundary는 owner 중복 금지(§9.3). boundary taxonomy 자체는 raw/branch-notes/feature-frontend-render-recovery-boundary-contractFE-OC-015소유.
- UNSUPPORTED_IMPL_DECISION: surface owner token 어휘 — 문서 미명세. trade-off: §10.1 boundary 명칭(
boot shell/route boundary/feature boundary/async boundary)을 owner token으로 재사용해 render-recovery branch와 어휘 정합(임의 선택, 문서 표 차용).
원칙(planned): expected operational 실패(API 실패 등)는 normal async state로 반환하고 render boundary에 throw하지 않음(§10.1). route render/lazy-chunk 실패만 errorSurface가 처리. loadingSurface는 route-level fallback owner.
엣지·실패·의존
- 실패·엣지 경로:
- unknown route →
NOT_FOUNDsurface, API 요청 0건(§9.3) session-requiredroute + 미인증 → automatic redirect ≤ 1; 동일 source→target 재발 → terminal auth-required surface(loop 없음)(§7.8·§10.2·FE-GATE-008)- invalid route param/search → application 호출 전 validation 실패 → not-found/route error surface(§9.3·§5.2)
- lazy route chunk fetch 실패 →
CHUNK_LOAD_FAILURE, controlled reload once(§8.2·§10.2) — reload guard는 render-recovery 소유; 본 registry는chunkId만 매핑 - in-flight 요청 중 navigation abort →
REQUEST_ABORTED, error toast 금지(§8.2) — API client 소유; route는routeId+abortReason=navigation만 공급(§7.2) - route render throw →
RENDER_FAILURE(route boundary, §8.2·§10.1) — boundary는 render-recovery 소유; 본 registry는errorSurfaceowner 선언만
- unknown route →
- 다른 계약 의존:
- raw/branch-notes/feature-frontend-auth-session-integration-contract
FE-OC-010—AuthSessionPortsession state를 UX hint로 소비. 이 계약이 바뀌면 guard의 session 판정 방식 영향. - raw/branch-notes/feature-frontend-error-classification-boundary-contract
FE-OC-008—401→AUTH_REQUIRED,404→NOT_FOUND,RENDER_FAILURE정규화. route-level 404/auth UX의 kind 매핑을 여기서 consume. - raw/branch-notes/feature-frontend-render-recovery-boundary-contract
FE-OC-015— route/React error boundary taxonomy + reload-loop guard. surface owner token 어휘 정합 대상. - raw/branch-notes/feature-runtime-schema-validation-contract
FE-OC-007— param/search schema의 Zod 검증 엔진. - raw/branch-notes/feature-frontend-release-cache-rollback-contract
FE-OC-016—chunkId↔ release manifest 매핑. - raw/branch-notes/feature-frontend-contract-registry-governance
FE-OC-022—FE-REG-ROUTEsingle-owner + compatibility governance.
- raw/branch-notes/feature-frontend-auth-session-integration-contract
검증해야 할 주장
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
| route registry가 유일 SSOT — component에 literal route path 0건 | frontend 코드 미존재, registry 우회 가능성 | registry snapshot 테스트(FE-OC-005 min evidence) + literal-path 정적 검사(component에 route literal 금지) |
needs-confirmation |
| dynamic route param/search가 application 호출 전 검증됨 | Declarative Mode에 loader가 없어 검증 위치가 impl 의존 | invalid param fixture로 param validation deterministic 테스트(§20 measurable) | needs-confirmation |
| unknown route가 API 요청 0건으로 not-found surface 렌더 | 라우팅 setup에 따라 우발적 fetch 가능 | 404 테스트에서 network 호출 0건 assert(§9.3) | needs-confirmation |
| navigation guard가 navigation attempt당 automatic redirect ≤ 1, 동일 source→target 반복 없음 | guard 자료구조 미설계(UNSUPPORTED_IMPL_DECISION) |
redirect-loop e2e 테스트(FE-GATE-008 invariant: automatic auth redirect ≤ 1, pair 무반복) |
needs-confirmation |
session-required route가 AuthSessionPort state를 UX hint로만 사용, token lifecycle 미소유 |
위임 경계가 코드로 강제되는지 미확인 | session UX 테스트 + token-lifecycle import 금지 assert(§4.3 dependency rule) | needs-confirmation |
| route error element와 React error boundary owner가 중복되지 않음 | boundary가 render-recovery 소유라 경계 조율 필요 | route surface owner vs boundary ownership 테스트(render-recovery와 공동)(§9.3·§10.1) | needs-confirmation |
Declarative Mode <Routes>/<Route>/<Outlet>가 registry 트리를 렌더(framework/file-based convention 없이) |
라이브러리 API 정합성 미검증 | registry 기반 route 트리 component 렌더 테스트(REACT-ROUTER-C1·C2) |
needs-confirmation |
관심사 커버리지 (coverage-auditor 자동 생성 — 있을 때)
/coverage가 채우는 생성물이며 손으로 유지하지 않는다.
| 관심사 | 상태 | owner | 심각도 | 근거 |
|---|---|---|---|---|
TODO — /coverage 실행 전 |
missing | (없음) | 미평가 | TODO |
마주친 문제
없음 — scaffolding 단계
묶음 (이 branch에서 파생된 자료)
가져온 프로젝트 계약
| Ref | Owner | 요약 | Branch 적용 |
|---|---|---|---|
FE-GATE-008@1 |
raw/branch-notes/feature-frontend-test-taxonomy-contract | critical e2e 시나리오가 실패하면 merge·release 를 MUST 차단 | import 참조로 적용 |
FE-OC-008@1 |
raw/branch-notes/feature-frontend-error-classification-boundary-contract | 모든 failure는 stable frontend error kind로 MUST 정규화하고 raw body·stack을 UI에 노출하면 안 됨 | import 참조로 적용 |
FE-OC-015@1 |
raw/branch-notes/feature-frontend-render-recovery-boundary-contract | expected operational error와 render defect를 MUST 분리하고 reload loop를 금지 | import 참조로 적용 |
Sub-branches (세부 작업)
없음 — scaffolding 단계
오류 기록 (이 branch 작업 중 발생)
없음 — scaffolding 단계
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
없음 — scaffolding 단계
강의 (이 작업을 위해 학습한 강의)
없음 — scaffolding 단계
job-posting tie-ins (이 작업에서 파생된 글감)
없음 — scaffolding 단계
관련 일일 노트
없음 — scaffolding 단계
완료 후 정리
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경:
- wiki 추출 대상 (verified만,
wiki/projects/로만 추출):actually-implemented항목:locally-verified항목:prod-verified항목:
- 추출하지 않을 항목 (planned / documented-only / abandoned):