# KBX FE QA Hardening v42

## 1. 결론

v41까지의 가장 큰 성과는 Reference Lab과 실제 Vue Golden Screen을 별도 Gate로 보기 시작한 것이다. 그러나 v42에서 한 단계 더 내려가 실제 배포 가능한 FE 제품 관점으로 점검하자 더 근본적인 결함이 드러났다.

**`apps/web`에 독립적인 Vite application entry가 없었다.** Vue/TypeScript 파일이 수백 개 존재하고 공통 컴포넌트와 화면 정의가 정교해도 `package.json`, `index.html`, `main.ts`, Vite config가 없으면 FE 제품을 독립적으로 기동·빌드·검증할 수 없다.

이는 코드 양의 문제가 아니라 제품화 경계의 문제다. v42는 BE 결합을 더 강화하지 않고 **Frontend Runtime 자체를 일급 산출물**로 만든다.

또한 Home이 `/oms/orders?exceptionOnly=true`처럼 업무 Context를 전달해도 주문조회 composable이 route query를 소비하지 않아 실제 화면에서 Context가 사라지는 결함, Excel 버튼이 CSV export와 표준 Excel 업무를 혼동하는 문제, 200% Zoom에서 Shell chrome이 업무공간을 과도하게 점유하는 문제를 함께 보강했다.

---

## 2. P0 — 실제 Vue Web Runtime 부재

### 문제

v41까지 `apps/web/src`에는 실제 업무 화면과 shell 코드가 존재했지만 Web App을 독립 실행하는 최소 runtime contract가 완결되지 않았다.

이 상태에서는 다음이 불가능하거나 외부 조립에 의존한다.

- FE 단독 기동
- FE 단독 typecheck/build
- Vue Router/Pinia/TanStack Query/PrimeVue 초기화 검증
- 실제 Golden Screen E2E 진입
- BE 없이 Loading/Empty/Error/Lookup/Grid 상태 재현

### v42 조치

추가:

- `apps/web/package.json`
- `apps/web/index.html`
- `apps/web/tsconfig.json`
- `apps/web/vite.config.ts`
- `apps/web/src/main.ts`
- `apps/web/src/App.vue`
- `apps/web/src/styles/app.css`
- `.env.demo`

Runtime은 실제 제품과 동일하게 다음을 초기화한다.

```text
Vue
→ Pinia
→ Vue Router
→ TanStack Query
→ PrimeVue
→ installKbx()
→ KbxAppFrame
```

Vite는 사용자 기술스택 기준인 **Vite 8**을 명시한다.

---

## 3. Demo Runtime은 별도 UI가 아니라 HTTP Adapter다

FE를 BE 없이 검증하기 위해 화면별 demo component를 만들면 다시 이중표준이 된다.

v42는 실제 다음 경계를 유지한다.

```text
Golden Screen
→ TanStack Query / Mutation
→ domain API client
→ kbxHttp(Axios)
→ demo adapter 또는 real transport
```

즉 Page, Lookup, Grid, Validation, Error Handler, Router는 운영 코드와 동일하다. Demo Mode에서 마지막 HTTP transport만 fixture adapter로 교체한다.

지원 fixture는 OMS 주문, Lookup, ERP 품목/재고, Queue, Reconcile, WMS Picking, Excel Import, Runtime Notification/Operation, AI/Suggestion 등 Golden Screen 검증에 필요한 업무 read/write를 포함한다.

알 수 없는 Demo API는 성공으로 위장하지 않고 `DEMO_OPERATION_UNSUPPORTED`로 명시적으로 실패한다.

---

## 4. 보안 — Demo Mode secure default

Demo Mode가 편리하다는 이유로 production/default runtime에서 fixture 또는 전체 권한이 켜지면 안 된다.

v42 정책:

