ERP-node/.agent-pipeline/pipeline-state.json

46 lines
6.4 KiB
JSON

{
"id": "single-task",
"status": "running",
"config": {
"maxRetries": 3,
"parallel": false,
"timeout": "5m",
"workspacePath": "/Users/gbpark/ERP-node"
},
"tasks": [
{
"id": "single-1772253563065",
"name": "**Phase D: V2→V3 Migration 정확도 향상**을 구현해라.\n\n## 작업 ",
"agent": "frontend",
"description": "**Phase D: V2→V3 Migration 정확도 향상**을 구현해라.\n\n## 작업 내용\n\n`frontend/lib/meta-components/migration/migrateTo3_0.ts` 파일을 수정하여 V2 컴포넌트의 풍부한 속성을 V3 config에 더 정확히 매핑해라.\n\n### 현재 문제\n- autoFill 설정이 마이그레이션 시 손실됨\n- fileConfig가 보존되지 않음\n- category widgetType이 인식 안 됨\n- entity 검색 join 설정이 부족\n- split-panel, tabs-widget, table-search-widget 변환이 부족\n\n### 구체적 수정 사항\n\n#### 1. FieldRenderer로의 변환 강화 (convertToField 함수)\n\nV2 properties에서 다음 추가 매핑:\n\n```typescript\n// autoFill 보존\nautoFill: v2Comp.autoFill || config.autoFill || (v2Comp.properties?.autoFill),\n\n// widgetType → webType 매핑 강화\nconst widgetTypeToWebType: Record<string, string> = {\n \"text\": \"text\",\n \"direct\": \"text\",\n \"entity\": \"entity\",\n \"category\": \"category\", // 추가\n \"date\": \"date\",\n \"number\": \"number\",\n \"image\": \"file\", // 추가\n \"file\": \"file\",\n \"button\": \"text\", // fallback\n \"checkbox\": \"checkbox\",\n \"radio\": \"radio\",\n \"toggle\": \"toggle\",\n};\n\n// fileConfig 보존\nfileConfig: v2Comp.fileConfig || config.fileConfig,\n\n// entity join 설정\njoin: config.joinConfig || config.join || v2Comp.joinConfig,\n\n// categoryGroupCode\ncategoryGroupCode: config.categoryGroupCode || v2Comp.categoryGroupCode,\n```\n\n#### 2. V2 componentType → V3 메타 컴포넌트 매핑 강화\n\n현재 매핑에서 누락된 V2 타입 추가:\n\n```typescript\n// Field로 변환\n\"text-input\" → meta-field\n\"select-basic\" → meta-field (webType: \"select\")\n\"date-input\" → meta-field (webType: \"date\")\n\"number-input\" → meta-field (webType: \"number\")\n\"entity-search-input\" → meta-field (webType: \"entity\")\n\"autocomplete-search-input\" → meta-field (webType: \"entity\")\n\"category-manager\" → meta-field (webType: \"category\")\n\"image-widget\" → meta-field (webType: \"file\")\n\"file-upload\" → meta-field (webType: \"file\")\n\"numbering-rule\" → meta-field (webType: \"numbering\")\n\"textarea-basic\" → meta-field (webType: \"textarea\")\n\n// DataView로 변환\n\"table-list\" → meta-dataview\n\n// Action으로 변환\n\"button-primary\" → meta-action\n\n// Search로 변환\n\"table-search-widget\" → meta-search\n\n// Layout으로 변환\n\"tabs-widget\" → meta-layout (mode: \"tabs\")\n\"screen-split-panel\" → meta-layout (mode: \"columns\")\n\"split-panel-layout\" → meta-layout (mode: \"columns\")\n\"split-panel-layout2\" → meta-layout (mode: \"columns\")\n\"conditional-container\" → meta-layout (mode: \"rows\")\n\"section-card\" → meta-layout (mode: \"card\")\n\"section-paper\" → meta-layout (mode: \"card\")\n\n// Display로 변환\n\"text-display\" → meta-display (displayType: \"text\")\n\"card-display\" → meta-display (displayType: \"stat\")\n\n// Modal로 변환\n\"modal-repeater-table\" → meta-modal\n\"universal-form-modal\" → meta-modal\n\"repeat-screen-modal\" → meta-modal\n```\n\n#### 3. table-search-widget → meta-search 변환\n\nV2 table-search-widget의 config에서 검색 필드 추출:\n```typescript\nfunction convertToSearch(v2Comp: V2Component): MetaComponent {\n const config = v2Comp.componentConfig || {};\n const properties = v2Comp.properties || {};\n \n // V2 검색 위젯에서 필드 추출\n const searchFields = (config.searchFields || config.fields || []).map((f: any) => ({\n columnName: f.columnName || f.field || f.key,\n label: f.label || f.title || f.columnName,\n searchType: f.type === \"select\" ? \"select\" : f.type === \"date\" ? \"date\" : \"text\",\n options: f.options,\n }));\n \n return {\n id: v2Comp.id,\n type: \"meta-search\",\n position: v2Comp.position,\n config: {\n fields: searchFields,\n targetTableId: config.targetTableId || config.linkedTableId,\n targetTableName: config.tableName || v2Comp.tableName,\n _originalConfig: config,\n _originalType: v2Comp.componentType,\n },\n };\n}\n```\n\n#### 4. tabs-widget → meta-layout 변환\n\n```typescript\nfunction convertToLayout(v2Comp: V2Component): MetaComponent {\n const config = v2Comp.componentConfig || {};\n \n let mode = \"rows\";\n if (v2Comp.componentType === \"tabs-widget\") mode = \"tabs\";\n if (v2Comp.componentType?.includes(\"split-panel\")) mode = \"columns\";\n if (v2Comp.componentType === \"section-card\" || v2Comp.componentType === \"section-paper\") mode = \"card\";\n \n return {\n id: v2Comp.id,\n type: \"meta-layout\",\n position: v2Comp.position,\n config: {\n mode,\n gap: config.gap || 16,\n tabs: config.tabs, // tabs-widget의 탭 정보\n children: config.children || config.panels || [],\n _originalConfig: config,\n _originalType: v2Comp.componentType,\n },\n };\n}\n```\n\n### 주의사항\n- 먼저 현재 migrateTo3_0.ts를 읽어서 구조를 파악한 후 수정\n- 기존 코드 구조를 최대한 유지하면서 매핑만 확장\n- MetaComponent 타입 호환성 유지\n- _originalConfig와 _originalType은 반드시 보존\n\n완료 후 `cd frontend && npx tsc --noEmit 2>&1 | head -50` 빌드 확인.",
"depends": [],
"testCommand": "cd frontend && npx tsc --noEmit 2>&1 | head -50",
"status": "success",
"attempts": 1,
"maxRetries": 3,
"logs": [
{
"timestamp": "2026-02-28T04:39:23.065Z",
"type": "info",
"message": "Agent(frontend) 호출 시작 (시도 1)"
},
{
"timestamp": "2026-02-28T04:42:37.267Z",
"type": "agent",
"message": "Agent 응답 수신 (2107자)"
},
{
"timestamp": "2026-02-28T04:42:41.979Z",
"type": "test",
"message": "테스트 통과"
}
],
"startedAt": "2026-02-28T04:39:23.065Z",
"completedAt": "2026-02-28T04:42:41.980Z"
}
],
"totalTasks": 1,
"completedTasks": 1,
"failedTasks": 0,
"runningTasks": 0
}