Files
llm-wiki/raw/branch-notes/feature-frontend-clean-architecture-layering-contract.md
T

26 KiB

title, source_type, status, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, branch, parent_branch, related_projects, governing_docs, tags, created, target_merge, status_label, contract_packet_sha256, imports, accepts_delegations
title source_type status id kind project work_item inherits refines overrides depends_on contract_packet branch parent_branch related_projects governing_docs tags created target_merge status_label contract_packet_sha256 imports accepts_delegations
branch / feature-frontend-clean-architecture-layering-contract branch-note raw BR-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-002 project-work-item ca-skeleton-frontend-operational-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-002
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-ARCHITECTURE-001@1
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-PORT-OWNERSHIP-001@1
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-COMPOSITION-ROOT-001@1
WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-001
1 feature-frontend-clean-architecture-layering-contract
ca-skeleton-frontend
ca-skeleton
raw/project-notes/ca-skeleton-frontend-operational-contract.md
branch
ca-skeleton
frontend
architecture
application
javascript
clean-architecture
2026-07-18 in-progress 1a7d904e9fe76e1aeb6ebd25fea852de7cc888232e96110e832f764d97e518ee
FE-OC-004@1
FE-OC-024@1
DELEG-FE-003@1
DELEG-FE-005@1

branch: feature-frontend-clean-architecture-layering-contract

Layer: raw/branch-notes/ — 단일 브랜치의 TODO·결정·진행 기록. 머지/종료 후 verified 결과는 /ingestwiki/projects/에 추출한다.

부모 (필수)

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 1
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: directory 책임·port owner·allowed import matrix가 문서와 fixture로 고정된다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-ARCHITECTURE-001@1 domain, application, presentation, adapters, bootstrap 책임을 분리한다 5-layer directory 책임과 allowed-import matrix에 적용 raw/project-notes/ca-skeleton-frontend-operational-contract
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-PORT-OWNERSHIP-001@1 output port interface는 application이 소유하고 adapter가 구현한다 port ownership matrix에 적용 raw/project-notes/ca-skeleton-frontend-operational-contract
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-COMPOSITION-ROOT-001@1 bootstrap을 단일 composition root로 두고 concrete adapter를 application에 주입한다 bootstrap boot order와 adapter injection 경계에 적용 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-002(domain <- application <- presentation 의존 방향 + application-owned output port를 MUST 지킴)를 구현 착수 가능한 상세 명세로 내린다. 구체적으로 세 가지 불변식을 고정한다: FE-D009(domain/application/presentation/adapters/bootstrap 5-layer 책임 분리), FE-D010(output port interface는 application 소유, adapter가 구현), FE-D011(단일 composition root bootstrap이 concrete adapter를 주입). 산출물은 §20 Measurable completion이 요구하는 directory responsibility + port owner + allowed import matrix 세 표다. frontend repository가 아직 없으므로 이 브랜치의 모든 항목은 planned 등급이며, 착수 시점의 blueprint 근거는 hub §4(§4.2 component responsibility / §4.3 dependency matrix / §4.4 port ownership / §4.5 composition root / §4.6 directory blueprint)다.

  • 이슈:
  • PR:

범위

포함 범위

  • domain / application / presentation / adapters / bootstrap 5-layer 책임 경계 정의 (hub §4.2) — FE-D009
  • planned directory blueprint 확정 (hub §4.6) — FE-D009
  • application-owned output port ownership matrix — port 정의 owner·consumer·I/O·failure vocabulary·"port는 application이 소유한다" 규칙 (hub §4.4) — FE-D010
  • allowed / forbidden import matrix 규칙 정의 (hub §4.3) — FE-D009 + FE-D010
  • 단일 composition root(bootstrap) injection 원칙 + boot order (hub §4.5) — FE-D011
  • FE-OC-002의 minimum evidence인 dependency rule report 산출물 정의

제외 범위

의도적으로 제외. 인접 계약은 다른 owner 브랜치가 소유하며, 여기서 detail을 쓰지 않고 그 브랜치를 가리킨다 (CLAUDE.md §15.5 R3 OUT_OF_BRANCH_SCOPE 방지).

