/** * Master Field Service * 마스터 필드(항목탭) 관련 도메인 로직 중앙화 * - validation (fieldService 재사용) * - parsing * - transform (폼 ↔ API) * - defaults */ import type { ItemMasterField } from '@/contexts/ItemMasterContext'; import type { ItemFieldType } from '@/types/item-master-api'; import { fieldService, type SingleFieldValidation } from './fieldService'; // ===== Types ===== export type MasterFieldType = ItemFieldType; export type AttributeType = 'custom' | 'unit' | 'material' | 'surface'; export interface MasterFieldFormData { name: string; key: string; inputType: MasterFieldType; required: boolean; category: string; description: string; options: string; // 콤마 구분 문자열 attributeType: AttributeType; multiColumn: boolean; columnCount: number; columnNames: string[]; } export interface MasterFieldValidationResult { valid: boolean; errors: { field_name?: string; field_key?: string; field_type?: string; }; } // ===== Service ===== export const masterFieldService = { // ===== Validation (fieldService 재사용) ===== /** * 전체 마스터 필드 폼 유효성 검사 */ validate: (data: Partial): MasterFieldValidationResult => { const errors: MasterFieldValidationResult['errors'] = {}; // 필드명 검증 (fieldService 재사용) const nameValidation = fieldService.validateFieldName(data.name || ''); if (!nameValidation.valid) { errors.field_name = (nameValidation as { valid: false; error: string }).error; } // 필드 키 검증 (fieldService 재사용) const keyValidation = fieldService.validateFieldKey(data.key || ''); if (!keyValidation.valid) { errors.field_key = (keyValidation as { valid: false; error: string }).error; } return { valid: Object.keys(errors).length === 0, errors, }; }, /** * 필드명 유효성 검사 (fieldService 위임) */ validateFieldName: fieldService.validateFieldName, /** * 필드 키 유효성 검사 (fieldService 위임) */ validateFieldKey: fieldService.validateFieldKey, /** * 필드 키 패턴 정규식 (fieldService 재사용) */ fieldKeyPattern: fieldService.fieldKeyPattern, /** * 필드 키가 유효한지 간단 체크 (fieldService 위임) */ isFieldKeyValid: fieldService.isFieldKeyValid, // ===== Parsing ===== /** * field_key에서 사용자 입력 부분 추출 (fieldService 위임) * 형식: {ID}_{사용자입력} → 사용자입력 반환 */ extractUserInputFromFieldKey: fieldService.extractUserInputFromFieldKey, /** * 옵션 문자열을 배열로 파싱 (fieldService 위임) */ parseOptionsFromString: fieldService.parseOptionsFromString, /** * 옵션 배열을 문자열로 변환 (fieldService 위임) */ optionsToString: fieldService.optionsToString, // ===== Transform ===== /** * 폼 데이터 → API 요청 객체 변환 */ toApiRequest: ( formData: MasterFieldFormData ): Omit => { const supportsMultiColumn = formData.inputType === 'textbox' || formData.inputType === 'textarea'; return { field_name: formData.name, field_key: formData.key, field_type: formData.inputType, category: formData.category || null, description: formData.description || null, is_common: false, default_value: null, options: formData.inputType === 'dropdown' ? fieldService.parseOptionsFromString(formData.options) : null, validation_rules: null, properties: { required: formData.required, attributeType: formData.inputType === 'dropdown' ? formData.attributeType : undefined, multiColumn: supportsMultiColumn ? formData.multiColumn : undefined, columnCount: supportsMultiColumn && formData.multiColumn ? formData.columnCount : undefined, columnNames: supportsMultiColumn && formData.multiColumn ? formData.columnNames : undefined, }, }; }, /** * ItemMasterField → 폼 데이터 변환 (수정 시 폼에 채우기 위함) */ toFormData: (field: ItemMasterField): MasterFieldFormData => { const properties = field.properties as Record | null; return { name: field.field_name, key: masterFieldService.extractUserInputFromFieldKey(field.field_key), inputType: field.field_type || 'textbox', required: properties?.required || false, category: field.category || '공통', description: field.description || '', options: masterFieldService.optionsToString(field.options), attributeType: properties?.attributeType || 'custom', multiColumn: properties?.multiColumn || false, columnCount: properties?.columnCount || 2, columnNames: properties?.columnNames || ['컬럼1', '컬럼2'], }; }, // ===== Defaults ===== /** * 새 마스터 필드 생성 시 기본값 */ getDefaultFormData: (): MasterFieldFormData => ({ name: '', key: '', inputType: 'textbox', required: false, category: '공통', description: '', options: '', attributeType: 'custom', multiColumn: false, columnCount: 2, columnNames: ['컬럼1', '컬럼2'], }), /** * 지원하는 필드 타입 목록 (fieldService 재사용) */ fieldTypes: fieldService.fieldTypes, /** * 지원하는 속성 타입 목록 */ attributeTypes: [ { value: 'custom', label: '직접 입력' }, { value: 'unit', label: '단위' }, { value: 'material', label: '재질' }, { value: 'surface', label: '표면처리' }, ] as const, /** * 다중 컬럼 지원 여부 확인 */ supportsMultiColumn: (inputType: MasterFieldType): boolean => { return inputType === 'textbox' || inputType === 'textarea'; }, };