36 KiB
KBX Design System v1.0
OMS · WMS · ERP Component Contract & Design Tokens
1. 설계 목표
KBX Design System의 목적은 예쁜 UI 라이브러리를 만드는 것이 아니다.
다음 문제를 구조적으로 제거하는 것이 목적이다.
- 화면별 입력 높이가 다름
- 조회 버튼 위치가 다름
- Lookup 방법이 다름
- Enter 동작이 다름
- Excel 처리 방식이 다름
- Grid 설정이 화면마다 다름
- 오류 표현이 다름
- 저장 후 Feedback이 다름
- AI Action 방식이 다름
- 개발자마다 PrimeVue 사용 방식이 다름
최종 원칙:
Vertical Slice는 업무를 구현하고, KBX는 UX를 구현한다.
2. 기술 계층
Vue 3 / TypeScript
│
▼
KBX Screen Templates
│
▼
KBX Business Components
│
▼
KBX Primitives
│
├──────── PrimeVue
│
└──────── AG Grid
Vertical Slice에서 PrimeVue 및 AG Grid를 직접 사용하는 것은 예외로 취급한다.
3. 패키지 구조
권장:
src/
└─ shared/
└─ kbx/
├─ tokens/
├─ primitives/
├─ business/
├─ grid/
├─ forms/
├─ lookup/
├─ excel/
├─ feedback/
├─ ai/
├─ templates/
├─ composables/
├─ directives/
├─ schemas/
└─ testing/
업무 모듈에서는:
modules/
├─ oms/
├─ wms/
└─ erp/
형태로 KBX를 소비한다.
4. Component 계층 규칙
Level 1 — Primitive
업무 의미를 모른다.
KbxButton
KbxInput
KbxNumberInput
KbxDatePicker
KbxSelect
KbxCheckbox
KbxRadio
KbxTextarea
KbxDialog
KbxDrawer
KbxTabs
KbxBadge
KbxTooltip
Level 2 — Business Component
업무용 UX 규칙을 포함한다.
KbxLookup
KbxSearchPanel
KbxCommandBar
KbxDataGrid
KbxMoneyField
KbxQuantityField
KbxBarcodeField
KbxStatus
KbxAuditTrail
KbxExcelImport
KbxBulkActionBar
KbxJobProgress
KbxHelpPanel
KbxAiPanel
KbxProposalPanel
Level 3 — Screen Template
업무 화면 골격을 책임진다.
KbxListPage
KbxMasterPage
KbxTransactionPage
KbxFastEntryPage
KbxMasterDetailPage
KbxQueuePage
KbxReconcilePage
KbxImportPage
KbxWmsMobilePage
5. 핵심 금지 규칙
Vertical Slice에서 다음과 같은 구현을 반복하지 않는다.
<InputText />
<Button />
<Dialog />
그리고 각 화면이 직접:
window.addEventListener("keydown", ...)
방식으로 F2/F3/F8을 구현하지 않는다.
KBX에서 공통 관리한다.
6. Design Token 체계
Token은 다음 계층으로 관리한다.
Primitive Token
↓
Semantic Token
↓
Component Token
7. Primitive Spacing Token
기준 Unit:
4px
space-0 0
space-1 4px
space-2 8px
space-3 12px
space-4 16px
space-5 20px
space-6 24px
space-8 32px
space-10 40px
space-12 48px
업무 Desktop에서는 8px을 기본 간격으로 사용한다.
과도한 24~32px 여백을 Form 내부에 반복하지 않는다.
8. Typography
기본 Font Stack:
Pretendard
"Apple SD Gothic Neo"
"Noto Sans KR"
Arial
sans-serif
권장 Token:
font-xs 12px
font-sm 13px
font-md 14px
font-lg 16px
font-xl 18px
font-2xl 20px
사용:
Grid 13px
Helper 12~13px
Form 14px
Section Heading 16px
Page Heading 20px
업무 본문에서 16px 이상을 무조건 기본으로 사용하지 않는다.
9. Font Weight
regular 400
medium 500
semibold 600
bold 700
일반 업무 데이터:
400
Label:
500
Section:
600
Page Title:
600
Bold 남용 금지.
10. Size Token
Desktop:
control-xs 28px
control-sm 32px
control-md 36px
control-lg 40px
KBX 기본:
control-sm / 32~34px
일반 업무 입력:
34px
WMS Mobile:
48px 이상
11. Radius
radius-sm 4px
radius-md 6px
radius-lg 8px
업무 화면 기본:
4px
Dashboard 카드가 아닌 Form과 Grid에 과도한 12~20px Radius를 사용하지 않는다.
12. Semantic Color
색상 자체보다 의미를 우선한다.
surface
surface-muted
border
border-strong
text
text-muted
primary
success
warning
danger
info
focus
disabled
특정 업무 상태를 RGB 값으로 직접 작성하지 않는다.
13. 상태 색상 사용 원칙
색상은 보조수단이다.
예:
⚠ 재고 부족
에서 ⚠와 텍스트를 함께 사용한다.
단순히 행 전체를 빨간색으로 표시하지 않는다.
14. Density Token
compact
comfortable
touch
Compact
ERP/OMS Desktop 기본.
Input 32~34
Grid row 32~34
Comfortable
일반관리 및 가독성 우선.
Input 36~40
Grid row 38~40
Touch
WMS PDA/Mobile.
48px+
15. KbxButton
목적
버튼의 외형뿐 아니라 다음 UX를 통제한다.
- 중요도
- Keyboard Hint
- Loading
- Disabled
- Permission
- Confirmation
Variants
primary
secondary
tertiary
danger
ghost
사용 규칙
한 Command 영역에 Primary 버튼은 원칙적으로 하나.
예:
[조회]
[신규]
[저장]
중 저장만 Primary.
16. KbxButton API
개념 계약:
interface KbxButtonProps {
label: string
variant?: 'primary' | 'secondary' | 'tertiary' | 'danger' | 'ghost'
size?: 'sm' | 'md' | 'lg'
shortcut?: string
loading?: boolean
disabled?: boolean
permission?: string
confirm?: ConfirmDefinition
}
사용:
<KbxButton
label="저장"
shortcut="F8"
variant="primary"
:loading="saving"
@click="save"
/>
표시:
[저장 F8]
17. 버튼 Label 정책
좋음:
조회
저장
출고확정
재고조정
주문취소
나쁨:
실행
처리
확인
Action
OK
업무 결과를 설명하는 동사를 사용한다.
18. KbxInput
기본 계약:
interface KbxInputProps {
modelValue?: string | null
label?: string
required?: boolean
readonly?: boolean
disabled?: boolean
placeholder?: string
helpText?: string
error?: string
maxLength?: number
}
19. Input 상태
모든 입력 컴포넌트는 동일하게 다음 상태를 지원한다.
Default
Hover
Focus
Filled
Readonly
Disabled
Changed
Error
Warning
AI Suggested
readonly와 disabled를 동일하게 표현하지 않는다.
20. Readonly 규칙
Readonly:
- 값 복사 가능
- Focus 허용 여부는 화면 목적에 따라 결정
- 수정 불가
Disabled:
- 업무 조건상 사용할 수 없음
- 일반적으로 Tab Stop 제외
사용자가 둘의 차이를 시각적으로 알 수 있어야 한다.
21. KbxNumberField
숫자를 String Input처럼 다루지 않는다.
지원:
integer
decimal
quantity
money
percentage
내부 값과 Display Format은 분리한다.
예:
Model = 1250000
Display = 1,250,000
22. KbxMoneyField
다음 정책을 가진다.
decimal precision
currency
negative allowed
zero allowed
max
min
사용:
<KbxMoneyField
v-model="unitPrice"
label="단가"
/>
23. KbxQuantityField
수량은 Money와 의미가 다르다.
추가 속성:
unit
availableQuantity
allowNegative
precision
예:
출고수량
[ 10 ] EA
가용 8 EA
오류:
출고 가능 수량은 8개입니다.
24. KbxDateField
기본적으로 지원:
직접입력
Calendar
YYYY-MM-DD
Keyboard
사용자가 날짜를 마우스로만 선택하도록 강제하지 않는다.
가능:
20260808
입력 후:
2026-08-08
로 Normalize할 수 있다.
25. KbxDateRange
ERP 조회화면 핵심 Component.
빠른 선택:
오늘
어제
최근 7일
이번달
지난달
직접선택
하지만 화면마다 빠른 기간 옵션을 다르게 만들지 않는다.
26. KbxSelect
값이 10~20개 이상이거나 검색 필요성이 높으면 Select보다 Lookup을 검토한다.
Select는 짧고 고정된 Enum에 사용한다.
적합:
상태
단위
사용여부
주문유형
부적합:
품목 50,000건
거래처 20,000건
27. KbxLookup
KBX에서 가장 중요한 Form Component 중 하나다.
목적:
Code + Name + Search + Keyboard
를 한 컴포넌트에서 해결한다.
28. KbxLookup 구조
거래처
[10001] [대한상사 ] [검색]
상태에 따라:
Code
Display
Search
구성.
29. Lookup API
개념 계약:
interface KbxLookupProps<TId> {
modelValue: TId | null
entity: string
label?: string
required?: boolean
disabled?: boolean
readonly?: boolean
allowCodeInput?: boolean
allowNameInput?: boolean
recent?: boolean
favorite?: boolean
}
30. Lookup Entity Provider
Lookup UI가 API URL을 직접 알지 않는다.
interface LookupProvider {
search(request: LookupSearchRequest): Promise<LookupResult>
resolve(request: LookupResolveRequest): Promise<LookupItem | null>
}
화면:
Customer Lookup
은 Provider만 지정한다.
31. Lookup Keyboard Contract
F2
→ 검색 Popup
Enter
→ 코드 Resolve 또는 선택
Esc
→ Popup 닫기
↑ ↓
→ 결과 이동
Enter
→ 결과 확정
선택 후:
다음 Form Control
로 Focus 이동.
32. Lookup 검색 결과
기본 컬럼은 Entity별로 Schema화한다.
Customer:
코드
거래처명
사업자번호
대표자
상태
Item:
품목코드
품목명
규격
단위
가용재고
Warehouse:
창고코드
창고명
구분
33. Lookup에서 AI 사용
검색 정확도를 높이기 위한 보조 용도로만 쓴다.
사용자:
대한 강남
AI/검색엔진이 후보를 넓힐 수 있지만 결과는 반드시 실제 Entity여야 한다.
AI가 Entity 자체를 생성하지 않는다.
34. KbxSearchPanel
조회 화면의 검색조건을 표준화한다.
구조:
Primary Filters
More Filters
Search Action
Reset
Saved Search
35. Search Panel API
interface KbxSearchPanelProps {
schema: SearchSchema
modelValue: Record<string, unknown>
remember?: boolean
savedSearch?: boolean
}
업무 화면에서 각 Label/Grid를 직접 배치하지 않는다.
36. Search Schema 예
const orderSearchSchema = [
{
field: 'period',
type: 'dateRange',
label: '주문기간'
},
{
field: 'channelId',
type: 'lookup',
label: '판매채널'
},
{
field: 'status',
type: 'select',
label: '상태'
}
]
단, 모든 복잡 화면을 Schema화할 필요는 없다.
37. 조회 Keyboard
화면 어디서든:
F3 = 조회
단 입력 Editor나 브라우저 기능과 충돌 여부를 KBX Keyboard Manager에서 판단한다.
38. KbxCommandBar
Command 순서를 통제한다.
Slot을 무제한으로 열어주지 않는다.
논리 그룹:
query
edit
workflow
output
more
39. Command Bar 예
<KbxCommandBar>
<KbxCommand group="query" action="search" />
<KbxCommand group="edit" action="new" />
<KbxCommand group="edit" action="save" />
<KbxCommand group="workflow" action="ship" />
<KbxCommand group="output" action="excel" />
</KbxCommandBar>
렌더링:
[조회] [신규] [저장] │ [출고지시] │ [엑셀▼]
40. KbxDataGrid
AG Grid를 직접 외부 API처럼 노출하지 않는다.
KbxDataGrid가 다음을 통합한다.
- 기본 Theme
- Header
- Row density
- Selection
- Clipboard
- Excel
- Editing
- Validation
- Status
- Empty
- Loading
- Saved columns
- Permission
- Keyboard
41. Grid API
개념:
interface KbxDataGridProps<T> {
rows: T[]
columns: KbxGridColumn<T>[]
rowKey: keyof T
loading?: boolean
selection?: 'none' | 'single' | 'multiple'
editable?: boolean
clipboard?: boolean
exportable?: boolean
personalization?: boolean
summary?: KbxGridSummary[]
}
42. Column Contract
interface KbxGridColumn<T> {
field: keyof T
header: string
width?: number
minWidth?: number
align?: 'left' | 'center' | 'right'
type?: GridDataType
editable?: boolean
sortable?: boolean
filterable?: boolean
pinned?: 'left' | 'right'
lookup?: LookupDefinition
formatter?: string
permission?: string
}
43. Grid Data Type
공통:
text
code
number
quantity
money
percent
date
datetime
status
boolean
lookup
link
타입에 따라 정렬과 포맷을 자동 설정한다.
예:
type = money
→ right align
→ thousand separator
44. Grid Column 기본 너비
권장:
Checkbox 42
Status 80~100
Code 110~140
Date 110
DateTime 150~170
Quantity 90~110
Money 120~150
Name 180~240
Remark 240+
무조건 Auto Size해서 화면이 흔들리게 하지 않는다.
45. Grid Selection
Checkbox selection은 항상 왼쪽에 위치한다.
□ │ 상태 │ 주문번호 ...
Header Checkbox:
현재 Filter 결과 전체 선택인지 현재 Page 선택인지 명확히 표시한다.
대량 데이터에서 클라이언트 전체 Select라고 오해하게 만들지 않는다.
46. Grid Multi Selection
선택하면 하단 또는 상단에:
17건 선택
을 명시한다.
BulkActionBar와 연결한다.
47. KbxBulkActionBar
17건 선택
[출고지시]
[보류]
[담당자 변경]
선택이 0이면 숨기거나 Disabled.
Action마다:
minSelection
maxSelection
permission
allowedStatuses
설정 가능.
48. Grid Editing
편집 상태를 Row 전체가 아니라 Cell 중심으로 표시한다.
변경 Cell:
Changed
Validation 실패:
Error + message
저장 성공:
Changed 상태 제거.
49. Grid Clipboard
Excel 호환성이 최우선이다.
지원:
Ctrl+C
Ctrl+V
multi-cell copy
multi-row paste
붙여넣기 전에 각 Cell 타입 변환.
예:
"1,200"
→ decimal 1200
50. 대량 Paste Validation
100행 붙여넣었다고 Validation Modal 100개를 띄우지 않는다.
Grid:
7개 셀 오류
표시.
오류 탐색:
[첫 오류로]
[다음 오류]
지원.
51. Enter 동작
Editing Grid:
Enter
→ 입력 확정
→ 다음 Cell 또는 다음 Row
구체적인 이동방향은 Template에서 정의하되 같은 유형 화면에서 일관되어야 한다.
52. Tab 동작
Tab은 Editor 안에 갇히면 안 된다.
Grid 내부:
Tab
→ 다음 Editable Cell
마지막 Cell:
새 Row가 허용되는 Fast Entry에서는:
새 행
일반 조회 Grid에서는 Grid 밖 다음 Control.
53. KbxStatus
제품 전체 상태 Dictionary를 사용한다.
공통 Semantic:
draft
pending
ready
processing
completed
hold
warning
error
cancelled
disabled
업무 상태는 여기에 Domain Label을 Mapping한다.
예:
Domain: PickingCompleted
Semantic: completed
Label: 피킹완료
54. Status 난립 방지
신규 상태 정의 전 다음을 확인한다.
이미 같은 의미가 존재하는가?
업무적으로 정말 다른 상태인가?
UI 표시만 다른 것인가?
완료, 완료됨, 처리완료 같은 중복 상태명 생성을 막는다.
55. KbxFormSection
Master/Transaction의 Section 표준.
기본정보
────────────────────────
Accordion은 정보가 많을 때 사용하지만 핵심 Section을 기본 접힘으로 만들지 않는다.
56. Form Grid
기본 Desktop:
12-column
그러나 개발자가 Bootstrap처럼 자유롭게 조합하게 두지 않는다.
대표 폭 Preset:
field-sm
field-md
field-lg
field-full
57. Label Width
기본:
96px
업무별 장문 Label:
120px
한 화면에서 Label 폭을 가능한 한 통일한다.
58. 오류 Message
Field 오류는 Field 바로 아래.
주문수량
[-1]
주문수량은 0보다 커야 합니다.
전체 오류가 있으면 상단에 Summary도 허용.
저장할 수 없습니다. 3개 항목을 확인하세요.
클릭 시 오류 Field로 이동 가능.
59. Business Error
Field에 귀속되지 않는 업무 오류:
출고할 수 없습니다.
주문 3건에 재고가 부족합니다.
[부족 주문 보기]
사용자가 다음 행동을 알 수 있어야 한다.
60. KbxDialog
Modal은 제한적으로 사용한다.
Size Preset:
sm
md
lg
전체 화면 Modal은 원칙적으로 금지.
복잡 업무는 Page 또는 Drawer.
61. Dialog Keyboard
Esc = 닫기
Enter = Primary Action
단 Textarea/Form 입력 중 Enter submit을 무조건 발생시키지 않는다.
Focus Trap 필수.
닫힌 뒤 Focus Restore 필수.
62. KbxDrawer
사용 용도:
- 상세 조회
- Audit
- Help
- AI
- Contextual Detail
편집이 길어지면 Page로 승격.
63. KbxToast
성공:
저장했습니다.
실패:
중요 업무 오류는 Toast만 사용하지 않는다.
Toast는 시간이 지나면 사라지므로 해결이 필요한 오류에는 부적합하다.
64. Confirm 표준
위험 수준:
low
medium
high
Low:
Undo 가능한 작업은 Confirmation 생략 가능.
High:
출고를 확정하시겠습니까?
128건의 주문이 출고 상태로 변경됩니다.
확정 후 주문수량을 수정할 수 없습니다.
[취소]
[출고 확정]
65. KbxExcelMenu
모든 입력형 화면의 Excel 메뉴:
엑셀 ▼
├ 현재 조회결과 다운로드
├ 업로드 양식 다운로드
├ 엑셀 업로드
├ Excel 붙여넣기
└ 최근 업로드 결과
화면별 메뉴명을 임의로 바꾸지 않는다.
66. Import Field Definition
공통 Field Metadata:
interface KbxFieldDefinition {
key: string
label: string
aliases?: string[]
dataType: string
required?: boolean
maxLength?: number
precision?: number
scale?: number
lookup?: string
importable?: boolean
exportable?: boolean
readonly?: boolean
sensitive?: boolean
}
67. Excel Mapping Confidence
자동 Mapping 유형:
Exact
Alias
Saved
AI
Manual
UI에서 Source를 식별 가능하게 한다.
예:
상품코드 → 품목코드
Alias 일치
AI:
업체 → 거래처코드
AI 추천 87%
AI 추천을 확정값처럼 보이지 않는다.
68. Import Validation
구분:
Format Error
Reference Error
Business Error
Duplicate
Warning
예:
Format
날짜 형식 오류
Reference
존재하지 않는 품목
Business
출고완료 주문 수정 불가
Duplicate
동일 주문번호 중복
69. KbxJobProgress
Hangfire 기반 장시간 작업 UX.
상태:
Queued
Running
Completed
PartiallyCompleted
Failed
Cancelled
UI:
주문 Excel Import
13,421 / 17,894
75%
정상 13,218
오류 203
70. SignalR 연결
장시간 작업은 Polling만으로 구현하지 않는다.
권장:
Command
→ Job 생성
→ Hangfire
→ Progress 저장
→ SignalR push
Refresh 후에도 Job 상태를 API로 복구한다.
SignalR은 편의 Channel이지 Source of Truth가 아니다.
71. KbxAuditTrail
필수 표현:
Actor
Time
Action
Old
New
Reason
Source
Source:
User
System
Import
API
AIApproved
Batch
72. 사용자용 Audit와 기술 Audit 분리
사용자:
수량 10 → 8
기술 추적:
CorrelationId
RequestId
EventId
CommandId
OutboxId
기술 ID를 일반 화면에 노출하지 않는다.
상세 기술정보에서만 확인 가능.
73. KbxHelpPanel
Help는 Screen ID와 연결한다.
screenId = OMS-ORD-001
구성:
화면 목적
기본 사용법
단축키
주요 상태
자주 발생하는 오류
관련 화면
74. 도움말 유지보수
화면 코드 내부에 긴 도움말 문자열을 직접 넣지 않는다.
Help Content는 버전 관리 가능한 별도 콘텐츠로 관리.
ScreenVersion과 연계하면 더 좋다.
75. KbxAiPanel
AI Panel이 직접 Domain API를 임의 호출하지 않는다.
AI interaction:
Screen Context
↓
AI Service
↓
Tool/Query
↓
Proposal
↓
Domain Command
76. AI Context
AI에 보낼 수 있는 Context는 명시적으로 정의한다.
예:
interface AiScreenContext {
screenId: string
module: string
selectedIds?: string[]
filters?: unknown
currentEntityId?: string
}
화면 전체 DOM이나 민감 데이터 전체를 무차별 전달하지 않는다.
77. AI Action Contract
AI 응답을 자연어로 Parsing하여 실행하지 않는다.
Structured Action:
type
entityIds
parameters
reason
confidence
source
형태로 검증한다.
78. AI Proposal Component
모든 변경 제안은 공통 UX:
AI 제안
대상
17건
변경
서울센터 → 인천센터
근거
인천센터 가용재고 충분
[취소]
[상세보기]
[적용]
79. AI Permission
AI가 사용자보다 높은 권한을 가지면 안 된다.
AI effective permission
=
current user permission
∩
AI allowed actions
로 이해하면 된다.
80. AI Hallucination Guard
Action 실행 전 Server가 반드시 확인:
Entity 존재
현재 상태
권한
Version
Business Rule
Reference Integrity
AI confidence는 Domain Validation을 대체하지 않는다.
81. Optimistic Concurrency UX
업무 시스템에서 중요한 항목이다.
사용자가 오래 열어둔 주문을 다른 사용자가 수정한 경우:
다른 사용자가 이 주문을 변경했습니다.
현재 화면
수량 10
최신 값
수량 8
[최신 내용 보기]
무조건 마지막 저장자가 덮어쓰게 하지 않는다.
82. Version Token
Transaction에:
version
rowVersion
updatedAt
등의 동시성 기준을 둔다.
PostgreSQL 환경에서는 별도 Version Column을 명시적으로 운영하는 편이 감사·재현성 측면에서 이해하기 쉽다.
83. Unsaved Change Standard
Form Dirty 상태는 공통 Composable에서 관리한다.
useKbxDirtyState()
Page/Workspace Tab 이동 모두 동일한 규칙 적용.
84. Keyboard Manager
전역 단축키는 하나의 Manager에서 관리한다.
개념:
useKbxShortcut()
Scope:
Application
Page
Grid
Dialog
Editor
우선순위가 있어야 한다.
85. Shortcut Priority
예:
Dialog Open 상태에서:
Esc
는 Page가 아니라 Dialog가 처리한다.
Grid Cell Editing 중:
Enter
는 Global Command가 아니라 Cell Editor가 처리한다.
86. 공통 단축키
F2 Lookup
F3 조회
F8 저장/Primary commit
Ctrl+S 저장
Esc Context cancel
화면별 임의 F-Key 추가는 검토 후 승인.
87. Browser Shortcut 보호
다음 키는 함부로 Override하지 않는다.
F5
Ctrl+L
Ctrl+T
Ctrl+W
Ctrl+R
웹 앱이 Desktop ERP를 흉내낸다는 이유로 브라우저 기본 기능을 파괴하지 않는다.
88. WMS Barcode Component
KbxBarcodeCapture
필요 기능:
keyboard wedge
camera scanner
duplicate debounce
terminator handling
offline queue
sound feedback
vibration
89. Barcode 중복 입력 방지
Scanner가 동일 Barcode를 매우 짧은 시간에 중복 전송할 수 있다.
Client UX 레벨 debounce와 Server Idempotency를 모두 둔다.
Client만으로 중복을 막지 않는다.
90. Offline Command
WMS 일부 업무가 Offline Queue를 허용한다면 Command마다 정책을 명확히 한다.
offlineAllowed
requiresOnlineValidation
conflictPolicy
모든 업무를 무조건 Offline 지원하려 하지 않는다.
재고 확정 등 강한 정합성이 필요한 Action은 Online 요구가 더 적절할 수 있다.
91. Network Indicator
PDA 상단:
● 온라인
불안정:
▲ 연결 불안정
3건 전송 대기
오프라인:
○ 오프라인
사용자가 동일 작업을 반복하지 않게 한다.
92. KbxWmsActionButton
현장 CTA는 Desktop Button과 별도 규격.
높이 52~56
큰 Label
아이콘은 보조
예:
[작업 시작]
[재고부족 신고]
[다음 주문]
93. WMS 오류 우선순위
- 사용자가 지금 무엇을 해야 하는가
- 무엇이 잘못되었는가
- 기술적인 상세
예:
좋음:
A-03-02 위치로 이동하세요.
현재 스캔한 위치는 A-03-01입니다.
나쁨:
Location validation failed.
94. Screen Template Contract
모든 Template은 기본적으로 다음 Slot을 가진다.
title
commands
search
content
summary
utility
임의 위치에 버튼을 넣는 것을 제한한다.
95. KbxListPage
표준:
PageHeader
CommandBar
SearchPanel
KPI/QuickFilter(optional)
Grid
Summary
UtilityRail
96. KbxMasterPage
표준:
PageHeader
CommandBar
MasterList(optional)
Form
Tabs(optional)
Audit
97. KbxTransactionPage
표준:
PageHeader
CommandBar
HeaderForm
DetailGrid
Summary
Workflow
Audit
98. KbxFastEntryPage
표준:
Minimal Header
Compact Command
Fast Entry Grid
Validation Summary
Total
불필요한 카드/Section을 줄인다.
99. KbxQueuePage
Work Summary
Exception Summary
Queue Grid
Quick Actions
시각적 Dashboard보다 Actionable Queue를 우선한다.
100. KbxReconcilePage
Criteria
Summary
Mismatch Filter
Comparison Grid
Resolution Action
Audit
101. Empty/Loading/Error Contract
모든 데이터 컴포넌트가 세 상태를 반드시 구현한다.
Loading
Empty
Error
화면마다 임의로 만들지 않는다.
102. Loading
첫 조회:
조회 중...
재조회:
기존 데이터를 유지하고 작은 Loading Indicator를 추가.
사용자가 화면 Context를 잃지 않게 한다.
103. Error Recovery
API 실패:
주문을 조회하지 못했습니다.
네트워크 연결을 확인한 후 다시 시도하세요.
[다시 조회]
가능하면 사용자가 입력한 검색조건을 보존한다.
104. Permission UX
권한 없음의 두 종류를 구분한다.
기능 자체가 필요 없는 사용자
숨김 가능.
기능 존재를 알아야 하지만 실행 권한 없음
Disabled + 이유.
예:
[출고취소]
권한이 없습니다.
업무 맥락에 따라 결정한다.
105. Masking
개인정보:
010-****-1234
권한이 있는 사용자는:
[전체보기]
Audit을 남기도록 설계 가능.
106. Component Telemetry
공통 Component에 최소한의 UX Event를 구조화한다.
예:
screen.open
search.execute
lookup.open
lookup.select
grid.bulk_action
excel.import
validation.error
ai.proposal
ai.accept
사용자 감시가 아니라 UX 개선과 장애 분석 목적.
민감 값을 Telemetry에 직접 넣지 않는다.
107. UX Metric 연결
이벤트로 다음을 계산할 수 있어야 한다.
Task completion time
Clicks per task
Manual intervention
Validation failure
Import failure
Bulk action rate
AI acceptance
Exception resolution time
108. Component Version
주요 공통 Component:
KbxDataGrid 1.4.2
KbxLookup 1.2.0
식의 Version을 배포 Artifact 수준에서 식별 가능하게 한다.
운영 오류 재현에 도움이 된다.
109. SOLID — SRP
KbxLookup은 Lookup UX를 담당한다.
거래처 Business Rule까지 넣지 않는다.
Lookup UX
≠
Customer Domain
110. OCP
새 Entity Lookup:
기존 KbxLookup 변경보다 Provider 추가를 우선한다.
CustomerLookupProvider
ItemLookupProvider
WarehouseLookupProvider
111. LSP
모든 Lookup Provider는 동일한 기본 Search/Resolve 계약을 지켜야 한다.
특정 Provider만 Enter가 다르게 동작하는 방식은 피한다.
112. ISP
거대한:
IKbxEverythingService
를 만들지 않는다.
예:
LookupProvider
ExcelSchemaProvider
PermissionProvider
HelpProvider
로 책임 분리.
113. DIP
KBX Component가 OMS/WMS/ERP Module을 직접 의존하지 않는다.
업무 Module이 KBX Contract를 구현한다.
114. Pattern 선택
적극 사용할 패턴:
Adapter
Strategy
Command
Specification
Provider
Policy
Composite
State
패턴 자체가 목적이 되어서는 안 된다.
115. 과도한 추상화 금지
컴포넌트 2개에서만 쓰는 로직을 미리 범용 Framework로 만들지 않는다.
원칙:
반복이 관찰된 뒤 추상화
단, Excel, Grid, Lookup, Audit처럼 반복이 명백한 핵심 영역은 선제 표준화한다.
116. Normalization
Field Dictionary는 정규화된 Concept를 유지한다.
CustomerId
CustomerCode
CustomerName
화면마다:
Cust
Client
Partner
Customer
식으로 내부 FieldKey를 달리 만들지 않는다.
표시 Label은 업무별 변경 가능.
117. Denormalized Read Model
Grid 성능과 UX를 위해:
OrderSearchRow
에는:
CustomerName
ChannelName
ItemSummary
ExceptionCount
등을 포함할 수 있다.
정규화 원칙을 UX 조회 Projection에 기계적으로 적용하지 않는다.
118. 코드 리팩토링 기준
다음 신호가 보이면 KBX로 끌어올릴지 검토한다.
동일 UI 코드 3회 이상
동일 Keyboard 처리 반복
동일 Validation 표시 반복
동일 Grid option 반복
동일 Excel 처리 반복
단 업무 Rule이 다르다면 공통화하지 않는다.
119. 기술부채 등록
KBX 예외 구현은 반드시 이유를 남긴다.
예:
KBX Exception
Screen: WMS-PACK-003
Reason:
Bluetooth scale integration requires custom input lifecycle.
Review:
2026-Q4
예외가 조용히 영구 기술부채가 되지 않게 한다.
120. Vibe Coding 규칙
AI Coding Agent에게 자유 디자인을 맡기지 않는다.
Prompt 계약:
Screen Template:
KbxListPage
Search:
OrderSearchSchema
Grid:
OrderGridSchema
Actions:
search, ship, hold, excel
AI가 결정할 영역:
업무 연결 코드
Type 정의
API 호출
테스트
AI가 임의 결정하지 않을 영역:
버튼 위치
Grid UX
Keyboard
Excel UX
Status UX
121. Hallucination 방지 — Code Generation
AI가 존재하지 않는 KBX Component를 생성하면 안 된다.
Component Manifest를 제공한다.
예:
KbxButton
KbxLookup
KbxDataGrid
...
Manifest에 없는 Component는 새로 만들기 전에 검토한다.
122. Component Manifest
각 Component에:
Name
Purpose
AllowedUse
ForbiddenUse
Props
Events
Keyboard
Accessibility
Examples
Version
Owner
를 기록한다.
이 문서가 AI Coding Grounding 자료가 된다.
123. Storybook 수준의 Component Catalog 권장
컴포넌트별:
Default
Readonly
Disabled
Required
Error
Loading
Keyboard
Compact
을 재현 가능하게 한다.
어떤 도구를 사용하든 목적은 동일하다.
컴포넌트 상태를 독립적으로 재현 가능하게 만드는 것.
124. Visual Regression
공통 Component 변경 시:
Desktop Compact
Desktop Comfortable
WMS Touch
최소 세 Density 검증.
125. Vitest Contract Test
예: KbxLookup
반드시 확인:
F2 opens lookup
Esc closes
Enter resolves
Arrow navigation
Enter selects
Focus returns
Readonly blocks edit
Disabled removes interaction
Invalid code shows error
126. Playwright Screen Test
OMS 주문조회:
화면 진입
→ 주문기간 확인
→ F3 조회
→ Grid 결과
→ 행 선택
→ Bulk Action
→ 결과 확인
127. Keyboard E2E
별도 Mouse 사용 없이:
주문등록 진입
→ 거래처 F2
→ 검색
→ Enter
→ 품목
→ 수량
→ F8 저장
완료 가능한지를 자동화한다.
이 테스트가 실제 ERP UX 품질을 상당히 잘 검증한다.
128. Excel E2E
양식 다운로드
→ 샘플 업로드
→ Mapping
→ Validation
→ Commit
→ 결과 확인
그리고 오류 파일 Scenario도 테스트한다.
129. WMS E2E
Scanner Event를 모사하여:
Location scan
→ Item scan
→ Quantity 증가
→ 다음 상품
을 검증한다.
중복 Scan과 Network 재시도도 포함한다.
130. UX Definition of Done
새 Component는 다음을 만족해야 한다.
Design Token 사용
Keyboard 정의
Mouse 정의
Loading 정의
Readonly 정의
Disabled 정의
Error 정의
Accessibility 정의
Permission 정의
Testing 정의
Documentation 정의
131. Screen Definition of Done
새 화면은:
Template 선택
Command 표준
Search 표준
Grid 표준
Keyboard 지원
Excel 정책
Validation
Audit
Permission
Error Recovery
Empty
Loading
Unsaved Change
Playwright
가 정의되어야 한다.
132. 사용자 교육 최소화 검증
디자인 리뷰 때 화면을 처음 보는 내부 사용자에게 설명 없이 다음 업무를 시켜본다.
예:
오늘 주문을 조회하세요.
재고부족 주문을 찾아보세요.
주문 3건을 선택해서 출고지시하세요.
사용자가 메뉴얼 없이 수행할 수 있어야 한다.
133. UX 혁신 판단
새 Component 제안이 나왔을 때:
기존 사용문법으로 해결 가능한가?
YES:
기존 문법을 우선.
새로운 Interaction이:
클릭 감소
입력 감소
오류 감소
판단 감소
중 명확한 이익을 주지 않으면 도입하지 않는다.
134. 최종 Component 구성
KBX 1차 필수 구현 범위:
KbxButton
KbxInput
KbxNumberField
KbxMoneyField
KbxQuantityField
KbxDateField
KbxDateRange
KbxSelect
KbxLookup
KbxPageHeader
KbxCommandBar
KbxSearchPanel
KbxFormSection
KbxDataGrid
KbxBulkActionBar
KbxStatus
KbxDialog
KbxDrawer
KbxToast
KbxConfirm
KbxExcelMenu
KbxExcelImport
KbxJobProgress
KbxAuditTrail
KbxHelpPanel
KbxAiPanel
KbxProposalPanel
KbxListPage
KbxMasterPage
KbxTransactionPage
KbxMasterDetailPage
KbxQueuePage
KbxReconcilePage
KbxWmsMobilePage
이 정도면 OMS/WMS/ERP 초기 업무 화면 대부분을 커버할 수 있다.
135. 가장 중요한 구현 원칙
PrimeVue와 AG Grid를 없애거나 대체하는 것이 목표가 아니다.
오히려 검증된 제품을 적극 사용한다.
다만:
PrimeVue API
AG Grid API
가 제품 화면 전체로 새어나가지 않게 한다.
우리 제품이 의존해야 할 API는:
KBX Business UX Contract
이다.
그래야 라이브러리 업그레이드, UX 개선, 키보드 정책 변경을 공통 계층에서 해결할 수 있다.
136. KBX의 최종 가치
이 구조가 정착되면 신규 화면을 만들 때 질문이 달라진다.
기존:
버튼은 어디에 두죠?
검색창은 어떻게 만들죠?
Grid는 어떤 옵션을 쓰죠?
Excel 업로드는 어떻게 하죠?
F2는 어떻게 처리하죠?
KBX 이후:
이 화면은 어떤 업무인가?
사용자가 정말 판단해야 하는 것은 무엇인가?
어떤 입력을 자동화할 수 있는가?
어떤 예외만 사용자에게 보여줄 것인가?
디자인 결정의 상당 부분이 이미 끝나 있기 때문이다.
그 상태가 우리가 원하는 표준화된 한국형 업무 UX/AX 플랫폼이다.