Files
llm-wiki/docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/process/pre-review-source.md
T

39 KiB

title, source_type, status, confidence, tags, related_projects, last_reviewed, diagrams, architecture_review, status_label
title source_type status confidence tags related_projects last_reviewed diagrams architecture_review status_label
CA Skeleton Frontend Operational Contract project-note draft unknown
project-note
ca-skeleton
frontend
clean-architecture
ca-skeleton-frontend
2026-07-18
active

CA Skeleton Frontend Operational Contract

Layer: raw/project-notes/ (primary, hub) → /ingest 후 검증된 사실은 wiki/projects/ 로 추출. 본 문서는 프로젝트의 최상위 hub. 프로젝트 전체 컨텍스트 / 문제 정의 / 시스템 아키텍처 / 핵심 시퀀스가 여기에 집중. 모든 branch / errors / interviews / lectures / job-postings / blog-topics / sources 가 본 문서로 upward link. status_label: active | paused | completed | archived

1. 프로젝트 개요 / Overview

외부인이 1분 안에 "이게 뭐 하는 프로젝트인가" 이해할 수 있어야 함.

  • 한 줄 요약: 도메인/비즈니스 로직을 제거한 Clean Architecture 프론트엔드 skeleton. 어떤 화면·기능을 붙여도 (1) 같은 방식으로 백엔드 API 를 호출하고, (2) 같은 방식으로 실패를 분류·표시하고, (3) 같은 계층 의존 규칙을 강제하고, (4) 같은 계약 테스트로 깨짐을 감지하는 React SPA 뼈대. 백엔드 raw/project-notes/ca-skeleton-operational-contract 의 프론트엔드 대응물이며, 개인 학습·포트폴리오·재사용 starter 로 쓴다.
  • 기간: 2026-07-18 ~ in-progress (기획 단계 — 코드 미착수, /branch-spec 로 계약별 상세 설계 예정)
  • 현재 상태: active
  • 나의 역할 / Role: 설계자 / 구현자 (개인 프로젝트)
  • 저장소 / Repo:
    • 메인: <미생성 — Vite + React + Tailwind SPA 레포 예정> · NO_GROUND_TRUTH: 아직 코드 레포가 없어 본 hub 의 모든 구현 주장은 planned 등급이다(§9). actually-implemented 승격은 레포 생성 후 src/ grep 으로만.
    • 부속: —

2. 문제 정의 / Problem

추상화 금지. 구체 시나리오·수치로.

2.1 현재 상태의 문제

  • 문제 1: 도메인 없는 React 프로젝트를 새로 시작할 때마다 API 호출 래퍼·에러 분류·로딩/빈/에러 UI 상태·응답 검증을 매번 다르게 재구현한다. 결과적으로 화면마다 실패 처리가 제각각이라, "이 화면은 500 을 어떻게 보여주지?"를 화면 수만큼 되묻게 된다.
  • 문제 2: JS(무타입) 환경에서 백엔드 응답 스키마가 바뀌면 컴파일타임이 아니라 런타임에서야 깨짐이 드러난다. 경계에서 검증 계약이 없으면 undefined 접근 에러가 UI 트리 깊숙한 곳에서 터져, 원인이 API 계약 변경임을 추적하기 어렵다.
  • 문제 3: "Clean Architecture"를 표방해도 강제 장치가 없으면 presentation 컴포넌트가 API DTO 를 직접 만지고 의존 방향이 역전된다(백엔드의 ArchUnit 대응물이 프론트엔드엔 부재). 리뷰어의 눈에만 의존하면 시간이 지나며 반드시 새어나간다.

2.2 왜 지금 해결해야 하는가

  • 트리거 (왜 지금): 백엔드 raw/project-notes/ca-skeleton-operational-contract 운영 계약을 구축 완료했다. 같은 "도메인 제거 + 운영 계약 우선" 철학을 프론트엔드에 대칭 적용할 시점 — 백엔드가 응답 envelope·error category·trace 를 계약화했으므로 프론트엔드도 그 계약의 소비 규약을 고정해야 짝이 맞는다.
  • 비용 (해결 안 했을 때 손실): 계약 없이 화면부터 만들면, 나중에 횡단 관심사(에러 분류·로깅·검증·접근성·성능 예산)를 소급 적용하는 비용이 화면 수에 비례해 폭증한다. 특히 무타입 JS 라 런타임 깨짐이 QA/운영 단계로 밀린다.
  • 기회 (해결 시 가치): 도메인 없는 재사용 skeleton 1벌 → 이후 모든 프론트엔드 프로젝트의 출발점 + 면접/포트폴리오에서 "계층·계약·강제 장치를 어떻게 설계했는가"를 증거로 말할 수 있는 자산.

2.3 성공 기준 / Success criteria

측정 가능해야 함. "잘 동작한다" 같은 모호 표현 금지.