```text
normal dev/build
→ VITE_KBX_DEMO_MODE != true
→ real HTTP transport
→ grantedPermissions = []
→ secure-default preference scope

vite --mode demo
→ VITE_KBX_DEMO_MODE = true
→ demo HTTP adapter
→ catalog demo permissions
```

Demo 활성 조건은 문자열 `true`의 명시적인 일치로 제한한다.

**FE Permission은 여전히 UX 표현이다.** 실제 API Permission, 상태전이, Reference Integrity, Concurrency, Idempotency, Audit은 Server가 최종 Enforcement한다.

---

## 5. P0/P1 — Home은 링크 목록이 아니라 Context Router여야 한다

### 발견 결함

Home/Notification은 예외 주문으로 다음과 같은 경로를 전달할 수 있었다.

```text
/oms/orders?exceptionOnly=true
```

하지만 `useOrderSearch()`가 route query를 hydrate하지 않아 화면 진입 후 실제 검색조건에서는 `exceptionOnly`가 사라졌다.

사용자 입장에서는 “재고부족 7건”을 눌렀는데 주문조회로 이동한 뒤 다시 조건을 찾게 된다. 이는 Home navigation 완성도가 높다고 평가할 수 없다.

### v42 조치

`useOrderSearch()`가 route query를 다음 allow-list만 소비한다.

- `from`, `to`: ISO date 형식
- `status`: 명시 상태 allow-list
- `exceptionOnly`: 정확히 `true`
- `keyword`: 최대 100자
- `channelId`: 최대 64자

허용 Context가 존재하면 mount 시 자동 조회한다.

임의 query를 그대로 내부 filter/API로 전달하지 않는다. Home의 편의성과 입력 경계 검증을 함께 유지한다.

---

## 6. P1 — Excel은 “버튼 하나”가 아니다

v41의 `엑셀`은 사실상 AG Grid CSV export에 가까웠다. KBX 표준의 Excel 계약과 동일하지 않다.

v42는 `KbxCommandDefinition.menu = 'excel'`을 도입하여 `KbxCommandBar`가 공통 `KbxExcelMenu`를 렌더링한다.

표준 메뉴:

- 현재 조회결과 다운로드
- 업로드 양식 다운로드
- 엑셀 업로드
- Excel 붙여넣기
- 최근 업로드 결과

`KbxExcelMenu`는 다음 키보드 계약을 가진다.

- Esc: 닫기 + Trigger Focus 복원
- ArrowUp/ArrowDown: 메뉴 이동
- Home/End: 처음/마지막
- outside pointer: 닫기
- `role=menu/menuitem`

### 데이터 유실 방지 판단

현재 T01은 전체 검색결과가 Browser에 모두 로드된 경우에만 local CSV export를 허용한다.

서버 검색결과가 8,241건인데 현재 Browser row가 일부뿐인 경우 **부분 CSV를 “전체 조회결과”로 다운로드하지 못하게 차단**한다.

Full-query XLSX/Job Export API는 아직 연결되지 않았으므로 v42에서도 이를 완료로 계산하지 않는다. 이는 잔여 P1이다.

---

## 7. 200% Zoom / Narrow Desktop Shell

업무 Desktop 기준 1440px를 200% Zoom하면 CSS viewport는 약 720px처럼 압박된다.

기존 Global Header는 narrow media에서도 220px navigation column을 예약하여 실제 Workspace를 불필요하게 줄였다.

v42:

- 56rem 이하 Global Header의 첫 열을 fixed Side Nav width가 아닌 `auto`로 변경
- Header search는 `minmax(0,1fr)`로 축소 가능
- 40rem 이하 Header actions는 3-column row로 reflow
- Side Nav가 expanded 상태여도 56rem 이하에서는 56px compact rail로 시각 수축
- 상세 module/personal navigation은 숨기고 Header module selector / Ctrl+K를 핵심 이동 경로로 유지
- WMS Mobile 정책은 기존 별도 Mobile Template 규칙을 유지

