# ADR-FE-CONTRACT-001 — FE API 계약과 Zod 검증 경계

- **WBS:** V13-FE-009
- **Requirement:** REQ-FE-OPENAPI
- **API/UI/Test:** UI-FOUND-09 / T-FE-CONTRACT-01
- **Status:** ACCEPTED FOR CURRENT IMPLEMENTATION BOUNDARY

## Context

v60 참조 구현은 `generated API client → shared contract package → feature query` 경계를 사용한다. 현재 K-ArtSell FE는 `axios → feature API → Zod schema → TanStack Query` 경계를 사용하고 있다. v60의 OMS 계약·생성 클라이언트·DTO를 그대로 복사하면 현재 금융 도메인의 API 의미와 일치하지 않는다.

## Source / Assumption / Unknown / Decision Required

- **Source:** `frontend/src/shared/api/client.ts`, `frontend/src/features/*/api.ts`, `frontend/src/features/*/schema.ts`, `frontend/src/shared/commands/idempotency.ts`, `contracts/ui/crud-resource.v2.json`, WBS `V13-FE-009`.
- **Assumption:** 서버 OpenAPI 또는 승인된 JSON Schema가 FE API response의 authoritative source이며, feature-local Zod는 runtime boundary validation을 담당한다.
- **Unknown:** 현재 모든 internal endpoint에 대해 versioned OpenAPI artifact가 저장소에 연결되어 있는지는 확인되지 않았다.
- **Decision Required:** OpenAPI artifact가 승인·보존되기 전에는 generated client 도입, DTO 자동 생성, v60 `@kbx/contracts` 의존성 도입을 금지한다.

## Decision

1. **현재 경계 유지:** `shared/api/client.ts`는 transport와 ProblemDetails 변환만 담당한다. 업무 정책·query key·도메인 mapping을 넣지 않는다.
2. **Runtime validation:** 각 feature의 response/request는 feature-owned Zod schema로 `parse`한다. TypeScript interface만으로 외부 응답을 신뢰하지 않는다.
3. **Server state ownership:** API 응답은 TanStack Query가 소유한다. Pinia에는 API response를 복제하지 않는다.
4. **Command retry:** 동일 재시도는 동일 `Idempotency-Key`를 재사용한다. 새 시도는 명시적 새 command로만 생성한다.
5. **Generated code gate:** 생성 클라이언트는 승인된 OpenAPI/JSON Schema artifact, generator version, input SHA, output diff, contract test가 모두 존재할 때 별도 Slice에서 도입한다.
6. **v60 차용 범위:** v60의 request routing·contract validation 아이디어만 차용한다. OMS endpoint, OMS status, KBX package, KBX permission host/router/store는 현재 FE에 이식하지 않는다.

## Consequences

- 현재 feature API의 명시적 Zod 경계와 existing tests를 보존한다.
- generated DTO 중복은 즉시 제거하지 않고, authoritative contract가 확인된 뒤 migration 대상으로 기록한다.
- OpenAPI artifact가 없는 endpoint는 자동생성 대상이 아니라 `DECISION_REQUIRED`로 남는다.
- 이 ADR만으로 API/DB schema 변경이나 새 endpoint를 승인하지 않는다.

## Verification Evidence

- `frontend`: `pnpm typecheck` PASS
- `frontend`: `pnpm test` PASS (34 files, 75 tests)
- `frontend`: `pnpm typecheck` and production build PASS via `dotnet build src/KArtSell.Host/KArtSell.Host.csproj --no-restore` on 2026-08-12
- 범위: FE contract boundary decision only. Build, E2E, migration, production runtime evidence는 주장하지 않는다.
