# KBX FE QA Hardening v44
## Theme State · Runtime Center · Empty Recovery · Forced Colors · Home/Shell Parity

## 1. 결론

v44의 목적은 Light/Dark 팔레트를 하나 더 다듬는 것이 아니다. v43에서 정리한 Semantic Theme가 실제 업무 상태와 복구 흐름을 방해하지 않는지 검증하고, **Home/Application Shell → 시스템 작업/알림 → T01~T09 → Empty/Error/Permission/Conflict/Network**의 표현 계약을 같은 FE 언어로 유지하는 것이 목적이다.

이번 버전에서 새 화면 유형이나 대형 Theme Engine은 만들지 않았다. 기존 T01~T09와 KBX Component 계약을 실제 HTML/CSS/JavaScript와 Vue 런타임 코드에 더 정확하게 연결했다.

첨부 표준의 핵심 근거는 다음이다.

- Business UX/AX: Familiar First, Keyboard Accelerated/Mouse Complete, Grid First, Exception Driven, Predictable Layout, Explicit State, Audit by Default.
- Design System: Semantic Color, Density, Focus, Empty/Loading/Error, KbxDataGrid/KbxTemplate 계층.
- Reference Screens: 1440×900 Desktop Shell, WMS 390×844 별도 Mobile Template, Empty/Error 복구, Home/Queue의 actionable navigation.
- Implementation Contract: KBX는 사용방법을 결정하고 Domain은 가능한 업무를 결정한다. Frontend Permission/Validation은 UX 방어선이며 Server Validation/Concurrency/DB Constraint/Idempotency/Audit가 최종 책임을 가진다.

Light/Dark 자체는 첨부 표준의 직접 요구사항이 아니다. v43/v44 Theme는 사용자 요구에 따라 기존 Semantic Token·Accessibility·Predictable Layout 계약을 확장한 구현 선택이다.

---

## 2. 30년 현장 QA 관점에서 본 v43 잔여 결함

### P1 — Application version traceability가 실제 코드와 달랐다

`apps/web/src/App.vue`가 `v42-fe-runtime` 문자열을 계속 사용하고 있었다. Theme/Navigation이 v43까지 진화했는데 운영 제안·문제재현 Context의 AppVersion이 과거 버전을 가리키면 화면 캡처와 이력이 맞지 않는다.

v44:

```text
App artifact version
v42-fe-runtime
→ v44-fe-theme-state
```

Release도 Foundation 44 / Contract 1.25.0으로 맞췄다.

### P1 — 작업/알림 Center가 Shell의 접근성 계약을 충분히 갖지 못했다

실제 Vue Runtime의 작업/알림 Panel은 비모달 방식이 타당했지만 다음이 약했다.

- Header Trigger의 open state를 Screen Reader가 알기 어려움
- Panel을 키보드로 즉시 닫는 명시적 계약 부족
- 닫은 뒤 Trigger Focus Restore 부족
- Ctrl+K 외 Header/Home 메뉴검색 버튼 경로에서 Panel과 Menu Search가 겹칠 가능성

v44는 System Center를 **비모달 Runtime Panel**로 고정했다.

```text
작업 / 알림 Trigger
→ aria-controls
→ aria-expanded
→ 비모달 Panel focus
→ Esc / 닫기
→ Trigger focus restore
```

Menu Search는 Ctrl+K, Header Trigger, Home Trigger 모두 같은 `openMenuSearch()` 경로를 사용하며 Runtime Panel을 먼저 정리한다.

### P1 — Reference HTML과 실제 Vue가 System Center에서 다른 문법을 사용했다

v43 Reference Lab에서는 작업/알림을 공통 Modal Drawer로 열었지만 실제 Vue는 비모달 Panel이었다.

이중표준을 제거했다.

```text
Help / AI / Suggestion / 상세조회
→ Drawer / Modal 성격

작업 Center / 알림 Center
→ 비모달 System Panel
```

작업 진행을 보면서 현재 화면을 유지할 수 있어야 하기 때문이다.

### P1 — T01 Empty가 상태는 표시하지만 복구 루프가 한 단계 부족했다

