diff --git a/AGENTS.md b/AGENTS.md index 31b8f5a8..cdd93264 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,6 +52,7 @@ - `spec/09_decision_flow.yaml` - `spec/12_field_dictionary.yaml` - `spec/13_formula_registry.yaml` +- `docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md` ## 2. 문서 역할 - `AGENTS.md`: 운영 헌법과 링크 인덱스. @@ -98,6 +99,7 @@ - `.gitea/workflows/snapshot_admin.yml`: snapshot admin workflow and scheduled validation. - `.gitea/workflows/ci_lint.yml`: CI workflow lint gate for `.gitea/workflows/ci.yml`. - `docs/CLOUD_SERVER_SETUP.md`: 클라우드 서버(hz-prod-01, 178.104.200.7) 설정 하네스 가이드. 시놀로지 → 클라우드 마이그레이션 매핑 포함. +- `docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md`: OMS·WMS·ERP CRUD 화면 및 입력 컴포넌트 상용화 지침 명세 (엔터프라이즈 컴포넌트/트랜잭션 헌법). - `docs/GITEA_SECRETS_SETUP.md`: Gitea secrets setup and verification guide. - `docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md`: `GatherTradingData.xlsx` 보조 자산 런북. - `docs/ROADMAP_WBS.md`: `.gs → Python` 및 `xlsx → sqlite` WBS. @@ -186,6 +188,17 @@ - **하네스 & 테스트 안정성**: 모든 패치는 `Temp/` 및 하네스 테스트 스위트의 빌드 및 통과 로그를 통해 데이터로 증빙한다. 하네스 실패 시 빌드 승격을 전면 차단한다. - **비즈니스 로직 단순화**: 다차원 중첩 조건이나 연쇄 트리거를 제거하고 선형 구조(Waterfall, Sequence)의 단순 프로세스 플로우로 구현하여 추적 가능성을 극대화한다. - **코드 및 다국어 규칙**: 모든 관리자 UI 레이블, 폼, 오류 메시지는 한국어로 작성하며, 소스 코드 주석 및 내부 예외 메시지는 영어 작성을 허용한다. 클래스, 메서드, 프로퍼티는 `PascalCase`를 사용하고 비동기 메서드에는 `Async` 접미사를 지정한다. +- **OMS·WMS·ERP 상용화 10대 설계 원칙 (`docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md`)**: + 1. 공통 `FieldContract` (`FieldStatus`, `FieldState`)를 최우선으로 확정한다. + 2. `UI Primitive`와 `도메인 입력 컴포넌트`를 엄격히 분리한다. + 3. 단순 CRUD가 아닌 업무 트랜잭션 템플릿(목록, 등록, 상세, 수정, 일괄, 승인, 취소·역처리)을 적용한다. + 4. 클라이언트(UI 1차 검증) → 서버(업무 규칙) → DB(무결성/낙관적 락) 4계층 검증 경계를 준수한다. + 5. 원본 마스터 모델은 정규화하고 조회/피킹/대시보드는 역정규화 Read Model로 구별하며 과거 문서는 스냅샷을 보존한다. + 6. 완료된 시점 거래는 물리 삭제/덮어쓰기 대신 취소·반제·역처리 트랜잭션을 생성한다. + 7. 현장 작업(WMS)은 바코드 연속 스캔, 100ms 이내 단결 판정, 오프라인 큐 적재, 오류 음향/진동 피드백을 필수 탑재한다. + 8. AI 보조(AX)는 초안/추천 역할에 국한하며 R0~R4 위험 등급 정책을 준수하고 결정론적 수식(금액/수량/세금)은 AI에 직접 위임하지 않는다. + 9. 바이브코딩(AI 생성 코드)도 동일한 품질 게이트(타입/정적분석/E2E 테스트/이력 추적)를 통과한 경우에만 반영한다. + 10. 화면 개수가 아닌 필드 오류율, 건당 처리시간, 역처리율, P95 지표로 개발 성과를 검증한다. ## 5c. 퀀트 엔진 엔지니어링 철학 및 구현 원칙 (Operational Philosophy) - **SOLID & 컴포넌트화(Componentization) & 정공법**: 모든 C#/.NET 코드 작성 시 SOLID 원칙을 준수한다. 각 모듈은 단일 책임 원칙(SRP)을 가지며, 인터페이스와 비즈니스 서비스 레이어로 철저히 **컴포넌트화**하여 결합도를 낮추는 **정공법** 아키텍처를 고수한다. diff --git a/docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md b/docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md new file mode 100644 index 00000000..1b861276 --- /dev/null +++ b/docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md @@ -0,0 +1,1152 @@ +# OMS·WMS·ERP CRUD 화면 및 입력 컴포넌트 상용화 지침 + +## 1. 최상위 설계 원칙 + +### 1.1 CRUD가 아니라 업무 트랜잭션으로 정의한다 + +OMS·WMS·ERP에서 단순한 Create, Read, Update, Delete만으로 화면을 정의하면 실제 업무를 제대로 표현하지 못한다. + +예를 들어 출고지시의 업무 행위는 다음과 같다. + +> 주문 조회 → 재고 할당 → 피킹 지시 → 피킹 확정 → 패킹 → 출고 확정 → 운송장 반영 → 취소 또는 역처리 + +따라서 표준 화면 모델은 다음과 같이 확장해야 한다. + +| 구분 | 주요 행위 | +| ----- | ------------------------------ | +| 조회 | 검색, 필터, 비교, 집계, 다운로드 | +| 생성 | 직접 입력, 복사 생성, 템플릿 생성, 외부 연동 생성 | +| 수정 | 일반 수정, 인라인 수정, 일괄 수정 | +| 상태 전이 | 승인, 확정, 할당, 마감, 보류, 해제 | +| 예외 처리 | 취소, 반품, 역입고, 재처리, 보정 | +| 이력 | 변경 전후 비교, 작업자, 사유, 원천 추적 | +| 협업 | 코멘트, 첨부, 승인 요청, 담당자 변경 | +| AI 보조 | 값 추천, 이상 탐지, 입력 보정, 업무 설명 | + +완료된 거래 데이터를 삭제하거나 직접 덮어쓰는 방식보다 **취소·반제·역처리 트랜잭션**을 생성하는 방식이 이력성과 재현성 측면에서 안전하다. + +--- + +## 2. 전체 아키텍처 방향 + +입력 화면은 다음 5개 계층으로 분리한다. + +```text +업무 프로세스 + ↓ +화면 템플릿 + ↓ +업무 패턴 컴포넌트 + ↓ +도메인 입력 컴포넌트 + ↓ +UI Primitive +``` + +### 계층별 책임 + +| 계층 | 예시 | 책임 | +| ------------ | --------------------------- | -------------- | +| UI Primitive | Input, Button, Dialog, Grid | 시각·키보드·포커스·접근성 | +| 도메인 필드 | 금액, 수량, 품목, 창고, 로케이션 | 도메인 형식과 정규화 | +| 업무 패턴 | 품목검색, 주소입력, 재고할당 | 여러 필드의 업무 조합 | +| 화면 템플릿 | 목록, 상세, 등록, 승인 | 화면 배치와 표준 동작 | +| 프로세스 | 주문확정, 입고검수, 출고확정 | 상태 전이와 업무 규칙 | + +`OrderForm`이나 `WarehouseForm` 같은 거대 컴포넌트 안에 모든 로직을 넣지 않는다. 표시, 입력, 정규화, 검증, 권한, 저장, 상태 전이를 분리해야 한다. + +--- + +## 3. 반드시 제공해야 할 화면 템플릿 + +### 3.1 목록·검색 템플릿 + +OMS·WMS·ERP에서 사용자가 가장 오래 머무는 화면이다. + +필수 요구사항: + +* 저장된 검색조건과 개인별 기본 필터 +* 컬럼 표시·숨김·순서·폭 저장 +* 다중 조건 필터 및 조건 그룹 +* 서버 기반 정렬·필터·페이지 처리 +* 선택 행 유지 +* 일괄 선택과 일괄 작업 +* 엑셀 다운로드와 비동기 대용량 다운로드 +* 상세 화면 이동 후 목록 상태 복원 +* 합계·소계·건수 표시 +* 오류·보류·미처리 건 우선 필터 +* URL로 조회조건 공유 +* 키보드 기반 행 이동과 실행 +* 데이터 최신 시각 및 새로고침 상태 표시 + +**목록에서 모든 것을 수정하게 만들지 않는다.** 인라인 수정은 상태, 담당자, 메모 등 변경 위험이 낮은 필드로 제한한다. + +--- + +### 3.2 등록 템플릿 + +등록 화면은 입력량에 따라 세 가지로 나눈다. + +| 유형 | 적용 대상 | +| ------------- | ---------------- | +| Quick Create | 단순 마스터, 반복 등록 | +| Standard Form | 일반 주문, 발주, 입고 예정 | +| Step Form | 계약, 복합 주문, 대량 입고 | + +필수 요구사항: + +* 최초 진입 시 합리적인 기본값 +* 이전 입력값 복사 +* 임시 저장 +* 중복 등록 탐지 +* 필수값뿐 아니라 업무상 미완성 항목 표시 +* 단계별 입력 완료 상태 +* 저장 전 변경 내용 요약 +* 저장 결과와 생성 식별번호 명확화 +* 연속 등록 모드 +* 입력 중 세션 만료 복구 +* 브라우저 종료나 네트워크 장애 이후 복원 + +필드가 많다고 무조건 스텝 화면을 사용하면 전체 관계를 파악하기 어렵다. 업무 단계가 명확하거나 단계 간 검증이 필요한 경우에만 사용한다. + +--- + +### 3.3 상세·조회 템플릿 + +상세 화면은 읽기 전용 정보를 단순히 폼 모양으로 보여주는 화면이 아니다. + +다음 구조를 권장한다. + +```text +핵심 상태 및 식별정보 +업무 실행 버튼 +주요 요약 KPI +기본정보 +라인 상세 +관련 문서·트랜잭션 +예외·경고 +변경 이력 +첨부·코멘트 +``` + +상태별 허용 작업을 서버 정책에 따라 노출한다. 버튼을 숨기는 것만으로 권한을 처리해서는 안 된다. + +--- + +### 3.4 수정 템플릿 + +수정 진입 시 다음을 명확하게 보여준다. + +* 수정 가능한 필드 +* 수정할 수 없는 이유 +* 현재 문서 상태 +* 다른 사용자의 수정 여부 +* 마지막 변경자와 변경 시각 +* 수정이 후속 프로세스에 미치는 영향 + +저장 시에는 변경된 필드만 서버에 전달하되, 서버는 전체 업무 정합성을 다시 검증한다. + +--- + +### 3.5 일괄 작업 템플릿 + +ERP와 WMS에서는 단건 작업보다 일괄 작업의 품질이 생산성을 결정한다. + +필수 요구사항: + +* 선택 대상 건수와 적용 범위 표시 +* 화면 선택과 전체 검색 결과 선택의 구분 +* 변경 전 예상 영향 건수 +* 성공·실패·제외 결과 분리 +* 부분 성공 허용 여부 명시 +* 실패 행 재다운로드 +* 작업 ID와 처리 이력 +* 대용량 작업의 비동기 실행 +* 재실행 시 중복 처리 방지 + +--- + +### 3.6 승인·확정 템플릿 + +승인과 업무 확정은 일반 저장과 구분해야 한다. + +필수 요소: + +* 승인 대상과 변경 요약 +* 금액·수량·재고 영향 +* 정책 위반과 예외 승인 항목 +* 승인 의견 +* 승인자 및 대결자 +* 직무분리, 즉 작성자와 승인자 분리 +* 재승인 필요 조건 +* 반려 사유 코드와 상세 사유 + +--- + +### 3.7 취소·역처리 템플릿 + +단순 확인창으로 처리하지 않는다. + +반드시 보여줄 정보: + +* 취소 대상 +* 이미 진행된 후속 프로세스 +* 취소 가능한 범위 +* 재고·회계·배송 영향 +* 자동으로 생성되는 역트랜잭션 +* 취소 불가능 항목 +* 사유 코드와 상세 사유 +* 실행 후 복구 가능 여부 + +--- + +## 4. 입력 컴포넌트 공통 계약 + +모든 입력 컴포넌트는 화면별로 제각각 구현하지 않고 공통 상태 계약을 따라야 한다. + +```ts +type FieldStatus = + | "idle" + | "focused" + | "dirty" + | "validating" + | "valid" + | "invalid" + | "saving" + | "saved" + | "conflict" + | "blocked" + | "readonly" + | "disabled"; + +interface FieldState { + value: T | null; + rawValue?: string; + displayValue?: string; + + initialValue: T | null; + status: FieldStatus; + + dirty: boolean; + touched: boolean; + required: boolean; + + source: "user" | "scanner" | "import" | "api" | "system" | "ai"; + confidence?: number; + + errors: FieldError[]; + warnings: FieldWarning[]; + + recordVersion?: string; + lastChangedAt?: string; + lastChangedBy?: string; +} +``` + +### `readonly`와 `disabled`는 반드시 구분한다 + +* `readonly`: 값은 제출 대상이며 사용자가 변경할 수 없음 +* `disabled`: 현재 기능 자체를 사용할 수 없고 일반적으로 제출 대상에서도 제외 +* `hidden`: 표시되지 않음 +* `masked`: 존재는 보여주지만 일부 값을 보호 +* `blocked`: 업무 규칙 때문에 현재 변경할 수 없음 + +하나의 `disabled=true`로 모든 상태를 처리하면 권한, 업무 상태와 데이터 전송에서 오류가 발생한다. + +--- + +## 5. 입력 컴포넌트별 상용 요구조건 + +### 5.1 텍스트·코드 입력 + +적용 대상: + +* 주문번호 +* 품목코드 +* 거래처 코드 +* 외부 참조번호 +* 메모 + +요구조건: + +* 최대·최소 길이 +* 허용 문자 +* 대소문자 정책 +* 앞뒤 공백 제거 정책 +* 연속 공백 처리 +* 한글 IME 조합 중 검증 방지 +* 붙여넣기 정규화 +* 중복 여부 확인 +* 코드 자동 대문자화 여부 +* 마스킹과 민감정보 보호 +* 미입력과 빈 문자열의 구분 +* 사용자 입력 원문 보존이 필요한 필드 구분 + +코드값은 표시명과 분리한다. + +```text +저장값: ITEM-000128 +표시값: ITEM-000128 / 냉동 닭가슴살 1kg +``` + +표시명 변경이 과거 문서의 의미를 바꾸지 않도록 거래 시점 스냅샷이 필요한지 결정해야 한다. + +--- + +### 5.2 수량 입력 + +수량 입력은 일반 숫자 입력으로 처리해서는 안 된다. + +필수 메타데이터: + +* 단위 +* 최소·최대값 +* 소수점 자릿수 +* 증감 단위 +* 음수 허용 여부 +* 0 허용 여부 +* 환산 단위 +* 기준 단위 +* 가용 수량 +* 허용 오차 +* 로트·시리얼 관리 여부 + +예: + +```text +입력: 2 BOX +환산: 24 EA +가용: 20 EA +결과: 가용수량 초과 오류 +``` + +표시 단위와 저장 단위를 분리하고, 서버에는 기준 단위로 정규화된 값과 사용자가 입력한 단위를 함께 보존하는 것을 권장한다. + +--- + +### 5.3 금액·세금·환율 입력 + +필수 요구사항: + +* 통화 코드 +* 통화별 소수 자릿수 +* 반올림 방식 +* 반올림 적용 시점 +* 공급가액·세액·합계 관계 +* 세금 포함 여부 +* 환율 기준일 +* 환율 출처 +* 원화 환산금액 +* 수동 환율 변경 권한 +* 할인 적용 순서 +* 허용 할인율 + +금액 계산에는 부동소수점 자료형을 사용하지 않고 decimal 계열을 사용한다. 화면과 서버가 동일한 반올림 규칙을 공유해야 한다. + +계산 결과는 원칙적으로 읽기 전용으로 두고, 수동 조정이 필요할 경우 별도 조정 필드와 조정 사유를 기록한다. + +--- + +### 5.4 날짜·시간 입력 + +필수 요구사항: + +* 업무일자와 시스템 처리시각 분리 +* 사용자 시간대 표시 +* 서버 기준시각 보존 +* 날짜만 있는 값과 시간 포함 값 구분 +* 시작·종료일 관계 검증 +* 휴일·마감일 정책 +* 과거·미래 입력 범위 +* 월말과 회계기간 잠금 +* DST 영향이 있는 해외 사업장 고려 +* 키보드 직접 입력과 달력 선택 동시 지원 + +예를 들어 출고일은 업무일자이며, 실제 시스템에서 출고 확정을 누른 시각은 이벤트 시각이다. 두 값을 하나로 합치지 않는다. + +--- + +### 5.5 Select·검색형 참조 입력 + +품목, 거래처, 창고처럼 데이터가 많은 항목은 일반 드롭다운으로 만들지 않는다. + +요구조건: + +* 코드와 명칭 동시 검색 +* 초성·부분 일치 정책 +* 최근 사용 항목 +* 즐겨찾기 +* 사업장·조직·상태 기반 필터 +* 비활성 데이터 표시 정책 +* 선택한 값의 핵심 속성 미리보기 +* 중복 명칭 구분 +* 검색 결과 페이지 처리 +* 서버 검색 취소 및 요청 순서 보장 +* 키보드 탐색 +* 선택값 캐싱 +* 신규 마스터 생성 권한이 있을 경우 별도 흐름 제공 + +검색 도중 오래된 응답이 나중에 도착해 최신 결과를 덮어쓰지 않도록 요청 식별자나 취소 처리가 필요하다. + +--- + +### 5.6 바코드·RFID·스캐너 입력 + +WMS에서 가장 중요한 현장 컴포넌트다. + +필수 요구사항: + +* 스캔과 키보드 입력 구분 +* Enter, Tab 등 스캐너 종료문자 대응 +* 연속 스캔 모드 +* 중복 스캔 방지 시간창 +* 성공·실패 음향과 진동 피드백 +* 장갑 착용을 고려한 큰 조작 영역 +* 포커스 자동 복귀 +* 잘못된 로케이션·품목·로트 즉시 경고 +* 네트워크 단절 시 로컬 큐 적재 +* 재연결 후 중복 없는 동기화 +* 오프라인 상태 명시 +* 스캔 원문과 해석 결과 보존 +* GS1 등 복합 바코드 파싱 계층 분리 +* 카메라 스캔과 전용 장비 스캔 구분 + +현장에서는 오류 메시지를 읽을 시간이 없다. 색상만이 아니라 짧은 문구, 음향, 진동, 다음 행동을 함께 제공해야 한다. + +--- + +### 5.7 로트·시리얼 입력 + +필수 요구사항: + +* 로트와 시리얼 모드 구분 +* 수량과 입력 개수의 정합성 +* 중복 시리얼 검증 +* 유효기간 +* 제조일 +* 입고 로트와 출고 로트 추적 +* FEFO·FIFO 정책 표시 +* 수동 선택 제한 +* 다중 붙여넣기 +* 스캔 리스트 +* 실패 행만 재입력 +* 현재 문서와 전체 시스템 범위의 중복 확인 + +시리얼 100개를 100개의 텍스트 필드로 표시하지 않고, 스캔 리스트와 결과 집계를 제공한다. + +--- + +### 5.8 창고·존·로케이션 입력 + +요구조건: + +* 사업장 → 창고 → 존 → 로케이션 종속 관계 +* 사용 가능 여부 +* 보관 유형 +* 온도·위험물 조건 +* 혼적 가능 여부 +* 품목 제한 +* 현재 적재량 +* 용량 초과 경고 +* 출발·도착 로케이션 동일 여부 +* 실물 스캔 검증 +* 추천 로케이션과 추천 근거 + +--- + +### 5.9 라인 아이템 Grid + +주문라인, 발주라인, 입출고라인에 사용한다. + +필수 요구사항: + +* 행 추가·복사·삭제 +* 엑셀 범위 붙여넣기 +* 붙여넣기 미리보기 +* 행 단위 오류 표시 +* 셀 단위 오류와 전체 오류 요약 +* 품목 변경 시 종속값 초기화 정책 +* 합계와 계산값 즉시 반영 +* 변경된 셀 강조 +* 고정 컬럼 +* 키보드 셀 이동 +* 행 가상화 +* 서버 페이지 처리 여부 구분 +* 편집 중 정렬·필터 제한 +* 임시 행 ID +* 부분 성공 저장 금지 또는 명확한 정책 +* 삭제 행 복구 +* 중복 품목 통합 여부 + +Grid는 폼이 아니다. 폼 라이브러리의 필드를 수천 개 생성하는 방식보다 행 편집 모델과 변경 집합을 별도로 관리해야 한다. + +--- + +### 5.10 첨부파일·이미지 입력 + +요구조건: + +* 파일 유형과 용량 제한 +* 악성 파일 검사 +* 업로드 진행률 +* 중단·재개 +* 업로드 완료 전 저장 정책 +* 이미지 회전·압축 +* 모바일 카메라 촬영 +* 원본 파일명과 저장명 분리 +* 문서 유형 지정 +* 개인정보 포함 경고 +* 삭제·교체 이력 +* 접근 권한 +* 보존기간 + +--- + +### 5.11 AI 추천 입력 + +AI가 제안한 값은 사용자 직접 입력값과 시각적·데이터적으로 구분한다. + +반드시 포함할 정보: + +* 추천값 +* 추천 이유 +* 근거 데이터 +* 생성 시각 +* 모델 또는 규칙 버전 +* 신뢰도 +* 적용 시 변경되는 필드 +* 적용·부분 적용·거절 +* 거절 사유 +* 원래 값으로 되돌리기 + +AI는 권위 데이터베이스에 직접 값을 쓰지 않고, 원칙적으로 **초안 또는 변경 명령**을 생성해야 한다. + +--- + +## 6. 검증과 데이터 정합성 + +### 6.1 검증은 네 계층으로 구성한다 + +```text +1. UI 형식 검증 +2. 스키마 검증 +3. 서버 업무 규칙 검증 +4. DB 무결성 검증 +``` + +### UI 형식 검증 + +* 필수값 +* 길이 +* 숫자 형식 +* 날짜 형식 +* 즉각적인 사용자 피드백 + +### 스키마 검증 + +* 데이터 타입 +* 허용 범위 +* enum +* 필드 구조 +* 조건부 필수값 + +JSON Schema는 데이터 구조와 검증 규칙을 기술하고 UI에 필요한 힌트를 제공하는 용도로 활용할 수 있다. 다만 업무 규칙 전체를 JSON Schema에 억지로 담지 말고, 표시 스키마와 업무 정책을 분리한다. + +### 서버 업무 규칙 검증 + +* 주문상태별 변경 가능 여부 +* 가용재고 +* 거래처 신용한도 +* 회계기간 마감 +* 중복 출고 +* 품목과 창고의 호환성 +* 승인 한도 +* 세금 및 가격 정책 + +입력값은 형식이 올바르더라도 업무 의미상 잘못될 수 있으므로 서버에서 의미 검증을 해야 한다. OWASP 역시 형식 검증과 업무 의미 검증을 구분할 것을 권고한다. + +### DB 무결성 검증 + +* Primary Key +* Foreign Key +* Unique Constraint +* Check Constraint +* Not Null +* 트랜잭션 격리 +* 버전 또는 잠금 컬럼 + +클라이언트 검증은 사용성 기능이고, 서버와 데이터베이스 검증이 정합성의 최종 방어선이다. + +--- + +### 6.2 오류 모델을 표준화한다 + +```ts +interface FieldError { + code: string; + fieldPath?: string; + severity: "error" | "warning" | "info"; + message: string; + remediation?: string; + rejectedValue?: unknown; + correlationId?: string; +} +``` + +좋지 않은 오류: + +> 처리할 수 없습니다. + +권장 오류: + +> 가용재고가 8EA 부족합니다. 주문수량을 20EA 이하로 변경하거나 다른 창고를 선택하세요. + +오류에는 최소한 다음이 있어야 한다. + +* 무엇이 잘못되었는가 +* 어느 값이 문제인가 +* 왜 처리할 수 없는가 +* 사용자가 무엇을 해야 하는가 +* 지원팀이 추적할 수 있는 식별자 + +--- + +### 6.3 동시 수정 제어 + +여러 사용자가 동일 주문이나 재고를 수정할 가능성이 있으므로 낙관적 잠금을 기본으로 적용한다. + +```text +클라이언트 전송: +recordId = 1001 +version = 17 +변경값 = {...} + +서버 현재 버전: +version = 18 + +결과: +409 Conflict +``` + +충돌 시 다음 선택지를 제공한다. + +* 최신 데이터 다시 불러오기 +* 내 변경과 최신 변경 비교 +* 충돌하지 않는 필드만 재적용 +* 권한이 있는 경우 강제 덮어쓰기 +* 임시 입력값 복사 + +재고 차감, 일련번호 배정, 회계 전표 생성처럼 경쟁 조건에 민감한 행위는 낙관적 잠금만으로 충분한지 트랜잭션 단위에서 별도로 판단한다. + +--- + +### 6.4 중복 요청 방지 + +저장 버튼 연속 클릭, 네트워크 재시도, 모바일 재연결로 같은 거래가 두 번 생성될 수 있다. + +다음 조합을 사용한다. + +* 클라이언트 요청 ID +* Idempotency Key +* 업무 중복 키 +* 처리 상태 저장 +* 동일 요청 결과 재반환 +* 버튼 잠금만으로 해결하지 않음 + +--- + +## 7. 정규화와 역정규화 기준 + +### 7.1 정규화해야 하는 데이터 + +* 품목 마스터 +* 거래처 마스터 +* 조직과 사용자 +* 창고와 로케이션 +* 단위 변환 +* 코드와 상태 +* 권한 정책 +* 현재 재고 원장 +* 참조 관계 + +중복 입력과 갱신 이상을 줄여야 하는 데이터는 정규화한다. + +### 7.2 역정규화가 필요한 데이터 + +* 조회 전용 검색 인덱스 +* 주문 목록 요약 +* 대시보드 집계 +* 피킹 작업 화면 +* 리포트용 Read Model +* 자주 사용하는 조합 표시값 +* 시점 기준 스냅샷 + +읽기 모델은 원본 데이터와 구분하고 재생성 가능해야 한다. + +### 7.3 반드시 스냅샷해야 하는 항목 + +과거 주문이나 전표가 현재 마스터 변경으로 달라져서는 안 된다. + +예: + +* 주문 당시 품목명 +* 주문 당시 판매가격 +* 세율 +* 청구·배송 주소 +* 거래처명 +* 계약조건 +* 환율 +* 담당 영업조직 +* 단위 환산값 + +참조 ID와 거래 당시 스냅샷을 함께 저장하는 방식이 실무적으로 안전하다. + +--- + +## 8. UX와 접근성 요구조건 + +접근성 기준은 최소 WCAG 2.2 AA를 목표로 하고, 복합 위젯은 WAI-ARIA APG의 키보드와 시맨틱 패턴을 따른다. WCAG 2.2는 웹 콘텐츠와 애플리케이션의 접근성 기준을 제공하며, APG는 Grid, Combobox, Dialog 등 공통 위젯의 접근성 구현 패턴을 제공한다. + +필수 요구사항: + +* 모든 기능을 키보드로 수행 +* 논리적인 Tab 순서 +* 명확한 포커스 표시 +* 오류 발생 시 오류 요약으로 이동 +* 필드 오류와 입력 필드 연결 +* 색상만으로 상태를 구분하지 않음 +* 스크린리더용 Label과 Description +* Dialog 포커스 트랩과 종료 후 포커스 복귀 +* Grid의 행·열 위치 안내 +* 확대 시 가로 스크롤과 콘텐츠 손실 최소화 +* 모션 감소 설정 지원 +* 충분한 터치 영역 +* 시간 제한 경고와 연장 +* 자동 완성 속성의 적절한 사용 + +ARIA는 네이티브 HTML로 해결할 수 없는 경우에만 사용한다. 잘못된 ARIA는 보조기술 사용자에게 시각 화면과 다른 의미를 전달할 수 있다. + +--- + +## 9. 역할별 UX 전략 + +### 9.1 사무 사용자 + +중점: + +* 고밀도 정보 +* 키보드 조작 +* 다중 창과 비교 +* 대량 붙여넣기 +* 개인화된 필터 +* 엑셀 연계 +* 일괄 처리 + +### 9.2 창고 현장 작업자 + +중점: + +* 스캔 우선 +* 한 화면 한 작업 +* 큰 터치 영역 +* 최소 타이핑 +* 즉각적인 음향·진동 +* 네트워크 단절 대응 +* 다음 행동 자동 포커스 +* 오류 복구 단순화 + +### 9.3 관리자·승인자 + +중점: + +* 요약과 예외 중심 +* 변경 전후 비교 +* 영향도 +* 근거 자료 +* 승인 한도 +* 위험 신호 +* 모바일 승인 + +### 9.4 고객·협력사 + +중점: + +* 내부 용어 최소화 +* 권한과 데이터 범위 격리 +* 단계별 안내 +* 입력 예시 +* 진행 상태 +* 문의 연결 + +하나의 화면 밀도를 모든 역할에 적용하지 않고 Compact, Standard, Touch 등의 밀도 모드를 제공한다. + +--- + +## 10. AX: AI·Agent Experience 설계 + +### 10.1 AI 적용 우선순위 + +AI보다 결정론적 규칙이 적합한 영역: + +* 세금 계산 +* 재고 차감 +* 단위 환산 +* 상태 전이 +* 권한 검증 +* 회계기간 검증 +* 중복 키 검증 + +AI가 적합한 영역: + +* 자연어 주문 해석 +* 메일·문서에서 주문 초안 추출 +* 이상 주문 설명 +* 유사 오류 해결책 추천 +* 품목 매핑 후보 +* 비정형 메모 요약 +* 작업 우선순위 추천 + +**규칙으로 정확히 결정할 수 있는 문제를 AI에 맡기지 않는다.** + +--- + +### 10.2 AI 행위 위험 등급 + +| 등급 | 예시 | 정책 | +| -- | ----------------- | ----------------- | +| R0 | 조회·요약 | 자동 허용 | +| R1 | 필드 추천 | 사용자 적용 | +| R2 | 가역적 변경 초안 | 변경 내용 확인 후 실행 | +| R3 | 출고·발주·금액 변경 | 명시적 승인 | +| R4 | 회계 확정·대량 삭제·권한 변경 | 이중 승인 또는 AI 실행 금지 | + +--- + +### 10.3 홀루시네이션 통제 + +필수 통제: + +* 허용된 데이터 소스만 검색 +* 답변과 근거 문서 연결 +* 스키마가 제한된 구조화 출력 +* enum과 코드값 화이트리스트 +* 존재하지 않는 품목·거래처 참조 금지 +* 실행 전 서버 업무 검증 +* 변경 필드 미리보기 +* 신뢰도 표시 +* 사람 승인 +* 전체 실행 로그 +* 원복 명령 +* 모델·프롬프트·검색 버전 기록 + +AI가 생성한 코드나 필드값을 신뢰하는 것이 아니라, 기존 시스템의 검증 경계를 통과한 값만 업무 데이터로 인정한다. + +--- + +## 11. SOLID와 컴포넌트 구조 + +### 11.1 SRP: 단일 책임 + +분리 대상: + +```text +표시 +입력 상태 +형식 변환 +정규화 +동기 검증 +비동기 검증 +업무 정책 +권한 +API 통신 +이력 기록 +``` + +하나의 입력 컴포넌트가 API 호출, 권한 판단, 업무 검증까지 직접 수행하지 않는다. + +### 11.2 OCP: 확장에는 열리고 변경에는 닫힘 + +필드 레지스트리 방식으로 확장한다. + +```ts +interface FieldAdapter { + parse(raw: string): T | null; + format(value: T | null): string; + normalize(value: T | null): T | null; + validate(value: T | null, context: ValidationContext): FieldError[]; +} + +interface FieldDefinition { + id: string; + path: string; + type: string; + label: string; + + requiredWhen?: Rule; + visibleWhen?: Rule; + editableWhen?: Rule; + + adapter: FieldAdapter; + audit?: AuditPolicy; +} +``` + +새로운 `lot-number`, `warehouse-location`, `currency-amount` 필드를 추가할 때 공통 폼 엔진을 수정하지 않도록 한다. + +### 11.3 LSP: 교체 가능성 + +모든 필드는 공통 계약을 지켜야 한다. + +* 값 읽기 +* 값 변경 +* 초기화 +* 검증 +* 오류 포커스 +* 읽기 전용 표시 +* 접근성 이름 +* 변경 여부 +* 직렬화 + +### 11.4 ISP: 인터페이스 분리 + +다음 인터페이스를 분리한다. + +* EditableField +* ReadonlyField +* ScannableField +* SearchableField +* BulkEditableField +* AuditableField + +모든 컴포넌트에 모든 기능을 강제하지 않는다. + +### 11.5 DIP: 의존성 역전 + +UI 컴포넌트가 특정 API 클라이언트나 특정 폼 라이브러리에 직접 의존하지 않도록 Port를 둔다. + +```text +UI → Form Port → Use Case → Domain → Repository Port +``` + +--- + +## 12. Schema-Driven Form 적용 범위 + +Schema-Driven 방식은 표준화에 유리하지만 모든 업무 화면을 메타데이터로 만들면 오히려 유지보수성이 떨어진다. + +권장 구분: + +### 스키마로 처리할 것 + +* 기본 필드 정의 +* Label +* 데이터 타입 +* 형식 +* 필수 여부 +* 기본적인 조건부 표시 +* 기본 검증 +* 레이아웃 힌트 +* 권한 힌트 + +### 코드로 처리할 것 + +* 복잡한 Grid +* 스캔 작업 +* 재고 할당 +* 가격 계산 +* 상태 전이 +* 대량 업로드 +* 복잡한 상호작용 +* 실시간 장비 연동 + +권장 구조: + +```text +Data Schema +UI Schema +Policy Schema +Workflow Definition +Domain Code +``` + +하나의 거대한 JSON 파일에 모든 것을 담지 않는다. + +--- + +## 13. 바이브코딩과 기술부채 통제 + +바이브코딩은 탐색과 프로토타이핑에는 효과적이지만 상용 코드를 그대로 생산하는 방식으로 사용하면 안 된다. + +### 허용 영역 + +* 화면 프로토타입 +* 테스트 데이터 +* Storybook 스토리 초안 +* 반복 코드 생성 +* 마이그레이션 스크립트 초안 +* 테스트 케이스 후보 +* 문서 초안 + +### 통제가 필요한 영역 + +* 재고 차감 +* 금액 계산 +* 권한 +* 인증 +* 회계 처리 +* 상태 전이 +* 대량 데이터 변경 +* 개인정보 처리 + +### AI 생성 코드 완료 조건 + +* 요구사항 추적 ID 존재 +* 타입 검사 통과 +* 정적 분석 통과 +* 단위 테스트 +* 계약 테스트 +* 보안 검토 +* 코드리뷰 +* 성능 검증 +* 변경 영향 확인 +* 롤백 방법 +* 생성 코드의 책임자 지정 + +AI가 생성했다는 이유로 별도 예외를 두지 않는다. 오히려 익숙하지 않은 구현이 포함될 가능성을 고려해 검토 수준을 높인다. + +--- + +## 14. 성능과 안정성 목표 + +다음은 상용 서비스의 내부 목표값으로 제안한다. + +| 지표 | 권장 목표 | +| -------------- | -------------: | +| 일반 입력 반응 | 100ms 이내 | +| 바코드 입력 후 로컬 판정 | 100ms 이내 | +| 검색 결과 응답 | P95 1초 이내 | +| 일반 저장 | P95 2초 이내 | +| 목록 최초 표시 | P75 2초 이내 | +| 대량 Grid 직접 렌더링 | 화면 가시 행 중심 가상화 | +| 1만 건 이상 처리 | 비동기 Job | +| 저장 실패 복구 | 입력값 손실 없음 | +| 충돌 발생 | 비교·재적용 가능 | +| 네트워크 재시도 | 중복 거래 없음 | + +모든 저장을 낙관적으로 성공 표시하지 않는다. 재고, 회계, 승인처럼 서버 확정이 중요한 업무는 서버 처리 결과를 받은 후 성공 처리한다. + +--- + +## 15. 보안 요구조건 + +* 화면 권한과 API 권한 이중 검증 +* RBAC와 필요 시 ABAC 병행 +* 필드 단위 조회·수정 권한 +* 조직·사업장 데이터 격리 +* 개인정보 마스킹 +* 다운로드 권한 분리 +* 대량 작업 추가 인증 +* 승인 직무분리 +* 서버 측 입력 검증 +* 파라미터화된 쿼리 +* 출력 인코딩 +* 첨부파일 악성코드 검사 +* 감사로그 위변조 방지 +* 민감정보 로그 제외 +* AI 프롬프트 전송 전 민감정보 제거 + +--- + +## 16. 이력성과 재현성 + +모든 중요 변경에는 다음 정보를 남긴다. + +```ts +interface AuditEvent { + eventId: string; + correlationId: string; + entityType: string; + entityId: string; + + action: string; + actorType: "user" | "system" | "integration" | "ai"; + actorId: string; + + before?: unknown; + after?: unknown; + changedPaths: string[]; + + reasonCode?: string; + reasonText?: string; + + source: string; + occurredAt: string; + + policyVersion?: string; + modelVersion?: string; + promptVersion?: string; +} +``` + +--- + +## 17. 현장 중심 프로세스 단순화 + +업무 단순화 순서: + +```text +삭제 가능한 단계 제거 +→ 자동 계산 +→ 기본값 적용 +→ 스캔 또는 검색으로 대체 +→ 일괄 처리 +→ 예외만 사용자 판단 +→ AI 추천 +``` + +--- + +## 18. 과유불급을 막는 원칙 + +하지 말아야 할 설계: + +* 모든 화면을 하나의 범용 폼 엔진으로 해결 +* 모든 필드를 인라인 수정 가능하게 구성 +* 모든 입력에 자동 저장 적용 +* 완료된 거래의 물리적 삭제 +* 클라이언트 검증만 신뢰 +* 계산값을 사용자가 직접 수정 +* 현재 마스터를 과거 문서에 그대로 표시 +* 드롭다운에 수천 개 항목 적재 +* 오류를 Toast 하나로만 표시 +* 색상만으로 상태 표시 +* 권한 없는 버튼만 숨기고 API는 허용 +* AI 결과를 검증 없이 자동 적용 +* 추상화를 위해 추상화 계층 추가 +* 재사용 가능성이 없는 코드를 성급하게 공통화 + +--- + +## 19. 테스트 전략 + +컴포넌트 테스트, 계약 테스트, 업무 규칙 테스트, 현장 시나리오 테스트, AI 재현성 테스트 스위트 전수 수행. + +--- + +## 20. 관측 지표 + +입력 품질, 효율, 정합성, 현장성, 프로세스 체류시간, UX, AI 수락률, 시스템 P95 지표 통합 모니터링. + +--- + +## 21. 상용화 Definition of Done + +입력 컴포넌트는 다음 조건을 충족해야 완료로 본다. + +* 디자인 시스템 규격 충족 +* TypeScript 타입 안정성 (Strict Null Check) +* 정상·오류·읽기 전용·권한 없음 상태 제공 +* 키보드 조작 및 접근성 (WCAG 2.2 AA / WAI-ARIA) +* 한국어 IME 및 산업용 스캐너 반응성 +* 서버 검증 및 동시성 낙관적 락 충돌 처리 +* 마이그레이션 및 재현 테스트 통과