Removed entire kbx-foundation-v36 directory as it's been replaced by the new KBX Foundation v4 patterns implemented in this session: - Registry-driven screen definitions - Density-aware UI adapter components - Feature module templates (ShadowRun, Models) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
7.3 KiB
KBX Foundation v33
Template State Matrix · Permission Host · Home Workbench Hardening
1. 배경
v32에서 T01~T09의 주요 Surface와 반복 조립 API를 표준화했지만, 다음 완성도 간극이 남아 있었다.
- 조회형 화면의 최초 진입 상태가 실제
0건 조회와 구분되지 않았다. loading/empty/error/ready는 존재했지만 Template별로 Dirty/Conflict/Validation/Job/Network까지 어떤 상태를 책임지는지 계약이 없었다.KbxCommandBar,KbxWorkflowBar,KbxBulkActionBar에 permission callback은 있었지만 화면마다 전달해야 해서 누락 가능성이 있었다.- Home의 확인 필요 영역은 미저장/진행중/읽지 않음 총량 위주라 실패·부분완료·중요 알림 우선순위가 충분히 드러나지 않았다.
- Navigation preference는 scope 분리와 safe route re-resolution은 있었지만 저장 payload 크기·문자열 길이·timestamp 검증·legacy migration 정규화가 더 필요했다.
v33은 이 다섯 지점을 해결하되 Domain Rule, Backend Permission, Server Validation을 UI framework로 끌어오지 않는다.
2. Template State Matrix
KbxTemplateManifestEntry.stateCapabilities를 추가했다.
| Template | 핵심 상태 책임 |
|---|---|
| T01 Search/List | idle, loading, refreshing, empty, error, permission |
| T02 Master CRUD | idle, loading, refreshing, empty, error, permission, dirty, conflict |
| T03 Transaction | loading, refreshing, error, permission, dirty, conflict, validation |
| T04 Fast Entry | loading, refreshing, error, permission, dirty, validation |
| T05 Master/Detail | idle, loading, refreshing, empty, error, permission |
| T06 Work Queue | idle, loading, refreshing, empty, error, permission |
| T07 Reconcile | idle, loading, refreshing, empty, error, permission |
| T08 Import | loading, refreshing, error, permission, validation, job |
| T09 WMS Mobile | loading, refreshing, error, permission, network |
핵심은 상태를 한 컴포넌트에 모두 몰아넣는 것이 아니라, 각 화면 유형이 책임져야 할 상태를 Manifest에서 검증 가능하게 만든 것이다.
3. idle — 조회 전과 Empty 분리
KbxAsyncState에 idle을 추가했다.
기존 문제:
화면 진입
→ 조회 API 미실행
→ rows = []
→ Empty처럼 보이거나 빈 Grid가 표시됨
v33:
화면 진입
→ idle
→ [조회 F3]
→ loading
→ ready | empty | error
KbxDataState는 조회 전입니다.를 표시하고, KbxTemplateStateBoundary는 선택적인 idleActionLabel / idleAction 계약을 제공한다.
조회 중심 Template T01/T02(list 존재 시)/T05/T06/T07은 기본적으로 조회 F3 복구 Action을 연결한다.
실제 적용 화면:
- OMS 주문관리
- OMS 클레임
- ERP 품목관리
- ERP 재고현황
- UX Metrics
- WMS 작업 Queue
따라서 사용자는 “데이터가 없다”와 “아직 조회하지 않았다”를 구분할 수 있다.
4. Permission Host — 화면 내부 권한 누락 방지
새 내부 Host:
KbxPermissionHostKey
Application Shell에서 현재 grantedPermissions를 Host로 제공한다.
자동 소비 Component:
- KbxScreenFrame
- KbxCommandBar
- KbxWorkflowBar
- KbxBulkActionBar
- KbxWmsMobilePage
명시적인 can(permission) prop이 있으면 prop을 우선하고, 없으면 Host를 사용한다.
효과:
기존
Page가 can() 전달을 잊음
→ Command가 보일 수 있음
→ Backend에서 최종 거부
v33
Shell Permission Host
→ Screen/Command/Workflow/Bulk/WMS가 자동 동기화
→ Frontend에서 먼저 불필요한 Action 제거
→ Backend 최종 Enforcement 유지
이는 Backend 보안을 대체하지 않는다. UI 권한 표현의 누락 가능성을 줄이는 defense-in-depth다.
5. Screen-level Permission State
KbxScreenFrame과 KbxWmsMobilePage는 화면 자체 permission이 만족되지 않으면 업무 본문을 표시하지 않는다.
표현:
이 화면을 사용할 권한이 없습니다.
현재 권한으로는 이 업무 화면을 열 수 없습니다.
DOM에는 data-access="allowed|denied"를 제공해 테스트/재현에서 상태를 식별할 수 있다.
App Shell의 route-level 권한 필터와 Backend Enforcement는 그대로 유지된다.
6. Home Actionable Attention
Home의 확인 필요를 다음 우선순위로 세분화했다.
- 미저장 업무
- 실패·부분완료 작업
- Warning/Error 중요 알림
- 진행 중 작업
- 일반 새 알림
실패/중요 항목은 danger semantic token을 사용하되 텍스트를 함께 표시하므로 색상에만 의존하지 않는다.
Home Workbench의 기존 재개 우선순위는 유지한다.
미저장 → 고정 → 열림 → 즐겨찾기 → 최근 → 권장
즉 Home은 Dashboard가 아니라 현재 사용자가 다음에 처리해야 할 업무와 재개할 업무를 연결하는 Navigation Workbench가 된다.
7. Navigation Preference v3 Hardening
저장 Key:
kbx.navigation.preference.v3:{scope}
보강:
- 전체 payload 64KB 상한
- scope 최대 160자, 초과 시 저장 scope로 사용하지 않음
- ScreenId 최대 128자, 초과 데이터 거부
- Title 최대 120자, 표시용이므로 sanitize 후 truncate 허용
- Recent Path 최대 1024자, 초과 데이터 거부
- visitedAt parse 검증
- favorites 중복 제거/상한 유지
- recents 최신순 정렬/상한 유지
v3 데이터가 없으면 v2를 읽어 normalizePreference()를 통과시킨 뒤 v3로 자동 migration한다.
legacy raw object를 그대로 재사용하지 않는다.
8. Workspace URL Hardening
기존 차단:
- backslash
- encoded slash/backslash
- null/newline/tab encoding
- encoded
.. - cross-origin
- route pattern mismatch
v33 추가:
- workspace candidate 최대 2048자
- raw ASCII control character 차단
Recent는 기존 정책대로 query/hash를 persistence/replay에서 제거한다.
9. 테스트/재현성
추가된 v33 Gate:
scripts/validate-template-navigation-v33.mjs
검증 범위:
- idle async contract
- T01~T09 stateCapabilities
- idle action wiring
- Permission Host 제공/소비
- Golden/Reference idle 적용
- Home failed/urgent attention wiring
- Preference v3 bounds/migration
- Workspace URL length/control-character hardening
- Component SemVer/Catalog scenario
기존 kbx-navigation-hardening.contract.spec.ts의 Recent query/hash 기대값도 현재 정책에 맞게 수정하고, oversized/control-character path 테스트를 추가했다.
kbx-template-state-matrix.contract.spec.ts를 추가하여 Template별 상태 책임을 계약 테스트로 고정했다.
10. 기술부채 판단
이번 변경에서 피한 것:
- 모든 상태를 하나의 거대한 Dynamic State Engine으로 통합
- Permission을 UI에만 의존
- Home에 그래프/카드 Dashboard를 추가
- Notification/Operation payload 전체를 Home에 복제
- localStorage 암호화로 보안을 가장
대신 적용한 것:
- 작은 상태 Union + Template Manifest
- Vue provide/inject Permission Host
- 기존 Runtime Operation/Notification의 집계만 Home에 전달
- bounded preference normalization
- 기존 route capability resolver 재사용
결과적으로 UX 완성도는 올라가되 Domain/Backend 경계를 침범하지 않는다.