근거 (필수, 최소 1개+)

Source 정당화하는 결정
raw/project-notes/ca-skeleton-frontend-operational-contract FE-OC-002 owner 계약 + FE-D009/FE-D010/FE-D011 결정 register + §4 architecture blueprint의 SSOT (본 브랜치의 모든 planned 경로·규칙 근거)
raw/project-notes/ca-skeleton-operational-contract FE-D009/FE-D010/FE-D011의 Clean Architecture 선례 — backend 운영계약의 layer 분리·"application use case는 output port에만 의존"·composition root 단일화(app-bootstrap) 철학을 frontend에 적용
raw/official-docs/react-ui-library-official import matrix의 React 경계 규칙REACT-UI-C1(React 앱은 컴포넌트 단위 UI 구성) → React는 presentation 전용, domain/application의 React import 금지

TODO

  • hub §4.2 component responsibility + §4.6 directory blueprint를 실제 폴더/모듈 책임표로 확정 — 등급: planned
  • hub §4.4 port ownership matrix를 application/ports 인터페이스 스텁 목록으로 표현 (정의 owner=application) — 등급: planned
  • hub §4.3 allowed/forbidden import matrix를 machine-readable 규칙 사양으로 문서화 (강제는 enforcement 브랜치) — 등급: planned
  • hub §4.5 composition root boot order(10단계) + adapter injection 지점 명세 — 등급: planned
  • FE-OC-002 minimum evidence인 dependency rule report 산출물 형식 정의 — 등급: planned

진행 중 메모

/branch-spec로 채움 (2026-07-19). frontend 코드 부재 → 전 항목 planned. 근거 SSOT = frontend hub §4 + backend CA 선례 + REACT-UI-C1. 웹 리서치 불필요 (hub가 이미 충분).

결정 사항

각 결정의 근거는 아래 Decision Evidence Map과 1:1. 대안과 함께 기록.

  • 2026-07-19: 5-layer 책임 분리 (domain/application/presentation/adapters/bootstrap) 채택 (FE-D009) / 이유: framework-neutral domain 보호 + 의존 방향을 domain <- application <- presentation 단방향으로 강제 / 검토한 대안: flat structure, Feature-Sliced Design(FSD) / 근거: backend ca-skeleton 운영계약 CA 철학 raw/project-notes/ca-skeleton-operational-contract
  • 2026-07-19: output port interface는 application 소유, adapter가 구현 (FE-D010) / 이유: dependency inversion — application이 concrete adapter 이름을 모르게 함 / 검토한 대안: adapter가 인터페이스 소유(전통적 layered) / 근거: project decision + backend port 소유 선례
  • 2026-07-19: 단일 composition root(bootstrap)가 concrete adapter 주입 (FE-D011) / 이유: owner ambiguity 제거, 조립 지점 1개로 고정 / 검토한 대안: framework DI container / 근거: project decision + backend app-bootstrap 선례
  • 2026-07-19: 선택된 UI framework(React, hub FE-D004)를 presentation에 가둠 (import matrix 규칙) / 이유: React는 UI 구성 관심사이므로 domain/application에 유입 금지 / 검토한 대안: domain/application에 rendering 혼입 / 근거: REACT-UI-C1
  • 2026-07-19: import 규칙 정의=본 브랜치, 강제=enforcement 브랜치 위임 (범위 경계) / 이유: 규칙 정의와 lint 강제 관심사 분리 / 근거: §20 분해표 + §4.3 Planned enforcement 컬럼

결정-근거 매핑