아래 임계 수치는 초기 기본값(default) 이며, 각 계약 branch(/branch-spec)에서 측정·조정한다. "잘 동작한다" 류 추상 표현을 쓰지 않는 것이 목적.

  • 기준 1 (계약 관통): 도메인 없는 sample feature slice 화면이 api-client → zod 검증 → error boundary → async 4-state → CA 의존 규칙을 모두 관통하고, 계약 위반 시 실패하는 contract test 가 CI 에서 green.
  • 기준 2 (의존 규칙 강제): CA 계층 의존 규칙 lint(ESLint boundaries / dependency-cruiser) 위반 0건. presentation → infrastructure 직접 의존 등 역방향 import 발생 시 빌드 실패.
  • 기준 3 (4-state 강제): 모든 async 화면 표면이 loading / empty / error / success 4상태를 렌더. sample slice 에 4상태 각각의 component test(RTL) 존재.
  • 기준 4 (성능 예산): 프로덕션 초기 JS 번들 < 200KB gzip(default, route-level code splitting 후), web-vitals LCP < 2.5s · CLS < 0.1 · INP < 200ms 임계를 CI 게이트가 검사.
  • 기준 5 (재사용성): 새 화면을 만들 때 개발자가 API 에러/로딩/검증을 재구현하지 않고 계약 훅·컴포넌트(useApiQuery, <AsyncBoundary>, apiClient)를 재사용 — sample slice 복제로 새 화면 골격이 나옴.

3. 시스템 아키텍처 / System architecture

필수 섹션. 아키텍처 다이어그램이 없는 project-note 는 hub 역할을 못 함.

Diagram tool 선택 — 엄격한 분리

다이어그램 종류 도구 이유
시스템 아키텍처 / 컴포넌트 구성도 / 배포 토폴로지 / 데이터 흐름 (정적 구조) draw.io XML (.drawio 또는 .drawio.svg) 자유 배치 / 시각적 그룹화 / 신뢰 경계 / 색상 코딩 / Obsidian draw.io 플러그인 native 편집
시퀀스 다이어그램 Mermaid sequenceDiagram 텍스트 기반·git diff 친화, 시간축 표현에 최적
ER 다이어그램 (데이터 모델, 선택) Mermaid erDiagram 텍스트 기반·관계 카디널리티 표기 직관적
작은 결정 트리 / 짧은 플로우차트 Mermaid flowchart 도 허용 (작은 규모 한정) 시퀀스가 아닌 단순 분기

금지:

  • 시스템 아키텍처를 Mermaid graph TD/graph LR 로 작성 — 시각 표현력 부족, draw.io 사용 의무
  • 시퀀스 흐름을 draw.io 로 작성 — 시간축 표현 불편, Mermaid 사용 의무

Diagram 컨퍼런스급 표준 (필수 정독)

rules/diagram-standards 에서 컨퍼런스급(Toss SLASH / Kakao if(dev) / Naver DEVIEW 수준) 다이어그램 표준 v2 (minimalist-first) 를 정의한다. 본 template 본문에 별도 기준을 두지 않는다 — 항상 rules/diagram-standards.md 를 정독.

핵심 원칙: "적을수록 좋다" (Less is more). 정보를 다이어그램에 몰아넣으면 청중이 어디부터 봐야 할지 모른다.

v2 의 요약 (전체는 rules 정독):

  • 요소 수 상한 (HARD): Vertex ≤ 10 / Edge ≤ 8 / Callout ≤ 1 / Boundary group ≤ 3 / Legend 항목 ≤ 6 / 색상 ≤ 4
  • 박스 라벨 ≤ 2줄, 화살표 라벨 ≤ 5단어
  • 80% 회색/흑백 + 강조색 ≤ 2 (color salad 금지)
  • Boundary 는 정보 있을 때만 (장식용 boundary 금지)
  • Legend 는 표준 컨벤션이면 생략 (점선=외부 / cylinder=DB / 실선=동기 / 점선=비동기 는 legend 불필요)
  • Callout 1개 (있을 때만) — 비자명한 함정·결정에만
  • 출처 wikilink 는 본문/캡션에, 다이어그램 안에 박지 말 것
  • 스케일 어노테이션 (QPS/latency) 은 다이어그램의 질문이 성능 일 때만
  • 5초 룰 + 30초 룰 통과

8항 self-check checklist (rules/diagram-standards §14) 를 모두 ✓ 해야 컨퍼런스 발표 가능 수준. 1개라도 미달 → 분할 또는 단순화.

wiki-diagram-reviewer agent 가 위 기준으로 .drawio XML 을 grep-카운트 후 0~100 점수 부여, ≥95 PASS.

3.1 아키텍처 다이어그램 (draw.io XML)

컴포넌트 구성도. 저장 경로: raw/diagrams/<project-slug>/ 하위에 .drawio 또는 .drawio.svg 형식으로 저장. Obsidian draw.io 플러그인으로 더블클릭 편집.

파일 명명 규약: architecture-{viewpoint}-YYYY-MM-DD.drawio.svg 예: architecture-overview-2026-05-25.drawio.svg, architecture-deployment-2026-05-25.drawio.svg, architecture-data-flow-2026-05-25.drawio.svg

임베드 작성 방법: 아래 code block 형식을 참고해 실제 파일명을 채워 wikilink 작성. placeholder 그대로 두지 말 것 — Obsidian이 placeholder를 파일명으로 채택해 root에 orphan 파일을 생성함.

실제 사용 예 (drawio 파일 생성 후 placeholder 부분을 실제 값으로 치환):
![[raw/diagrams/my-project/architecture-overview-2026-05-25.drawio.svg]]

needs-diagram (DIAGRAM_PENDING_USER) — 아키텍처 .drawio/project-spec 가 자동 생성할 수 없다. 아래 대상 파일을 사용자가 직접 작성한 뒤, 백틱을 풀어 활성 임베드(![[...]])로 바꾼다. 그때까지는 inline code span 이라 구조 린터의 BROKEN_LINK 를 발생시키지 않는다. 이 항목은 readiness 게이트에서 Blocking 이 아니라 Should-fix 로 취급되어 판정이 Ready-pending-user 가 된다.