조회 결과가 0건일 때 사용자가 다시 Search Panel을 찾아 조건을 지워야 했다. 업무형 Empty는 장식용 일러스트가 아니라 즉시 복구 Action이 중요하다.

v44:

```text
KbxTemplateStateBoundary
→ emptyActionLabel / emptyAction

KbxListPage
→ Template contract로 전달

OMS-ORD-001
→ [조회조건 초기화]
→ 기본 조건 복원
→ 즉시 재조회
```

즉 `empty → manual filter editing`이 아니라 `empty → one action → ready`의 루프로 닫았다.

### P2 — Light/Dark만으로는 Windows 고대비 사용자를 보장할 수 없었다

Dark Theme를 잘 만드는 것과 OS Forced Colors를 지원하는 것은 다른 문제다. 사용자가 Windows High Contrast/Forced Colors를 사용하면 브라우저가 제품 색을 강제로 재매핑한다.

v44는 Forced Colors를 제3의 KBX Theme로 만들지 않았다.

```text
KBX Light / Dark
        ↓
OS forced-colors active
        ↓
Canvas / CanvasText / Highlight / LinkText 우선
```

이 방식이 안정적이다. 업무 상태를 임의 RGB로 다시 싸우지 않고 OS 접근성 정책을 존중한다.

---

## 3. Theme 적용 원칙

v44 Theme 판단 기준은 다음과 같다.

```text
색이 예쁜가?               후순위
업무 우선순위가 보이는가?  우선
상태를 색 없이도 아는가?   필수
Focus가 보이는가?          필수
Grid 데이터가 읽히는가?     필수
복구 Action이 보이는가?     필수
```

Light/Dark에서도 Control Height, Grid Row, Command Bar, Search Panel, WMS Touch Target은 변하지 않는다. Theme 전환 때문에 사용자가 학습한 업무 위치와 밀도가 달라지면 실패다.

Forced Colors에서도 `aria-current`, `aria-selected`, `aria-pressed`에 Highlight outline을 제공하여 현재 위치와 선택을 색상 배경만으로 의존하지 않게 했다.

---

## 4. 실제 코드 보강

### Application Shell / Home

- `KbxGlobalHeader`
  - operation/notification open state props
  - `aria-controls`
  - `aria-expanded`
- `KbxApplicationShell`
  - Header open-state pass-through
- `KbxAppFrame`
  - non-modal Runtime Panel
  - `role="region"`
  - explicit close button
  - Esc close
  - focus restore
  - route change 시 안전하게 close
  - Help/AI/Suggestion과 중첩 방지
  - Ctrl+K/Header/Home menu search 경로 통합
- App version을 v44 FE artifact와 일치

### Template State

- `KbxTemplateStateBoundary 1.2.0`
  - `emptyActionLabel`
  - `emptyAction`
- `KbxListPage 1.7.0`
  - Empty Recovery contract 노출
- `KbxDataState 1.1.1`
  - Idle/Loading/Error를 semantic surface로 표현
- `OMS-ORD-001`
  - `[조회조건 초기화] → resetAndSearch()`

### Theme / Accessibility

- generated KBX token CSS에 `@media (forced-colors: active)` 추가
- Light/Dark 의미 토큰을 OS System Color로 안전하게 override
- Focus `Highlight`
- surface `Canvas`
- text `CanvasText`
- primary `LinkText`
- 앱 CSS와 Reference CSS 모두 current/selected/pressed 상태의 고대비 outline 적용

### Component versioning / Catalog

공개 계약 변경을 버전 없이 숨기지 않았다.

- `KbxGlobalHeader 1.4.0`
- `KbxApplicationShell 1.6.0`
- `KbxListPage 1.7.0`
- `KbxTemplateStateBoundary 1.2.0`
- `KbxDataState 1.1.1`

Catalog에도 다음 재현 상태를 보강했다.

- ListPage Empty Recovery
- ApplicationShell Runtime Center
- DataState Forced Colors
- TemplateStateBoundary Empty Recovery

---

## 5. 보안 판단

v44 변경은 FE 보안과 Domain 보안을 섞지 않는다.

Frontend 책임:

- Panel/Drawer 중첩 및 Focus 오류 방지
- route 변경 시 stale UI 정리
- Theme preference 표현 상태만 보존
- Empty/Error의 명시적 복구 UX
- Forced Colors 접근성
- 메뉴검색과 Runtime Panel 상태 충돌 방지

Server 최종 책임:

- Permission enforcement
- Entity existence
- Business Rule
- Optimistic Concurrency
- DB Constraint
- Import staging/commit
- Idempotency
- Audit / Outbox / Inbox
- AI proposal revalidation

Theme 값, `aria-expanded`, disabled 상태가 보안 판단의 Source of Truth가 되어서는 안 된다.

---

## 6. Browser QA

### Feature Browser QA

정확한 FE Reference HTML/CSS/JavaScript asset을 Chromium `set_content` harness로 실행했다.

결과:

```text
14 / 14 PASS
```

검증:

- Home Light render
- 작업 Center open
- `aria-expanded=true`
- Panel focus
- 비모달 유지(shell inert 아님)
- Esc close
- Trigger focus restore
- Dark 전환
- T01 Dark
- Forced Colors active
- system semantic color override
- runtime error 0

### T01~T09 Matrix

```text
28 / 28 PASS
```

검증:

- T01~T09 Light
- T01~T09 Dark
- T09 `wms-mobile` 전용 mode
- T01 Empty 표시
- Empty → 조회조건 초기화 → 8 rows 복구
- Runtime center open/focus/Esc/focus restore
- 1280×720 document horizontal overflow = 0
- Forced Colors active
- Forced Colors T01 Grid visible
- runtime error = 0

T09는 Desktop `[data-template]` 존재 여부를 검사하지 않았다. 실제 표준대로 `#app[data-mode="wms-mobile"]`인지 검증했다. 테스트가 구현을 잘못 가정하면 테스트도 결함이다.

---

## 7. 전체 Foundation Gate

최종 `node scripts/validate-kbx.mjs` 결과 전체 PASS.

```text
Design Tokens             153
Screen Recipes               9
Recipe Verification        9/9
Screen Definitions          20
Component Definitions       84
Component Catalog Entries   66
Navigation Entries          16
Canonical Scenarios         30
Canonical Fields            51
API Operations              66
TS/Vue Script Units        305
Design Debt                116 / ratchet 131
```

Release Governance:

```text
Foundation iteration 44
Contract 1.25.0
Required major
Declared major
PASS
```

Design Debt를 Theme/State 기능 추가 대가로 올리지 않았다.

---

## 8. 증적 한계

이 실행환경에는 `pnpm` 실행파일과 `node_modules`가 없으며 package registry를 사용할 수 없다.

따라서 다음을 실행했다고 주장하지 않는다.

- 실제 Vite dev server
- 실제 Vue/PrimeVue/AG Grid live runtime
- `vue-tsc` full semantic typecheck
- 실제 runtime Playwright
- 실제 Screen Reader 자동화

이번 v44의 실제 Vue 코드는 syntax/static/governance gate로 검증했고, Browser QA는 동일한 Reference HTML/CSS/JavaScript asset을 Chromium에서 실행했다.

이 구분을 지키는 것이 QA 증적의 신뢰성에 중요하다.

---

## 9. 다음 우선순위

다음 버전에서 T10/T11, 새로운 Theme Engine, Runtime JSON Builder를 추가하는 것은 우선순위가 아니다.

순서는 다음이 적절하다.

1. network-enabled CI에서 `pnpm install → typecheck → Vite build`
2. 실제 Vue Golden Screen Light/Dark Playwright
3. `1440×900 / 1280×720 / 200% Zoom × Light/Dark`
4. Windows Forced Colors 실제 Vue Visual Regression
5. keyboard-only `OMS-ORD-002` F2→Enter→Grid→F8
6. T02/T03 Conflict/Permission/Business Error 실제 API E2E
7. Server-side full-query XLSX + Hangfire Job
8. 실제 WMS PDA/Scanner에서 조도·장갑·네트워크 불안정 현장 QA

핵심은 화면 개수를 늘리는 것이 아니라 **현재 9개 Template의 성공/실패/복구 상태를 실제 제품에서 끝까지 재현 가능하게 만드는 것**이다.
