Files
KArtSell.Aegis/docs/Design/KBX Design System v1.0.md
T

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

readonlydisabled를 동일하게 표현하지 않는다.


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 오류 우선순위

  1. 사용자가 지금 무엇을 해야 하는가
  2. 무엇이 잘못되었는가
  3. 기술적인 상세

예:

좋음:

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 플랫폼이다.