작성 대상 (권장 viewpoint 2개, 저장 경로 raw/diagrams/ca-skeleton-frontend/):

  • ![[raw/diagrams/ca-skeleton-frontend/architecture-overview-2026-07-18.drawio.svg]] — CA 계층(presentation → application → domain, adapters 는 바깥) + 백엔드 API 신뢰 경계 + cross-cutting(error boundary / observability / config). 화살표는 의존 방향(안쪽을 향함)을 보여준다.
  • ![[raw/diagrams/ca-skeleton-frontend/architecture-deployment-2026-07-18.drawio.svg]] — 정적 호스팅(CDN/오브젝트 스토리지) → 브라우저 SPA → 백엔드 API 토폴로지 (서버 런타임 없음).

작성 후: wiki-diagram-reviewer 로 ≥95 점 확인(게이트가 판정 못 하는 권고 단계rules/project-readiness-gate.md R2 ≥95 주). 이후 frontmatter diagrams: 배열에 두 파일 등재 + architecture_review: 날짜 기입.

다이어그램 작성 요약 (v2 minimalist, 상세는 rules/diagram-standards 정독):

  • 컴포넌트 라벨: 시스템 이름 (Bold 1줄) + 핵심 한 줄 (Stack OR 역할, 둘 중 하나만). 절대 ≥3 줄 금지. 예: **User Service** / Spring Boot 3.4 · :8080 (2줄)
  • 화살표 라벨: <step?> <verb/protocol> <object> — 5단어 이내 예: ① GET /, proxy_pass :8080, Kafka publish user.signed-up
  • 외부 시스템: 점선 (#D0D7DE) + fill #F6F8FA. Legend 불필요 (표준 컨벤션)
  • Boundary: Trust / Network / External — 정보 있을 때만. 모든 컴포넌트를 boundary 1개 안에 넣지 말 것 (정보 0)
  • 색상 ≤ 4 — 80% 회색 + 강조 ≤ 2 (blue / orange 한 family씩) + (선택) warning red callout
  • Legend 생략 가능 — 점선=외부 / cylinder=DB / 실선=동기 같은 표준 컨벤션이면 legend 불필요. 비표준 색·기호 있을 때만 ≤6 항목 legend.
  • 데이터 모델 카디널리티 는 ER 다이어그램 (Mermaid erDiagram)에서만. 아키텍처 다이어그램의 화살표에 1..N 같은 cardinality 박지 말 것.

3.2 컴포넌트 책임 분담

다이어그램의 각 컴포넌트가 정확히 무엇을 책임지는지 표로.

컴포넌트 = Clean Architecture 계층. 의존 방향은 항상 바깥→안(presentation → application → domain). adapters 는 domain 이 정의한 port 를 구현해 바깥에서 주입된다. 이 방향을 feature-frontend-architecture-enforcement-lint-contract branch 가 lint 로 강제한다.

컴포넌트 (계층) 역할 기술 스택 의존하는 외부
presentation (components / pages) UI 렌더 · 사용자 입력 · view-model 만 소비 (raw API DTO 직접 접근 금지) React 19 + Tailwind (하위 계층만)
application (hooks / use-cases) 화면 로직 · 상태 오케스트레이션 · use-case 훅 React hooks + TanStack Query adapters port (인터페이스)
domain (models / policies) 도메인 제거 skeleton 이라 최소 — view-model 스키마 · 불변식 · 순수 함수 순수 JS + zod schema 없음 (가장 안쪽, 의존 0)
adapters/infrastructure (api-client / storage / logger) HTTP client · 응답 envelope 파싱 · zod 검증 · storage · 로깅 sink fetch + zod + TanStack Query Backend API · 브라우저 storage
cross-cutting (error-boundary / observability / config) 에러 경계 · 구조화 로깅 · env config · trace 전파 React ErrorBoundary + logger Backend(trace) · error sink

3.3 외부 의존성 / External dependencies

외부 시스템 용도 통신 방식 장애 시 영향 (degrade / fail / fallback)
Backend API 데이터 read/write (인증 자체는 위임 — 아래) REST/JSON, structured envelope ({success,data,meta} / {success:false,error}) async 4-state 의 error 로 degrade + TanStack Query 가 retryable 만 backoff 재시도
브라우저 런타임 실행 환경 (fetch / history / storage) Web API 미지원 API 는 feature-detect + fallback, 앱 셸은 유지
(선택) 에러 트래킹 sink 관측 (feature-frontend-observability-logging-trace-contract) HTTPS, best-effort async fail 시 콘솔 fallback, 화면 영향 0

인증 경계 주의: 토큰 획득/저장/refresh 는 본 skeleton 범위 밖 → raw/project-notes/keycloak-patterns-overview 로 위임. 본 skeleton 은 "이미 인증된 요청" 을 전제로 API 호출 계약만 다룬다(§7 보안 참조).

3.4 배포 다이어그램 / Deployment (선택)

운영 환경 토폴로지가 비자명하면 별도 draw.io.

실제 사용 예 (placeholder 치환 후 사용):
![[raw/diagrams/my-project/architecture-deployment-2026-05-25.drawio.svg]]

4. 핵심 시퀀스 / Key sequences

필수 섹션. 최소 1개의 주요 user flow 를 Mermaid sequence diagram 으로. happy path + 주요 error path 함께.

4.1 인증된 API 호출 + 응답 검증 + 에러 정규화 (핵심 계약 흐름)

시나리오: 이미 인증된 사용자가 화면에 진입해 백엔드 데이터를 읽는다. api-client 가 응답 envelope 을 파싱하고 zod 로 검증한 뒤, 성공/스키마위반/envelope에러를 각각 정규화해 async 4-state 로 표시한다. 이 흐름이 skeleton 의 대다수 계약(api-client · runtime 검증 · error 분류 · async UI state)을 관통한다.

sequenceDiagram
    autonumber
    actor User
    participant UI as Presentation (React)
    participant Hook as Application (use-case hook)
    participant Q as TanStack Query
    participant Client as api-client (adapter)
    participant Zod as zod schema
    participant API as Backend API

    User->>UI: 화면 진입 / 액션
    UI->>Hook: useResource()
    Hook->>Q: useQuery(key, fetcher)
    Q->>Client: GET /api/v1/resource
    Client->>API: HTTP GET (traceparent 전파)
    alt 200 OK
        API-->>Client: {success:true, data, meta}
        Client->>Zod: schema.parse(data)
        alt 스키마 유효
            Zod-->>Client: 검증된 model
            Client-->>Q: model
            Q-->>Hook: {data, isLoading:false}
            Hook-->>UI: view-model
            UI-->>User: success 상태 렌더
        else 스키마 위반 (SCHEMA_MISMATCH)
            Zod-->>Client: ZodError
            Client-->>Q: throw ContractError(non-retryable)
            Q-->>Hook: {error}
            Hook-->>UI: error 상태
            UI-->>User: 안전 메시지 (원본/스택 미노출)
        end
    else 4xx / 5xx (envelope error)
        API-->>Client: {success:false, error:{code,category,retryable}}
        Client-->>Q: throw ApiError(category)
        Q-->>Q: retryable=true 면 exponential backoff 재시도
        Q-->>Hook: {error}
        Hook-->>UI: error 상태 (category 별 분기)
        UI-->>User: error 상태 렌더 (retry 버튼 등)
    end

시퀀스 작성 표준 (필수 준수):

  • autonumber 활성화 — 본문에서 "단계 3에서 ..." 처럼 참조 가능
  • actor vs participant: 사람은 actor, 시스템은 participant
  • 순서: User → Frontend → Backend → External (좌→우)
  • 화살표 라벨 명세:
    • HTTP: METHOD /path {body 요약} (예: POST /api/v1/login {email, password})
    • 메시징: event-name {payload 요약} (예: user.signed-up {userId})
    • 메서드 호출: method() (예: validateCredentials())
  • 응답: -->> (점선 화살표)
  • alt / opt / loop: 분기·옵션·반복은 명시적 블록
  • Note over X,Y: 비자명한 동작은 노트로 명시
  • 에러 경로 1개 이상 필수: happy path 만 그리면 미완성

4.2 앱 부팅 + 런타임 config 검증 (fail-fast)

시나리오: SPA 부팅 시 VITE_* env 를 zod 로 검증한다. 필수 값 누락/형식 오류면 화면을 렌더하지 않고 부팅 에러로 즉시 실패시켜 "잘못된 config 로 반쯤 동작하는 상태" 를 차단한다. (Vite 는 import.meta.env 로만 env 를 노출하고 VITE_ 접두 변수는 번들에 박히므로 secret 은 여기 두지 않는다 — raw/official-docs/vite-build-tool-official.)

sequenceDiagram
    autonumber
    participant Boot as main.jsx (bootstrap)
    participant Cfg as config loader (adapter)
    participant Env as import.meta.env
    participant Zod as env schema (zod)
    participant App as React App

    Boot->>Cfg: loadConfig()
    Cfg->>Env: read VITE_* 변수
    Cfg->>Zod: envSchema.parse(raw)
    alt env 유효
        Zod-->>Cfg: 검증된 config
        Cfg-->>Boot: config
        Boot->>App: render(App with config)
    else 필수 env 누락 / 형식 오류
        Zod-->>Cfg: ZodError
        Cfg-->>Boot: throw ConfigError (fail-fast)
        Boot-->>Boot: 렌더 중단 + 부팅 에러 화면 (secret 미노출)
    end

5. 데이터 모델 / Data model (선택)

핵심 엔터티가 5~10개 이상이면 ER 다이어그램으로. 그 미만이면 글로만.

본 skeleton: 해당 없음 (N/A). 도메인/비즈니스 로직을 제거했으므로 영속 엔터티가 없다. sample feature slice 의 최소 view-model 만 zod schema 로 정의하며(런타임 계약), 관계형 ER 다이어그램은 불요. 도메인 채택 시 각 feature branch 가 자체 view-model schema 를 정의한다.

ER 작성 표준:

  • PK / FK 표시 필수
  • 관계 카디널리티 기호:
    • ||--|| (1:1)
    • ||--o{ (1:N)
    • }o--o{ (M:N)
    • ||..o{ (identifying vs non-identifying 표현)
  • 관계 라벨: 동사로 (예: places, contains, ordered as)
  • 핵심 엔터티만 (5~10개 이내). 모든 테이블 그리지 말 것.

6. 기술 결정 / Tech decisions

주요 기술 선택과 이유. 트레이드오프 + 근거 자료 link 필수.

범례: deferred = 이번 /project-spec 자동조사 6개 한도 밖으로 미룬 결정 — 근거는 해당 branch 의 /branch-spec 단계에서 채운다(R3 Blocking 면제). 사용자 결정 은 근거 자료 없이도 확정된 제약이다.

결정 영역 선택 검토한 대안 채택 이유 트레이드오프 근거 자료
언어 JavaScript (ESM) TypeScript · JS+JSDoc 사용자 지정 제약. 진입 장벽·빌드 단순 ⚠️ 컴파일타임 타입 계약 부재 → 경계 계약을 런타임(zod)이 짊. UNSUPPORTED 아니라 사용자 결정 (사용자 결정)
빌드/번들 Vite (client-only SPA) Next.js · CRA · Remix 서버 런타임 불필요·백엔드 API 와 분리, native ESM dev server + HMR, import.meta.env 로 env 노출(secret 은 번들 금지) SSR/SEO 필요 시 부적합(범위 밖) [[raw/official-docs/vite-build-tool-official]]
UI 라이브러리 React 19 Vue · Svelte · SolidJS 컴포넌트 기반 UI 분해, 생태계·채용시장, 기존 SPA 자산 러닝커브·리렌더 관리 [[raw/official-docs/react-ui-library-official]]
스타일링 Tailwind CSS CSS Modules · styled-components · vanilla-extract utility-first + theme 토큰으로 magic number 제거, 런타임 CSS-in-JS 비용 0 클래스 verbosity·초기 학습 [[raw/official-docs/tailwind-css-utility-first-official]]
server-state TanStack Query SWR · RTK Query · 수제 server-state 를 client-state 와 분리, 캐시·동기화·stale 계약을 표준 제공(수제 시 놓침) 의존성·개념 학습 [[raw/official-docs/tanstack-query-server-state-official]]
런타임 검증 zod yup · valibot · 수제 무타입 JS 에서 경계 계약을 .parse() 런타임으로 강제, ZodError 로 실패 신호 번들 크기·스키마 유지 [[raw/official-docs/zod-runtime-schema-validation-official]]
라우팅 React Router (Declarative Mode) TanStack Router · wouter client-only SPA nested route 표준(SSR/framework 모드 불요) 타입-라우팅은 TanStack 우위; guard/loader 는 별도 계약(branch) [[raw/official-docs/react-router-official]]
client-state Context / Zustand (경량) Redux Toolkit · Jotai server-state 는 Query 담당 → client-state 경량으로 충분 규모 증가 시 재검토 deferred/branch-spec
테스트 Vitest + RTL + Playwright Jest · Cypress Vite 정합(Vitest), 컴포넌트(RTL)·e2e(Playwright) 계층 분리 도구 3종 셋업 deferred/branch-spec
아키텍처 패턴 Clean Architecture (계층 + 의존 규칙) Feature-Sliced Design · Layered · Atomic 의존 방향 강제 + 도메인 순수성(백엔드 대칭) 프론트 적용 시 boilerplate deferred — branch 단계 wiki-decision-researcher 로 FSD 심층 비교
계층 강제 도구 ESLint boundaries / dependency-cruiser 수동 리뷰 의존 규칙 자동 강제(백엔드 ArchUnit 대응) 규칙 유지보수 deferred/branch-spec

7. 비기능 요구사항 / Non-functional

측정 가능한 비기능 목표. 없으면 명시적으로 "해당 없음".

수치는 초기 default. 각 값의 측정·강제는 대응 계약 branch 가 담당(§8.0).

  • 성능: 초기 JS 번들 < 200KB gzip(default) · route-level code splitting · web-vitals LCP < 2.5s / CLS < 0.1 / INP < 200ms 를 CI 게이트가 검사 → feature-web-vitals-performance-budget-contract (선택 포함).
  • 가용성: 정적 자산이므로 프론트 자체 다운타임은 CDN 가용성에 종속. 백엔드 장애 시 async 4-state 의 error부분 degrade(앱 셸 유지), retryable 요청만 backoff 재시도.
  • 확장성: 정적 자산 CDN 배포, 상태는 클라이언트 → 수평 확장 무관(서버 인스턴스 없음).
  • 보안: 인증 토큰 획득/저장/refresh 는 범위 밖 → raw/project-notes/keycloak-patterns-overview 로 위임. 본 skeleton 은 (1) secret 의 클라이언트 번들 유입 금지(VITE_* 에 secret 금지), (2) XSS 기본 방어(dangerouslySetInnerHTML 금지·CSP 권고), (3) 응답 원본/스택/토큰의 화면·로그 노출 금지만 계약화.
  • 운영 / Observability: 구조화 클라이언트 로깅 + 백엔드로 traceparent 전파 + (선택) 에러 트래킹 sink. 토큰·PII 로그 금지 → feature-frontend-observability-logging-trace-contract (선택 포함).
  • 접근성 / a11y: WCAG 2.1 AA 기본선 — 키보드 네비게이션·focus 관리·ARIA·a11y lint → feature-accessibility-baseline-contract (선택 포함).
  • 재해 복구 / DR: 정적 자산 재배포로 복구(RTO 낮음), 클라이언트 무상태(RPO 무관).
  • 컴플라이언스: 해당 없음 — 도메인·PII 미수집(skeleton). 도메인 채택 시 재평가.
  • i18n: 범위 밖 (deferred) — 이번 skeleton 미포함(사용자 미선택). 후속 프로젝트에서 별도 계약으로.

8.0 Branch 분해 / 실행계획 (Branch decomposition)

/project-spec 가 채우는 핸드오프 섹션. 이 hub 에서 깊은 조사로 도출된 자식 branch 의 네이밍과 달성 목표 조건만 적는다. 각 branch 의 결정 내용·메커니즘은 여기 적지 않는다 (SSOT 이중화 방지) — 그건 /branch <slug> 로 생성 후 /branch-spec 가 깊게 채운다.

작성 규칙:

  • branch slugrules/naming-conventions.md §2.1 준수 (prefix 4종 feature-/fix-/chore-/experiment- 중 하나 + kebab-case, numbered hierarchy 금지).
  • 달성 목표 조건측정가능해야 함 ("잘 된다" 금지). 그 branch 가 "끝났다"고 말할 수 있는 검증 가능한 결과.
  • 우선순위 는 실행 순서(P1 먼저). 의존이 있으면 의존 칸에 선행 branch slug.
branch slug 달성 목표 조건 (측정가능) 우선순위 의존
feature-frontend-clean-architecture-layering-contract presentation/application/domain/adapters 4계층 디렉터리 + 계층별 허용 import 규칙 문서화, sample import 예시가 규칙과 일치 P1 -
feature-api-client-response-envelope-contract fetch 래퍼가 성공/실패 envelope 파싱 + requestId/traceId 전파, 계약 위반 응답 시 정의된 에러 throw (contract test green) P1 -
feature-runtime-schema-validation-contract 경계(API 응답·form)에서 zod parse 강제, 위반 시 SCHEMA_MISMATCH 로 정규화 (test) P1 feature-api-client-response-envelope-contract
feature-frontend-error-classification-boundary-contract 에러 category(retryable/non-retryable/auth/validation) 분류 + React ErrorBoundary + 원본/스택 미노출 test P1 feature-api-client-response-envelope-contract
feature-frontend-env-runtime-config-contract 부팅 시 VITE_ env 를 zod 검증, 필수값 누락 시 fail-fast, secret 번들 미유입 lint (test) P1 -
feature-frontend-architecture-enforcement-lint-contract ESLint boundaries/dependency-cruiser 가 역방향 import 시 CI 실패, 위반 0건 리포트 P1 feature-frontend-clean-architecture-layering-contract
feature-async-ui-state-contract 모든 async 표면이 loading/empty/error/success 4상태 렌더, sample 에 4상태 각각 RTL test P2 feature-frontend-error-classification-boundary-contract
feature-boundary-mapper-viewmodel-contract API DTO → view-model 매핑 강제(presentation 이 raw DTO 미접근), 매핑 누락 시 test 실패 P2 feature-runtime-schema-validation-contract
feature-server-state-caching-contract TanStack Query query-key 규약·staleTime·invalidation·retry 정책 + 캐시 무효화 시나리오 test P2 feature-api-client-response-envelope-contract
feature-client-state-management-contract client-state 경계: server data 를 client store 에 중복 저장 금지, 위반 감지 test P2 feature-server-state-caching-contract
feature-routing-navigation-guard-contract route 구조 + guarded route(비인증 redirect)·error/loading route·404 정의, 네비게이션 test P2 -
feature-tailwind-design-token-styling-contract theme 토큰(spacing/color scale) 정의 + arbitrary value 금지 lint + 컴포넌트 스타일 경계 규칙 P2 -
feature-frontend-test-taxonomy-contract unit/component(RTL)/integration(msw)/e2e(Playwright) 4계층 정의 + 각 계층 예제 test 1개 P2 -
feature-frontend-observability-logging-trace-contract 구조화 로거 + traceparent 전파 + 토큰/PII redaction, 금지 필드 로그 유입 시 test 실패 P2 feature-api-client-response-envelope-contract
feature-sample-feature-slice-contract-fixture 도메인 없는 sample slice 가 api-client·zod·error·4-state·CA 계층 모두 관통 + 계약 위반 시 실패 test 세트, 채택 시 제거 가능 표시 P2 feature-async-ui-state-contract
feature-frontend-build-bundle-supply-chain-contract Vite 프로덕션 빌드 + code splitting + lockfile 고정 + 번들 분석, 번들 예산 초과 시 CI 실패 P3 -
feature-web-vitals-performance-budget-contract LCP/CLS/INP 임계 + 번들 크기 예산을 CI 게이트로 측정, 초과 시 실패 P3 feature-frontend-build-bundle-supply-chain-contract
feature-accessibility-baseline-contract WCAG 2.1 AA 기본선 + 키보드 네비·focus·ARIA + a11y lint(axe) CI 게이트, sample slice 통과 P3 feature-async-ui-state-contract
feature-frontend-ci-quality-gates-contract lint·test·번들예산·a11y 게이트를 CI 로 통합, 하나라도 실패 시 머지 차단 P3 feature-frontend-test-taxonomy-contract
feature-frontend-api-compatibility-contract 백엔드 API additive 변경 관대 + breaking 감지(스키마 버전) 정책, 불일치 시 명시적 실패 P3 feature-runtime-schema-validation-contract

채운 뒤: /branch <slug>/branch-spec <slug> <근거 URL...>/depth <slug> 순으로 각 branch 를 깊게 작성.

8. Cluster / 묶음 (이 프로젝트에 묶이는 모든 raw 자료)

본 project-note 는 cluster 의 entry point. 모든 branch / errors / interviews / lectures / job-postings / blog-topics / sources 가 여기로 upward link. hub 측에서도 카테고리별 명시.

8.1 Branches (project 의 직접 자식 branch — parent_branch: 비어있음)

project-note 가 직접 가리키는 branch 들. 자식 branch 가 있는 branch 는 자기 Cluster 섹션에서 자식들을 참조하므로 여기에는 등재 안 함.

아직 branch 미생성. §8.0 분해표의 각 slug 를 /branch <slug>/branch-spec <slug> <근거>/depth <slug> 로 전개하면 여기에 등재한다. P1 6개(layering / api-client / runtime-validation / error-boundary / env-config / arch-enforcement-lint)부터 착수 권장.

8.2 Sources (프로젝트 전체 차원 foundational 조사)

특정 branch 에 묶이지 않는 전체 프로젝트 단위 근거 자료.

  • [[raw/official-docs/vite-build-tool-official]] — Vite 빌드/dev server + import.meta.env env·secret 계약 근거
  • [[raw/official-docs/react-ui-library-official]] — React 컴포넌트 모델
  • [[raw/official-docs/tailwind-css-utility-first-official]] — Tailwind utility-first + theme 토큰(magic number 제거)
  • [[raw/official-docs/tanstack-query-server-state-official]] — server-state vs client-state 구분 + 캐시 계약
  • [[raw/official-docs/zod-runtime-schema-validation-official]] — 무타입 JS 런타임 경계 검증(.parse/.safeParse)
  • [[raw/official-docs/react-router-official]] — Declarative Mode nested routing (SSR/framework 모드 아님)

8.3 Errors (branch 외 발생한 환경·운영 이슈)

  • (아직 없음 — 구현 착수 후 환경·운영 이슈 발생 시 등재)

8.4 Interview prep (프로젝트 전체 차원 면접 질문)

  • (아직 없음)

8.5 Blog topics / job-posting tie-ins

  • (아직 없음)

8.6 Derived wiki documents

  • (아직 없음 — canonical 승급은 verified 사실 발생 후 /ingestwiki/projects/ 에)

9. 검증 등급 / Verification status

본 project-note 의 각 부분이 어느 등급까지 검증되었는지. CLAUDE.md §15 lifecycle 참조.

영역 등급 근거
아키텍처 다이어그램 planned (needs-diagram) §3.1 사용자 작성 예정, 아직 파일 없음
시퀀스 다이어그램 documented-only §4 Mermaid 2개(설계 흐름), 코드 대응물 없음
기술 결정 documented-only §6 6개 결정이 official 근거 보유 — 단 결정일 뿐 구현 아님
비기능 요구사항 planned §7 임계는 목표치, 측정값 없음(코드 미착수)

9.1 실제 구현 내용 (actually-implemented)

코드에 존재하는 것만. 파일·함수 단위로 구체적으로. 면접에서 "구현했다"고 말해도 되는 부분.

  • 없음 — 레포 미생성(NO_GROUND_TRUTH). 이 항목은 Vite 레포 생성 + src/ grep 확인 후에만 채운다.

9.2 로컬/dev 검증 (locally-verified)

로컬 또는 dev 환경에서 동작 확인한 부분. 어떻게 검증했는지(로그/테스트/측정값).

  • 없음 (기획 단계).

9.3 운영 검증 (prod-verified)

운영(prod) 환경에서 동작·성능을 확인한 부분. 근거(릴리즈 노트 / 운영 로그 / 모니터링 대시보드 / 인시던트 보고서)를 함께 명시.

  • 없음 (기획 단계).

9.4 문서/계획만 존재 (documented-only / planned)

설계 문서에만 있고 아직 구현 안 된 것. 면접에서 "구현했다"고 말하면 안 되는 부분.

  • 본 hub 전체가 현재 이 등급 — §1~§8 의 모든 계약·아키텍처·branch 분해는 planned(설계만). 외부에 "구현했다"고 말하면 안 됨.
  • 아키텍처 .drawio = needs-diagram(§3.1, 사용자 작성 예정).
  • 각 계약의 actually-implemented 승격은 대응 branch 착수 + 코드 커밋 + contract test green 후 src/ grep 으로 확정.

10. 면접·외부 공개 답변 경계

10.1 자신 있게 답할 수 있는 범위

  • 이 skeleton 이 필요한가 — 도메인 없는 운영 계약을 프론트엔드에 대칭 적용한 설계 의도(§1·§2)와 백엔드 skeleton 과의 대응 관계.
  • 각 스택의 설계 선택과 트레이드오프(§6) — Vite/React/Tailwind/TanStack Query/zod/React Router 를 왜 골랐는지 + 검토한 대안 + 근거(official 문서).
  • CA 계층을 프론트엔드에 적용하고 lint 로 의존 방향을 강제하려는 설계(§3, §8.0), 무타입 JS 에서 zod 로 계약을 런타임 강제하는 이유.

10.2 적당히 답할 수 있는 범위

  • 각 계약의 구체 구현 메커니즘 — 아직 branch 설계 단계이므로 "이렇게 설계했다" 수준까지만. "이미 구현했다"로 넘어가면 안 됨.

10.3 답하면 안 되는 / "공식 문서 다시 확인" 해야 하는 범위

  • "이 skeleton 을 실제로 구현/운영했다" — 거짓(코드 미착수). "설계·계획했다"만 사실.
  • 성능 수치(200KB, LCP/CLS/INP)를 측정 결과처럼 — 전부 목표치.
  • 인증 토큰 처리 세부 — 본 skeleton 범위 밖(raw/project-notes/keycloak-patterns-overview).

10.4 과장 금지 지점

외부에 설명할 때 사실보다 부풀려지기 쉬운 표현. 자기 검열용.

  • "프로덕션 검증된 프론트엔드 아키텍처" planned.
  • "번들 200KB 달성 / web-vitals 통과" → 목표치, 미측정.
  • "TanStack Query 로 캐시 최적화 경험" → 설계 결정일 뿐 구현 경험 아님.

11. Architecture Review Checklist (작성 / 갱신 시 self-check)

본 project-note 가 hub 역할을 제대로 하려면 모두 ✓ 여야 함.

  • 한 줄 요약 + 현재 상태 + 나의 역할 채워짐 (§1)
  • 측정 가능한 성공 기준 1개 이상 (§2.3)
  • 아키텍처 다이어그램 (.drawio.svg) 1개 이상 첨부 (§3.1)
  • 다이어그램이 rules/diagram-standards v2 minimalist 통과 — wiki-diagram-reviewer 로 ≥95 점 (vertex ≤ 10 / edge ≤ 8 / callout ≤ 1 / 박스 라벨 ≤ 2줄 / 화살표 라벨 ≤ 5단어 / 80% 회색 + 강조 ≤ 2 / boundary 정보 있을 때만 / 5초 + 30초 룰)
  • 외부 시스템이 점선 + 회색 fill 로 시각적 구분 (legend 불필요 — 표준 컨벤션)
  • 시퀀스 다이어그램 1개 이상 (Mermaid) — happy path + error path 함께 (§4)
  • 데이터 모델은 5~10개 이상 엔터티 시에만 ER 그림 (§5)
  • 주요 기술 결정 표에 트레이드오프 + 근거 자료 link 명시 (§6)
  • 비기능 요구사항이 측정 가능한 수치 (§7)
  • Branch 분해표 채워짐 — 각 자식 branch 가 naming-conventions slug + 측정가능 목표조건 (§8.0)
  • Cluster 섹션의 project 직접 자식 branch 목록 채워짐 (§8.1)
  • 검증 등급이 각 영역별로 매겨짐 (§9)
  • 면접 답변 경계 명시 (§10)
  • 마지막 architecture review 날짜 frontmatter architecture_review: 에 기록

12. 다이어그램 파일 관리 가이드

draw.io 파일과 Mermaid 코드 모두 본 project-note 와 함께 라이프사이클 관리.

12.1 draw.io (.drawio.svg)

  • 저장 위치: raw/diagrams/<project-slug>/
  • 명명: architecture-{viewpoint}-{YYYY-MM-DD}.drawio.svg
    • viewpoint 예: overview, deployment, data-flow, security, network
  • 갱신 시: 새 날짜로 파일 추가 + frontmatter diagrams: 에 모든 활성 다이어그램 나열
  • 폐기 시: 파일 삭제하지 말고 diagrams/<project>/archived/ 하위로 이동 + project-note 에서 link 제거
  • Obsidian 임베딩 문법: ![[architecture-overview-2026-05-25.drawio.svg]]

12.2 Mermaid

  • 본 문서 본문에 직접. 외부 파일로 분리 안 함.
  • 갱신 시: code block 그대로 수정 (git diff 친화적)
  • 너무 커지면 (>50줄) 별도 sub-branch 의 branch-note 로 분리하고 본문에서는 요약만

12.3 그림 변경 시 의무

  • 아키텍처가 변경되면 본 project-note 의 architecture_review: frontmatter 날짜 갱신
  • 변경 사유는 §6 "기술 결정" 표에 한 줄 추가 (예: "2026-06-01: PostgreSQL → Aurora 변경 — 이유: 가용성 SLO 99.99%")
  • 폐기된 결정도 표에서 지우지 말고 status 컬럼 추가로 표시 (active / deprecated / superseded-by-<row>)

§3~§6 표에 등장하지 않은 보조 개념·자료.

  • [[raw/project-notes/ca-skeleton-operational-contract]] — 백엔드 대응 skeleton (운영 계약 철학의 원본, 본 프로젝트의 대칭 기준)
  • [[raw/project-notes/keycloak-patterns-overview]] — 인증 토큰 처리 위임처(본 skeleton 범위 밖 경계)
  • [[rules/diagram-standards]] — §3 아키텍처 / §4 시퀀스 다이어그램 컨퍼런스급 표준
  • [[rules/naming-conventions]] — §8.0 branch slug 규칙

14. 다음 단계 / Next steps

  • 아키텍처 .drawio 2개 작성(§3.1) → wiki-diagram-reviewer ≥95 확인 → frontmatter diagrams:/architecture_review: 기입 (readiness Ready-pending-user 해소)
  • Vite + React + Tailwind 레포 생성 (§1 저장소 채우기 — 이후 actually-implemented 승격 근거)
  • P1 6개 branch 착수: /branch feature-frontend-clean-architecture-layering-contract/branch-spec/depth (나머지 P1 동일)
  • deferred 결정(client-state / 테스트 / 계층강제 도구 / 아키텍처 패턴)을 branch 단계에서 wiki-decision-researcher 로 대안 심층 조사
  • frontmatter tags: 확장 검토 — 필요 시 taxonomy 에 L4 vite·tanstack-query·zod 등재 후 반영