/** * 품목기준관리 타입 정의 * * 동적 페이지 구성, 버전 관리, 멀티테넌시 지원 */ import type { ItemType } from './item'; // ===== 페이지 타입 ===== /** * 페이지 유형 * - item-master: 품목기준정보 * - quotation: 견적 * - sales-order: 수주 * - formula: 계산식 * - pricing: 단가 */ export type PageType = 'item-master' | 'quotation' | 'sales-order' | 'formula' | 'pricing'; /** * 필드 입력 타입 */ export type FieldInputType = | 'textbox' | 'dropdown' | 'checkbox' | 'number' | 'date' | 'textarea' | 'file' | 'multi-column'; /** * 섹션 타입 */ export type SectionType = 'fields' | 'bom' | 'table'; // ===== 필드 설정 ===== /** * 필드 표시 조건 */ export interface FieldDisplayCondition { dependsOn: string; // 의존하는 필드 키 showWhen?: string | string[]; // 표시 조건 값 hideWhen?: string | string[]; // 숨김 조건 값 } /** * 필드 유효성 검사 규칙 */ export interface FieldValidationRule { type: 'required' | 'min' | 'max' | 'pattern' | 'custom'; value?: any; message: string; } /** * 필드 속성 */ export interface FieldProperty { inputType: FieldInputType; required: boolean; row: number; // 그리드 행 번호 col: number; // 그리드 열 번호 options?: string[]; // 드롭다운 옵션 defaultValue?: any; placeholder?: string; // 멀티컬럼 필드 관련 multiColumn?: boolean; columnCount?: number; columnNames?: string[]; // 유효성 검사 validation?: FieldValidationRule[]; // 표시 조건 displayCondition?: FieldDisplayCondition; } /** * 필드 정의 */ export interface FieldConfig { id: string; name: string; // 필드 라벨 fieldKey: string; // 데이터 키 property: FieldProperty; helpText?: string; // 도움말 텍스트 } // ===== 섹션 설정 ===== /** * 섹션 정의 */ export interface SectionConfig { id: string; title: string; // 섹션 제목 description?: string; type: SectionType; fields: FieldConfig[]; order: number; // 섹션 순서 isCollapsible: boolean; // 접기/펼치기 가능 여부 isCollapsed: boolean; // 기본 접힘 상태 // 조건부 표시 category?: string[]; // 특정 카테고리에서만 표시 } // ===== 페이지 설정 ===== /** * 페이지 구성 정보 */ export interface PageConfig { id: string; pageName: string; // 페이지명 pageType: PageType; // 페이지 유형 itemType?: ItemType; // 연결된 품목 유형 (optional) sections: SectionConfig[]; // 섹션 목록 isActive: boolean; // 사용 여부 // 버전 관리 version: number; // 현재 버전 isFinal: boolean; // 최종 확정 여부 // 멀티테넌시 tenantId: string; // 테넌트 ID // 메타데이터 createdAt: string; updatedAt: string; createdBy: string; updatedBy?: string; } // ===== 버전 관리 ===== /** * 페이지 구성 변경 이력 */ export interface PageConfigRevision { id: string; pageConfigId: string; version: number; // 버전 번호 previousVersion: number; // 이전 버전 changes: PageConfigChange[]; // 변경 내역 snapshot: PageConfig; // 전체 스냅샷 // 변경 정보 changedAt: string; changedBy: string; changeReason?: string; // 승인 정보 isApproved: boolean; approvedAt?: string; approvedBy?: string; } /** * 페이지 구성 변경 상세 */ export interface PageConfigChange { type: 'field_added' | 'field_removed' | 'field_modified' | 'section_added' | 'section_removed' | 'section_modified'; targetId: string; // 변경된 필드/섹션 ID fieldName?: string; // 변경된 항목명 oldValue?: any; newValue?: any; description: string; } // ===== 데이터 입력 ===== /** * 동적 폼 데이터 */ export interface DynamicFormData { id?: string; pageConfigId: string; pageType: PageType; tenantId: string; // 동적 필드 데이터 (key-value) fieldData: Record; // 버전 관리 version: number; isFinal: boolean; // 메타데이터 createdAt?: string; updatedAt?: string; createdBy?: string; updatedBy?: string; } // ===== API 응답 ===== /** * API 응답 기본 구조 */ export interface MasterDataApiResponse { success: boolean; data: T; message?: string; errors?: Record; } /** * 페이지네이션 응답 */ export interface MasterDataPaginatedResponse { data: T[]; current_page: number; last_page: number; per_page: number; total: number; } /** * 페이지 구성 조회 파라미터 */ export interface FetchPageConfigParams { pageType?: PageType; itemType?: ItemType; isActive?: boolean; version?: number; } /** * 버전 비교 결과 */ export interface VersionComparisonResult { version1: number; version2: number; changes: PageConfigChange[]; addedFields: FieldConfig[]; removedFields: FieldConfig[]; modifiedFields: Array<{ field: FieldConfig; changes: Record; }>; } // ===== 유틸리티 타입 ===== /** * 페이지 타입 라벨 */ export const PAGE_TYPE_LABELS: Record = { 'item-master': '품목기준정보', 'quotation': '견적', 'sales-order': '수주', 'formula': '계산식', 'pricing': '단가', } as const; /** * 섹션 타입 라벨 */ export const SECTION_TYPE_LABELS: Record = { 'fields': '입력 필드', 'bom': '부품구성표', 'table': '테이블', } as const; /** * 필드 입력 타입 라벨 */ export const FIELD_INPUT_TYPE_LABELS: Record = { 'textbox': '텍스트 입력', 'dropdown': '드롭다운', 'checkbox': '체크박스', 'number': '숫자 입력', 'date': '날짜', 'textarea': '텍스트 영역', 'file': '파일', 'multi-column': '다중 컬럼', } as const;