각 결정과 raw source claim의 연결. Decision ID는 이 노트 안에서 안정적으로 유지. Supporting Claims는 backtick 포인터(raw/<cat>/<slug>.md#<CLAIM>) 또는 hub FE-D### / live wikilink.

Decision ID Decision 선택 조건 (언제 이 결정 / 언제 대안) Supporting Claims Evidence Strength Open Risk
D1 5-layer 책임 분리 domain/application/presentation/adapters/bootstrap (FE-D009 / FE-OC-002) sample slice가 경계의 값을 증명하는 한 default 유지; sample이 불필요한 ceremony임을 증명하거나 FSD fork 승인 시 flat/FSD로 전환 프로젝트 결정 FE-D009; backend CA 선례 raw/project-notes/ca-skeleton-operational-contract (domain이 CA 심장, 모든 의존 화살표가 domain으로 수렴) project-decision 코드 없음 — 5-layer 경계가 실제로 값을 하는지 sample slice(FE-OC-024) 전까지 미검증 (over-engineering 위험)
D2 output port interface는 application 소유, adapter가 구현 (FE-D010 / FE-OC-002) default 유지; port가 domain invariant 자체를 표현해야 하는 concrete case 발생 시 그 port를 domain으로 이동 프로젝트 결정 FE-D010 (dependency inversion); backend "application use case는 output port에만 의존" 선례 raw/project-notes/ca-skeleton-operational-contract project-decision port granularity/개수 미검증 — 잘못된 분할 시 adapter 표면 폭증
D3 단일 composition root(bootstrap)가 concrete adapter 주입 (FE-D011 / FE-OC-002·FE-OC-004) hand-wired DI default 유지; framework DI container 도입 시 재검토 프로젝트 결정 FE-D011; backend app-bootstrap composition-root 선례 raw/project-notes/ca-skeleton-operational-contract project-decision boot order(§4.5 10단계) 결합 — 단계 순서 변경이 여러 adapter 조립에 영향
D4 선택된 UI framework(React)를 presentation에 가둠 — import matrix의 React 금지 row (FE-OC-002; framework 선택은 hub FE-D004, async-ui 소유) React가 UI framework인 동안 유지; native/custom-element 또는 다른 framework로 fork(hub FE-D004 revisit) 시 matrix의 React 금지 심볼만 갱신 raw/official-docs/react-ui-library-official.md#REACT-UI-C1; hub §4.3 dependency matrix official-doc framework 교체 시 domain/application 격리 규칙 자체는 불변이나 구체 금지 심볼 목록이 바뀜
D5 import 규칙 정의=본 브랜치, 강제=enforcement 브랜치 위임 (범위 경계) (FE-OC-002 contributes) 규칙 정의(여기)와 lint 강제(enforcement 브랜치) 분리 유지; 두 관심사 병합 승인 시 재검토 §20 분해표 (feature-frontend-architecture-enforcement-lint-contract Primary=—, contributes FE-OC-002); hub §4.3 Planned enforcement 컬럼 project-decision 규칙/강제 drift — matrix 변경이 enforcement fixture 미갱신 시 규칙이 무력화

구현 가이드

planned blueprint. 경로/책임은 hub §4.2/§4.3/§4.4/§4.5/§4.6에서 도출(근거 있음). frontend 코드는 존재하지 않으므로 전 항목 planned. 3-rule (R1 Trace / R2 UNSUPPORTED_IMPL_DECISION / R3 OUT_OF_BRANCH_SCOPE 정제) 준수.

1. Layer 책임 · directory 책임 map

Trace: D1 (FE-D009) + FE-OC-002; hub §4.2 component responsibility + §4.6 directory blueprint.

  • UNSUPPORTED_IMPL_DECISION: §4.6 blueprint보다 깊은 하위 파일/모듈 명명(예: domain/models/* 개별 파일명, application/use-cases/* 클래스명)은 hub가 권고하지 않음 → 구현 repository 생성 시 확정. trade-off: blueprint 수준(폴더 책임)까지만 grounded, 그 이하 명명은 첫 sample slice에서 정한다.

아래 표에서 본 브랜치가 더하는 것은 planned path 열 뿐이다. Owns·Consumes·MUST NOT own 의 owner 는 raw/project-notes/ca-skeleton-frontend-operational-contract §4.2 이므로 여기서 값을 고치지 않는다 — 고쳐야 하면 §4.2 를 고치고 이 표를 따라 갱신한다.

Layer (planned path — 본 브랜치 소유) Owns (§4.2) Consumes (§4.2) MUST NOT own (§4.2)
src/domain/ framework-neutral model, value semantics, pure policy standard JavaScript only React, router, Query, fetch, storage, telemetry
src/application/ use case, input/output port, QueryCachePort policy, orchestration, view-model contract domain concrete adapter, browser global, React component
src/presentation/ page/component, user event, view state rendering application public API raw API DTO, fetch, storage key, telemetry transport
src/adapters/http · storage · telemetry · query-cache · auth · release application output port 구현, envelope/schema/error·serialization·redaction·key mapping application port + 해당 browser API use-case policy, component rendering
src/bootstrap/ (main.jsx, composition-root.js, load-runtime-config.js) config load, adapter 생성, DI, React mount 모든 runtime module business rule, page-specific orchestration

src/contracts/ 8개 registry 파일(routes.jsrelease-tokens.js)은 각 registry owner 브랜치가 채운다 — 본 브랜치는 디렉토리 위치만 blueprint로 고정 (§4.6). registry schema 내용은 governance/owner 브랜치 소유 (R3).

2. forbidden import matrix (규칙 정의)

Trace: D1 (FE-D009) + D2 (FE-D010) + D4 (REACT-UI-C1) + FE-OC-002; hub §4.3 dependency matrix.

  • UNSUPPORTED_IMPL_DECISION: Planned enforcement 컬럼의 도구(dependency-cruiser + ESLint restricted imports)는 §4.3에 명시되어 grounded이나, 구체 rule config/glob은 본 브랜치가 정하지 않음 → enforcement 브랜치 소유 (D5, R3). trade-off: 본 표는 "무엇이 금지인가"(machine-readable 규칙)까지만, "어떤 lint 설정으로 잡는가"는 위임.

matrix 본문은 raw/project-notes/ca-skeleton-frontend-operational-contract §4.3 소유다 — 여기에 옮겨 적지 않는다. 이전 판은 §4.3 의 6행 중 5행만 복제해 test fixtures 행과 "May import 열은 예시(illustrative)이고 MUST NOT 열이 규범(normative)" 이라는 §4.3 의 경고 문단을 통째로 빠뜨렸고, 그 사본만 읽는 구현자는 §4.3 이 명시적으로 경고한 allow-only 오독(= FE-D022 가 의무화한 test stack 이 전부 금지되는 해석)에 그대로 빠진다. test fixtures 행의 enforcement 는 raw/branch-notes/feature-frontend-architecture-enforcement-lint-contract 가 소유한다.

Normative 요약: application -> adapters concrete import는 MUST NOT; output port는 application이 MUST 소유; adapter는 application을 모름; presentation은 raw envelope를 직접 다루지 않음; bootstrap만 concrete adapter 조립. 이 규칙의 강제(fixture pass/fail)는 D5(범위 경계)에 따라 위임한다 → raw/branch-notes/feature-frontend-architecture-enforcement-lint-contract.

3. Port ownership + composition-root wiring

Trace: D2 (FE-D010) + D3 (FE-D011) + FE-OC-002·FE-OC-004; hub §4.4 port ownership matrix + §4.5 composition root.

  • UNSUPPORTED_IMPL_DECISION: §4.4의 I/O·failure vocabulary 컬럼 이상의 concrete method 시그니처는 각 adapter/port owner 브랜치 소유 (R3) — 본 브랜치는 "port 정의는 application, 구현은 adapter, 조립은 bootstrap"이라는 ownership 규칙만 명세. AuthSessionPort의 opaque-credential shape는 auth owner가 정함(§4.4 주석).

Port 정의 owner = application (전부). 구현 위치 = adapters/*. 정의된 port(§4.4): ResourceQueryPort·ResourceCommandPort(→http), QueryCachePort(→query-cache), AuthSessionPort(→외부 auth), StoragePort(→storage), TelemetryPort(→telemetry), ClockPort(→system), ReleaseInfoPort(→release). 각 port의 concrete impl은 해당 owner 브랜치 (Out of scope 참조).

Composition root boot order (§4.5, MUST): (1) build identity → (2) runtime config fetch → (3) config envelope·schema·compatibility 검증 → (4) release manifest 정합성 → (5) registry snapshot load → (6) auth adapter 주입 → (7) http/storage/telemetry/query-cache adapter 생성 → (8) application facade 생성 → (9) router 생성 → (10) React root mount. 2~4단계 실패 시 product route를 mount하지 않고 boot error shell만 렌더; telemetry adapter(7) 생성 실패는 console-safe fallback으로 진행. (config 검증 내용=env-config 브랜치, boot error shell 렌더=render-recovery 브랜치 — R3.)

4. Dependency rule report 산출물

Trace: D5 + FE-OC-002 minimum evidence("dependency rule report", hub §2.1).

  • UNSUPPORTED_IMPL_DECISION: report의 정확한 파일 형식(JSON/HTML)·CI 배치는 미결 → enforcement + test-taxonomy 브랜치와 조율. trade-off: 본 브랜치는 report가 검증해야 할 명제(allowed pass / forbidden fail / domain framework-free)만 정의, 형식은 산출 브랜치 소유.

report가 assert해야 할 명제: (a) allowed import fixture green, (b) forbidden import fixture red, (c) domain의 프레임워크/브라우저 전역 import 0건, (d) concrete adapter 생성이 bootstrap 밖에 없음, (e) output port 정의가 application에만 존재. 생성 주체·artifact 경로는 enforcement/test-taxonomy 브랜치 (R3, FE-OC-020).

엣지·실패·의존

검증해야 할 주장

Claim Why uncertain How to verify Status
domain 모듈이 프레임워크/브라우저 전역을 0건 import한다 코드 없음 — 규칙만 존재 dependency graph snapshot + forbidden-import fixture (enforcement 브랜치 산출) needs-confirmation
application이 concrete adapter를 직접 import하지 않는다 위와 동일 allowed/forbidden import fixture (allowed pass / forbidden fail) needs-confirmation
composition root(bootstrap)만 concrete adapter를 생성한다 위와 동일 grep + composition-root review — adapter 생성이 bootstrap 밖에 없음 needs-confirmation
output port 정의는 application에, 구현은 adapters/*에 위치한다 위와 동일 directory 검사 + import graph snapshot needs-confirmation
5-layer 분리가 sample slice에서 실제로 경계 값을 한다 (over-engineering 아님) hub FE-D009 revisit trigger — 미검증 sample-feature-slice fixture(FE-OC-024)로 경계가 값을 증명 / 아니면 재검토 needs-confirmation
이 import matrix가 dependency-cruiser + ESLint로 실제 강제 가능하다 도구 미도입 enforcement 브랜치의 allowed/forbidden fixture pass/fail (dependency rule report) needs-confirmation

관심사 커버리지 (coverage-auditor 자동 생성 — 있을 때)

/coverage가 채우는 생성물이며 손으로 유지하지 않는다.

관심사 상태 owner 심각도 근거
TODO — /coverage 실행 전 missing (없음) 미평가 TODO

마주친 문제

없음 — scaffolding/spec 단계 (frontend 코드 부재).

묶음 (이 branch에서 파생된 자료)

수신한 위임

Delegation Ref From Concern Status
DELEG-FE-003@1 raw/branch-notes/feature-frontend-architecture-enforcement-lint-contract fe.deleg.composition-root-review accepted
DELEG-FE-005@1 raw/branch-notes/feature-api-client-response-envelope-contract fe.deleg.injectable-random accepted

가져온 프로젝트 계약

Ref Owner 요약 Branch 적용
FE-OC-004@1 raw/branch-notes/feature-frontend-env-runtime-config-contract build-time, runtime-public, secret config를 MUST 분리하고 boot 전에 runtime config를 검증 import 참조로 적용
FE-OC-024@1 raw/branch-notes/feature-sample-feature-slice-contract-fixture sample은 contract fixture이며 production feature가 의존하면 안 됨 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):