목표는 Desktop 화면을 Mobile 카드 UI로 바꾸는 것이 아니라 **업무 Workspace를 우선 보존**하는 것이다.

---

## 8. QA 자동화 — v42 Runtime Readiness Gate

신규 `scripts/validate-fe-runtime-v42.mjs`가 다음을 자동 확인한다.

- `apps/web` workspace/package 존재
- Vite 8 명시
- build 전에 `vue-tsc --noEmit`
- main entry의 Pinia / Query / Router / PrimeVue / KBX wiring
- Demo Mode explicit activation
- production permission secure default
- demo adapter가 HTTP boundary 아래에만 존재
- unknown demo operation fail-explicit
- WMS fixture state transition
- Home → Order route context allow-list / 길이 제한 / auto-search
- CommandBar → standard Excel menu
- Excel menu keyboard/focus contract
- duplicate Grid export 진입점 제거
- 56rem/40rem Shell pressure 대응

이 Gate는 실제 Browser E2E를 대체하지 않는다. **런타임을 실행할 수 있도록 구성되어 있는지와 보안/구조 계약이 소스에서 유지되는지**를 검증한다.

---

## 9. 실행환경 제한 — 완료로 과장하지 않는 항목

현재 작업 컨테이너에서는 `pnpm` 실행파일이 없고 Corepack을 통한 pnpm 준비도 npm registry network 정책에 의해 실패했다.

따라서 이번 환경에서 다음을 실제 실행했다고 주장하지 않는다.

- `pnpm install`
- `pnpm --filter @kbx/web build`
- 실제 Vite server
- 실제 Vue/PrimeVue/AG Grid Browser Playwright
- 200% Zoom actual screenshot regression

대신 다음은 실제 실행하여 PASS했다.

- 304 TS/Vue syntax transpile
- API governance
- v42 FE runtime readiness Gate
- 전체 `validate:kbx`

Network-enabled CI/dev 환경의 다음 필수 Gate는:

```bash
pnpm install --frozen-lockfile
pnpm typecheck:web
pnpm build:web:demo
pnpm dev:web:demo
# Playwright actual runtime E2E
```

이다.

---

## 10. 30년 현장 QA 관점의 우선순위

### 1. 화면 개수보다 “기동 가능한 제품”이 먼저다

300개 Vue/TS unit이 있어도 Application Entry가 없다면 FE 제품 완성도를 높게 평가하면 안 된다.

### 2. Home 카드보다 Context 전달이 중요하다

“오류 16”을 보여주는 것보다 그 숫자를 눌렀을 때 오류 16건이 그대로 조회되는 것이 중요하다.

### 3. Demo는 운영 코드와 달라지면 QA 가치가 급격히 떨어진다

별도 Mock Page가 아니라 동일 API boundary 아래의 adapter로 검증해야 한다.

### 4. Excel은 가장 쉽게 기능 착시가 생기는 영역이다

CSV 한 번 내려간다고 Excel 표준이 완료된 것이 아니다. 전체 조회결과, Import, Mapping, Validation, Job, Result가 하나의 제품 계약이다.

### 5. 200% Zoom은 접근성 QA이면서 업무 생산성 QA다

Side Nav와 Header가 화면의 절반을 차지하면 접근성 준수 여부 이전에 실제 업무가 불가능해진다.

### 6. 다음 iteration도 새 Template을 만들 시점이 아니다

v43 우선순위:

1. network-enabled actual `pnpm install/build/typecheck`
2. 실제 Vue OMS-ORD-001 browser E2E
3. OMS-ORD-002 keyboard-only E2E
4. ERP-MST-ITEM-001 Dirty transition E2E
5. 실제 200% Zoom / 1280×720 visual regression
6. server-side full-query XLSX export + background job
7. Permission / Conflict / Integration error 실제 API contract E2E

그 전에는 T10 추가, Runtime JSON UI Builder, 새로운 Grid abstraction을 우선하지 않는다.
