feat(templates): implement 11 standard CRUD template contracts and WBS roadmap with harness CLI v2.0 verification
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 12s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 8s
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 11s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 20s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 10s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped

This commit is contained in:
2026-07-26 01:36:43 +09:00
parent 827d4f5aba
commit 1e37e715e9
5 changed files with 406 additions and 1151 deletions
@@ -0,0 +1,161 @@
/**
* src/frontend/src/types/enterpriseTemplateContracts.ts
* OMS·WMS·ERP 공통 CRUD 화면 템플릿 표준 계약 및 타입 정의
* Specification: docs/ENTERPRISE_CRUD_DESIGN_SPECIFICATION.md
* Roadmap: docs/ROADMAP_ENTERPRISE_TEMPLATES_WBS.md
*/
/** 11대 표준 템플릿 ID */
export type EnterpriseTemplateId =
| 'TPL-LIST-01' // 목록·검색
| 'TPL-CREATE-01' // 단일 등록
| 'TPL-CREATE-02' // 헤더·라인 등록
| 'TPL-CREATE-03' // 단계형 등록
| 'TPL-DETAIL-01' // 상세 조회
| 'TPL-EDIT-01' // 일반 수정
| 'TPL-BULK-01' // 일괄 수정
| 'TPL-DELETE-01' // 삭제
| 'TPL-CANCEL-01' // 취소·역처리
| 'TPL-APPROVAL-01' // 승인·반려
| 'TPL-HISTORY-01'; // 변경 이력
/** 입력 필드 공통 상태 계약 */
export type FieldStatus =
| 'idle'
| 'focused'
| 'dirty'
| 'validating'
| 'valid'
| 'invalid'
| 'saving'
| 'saved'
| 'conflict'
| 'blocked'
| 'readonly'
| 'disabled';
export interface FieldError {
code: string;
fieldPath?: string;
severity: 'error' | 'warning' | 'info';
message: string;
remediation?: string;
rejectedValue?: unknown;
correlationId?: string;
}
export interface FieldWarning {
code: string;
message: string;
}
export interface FieldState<T = unknown> {
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;
}
/** Grid 컬럼 정의 계약 */
export interface GridColumnDefinition {
key: string;
label: string;
dataType:
| 'text'
| 'code'
| 'number'
| 'quantity'
| 'money'
| 'date'
| 'datetime'
| 'status'
| 'user'
| 'link';
width?: number;
minWidth?: number;
maxWidth?: number;
sortable: boolean;
filterable: boolean;
resizable: boolean;
hideable: boolean;
pinnable?: boolean;
align?: 'left' | 'center' | 'right';
permission?: string;
}
/** 변경 감지 및 동시 수정 3-Way Diff 모델 */
export interface ChangeFieldDiff {
path: string;
before: unknown;
after: unknown;
serverValue?: unknown;
}
export interface ChangeSet {
entityId: string;
baseVersion: number;
changedFields: ChangeFieldDiff[];
reasonCode?: string;
reasonText?: string;
}
/** 표준 API 오류 응답 계약 */
export interface ApiErrorResponse {
code: string;
message: string;
severity: 'ERROR' | 'WARNING';
fieldErrors?: Array<{
path: string;
code: string;
message: string;
rejectedValue?: unknown;
}>;
businessErrors?: Array<{
code: string;
message: string;
remediation?: string;
relatedEntity?: {
type: string;
id: string;
displayName?: string;
};
}>;
correlationId: string;
occurredAt: string;
}
/** 감사 및 이력 이벤트 계약 */
export interface AuditEvent {
eventId: string;
correlationId: string;
entityType: string;
entityId: string;
action: 'CREATE' | 'READ' | 'UPDATE' | 'DELETE' | 'CANCEL' | 'APPROVE';
actor: {
type: 'USER' | 'SYSTEM' | 'INTEGRATION' | 'AI';
id: string;
name: string;
};
changes?: ChangeFieldDiff[];
reason?: {
code: string;
text: string;
};
occurredAt: string;
source: {
channel: string;
screenId: string;
clientVersion?: string;
};
}