From 5df369100a85cefab616a262746e2ede6f3eb167 Mon Sep 17 00:00:00 2001 From: Hyein Date: Tue, 23 Jun 2026 17:56:00 +0900 Subject: [PATCH] Initial program flow page --- .gitignore | 6 + Dockerfile | 9 + data/backups/recovered-content-20260623.json | 422 ++++ data/backups/recovered-state-20260623.json | 1 + data/flow-db.json | 426 ++++ flow.html | 14 + index.html | 14 + package.json | 13 + recovered-content.json | 422 ++++ src/App.jsx | 2213 ++++++++++++++++++ src/main.jsx | 9 + vite.config.js | 90 + 12 files changed, 3639 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 data/backups/recovered-content-20260623.json create mode 100644 data/backups/recovered-state-20260623.json create mode 100644 data/flow-db.json create mode 100644 flow.html create mode 100644 index.html create mode 100644 package.json create mode 100644 recovered-content.json create mode 100644 src/App.jsx create mode 100644 src/main.jsx create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ce8d37d --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +.env +.env.* +.DS_Store +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f5b490e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM node:22-alpine + +WORKDIR /app +COPY package.json package-lock.json* ./ +RUN npm install +COPY . . + +EXPOSE 5173 +CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"] diff --git a/data/backups/recovered-content-20260623.json b/data/backups/recovered-content-20260623.json new file mode 100644 index 0000000..dae3258 --- /dev/null +++ b/data/backups/recovered-content-20260623.json @@ -0,0 +1,422 @@ +{ + "cheonjiin": { + "name": "천지인", + "description": "지형정보 생성", + "steps": [ + { + "title": "자료수집", + "feature": "직접선택, 도면 불러오기", + "note": "사업 대상지와 원본 도면 범위를 확정하여 지형도, 수치지형도, 정사영상등 취득" + }, + { + "title": "선택/검토", + "feature": "등고선, 레이어 선택", + "note": " 필요한 도면 요소와 레이어만 선택가능" + }, + { + "title": "현장조사", + "feature": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 적용 후 지형, 지층 보정", + "note": "실측 자료를 반영해 지형 정보를 보정(dwg, dxf 파일 등)\n지층은 .bori파일만 지원\n3d 형상 내보내기 가능" + }, + { + "title": "구조물편집", + "feature": "도로(방음벽, 난간),\n건물(텍스처, 외부모델),\n하천 배수구조물,\n지형(지표면, 지층, 구역텍스쳐)등 적용 후 모델재생성", + "note": "구조물과 지형 요소를 편집\n3d 형상 내보내기 가능" + }, + { + "title": "유역면적", + "feature": "유역 구분 및 면적 산정", + "note": "" + } + ], + "deliverables": [ + "지형도", + "수치지형도", + "정사영상", + "지형,지층 보정 모델" + ], + "format": "glb", + "predecessors": [], + "successors": [ + "wayPrimal", + "program-1782180934346" + ], + "detailGates": [ + { + "key": "gate1", + "stepId": "1-1", + "question": "노선변경?", + "yes": "자료수집 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate2", + "stepId": "1-2", + "question": "등고선 또는 적용 레이어 변경?", + "yes": "선택/검토 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate3", + "stepId": "1-3", + "question": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 정보 변경?", + "yes": "현장조사 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate4", + "stepId": "1-4", + "question": "도로(방음벽, 난간), 건물(텍스처, 외부모델),\n하천 배수구조물, 지형(지표면, 지층, 구역텍스쳐)등 정보 변경?", + "yes": "구조물편집 재실행", + "no": "WayPrimal로 이동", + "targetProgramId": "cheonjiin" + } + ] + }, + "wayPrimal": { + "name": "WayPrimal", + "description": "기본설계 성과물 생성", + "steps": [ + { + "title": "설계조건", + "feature": "사업개요, 도로의 종류 등 설계기준 입력\n횡단구성, 포장, 비탈면경사 입력\n발파영향권 및 교량, 터널 형식 확인가능\n정온시설 위치 입력", + "note": "도로와 주변 조건등 적용기준 입력" + }, + { + "title": "노폭계획", + "feature": "선형계획, 노즈, 편경사,\n구조물, 시설계획 입력", + "note": "노선의 폭, 선형, 구조물 조건 입력" + }, + { + "title": "기본계획", + "feature": "길어깨편경사, 비탈면,\n부체도로, 횡단통로, 수로암거 계획 입력", + "note": "기본 단면과 주변 계획 조건 입력" + }, + { + "title": "기본설계", + "feature": "선형 기준 배수공, 포장공, 부대공 자동설치\n횡단면도 생성, 도공계산서 내보내기", + "note": "자동 설계 성과물과 기본설계 모델을 생성" + } + ], + "format": "way", + "deliverables": [ + "평면도, 횡단면도, 종평면도, 기본설계모델" + ], + "predecessors": [ + "cheonjiin" + ], + "successors": [ + "program-1782180934346", + "program-1782201626309" + ], + "linkLabel": "천지인 결과물을 WayPrimal로 연계", + "linkSourceIds": [ + "cheonjiin" + ], + "linkSourceId": "cheonjiin", + "detailGates": [ + { + "key": "gate5-1782181928630", + "stepId": "1-1", + "question": "노선 구역 변경?", + "yes": "천지인 재실행", + "no": "변경사항 없음", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate6-1782188756313", + "targetProgramId": "wayPrimal", + "stepId": "wp-1", + "question": "사업개요, 도로의 종류 등 설계기준 변경?", + "yes": "설계조건 재실행", + "no": "다음 검토" + }, + { + "key": "gate1", + "stepId": "wp-1", + "question": "적용조건 입력(횡단구성, 비탈면 경사, 포장단면 등) 정온시설 위치 입력 변경?", + "yes": "설계조건 재실행", + "no": "다음 검토" + }, + { + "key": "gate2", + "stepId": "wp-2", + "question": "선형계획, 노즈, 편경사, 구조물, 시설계획 변경?", + "yes": "노폭계획 재실행", + "no": "다음 검토" + }, + { + "key": "gate3", + "stepId": "wp-3", + "question": "길어깨편경사, 비탈면계획, 부체도로, 횡단통로 변경?", + "yes": "기본계획 재실행", + "no": "다음 검토" + }, + { + "key": "gate5-1782182405217", + "targetProgramId": "wayPrimal", + "stepId": "wp-4", + "question": "배수공, 포장공, 부대공 변경?", + "yes": "기본설계 재실행", + "no": "WayConfirm으로 이동" + } + ] + }, + "extraPrograms": [ + { + "id": "program-1782201626309", + "name": "WayConfirm", + "description": "새 프로그램 업무 플로우", + "steps": [ + { + "id": "program-1782201626309-2", + "title": "-", + "feature": "-", + "note": "-" + } + ], + "format": "way", + "deliverables": [ + "설계도면, 수량산출서, 3D모델" + ], + "predecessors": [ + "wayPrimal" + ], + "successors": [ + "program-1782180934346", + "program-1782191391645", + "program-1782194494893" + ], + "linkLabel": "이전 프로그램 산출물을 새 프로그램 입력으로 연계" + }, + { + "id": "program-1782194494893", + "name": "WallZainer", + "description": "옹벽 설계 프로그램", + "steps": [ + { + "id": "program-1782194494893-1", + "title": "현황 및 설계조건", + "feature": "사업개요, 옹벽리스트, 지역조건, 설계조건 입력", + "note": "사업구간내 옹벽 현황과 설계조건 입력" + }, + { + "id": "program-1782194494893-1782194544681-5", + "title": "계획", + "feature": "평면, 종단면도 확인 및 횡단면도에서 문양거푸집 및 상세 사이즈(하단폭, 뒷굽길이) 변경 입력", + "note": "단면확인 및 블럭별 치수변경(지정폭만 변경가능)" + }, + { + "id": "program-1782194494893-2", + "title": "모델링 및 하중재하", + "feature": "옹벽의 단면형상 및 상세치수 확인 및 구조해석 확인", + "note": "사용자 입력사항 없는 확인 페이지" + }, + { + "id": "program-1782194494893-1782194542462-3", + "title": "부재력 및 반력", + "feature": "구조해석 통해 구해진 블럭, 하중조건별 \n부재력(휨모멘트, 전단력) 및 반력, 토압, \n연직변위 값 확인", + "note": "사용자 입력사항 없는 확인 페이지" + }, + { + "id": "program-1782194494893-1782194542837-4", + "title": "안정성검토", + "feature": "지지력, 침하량 확인", + "note": "NG시 단면치수 변경" + }, + { + "id": "program-1782194494893-1782195438993-6", + "title": "설계최적화", + "feature": "프로그램이 넘어가지 않아서 이후 확인 불가\n", + "note": "단계 설명을 입력합니다." + } + ], + "format": "rtwl", + "deliverables": [ + "설계도면, 계산서, 수량산출서, 3D모델" + ], + "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", + "detailGates": [ + { + "key": "gate1", + "targetProgramId": "program-1782194494893", + "stepId": "program-1782194494893-1", + "question": "현황 및 설계조건 변경?", + "yes": "현황 및 설계조건 재실행", + "no": "아니오: 다음 검토" + }, + { + "key": "gate2-1782196512625", + "targetProgramId": "program-1782194494893", + "stepId": "program-1782194494893-1782194544681-5", + "question": "NG?", + "yes": "계획 재실행(치수변경)", + "no": "아니오: 변경사항 없음" + } + ], + "predecessors": [ + "program-1782201626309" + ], + "successors": [ + "program-1782180934346" + ] + }, + { + "id": "program-1782191391645", + "name": "BridgeModeler", + "description": "구조물 상세치수 수정 후 모델 생성 (전환BIM 전용 프로그램) - 철근 X", + "steps": [ + { + "id": "program-1782191391645-1", + "title": "공통", + "feature": "교량의 형식, 포장, 접속시스템(교대형식), 앞성토 형태 선택", + "note": "교량 공통 형식 선정" + }, + { + "id": "program-1782191391645-2", + "title": "상부", + "feature": "거더&가로보, 바닥판의 상세 형식 및 상세치수 입력", + "note": "교량 상부 변수 입력\n(전환BIM - 도면 치수 입력)" + }, + { + "id": "program-1782191391645-3", + "title": "교대", + "feature": "교좌면, 흉벽, 벽체, 기초, 날개벽, 접속슬래브 형식 및 상세치수 입력", + "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)" + }, + { + "id": "program-1782191391645-4", + "title": "교각", + "feature": "교좌면, 코핑, 기둥, 기초 형식 및 상세치수 입력", + "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)" + } + ], + "format": "obj", + "deliverables": [ + "3D 모델" + ], + "linkSourceIds": [ + "program-1782180934346" + ], + "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", + "detailGates": [ + { + "key": "gate1", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-1", + "question": "교량의 형식, 포장, 접속시스템(교대형식), \n앞성토 형태수 변경?", + "yes": "공통 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate2", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-2", + "question": "상부 거더&가로보,\n바닥판의 상세 형식 및 치수 변경?", + "yes": "상부 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate3", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-3", + "question": "교대 교좌면, 흉벽, 벽체, 기초, 날개벽,\n접속슬래브 형식 및 치수 변경?", + "yes": "교대 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate4-1782192060008", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-4", + "question": "교각교좌면, 코핑, 기둥, 기초 형식 및 치수 변경?", + "yes": "교각 페이지 재실행", + "no": "Rhino에서 모델 확인" + } + ], + "predecessors": [ + "program-1782201626309" + ], + "successors": [ + "program-1782180934346" + ] + }, + { + "id": "program-1782180934346", + "name": "Rhino", + "description": "3D 모델 편집 및 포맷 변경", + "steps": [ + { + "id": "program-1782180934346-1", + "title": "모델병합 및 수정", + "feature": "모델의 정합성 확인 및 편집\n기본기능 및 Grasshopper 사용", + "note": "Way 파일 내 도로 형상 모델 추출 시WayExport3DAppo를 사용하여 obj 모델 생성\n그 외의 구조물을 각 프로그램에서 obj 불러오기" + }, + { + "id": "program-1782180934346-2", + "title": "속성정보", + "feature": "속성정보 입력\n현재 Plugin에 도로정보만 자동으로 입력", + "note": "Plugin 설치하여 객체별 WBS 정보 입력" + }, + { + "id": "program-1782180934346-3", + "title": "3단계", + "feature": "wpbifc 포맷으로 저장", + "note": "설치된 Plugin에서 wbpifc 포맷으로 저장" + }, + { + "id": "program-1782180934346-4", + "title": "중립포맷 생성", + "feature": "ifc파일 생성", + "note": "DataChange 프로그램 사용으로 ifc 파일 추출" + } + ], + "format": "obj, wbpifc, ifc", + "deliverables": [ + "3D 모델" + ], + "linkLabel": "생성 모델 확인 및 변경", + "detailGates": [ + { + "key": "gate2-1782192916845", + "targetProgramId": "wayPrimal", + "stepId": "wp-1", + "question": "도로 모델 변경?", + "yes": "Way 재실행", + "no": "아니오: 변경사항 없음" + }, + { + "key": "gate1", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-1", + "question": "교량 구조물 모델 상세 치수 변경?", + "yes": "BridgeModeler 재실행", + "no": "아니오: 다음 검토" + }, + { + "key": "gate3-1782194421761", + "targetProgramId": "program-1782180934346", + "stepId": "program-1782180934346-3", + "question": "Wall 구조물 모델 상세 치수 변경?", + "yes": "예: 3단계 재진입", + "no": "아니오: 변경사항 없음" + } + ], + "linkSourceId": "wayPrimal", + "linkSourceIds": [ + "wayPrimal", + "cheonjiin" + ], + "predecessors": [ + "program-1782191391645", + "program-1782194494893", + "cheonjiin", + "wayPrimal", + "program-1782201626309" + ], + "successors": [] + } + ] +} \ No newline at end of file diff --git a/data/backups/recovered-state-20260623.json b/data/backups/recovered-state-20260623.json new file mode 100644 index 0000000..78c88cc --- /dev/null +++ b/data/backups/recovered-state-20260623.json @@ -0,0 +1 @@ +{"content": {"cheonjiin": {"name": "천지인", "description": "지형정보 생성", "steps": [{"title": "자료수집", "feature": "직접선택, 도면 불러오기", "note": "사업 대상지와 원본 도면 범위를 확정하여 지형도, 수치지형도, 정사영상등 취득"}, {"title": "선택/검토", "feature": "등고선, 레이어 선택", "note": " 필요한 도면 요소와 레이어만 선택가능"}, {"title": "현장조사", "feature": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 적용 후 지형, 지층 보정", "note": "실측 자료를 반영해 지형 정보를 보정(dwg, dxf 파일 등)\n지층은 .bori파일만 지원\n3d 형상 내보내기 가능"}, {"title": "구조물편집", "feature": "도로(방음벽, 난간),\n건물(텍스처, 외부모델),\n하천 배수구조물,\n지형(지표면, 지층, 구역텍스쳐)등 적용 후 모델재생성", "note": "구조물과 지형 요소를 편집\n3d 형상 내보내기 가능"}, {"title": "유역면적", "feature": "유역 구분 및 면적 산정", "note": ""}], "deliverables": ["지형도", "수치지형도", "정사영상", "지형,지층 보정 모델"], "format": "glb", "predecessors": [], "successors": ["wayPrimal", "program-1782180934346"], "detailGates": [{"key": "gate1", "stepId": "1-1", "question": "노선변경?", "yes": "자료수집 재실행", "no": "다음 검토", "targetProgramId": "cheonjiin"}, {"key": "gate2", "stepId": "1-2", "question": "등고선 또는 적용 레이어 변경?", "yes": "선택/검토 재실행", "no": "다음 검토", "targetProgramId": "cheonjiin"}, {"key": "gate3", "stepId": "1-3", "question": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 정보 변경?", "yes": "현장조사 재실행", "no": "다음 검토", "targetProgramId": "cheonjiin"}, {"key": "gate4", "stepId": "1-4", "question": "도로(방음벽, 난간), 건물(텍스처, 외부모델),\n하천 배수구조물, 지형(지표면, 지층, 구역텍스쳐)등 정보 변경?", "yes": "구조물편집 재실행", "no": "WayPrimal로 이동", "targetProgramId": "cheonjiin"}]}, "wayPrimal": {"name": "WayPrimal", "description": "기본설계 성과물 생성", "steps": [{"title": "설계조건", "feature": "사업개요, 도로의 종류 등 설계기준 입력\n횡단구성, 포장, 비탈면경사 입력\n발파영향권 및 교량, 터널 형식 확인가능\n정온시설 위치 입력", "note": "도로와 주변 조건등 적용기준 입력"}, {"title": "노폭계획", "feature": "선형계획, 노즈, 편경사,\n구조물, 시설계획 입력", "note": "노선의 폭, 선형, 구조물 조건 입력"}, {"title": "기본계획", "feature": "길어깨편경사, 비탈면,\n부체도로, 횡단통로, 수로암거 계획 입력", "note": "기본 단면과 주변 계획 조건 입력"}, {"title": "기본설계", "feature": "선형 기준 배수공, 포장공, 부대공 자동설치\n횡단면도 생성, 도공계산서 내보내기", "note": "자동 설계 성과물과 기본설계 모델을 생성"}], "format": "way", "deliverables": ["평면도, 횡단면도, 종평면도, 기본설계모델"], "predecessors": ["cheonjiin"], "successors": ["program-1782180934346", "program-1782201626309"], "linkLabel": "천지인 결과물을 WayPrimal로 연계", "linkSourceIds": ["cheonjiin"], "linkSourceId": "cheonjiin", "detailGates": [{"key": "gate5-1782181928630", "stepId": "1-1", "question": "노선 구역 변경?", "yes": "천지인 재실행", "no": "변경사항 없음", "targetProgramId": "cheonjiin"}, {"key": "gate6-1782188756313", "targetProgramId": "wayPrimal", "stepId": "wp-1", "question": "사업개요, 도로의 종류 등 설계기준 변경?", "yes": "설계조건 재실행", "no": "다음 검토"}, {"key": "gate1", "stepId": "wp-1", "question": "적용조건 입력(횡단구성, 비탈면 경사, 포장단면 등) 정온시설 위치 입력 변경?", "yes": "설계조건 재실행", "no": "다음 검토"}, {"key": "gate2", "stepId": "wp-2", "question": "선형계획, 노즈, 편경사, 구조물, 시설계획 변경?", "yes": "노폭계획 재실행", "no": "다음 검토"}, {"key": "gate3", "stepId": "wp-3", "question": "길어깨편경사, 비탈면계획, 부체도로, 횡단통로 변경?", "yes": "기본계획 재실행", "no": "다음 검토"}, {"key": "gate5-1782182405217", "targetProgramId": "wayPrimal", "stepId": "wp-4", "question": "배수공, 포장공, 부대공 변경?", "yes": "기본설계 재실행", "no": "WayConfirm으로 이동"}]}, "extraPrograms": [{"id": "program-1782201626309", "name": "WayConfirm", "description": "새 프로그램 업무 플로우", "steps": [{"id": "program-1782201626309-2", "title": "-", "feature": "-", "note": "-"}], "format": "way", "deliverables": ["설계도면, 수량산출서, 3D모델"], "predecessors": ["wayPrimal"], "successors": ["program-1782180934346", "program-1782191391645", "program-1782194494893"], "linkLabel": "이전 프로그램 산출물을 새 프로그램 입력으로 연계"}, {"id": "program-1782194494893", "name": "WallZainer", "description": "옹벽 설계 프로그램", "steps": [{"id": "program-1782194494893-1", "title": "현황 및 설계조건", "feature": "사업개요, 옹벽리스트, 지역조건, 설계조건 입력", "note": "사업구간내 옹벽 현황과 설계조건 입력"}, {"id": "program-1782194494893-1782194544681-5", "title": "계획", "feature": "평면, 종단면도 확인 및 횡단면도에서 문양거푸집 및 상세 사이즈(하단폭, 뒷굽길이) 변경 입력", "note": "단면확인 및 블럭별 치수변경(지정폭만 변경가능)"}, {"id": "program-1782194494893-2", "title": "모델링 및 하중재하", "feature": "옹벽의 단면형상 및 상세치수 확인 및 구조해석 확인", "note": "사용자 입력사항 없는 확인 페이지"}, {"id": "program-1782194494893-1782194542462-3", "title": "부재력 및 반력", "feature": "구조해석 통해 구해진 블럭, 하중조건별 \n부재력(휨모멘트, 전단력) 및 반력, 토압, \n연직변위 값 확인", "note": "사용자 입력사항 없는 확인 페이지"}, {"id": "program-1782194494893-1782194542837-4", "title": "안정성검토", "feature": "지지력, 침하량 확인", "note": "NG시 단면치수 변경"}, {"id": "program-1782194494893-1782195438993-6", "title": "설계최적화", "feature": "프로그램이 넘어가지 않아서 이후 확인 불가\n", "note": "단계 설명을 입력합니다."}], "format": "rtwl", "deliverables": ["설계도면, 계산서, 수량산출서, 3D모델"], "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", "detailGates": [{"key": "gate1", "targetProgramId": "program-1782194494893", "stepId": "program-1782194494893-1", "question": "현황 및 설계조건 변경?", "yes": "현황 및 설계조건 재실행", "no": "아니오: 다음 검토"}, {"key": "gate2-1782196512625", "targetProgramId": "program-1782194494893", "stepId": "program-1782194494893-1782194544681-5", "question": "NG?", "yes": "계획 재실행(치수변경)", "no": "아니오: 변경사항 없음"}], "predecessors": ["program-1782201626309"], "successors": ["program-1782180934346"]}, {"id": "program-1782191391645", "name": "BridgeModeler", "description": "구조물 상세치수 수정 후 모델 생성 (전환BIM 전용 프로그램) - 철근 X", "steps": [{"id": "program-1782191391645-1", "title": "공통", "feature": "교량의 형식, 포장, 접속시스템(교대형식), 앞성토 형태 선택", "note": "교량 공통 형식 선정"}, {"id": "program-1782191391645-2", "title": "상부", "feature": "거더&가로보, 바닥판의 상세 형식 및 상세치수 입력", "note": "교량 상부 변수 입력\n(전환BIM - 도면 치수 입력)"}, {"id": "program-1782191391645-3", "title": "교대", "feature": "교좌면, 흉벽, 벽체, 기초, 날개벽, 접속슬래브 형식 및 상세치수 입력", "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)"}, {"id": "program-1782191391645-4", "title": "교각", "feature": "교좌면, 코핑, 기둥, 기초 형식 및 상세치수 입력", "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)"}], "format": "obj", "deliverables": ["3D 모델"], "linkSourceIds": ["program-1782180934346"], "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", "detailGates": [{"key": "gate1", "targetProgramId": "program-1782191391645", "stepId": "program-1782191391645-1", "question": "교량의 형식, 포장, 접속시스템(교대형식), \n앞성토 형태수 변경?", "yes": "공통 페이지 재실행", "no": "다음 검토"}, {"key": "gate2", "targetProgramId": "program-1782191391645", "stepId": "program-1782191391645-2", "question": "상부 거더&가로보,\n바닥판의 상세 형식 및 치수 변경?", "yes": "상부 페이지 재실행", "no": "다음 검토"}, {"key": "gate3", "targetProgramId": "program-1782191391645", "stepId": "program-1782191391645-3", "question": "교대 교좌면, 흉벽, 벽체, 기초, 날개벽,\n접속슬래브 형식 및 치수 변경?", "yes": "교대 페이지 재실행", "no": "다음 검토"}, {"key": "gate4-1782192060008", "targetProgramId": "program-1782191391645", "stepId": "program-1782191391645-4", "question": "교각교좌면, 코핑, 기둥, 기초 형식 및 치수 변경?", "yes": "교각 페이지 재실행", "no": "Rhino에서 모델 확인"}], "predecessors": ["program-1782201626309"], "successors": ["program-1782180934346"]}, {"id": "program-1782180934346", "name": "Rhino", "description": "3D 모델 편집 및 포맷 변경", "steps": [{"id": "program-1782180934346-1", "title": "모델병합 및 수정", "feature": "모델의 정합성 확인 및 편집\n기본기능 및 Grasshopper 사용", "note": "Way 파일 내 도로 형상 모델 추출 시WayExport3DAppo를 사용하여 obj 모델 생성\n그 외의 구조물을 각 프로그램에서 obj 불러오기"}, {"id": "program-1782180934346-2", "title": "속성정보", "feature": "속성정보 입력\n현재 Plugin에 도로정보만 자동으로 입력", "note": "Plugin 설치하여 객체별 WBS 정보 입력"}, {"id": "program-1782180934346-3", "title": "3단계", "feature": "wpbifc 포맷으로 저장", "note": "설치된 Plugin에서 wbpifc 포맷으로 저장"}, {"id": "program-1782180934346-4", "title": "중립포맷 생성", "feature": "ifc파일 생성", "note": "DataChange 프로그램 사용으로 ifc 파일 추출"}], "format": "obj, wbpifc, ifc", "deliverables": ["3D 모델"], "linkLabel": "생성 모델 확인 및 변경", "detailGates": [{"key": "gate2-1782192916845", "targetProgramId": "wayPrimal", "stepId": "wp-1", "question": "도로 모델 변경?", "yes": "Way 재실행", "no": "아니오: 변경사항 없음"}, {"key": "gate1", "targetProgramId": "program-1782191391645", "stepId": "program-1782191391645-1", "question": "교량 구조물 모델 상세 치수 변경?", "yes": "BridgeModeler 재실행", "no": "아니오: 다음 검토"}, {"key": "gate3-1782194421761", "targetProgramId": "program-1782180934346", "stepId": "program-1782180934346-3", "question": "Wall 구조물 모델 상세 치수 변경?", "yes": "예: 3단계 재진입", "no": "아니오: 변경사항 없음"}], "linkSourceId": "wayPrimal", "linkSourceIds": ["wayPrimal", "cheonjiin"], "predecessors": ["program-1782191391645", "program-1782194494893", "cheonjiin", "wayPrimal", "program-1782201626309"], "successors": []}]}, "programStates": {}} \ No newline at end of file diff --git a/data/flow-db.json b/data/flow-db.json new file mode 100644 index 0000000..35f94ef --- /dev/null +++ b/data/flow-db.json @@ -0,0 +1,426 @@ +{ + "content": { + "cheonjiin": { + "name": "천지인", + "description": "지형정보 생성", + "steps": [ + { + "title": "자료수집", + "feature": "직접선택, 도면 불러오기", + "note": "사업 대상지와 원본 도면 범위를 확정하여 지형도, 수치지형도, 정사영상등 취득" + }, + { + "title": "선택/검토", + "feature": "등고선, 레이어 선택", + "note": " 필요한 도면 요소와 레이어만 선택가능" + }, + { + "title": "현장조사", + "feature": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 적용 후 지형, 지층 보정", + "note": "실측 자료를 반영해 지형 정보를 보정(dwg, dxf 파일 등)\n지층은 .bori파일만 지원\n3d 형상 내보내기 가능" + }, + { + "title": "구조물편집", + "feature": "도로(방음벽, 난간),\n건물(텍스처, 외부모델),\n하천 배수구조물,\n지형(지표면, 지층, 구역텍스쳐)등 적용 후 모델재생성", + "note": "구조물과 지형 요소를 편집\n3d 형상 내보내기 가능" + }, + { + "title": "유역면적", + "feature": "유역 구분 및 면적 산정", + "note": "" + } + ], + "deliverables": [ + "지형도", + "수치지형도", + "정사영상", + "지형,지층 보정 모델" + ], + "format": "glb", + "predecessors": [], + "successors": [ + "wayPrimal", + "program-1782180934346" + ], + "detailGates": [ + { + "key": "gate1", + "stepId": "1-1", + "question": "노선변경?", + "yes": "자료수집 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate2", + "stepId": "1-2", + "question": "등고선 또는 적용 레이어 변경?", + "yes": "선택/검토 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate3", + "stepId": "1-3", + "question": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 정보 변경?", + "yes": "현장조사 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate4", + "stepId": "1-4", + "question": "도로(방음벽, 난간), 건물(텍스처, 외부모델),\n하천 배수구조물, 지형(지표면, 지층, 구역텍스쳐)등 정보 변경?", + "yes": "구조물편집 재실행", + "no": "WayPrimal로 이동", + "targetProgramId": "cheonjiin" + } + ] + }, + "wayPrimal": { + "name": "WayPrimal", + "description": "기본설계 성과물 생성", + "steps": [ + { + "title": "설계조건", + "feature": "사업개요, 도로의 종류 등 설계기준 입력\n횡단구성, 포장, 비탈면경사 입력\n발파영향권 및 교량, 터널 형식 확인가능\n정온시설 위치 입력", + "note": "도로와 주변 조건등 적용기준 입력" + }, + { + "title": "노폭계획", + "feature": "선형계획, 노즈, 편경사,\n구조물, 시설계획 입력", + "note": "노선의 폭, 선형, 구조물 조건 입력" + }, + { + "title": "기본계획", + "feature": "길어깨편경사, 비탈면,\n부체도로, 횡단통로, 수로암거 계획 입력", + "note": "기본 단면과 주변 계획 조건 입력" + }, + { + "title": "기본설계", + "feature": "선형 기준 배수공, 포장공, 부대공 자동설치\n횡단면도 생성, 도공계산서 내보내기", + "note": "자동 설계 성과물과 기본설계 모델을 생성" + } + ], + "format": "way", + "deliverables": [ + "평면도, 횡단면도, 종평면도, 기본설계모델" + ], + "predecessors": [ + "cheonjiin" + ], + "successors": [ + "program-1782180934346", + "program-1782201626309" + ], + "linkLabel": "천지인 결과물을 WayPrimal로 연계", + "linkSourceIds": [ + "cheonjiin" + ], + "linkSourceId": "cheonjiin", + "detailGates": [ + { + "key": "gate5-1782181928630", + "stepId": "1-1", + "question": "노선 구역 변경?", + "yes": "천지인 재실행", + "no": "변경사항 없음", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate6-1782188756313", + "targetProgramId": "wayPrimal", + "stepId": "wp-1", + "question": "사업개요, 도로의 종류 등 설계기준 변경?", + "yes": "설계조건 재실행", + "no": "다음 검토" + }, + { + "key": "gate1", + "stepId": "wp-1", + "question": "적용조건 입력(횡단구성, 비탈면 경사, 포장단면 등) 정온시설 위치 입력 변경?", + "yes": "설계조건 재실행", + "no": "다음 검토" + }, + { + "key": "gate2", + "stepId": "wp-2", + "question": "선형계획, 노즈, 편경사, 구조물, 시설계획 변경?", + "yes": "노폭계획 재실행", + "no": "다음 검토" + }, + { + "key": "gate3", + "stepId": "wp-3", + "question": "길어깨편경사, 비탈면계획, 부체도로, 횡단통로 변경?", + "yes": "기본계획 재실행", + "no": "다음 검토" + }, + { + "key": "gate5-1782182405217", + "targetProgramId": "wayPrimal", + "stepId": "wp-4", + "question": "배수공, 포장공, 부대공 변경?", + "yes": "기본설계 재실행", + "no": "WayConfirm으로 이동" + } + ] + }, + "extraPrograms": [ + { + "id": "program-1782201626309", + "name": "WayConfirm", + "description": "새 프로그램 업무 플로우", + "steps": [ + { + "id": "program-1782201626309-2", + "title": "-", + "feature": "-", + "note": "-" + } + ], + "format": "way", + "deliverables": [ + "설계도면, 수량산출서, 3D모델" + ], + "predecessors": [ + "wayPrimal" + ], + "successors": [ + "program-1782180934346", + "program-1782191391645", + "program-1782194494893" + ], + "linkLabel": "이전 프로그램 산출물을 새 프로그램 입력으로 연계" + }, + { + "id": "program-1782194494893", + "name": "WallZainer", + "description": "옹벽 설계 프로그램", + "steps": [ + { + "id": "program-1782194494893-1", + "title": "현황 및 설계조건", + "feature": "사업개요, 옹벽리스트, 지역조건, 설계조건 입력", + "note": "사업구간내 옹벽 현황과 설계조건 입력" + }, + { + "id": "program-1782194494893-1782194544681-5", + "title": "계획", + "feature": "평면, 종단면도 확인 및 횡단면도에서 문양거푸집 및 상세 사이즈(하단폭, 뒷굽길이) 변경 입력", + "note": "단면확인 및 블럭별 치수변경(지정폭만 변경가능)" + }, + { + "id": "program-1782194494893-2", + "title": "모델링 및 하중재하", + "feature": "옹벽의 단면형상 및 상세치수 확인 및 구조해석 확인", + "note": "사용자 입력사항 없는 확인 페이지" + }, + { + "id": "program-1782194494893-1782194542462-3", + "title": "부재력 및 반력", + "feature": "구조해석 통해 구해진 블럭, 하중조건별 \n부재력(휨모멘트, 전단력) 및 반력, 토압, \n연직변위 값 확인", + "note": "사용자 입력사항 없는 확인 페이지" + }, + { + "id": "program-1782194494893-1782194542837-4", + "title": "안정성검토", + "feature": "지지력, 침하량 확인", + "note": "NG시 단면치수 변경" + }, + { + "id": "program-1782194494893-1782195438993-6", + "title": "설계최적화", + "feature": "프로그램이 넘어가지 않아서 이후 확인 불가\n", + "note": "단계 설명을 입력합니다." + } + ], + "format": "rtwl", + "deliverables": [ + "설계도면, 계산서, 수량산출서, 3D모델" + ], + "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", + "detailGates": [ + { + "key": "gate1", + "targetProgramId": "program-1782194494893", + "stepId": "program-1782194494893-1", + "question": "현황 및 설계조건 변경?", + "yes": "현황 및 설계조건 재실행", + "no": "아니오: 다음 검토" + }, + { + "key": "gate2-1782196512625", + "targetProgramId": "program-1782194494893", + "stepId": "program-1782194494893-1782194544681-5", + "question": "NG?", + "yes": "계획 재실행(치수변경)", + "no": "아니오: 변경사항 없음" + } + ], + "predecessors": [ + "program-1782201626309" + ], + "successors": [ + "program-1782180934346" + ] + }, + { + "id": "program-1782191391645", + "name": "BridgeModeler", + "description": "구조물 상세치수 수정 후 모델 생성 (전환BIM 전용 프로그램) - 철근 X", + "steps": [ + { + "id": "program-1782191391645-1", + "title": "공통", + "feature": "교량의 형식, 포장, 접속시스템(교대형식), 앞성토 형태 선택", + "note": "교량 공통 형식 선정" + }, + { + "id": "program-1782191391645-2", + "title": "상부", + "feature": "거더&가로보, 바닥판의 상세 형식 및 상세치수 입력", + "note": "교량 상부 변수 입력\n(전환BIM - 도면 치수 입력)" + }, + { + "id": "program-1782191391645-3", + "title": "교대", + "feature": "교좌면, 흉벽, 벽체, 기초, 날개벽, 접속슬래브 형식 및 상세치수 입력", + "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)" + }, + { + "id": "program-1782191391645-4", + "title": "교각", + "feature": "교좌면, 코핑, 기둥, 기초 형식 및 상세치수 입력", + "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)" + } + ], + "format": "obj", + "deliverables": [ + "3D 모델" + ], + "linkSourceIds": [ + "program-1782180934346" + ], + "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", + "detailGates": [ + { + "key": "gate1", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-1", + "question": "교량의 형식, 포장, 접속시스템(교대형식), \n앞성토 형태수 변경?", + "yes": "공통 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate2", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-2", + "question": "상부 거더&가로보,\n바닥판의 상세 형식 및 치수 변경?", + "yes": "상부 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate3", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-3", + "question": "교대 교좌면, 흉벽, 벽체, 기초, 날개벽,\n접속슬래브 형식 및 치수 변경?", + "yes": "교대 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate4-1782192060008", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-4", + "question": "교각교좌면, 코핑, 기둥, 기초 형식 및 치수 변경?", + "yes": "교각 페이지 재실행", + "no": "Rhino에서 모델 확인" + } + ], + "predecessors": [ + "program-1782201626309" + ], + "successors": [ + "program-1782180934346" + ] + }, + { + "id": "program-1782180934346", + "name": "Rhino", + "description": "3D 모델 편집 및 포맷 변경", + "steps": [ + { + "id": "program-1782180934346-1", + "title": "모델병합 및 수정", + "feature": "모델의 정합성 확인 및 편집\n기본기능 및 Grasshopper 사용", + "note": "Way 파일 내 도로 형상 모델 추출 시WayExport3DAppo를 사용하여 obj 모델 생성\n그 외의 구조물을 각 프로그램에서 obj 불러오기" + }, + { + "id": "program-1782180934346-2", + "title": "속성정보", + "feature": "속성정보 입력\n현재 Plugin에 도로정보만 자동으로 입력", + "note": "Plugin 설치하여 객체별 WBS 정보 입력" + }, + { + "id": "program-1782180934346-3", + "title": "3단계", + "feature": "wpbifc 포맷으로 저장", + "note": "설치된 Plugin에서 wbpifc 포맷으로 저장" + }, + { + "id": "program-1782180934346-4", + "title": "중립포맷 생성", + "feature": "ifc파일 생성", + "note": "DataChange 프로그램 사용으로 ifc 파일 추출" + } + ], + "format": "obj, wbpifc, ifc", + "deliverables": [ + "3D 모델" + ], + "linkLabel": "생성 모델 확인 및 변경", + "detailGates": [ + { + "key": "gate2-1782192916845", + "targetProgramId": "wayPrimal", + "stepId": "wp-1", + "question": "도로 모델 변경?", + "yes": "Way 재실행", + "no": "아니오: 변경사항 없음" + }, + { + "key": "gate1", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-1", + "question": "교량 구조물 모델 상세 치수 변경?", + "yes": "BridgeModeler 재실행", + "no": "아니오: 다음 검토" + }, + { + "key": "gate3-1782194421761", + "targetProgramId": "program-1782180934346", + "stepId": "program-1782180934346-3", + "question": "Wall 구조물 모델 상세 치수 변경?", + "yes": "예: 3단계 재진입", + "no": "아니오: 변경사항 없음" + } + ], + "linkSourceId": "wayPrimal", + "linkSourceIds": [ + "wayPrimal", + "cheonjiin" + ], + "predecessors": [ + "program-1782191391645", + "program-1782194494893", + "cheonjiin", + "wayPrimal", + "program-1782201626309" + ], + "successors": [] + } + ] + }, + "programStates": {}, + "updatedAt": "2026-06-23T08:50:22.594Z" +} \ No newline at end of file diff --git a/flow.html b/flow.html new file mode 100644 index 0000000..de66747 --- /dev/null +++ b/flow.html @@ -0,0 +1,14 @@ + + + + + + 유역면적 산정 피드백 엔진 + + + + +
+ + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..de66747 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + 유역면적 산정 피드백 엔진 + + + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..a571e76 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "dev": "vite --host 0.0.0.0" + }, + "dependencies": { + "@vitejs/plugin-react": "^4.3.4", + "vite": "^6.0.5", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "lucide-react": "^0.468.0" + }, + "devDependencies": {} +} diff --git a/recovered-content.json b/recovered-content.json new file mode 100644 index 0000000..dae3258 --- /dev/null +++ b/recovered-content.json @@ -0,0 +1,422 @@ +{ + "cheonjiin": { + "name": "천지인", + "description": "지형정보 생성", + "steps": [ + { + "title": "자료수집", + "feature": "직접선택, 도면 불러오기", + "note": "사업 대상지와 원본 도면 범위를 확정하여 지형도, 수치지형도, 정사영상등 취득" + }, + { + "title": "선택/검토", + "feature": "등고선, 레이어 선택", + "note": " 필요한 도면 요소와 레이어만 선택가능" + }, + { + "title": "현장조사", + "feature": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 적용 후 지형, 지층 보정", + "note": "실측 자료를 반영해 지형 정보를 보정(dwg, dxf 파일 등)\n지층은 .bori파일만 지원\n3d 형상 내보내기 가능" + }, + { + "title": "구조물편집", + "feature": "도로(방음벽, 난간),\n건물(텍스처, 외부모델),\n하천 배수구조물,\n지형(지표면, 지층, 구역텍스쳐)등 적용 후 모델재생성", + "note": "구조물과 지형 요소를 편집\n3d 형상 내보내기 가능" + }, + { + "title": "유역면적", + "feature": "유역 구분 및 면적 산정", + "note": "" + } + ], + "deliverables": [ + "지형도", + "수치지형도", + "정사영상", + "지형,지층 보정 모델" + ], + "format": "glb", + "predecessors": [], + "successors": [ + "wayPrimal", + "program-1782180934346" + ], + "detailGates": [ + { + "key": "gate1", + "stepId": "1-1", + "question": "노선변경?", + "yes": "자료수집 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate2", + "stepId": "1-2", + "question": "등고선 또는 적용 레이어 변경?", + "yes": "선택/검토 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate3", + "stepId": "1-3", + "question": "지표(평면,종단,횡단,표고)\n지층(탄성파, 지질주상도, 종단, 횡단)\n상세(드론지형, PointCloud) 정보 변경?", + "yes": "현장조사 재실행", + "no": "다음 검토", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate4", + "stepId": "1-4", + "question": "도로(방음벽, 난간), 건물(텍스처, 외부모델),\n하천 배수구조물, 지형(지표면, 지층, 구역텍스쳐)등 정보 변경?", + "yes": "구조물편집 재실행", + "no": "WayPrimal로 이동", + "targetProgramId": "cheonjiin" + } + ] + }, + "wayPrimal": { + "name": "WayPrimal", + "description": "기본설계 성과물 생성", + "steps": [ + { + "title": "설계조건", + "feature": "사업개요, 도로의 종류 등 설계기준 입력\n횡단구성, 포장, 비탈면경사 입력\n발파영향권 및 교량, 터널 형식 확인가능\n정온시설 위치 입력", + "note": "도로와 주변 조건등 적용기준 입력" + }, + { + "title": "노폭계획", + "feature": "선형계획, 노즈, 편경사,\n구조물, 시설계획 입력", + "note": "노선의 폭, 선형, 구조물 조건 입력" + }, + { + "title": "기본계획", + "feature": "길어깨편경사, 비탈면,\n부체도로, 횡단통로, 수로암거 계획 입력", + "note": "기본 단면과 주변 계획 조건 입력" + }, + { + "title": "기본설계", + "feature": "선형 기준 배수공, 포장공, 부대공 자동설치\n횡단면도 생성, 도공계산서 내보내기", + "note": "자동 설계 성과물과 기본설계 모델을 생성" + } + ], + "format": "way", + "deliverables": [ + "평면도, 횡단면도, 종평면도, 기본설계모델" + ], + "predecessors": [ + "cheonjiin" + ], + "successors": [ + "program-1782180934346", + "program-1782201626309" + ], + "linkLabel": "천지인 결과물을 WayPrimal로 연계", + "linkSourceIds": [ + "cheonjiin" + ], + "linkSourceId": "cheonjiin", + "detailGates": [ + { + "key": "gate5-1782181928630", + "stepId": "1-1", + "question": "노선 구역 변경?", + "yes": "천지인 재실행", + "no": "변경사항 없음", + "targetProgramId": "cheonjiin" + }, + { + "key": "gate6-1782188756313", + "targetProgramId": "wayPrimal", + "stepId": "wp-1", + "question": "사업개요, 도로의 종류 등 설계기준 변경?", + "yes": "설계조건 재실행", + "no": "다음 검토" + }, + { + "key": "gate1", + "stepId": "wp-1", + "question": "적용조건 입력(횡단구성, 비탈면 경사, 포장단면 등) 정온시설 위치 입력 변경?", + "yes": "설계조건 재실행", + "no": "다음 검토" + }, + { + "key": "gate2", + "stepId": "wp-2", + "question": "선형계획, 노즈, 편경사, 구조물, 시설계획 변경?", + "yes": "노폭계획 재실행", + "no": "다음 검토" + }, + { + "key": "gate3", + "stepId": "wp-3", + "question": "길어깨편경사, 비탈면계획, 부체도로, 횡단통로 변경?", + "yes": "기본계획 재실행", + "no": "다음 검토" + }, + { + "key": "gate5-1782182405217", + "targetProgramId": "wayPrimal", + "stepId": "wp-4", + "question": "배수공, 포장공, 부대공 변경?", + "yes": "기본설계 재실행", + "no": "WayConfirm으로 이동" + } + ] + }, + "extraPrograms": [ + { + "id": "program-1782201626309", + "name": "WayConfirm", + "description": "새 프로그램 업무 플로우", + "steps": [ + { + "id": "program-1782201626309-2", + "title": "-", + "feature": "-", + "note": "-" + } + ], + "format": "way", + "deliverables": [ + "설계도면, 수량산출서, 3D모델" + ], + "predecessors": [ + "wayPrimal" + ], + "successors": [ + "program-1782180934346", + "program-1782191391645", + "program-1782194494893" + ], + "linkLabel": "이전 프로그램 산출물을 새 프로그램 입력으로 연계" + }, + { + "id": "program-1782194494893", + "name": "WallZainer", + "description": "옹벽 설계 프로그램", + "steps": [ + { + "id": "program-1782194494893-1", + "title": "현황 및 설계조건", + "feature": "사업개요, 옹벽리스트, 지역조건, 설계조건 입력", + "note": "사업구간내 옹벽 현황과 설계조건 입력" + }, + { + "id": "program-1782194494893-1782194544681-5", + "title": "계획", + "feature": "평면, 종단면도 확인 및 횡단면도에서 문양거푸집 및 상세 사이즈(하단폭, 뒷굽길이) 변경 입력", + "note": "단면확인 및 블럭별 치수변경(지정폭만 변경가능)" + }, + { + "id": "program-1782194494893-2", + "title": "모델링 및 하중재하", + "feature": "옹벽의 단면형상 및 상세치수 확인 및 구조해석 확인", + "note": "사용자 입력사항 없는 확인 페이지" + }, + { + "id": "program-1782194494893-1782194542462-3", + "title": "부재력 및 반력", + "feature": "구조해석 통해 구해진 블럭, 하중조건별 \n부재력(휨모멘트, 전단력) 및 반력, 토압, \n연직변위 값 확인", + "note": "사용자 입력사항 없는 확인 페이지" + }, + { + "id": "program-1782194494893-1782194542837-4", + "title": "안정성검토", + "feature": "지지력, 침하량 확인", + "note": "NG시 단면치수 변경" + }, + { + "id": "program-1782194494893-1782195438993-6", + "title": "설계최적화", + "feature": "프로그램이 넘어가지 않아서 이후 확인 불가\n", + "note": "단계 설명을 입력합니다." + } + ], + "format": "rtwl", + "deliverables": [ + "설계도면, 계산서, 수량산출서, 3D모델" + ], + "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", + "detailGates": [ + { + "key": "gate1", + "targetProgramId": "program-1782194494893", + "stepId": "program-1782194494893-1", + "question": "현황 및 설계조건 변경?", + "yes": "현황 및 설계조건 재실행", + "no": "아니오: 다음 검토" + }, + { + "key": "gate2-1782196512625", + "targetProgramId": "program-1782194494893", + "stepId": "program-1782194494893-1782194544681-5", + "question": "NG?", + "yes": "계획 재실행(치수변경)", + "no": "아니오: 변경사항 없음" + } + ], + "predecessors": [ + "program-1782201626309" + ], + "successors": [ + "program-1782180934346" + ] + }, + { + "id": "program-1782191391645", + "name": "BridgeModeler", + "description": "구조물 상세치수 수정 후 모델 생성 (전환BIM 전용 프로그램) - 철근 X", + "steps": [ + { + "id": "program-1782191391645-1", + "title": "공통", + "feature": "교량의 형식, 포장, 접속시스템(교대형식), 앞성토 형태 선택", + "note": "교량 공통 형식 선정" + }, + { + "id": "program-1782191391645-2", + "title": "상부", + "feature": "거더&가로보, 바닥판의 상세 형식 및 상세치수 입력", + "note": "교량 상부 변수 입력\n(전환BIM - 도면 치수 입력)" + }, + { + "id": "program-1782191391645-3", + "title": "교대", + "feature": "교좌면, 흉벽, 벽체, 기초, 날개벽, 접속슬래브 형식 및 상세치수 입력", + "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)" + }, + { + "id": "program-1782191391645-4", + "title": "교각", + "feature": "교좌면, 코핑, 기둥, 기초 형식 및 상세치수 입력", + "note": "교대 변수 입력\n(전환BIM - 도면 치수 입력)" + } + ], + "format": "obj", + "deliverables": [ + "3D 모델" + ], + "linkSourceIds": [ + "program-1782180934346" + ], + "linkLabel": "Way에서 나온 구조물을 각 프로그램에 연계", + "detailGates": [ + { + "key": "gate1", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-1", + "question": "교량의 형식, 포장, 접속시스템(교대형식), \n앞성토 형태수 변경?", + "yes": "공통 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate2", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-2", + "question": "상부 거더&가로보,\n바닥판의 상세 형식 및 치수 변경?", + "yes": "상부 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate3", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-3", + "question": "교대 교좌면, 흉벽, 벽체, 기초, 날개벽,\n접속슬래브 형식 및 치수 변경?", + "yes": "교대 페이지 재실행", + "no": "다음 검토" + }, + { + "key": "gate4-1782192060008", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-4", + "question": "교각교좌면, 코핑, 기둥, 기초 형식 및 치수 변경?", + "yes": "교각 페이지 재실행", + "no": "Rhino에서 모델 확인" + } + ], + "predecessors": [ + "program-1782201626309" + ], + "successors": [ + "program-1782180934346" + ] + }, + { + "id": "program-1782180934346", + "name": "Rhino", + "description": "3D 모델 편집 및 포맷 변경", + "steps": [ + { + "id": "program-1782180934346-1", + "title": "모델병합 및 수정", + "feature": "모델의 정합성 확인 및 편집\n기본기능 및 Grasshopper 사용", + "note": "Way 파일 내 도로 형상 모델 추출 시WayExport3DAppo를 사용하여 obj 모델 생성\n그 외의 구조물을 각 프로그램에서 obj 불러오기" + }, + { + "id": "program-1782180934346-2", + "title": "속성정보", + "feature": "속성정보 입력\n현재 Plugin에 도로정보만 자동으로 입력", + "note": "Plugin 설치하여 객체별 WBS 정보 입력" + }, + { + "id": "program-1782180934346-3", + "title": "3단계", + "feature": "wpbifc 포맷으로 저장", + "note": "설치된 Plugin에서 wbpifc 포맷으로 저장" + }, + { + "id": "program-1782180934346-4", + "title": "중립포맷 생성", + "feature": "ifc파일 생성", + "note": "DataChange 프로그램 사용으로 ifc 파일 추출" + } + ], + "format": "obj, wbpifc, ifc", + "deliverables": [ + "3D 모델" + ], + "linkLabel": "생성 모델 확인 및 변경", + "detailGates": [ + { + "key": "gate2-1782192916845", + "targetProgramId": "wayPrimal", + "stepId": "wp-1", + "question": "도로 모델 변경?", + "yes": "Way 재실행", + "no": "아니오: 변경사항 없음" + }, + { + "key": "gate1", + "targetProgramId": "program-1782191391645", + "stepId": "program-1782191391645-1", + "question": "교량 구조물 모델 상세 치수 변경?", + "yes": "BridgeModeler 재실행", + "no": "아니오: 다음 검토" + }, + { + "key": "gate3-1782194421761", + "targetProgramId": "program-1782180934346", + "stepId": "program-1782180934346-3", + "question": "Wall 구조물 모델 상세 치수 변경?", + "yes": "예: 3단계 재진입", + "no": "아니오: 변경사항 없음" + } + ], + "linkSourceId": "wayPrimal", + "linkSourceIds": [ + "wayPrimal", + "cheonjiin" + ], + "predecessors": [ + "program-1782191391645", + "program-1782194494893", + "cheonjiin", + "wayPrimal", + "program-1782201626309" + ], + "successors": [] + } + ] +} \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..15bdf41 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,2213 @@ +import React, { useEffect, useState } from 'react'; +import { + ArrowDown, + ArrowRight, + ArrowUp, + Building2, + ClipboardList, + DraftingCompass, + Edit3, + Layers3, + Map, + Mountain, + Plus, + Route, + Save, + ScanLine, + Trash2, + Waypoints, + X +} from 'lucide-react'; + +const cheonjiinFlow = [ + { + id: '1-1', + title: '범위입력', + icon: ScanLine, + feature: '직접선택, 도면 불러오기', + note: '사업 대상지와 원본 도면 범위를 먼저 확정합니다.' + }, + { + id: '1-2', + title: '선택/검토', + icon: Layers3, + feature: '등고선, 레이어 선택', + note: '해석에 필요한 도면 요소와 레이어만 정리합니다.' + }, + { + id: '1-3', + title: '현장조사', + icon: Mountain, + feature: '지표, 지층, 상세측량\n파일 불러오기\n지형, 지층 보정 모델', + note: '실측 자료를 반영해 지형과 지층 정보를 보정합니다.' + }, + { + id: '1-4', + title: '구조물편집', + icon: Building2, + feature: '도로, 건물, 하천, 지형\n수치지형도 v2 다운로드 시 적용\n구조물 포함 모델', + note: '구조물과 지형 요소를 편집해 통합 모델을 만듭니다.' + }, + { + id: '1-5', + title: '유역면적', + icon: Map, + feature: '유역 구분 및 면적 산정', + note: '정리된 공간 정보를 바탕으로 유역면적 결과를 산정합니다.' + } +]; + +const wayPrimalFlow = [ + { + id: 'wp-1', + title: '설계조건', + icon: ClipboardList, + feature: '전용조건 입력(도로, 포장 등)\n정온시설 위치 입력', + note: '도로와 주변 조건을 설계 입력값으로 등록합니다.' + }, + { + id: 'wp-2', + title: '노폭계획', + icon: Route, + feature: '선형계획, 노즈, 편경사,\n구조물, 시설계획 입력', + note: '노선의 폭, 선형, 구조물 조건을 계획합니다.' + }, + { + id: 'wp-3', + title: '기본계획', + icon: Waypoints, + feature: '길어깨편경사, 비탈면계획,\n부체도로, 횡단등도', + note: '기본 단면과 주변 계획 조건을 정리합니다.' + }, + { + id: 'wp-4', + title: '기본설계', + icon: DraftingCompass, + feature: '배수공, 포장공, 부대공 자동설치\n횡단면도 생성, 도공계산서 내보내기\n평면도, 횡단면도, 종평면도, 기본설계모델', + note: '자동 설계 성과물과 기본설계 모델을 생성합니다.' + } +]; + +const cheonjiinDeliverables = [ + '지형도', + '수치지형도', + '정사영상', + '지형,지층 보정 모델' +]; + +const detailSteps = [ + { + id: '1-1', + title: '범위 입력', + feature: '직접 선택 · 도면 불러오기', + detail: '대상 유역 영역의 좌표 체계와 경계를 지정하고 원천 도면 파일을 등록합니다.', + output: '활성 작업 영역 레이어' + }, + { + id: '1-2', + title: '선택·검토', + feature: '등고선 · 적용 레이어 선택', + detail: '설계 연산에 사용할 등고선 데이터와 속성별 물리 레이어를 선별합니다.', + output: '정제된 등고선 추출본' + }, + { + id: '1-3', + title: '현장조사', + feature: '지표 · 지층 · 상세측량 자료 입력', + detail: 'GPS 고도 측량치와 시추 분석 데이터를 입력해 지형과 지층을 보정합니다.', + output: '3차원 지표·지층 보정 모델' + }, + { + id: '1-4', + title: '구조물 편집', + feature: '도로 · 건물 · 하천 · 지형 편집', + detail: '도로 중심선, 건물 폴리곤, 하천 경계 등 구조물 정보를 지형면에 정합합니다.', + output: '구조물 포함 통합 3D GIS 모델' + }, + { + id: '1-5', + title: '유역면적 산정', + feature: '유역 구분 · 면적 산정 · 결과 검토', + detail: '정립된 지형과 구조물 모델을 분석해 유역 경계를 구분하고 면적을 계산합니다.', + output: '유역면적 최종 산정 결과' + } +]; + +const reviewGates = [ + { + key: 'gate1', + stepId: '1-1', + question: '범위 또는 원본 도면 변경?', + yes: '예: 1-1 재진입', + no: '아니오: 다음 검토' + }, + { + key: 'gate2', + stepId: '1-2', + question: '등고선 또는 적용 레이어 변경?', + yes: '예: 1-2 재진입', + no: '아니오: 다음 검토' + }, + { + key: 'gate3', + stepId: '1-3', + question: '지표·지층 또는 상세측량 정보 변경?', + yes: '예: 1-3 재진입', + no: '아니오: 다음 검토' + }, + { + key: 'gate4', + stepId: '1-4', + question: '도로·건물·하천 또는 지형 정보 변경?', + yes: '예: 1-4 재진입', + no: '아니오: 변경사항 없음' + } +]; + +const initialGates = { + gate1: 'no', + gate2: 'no', + gate3: 'no', + gate4: 'no' +}; + +const channelName = 'program-flow-state'; +const contentStorageKey = 'program-flow-content'; +const programStateStorageKey = 'program-flow-gates'; +const serverStateEndpoint = '/api/state'; +const disabledFlowStep = '__disabled__'; + +const defaultContent = { + cheonjiin: { + name: '천지인', + description: '공간정보 입력·검토·보정·유역면적 산정', + steps: cheonjiinFlow.map(({ title, feature, note }) => ({ title, feature, note })), + deliverables: cheonjiinDeliverables, + format: 'glb', + predecessors: [], + successors: [] + }, + wayPrimal: { + name: 'WayPrimal', + description: '설계조건 입력부터 기본설계 성과물 생성', + steps: wayPrimalFlow.map(({ title, feature, note }) => ({ title, feature, note })), + format: '', + deliverables: ['기본설계 모델'], + predecessors: [], + successors: [], + linkLabel: '천지인 산출 모델을 WayPrimal 설계 입력으로 연계' + }, + extraPrograms: [] +}; + +function normalizeStoredContent(parsed) { + if (!parsed) return defaultContent; + return { + cheonjiin: { + ...defaultContent.cheonjiin, + ...(parsed.cheonjiin ?? {}), + predecessors: parsed.cheonjiin?.predecessors ?? [], + successors: parsed.cheonjiin?.successors ?? [], + format: + !parsed.cheonjiin?.format || parsed.cheonjiin.format === '예: DXF, SHP, GeoTIFF, 수치지형도 v2 등' + ? defaultContent.cheonjiin.format + : parsed.cheonjiin.format + }, + wayPrimal: { + ...defaultContent.wayPrimal, + ...(parsed.wayPrimal ?? {}), + predecessors: parsed.wayPrimal?.predecessors ?? [], + successors: parsed.wayPrimal?.successors ?? [], + format: + parsed.wayPrimal?.format === '예: DWG, LandXML, XLSX, 도공계산서, 기본설계 모델 등' + ? defaultContent.wayPrimal.format + : (parsed.wayPrimal?.format ?? defaultContent.wayPrimal.format) + }, + extraPrograms: (parsed.extraPrograms ?? []).map((program, index, programs) => ({ + ...program, + predecessors: program.predecessors ?? [], + successors: program.successors ?? [], + linkLabel: program.linkLabel ?? `이전 프로그램 산출물을 ${program.name} 입력으로 연계` + })) + }; +} + +function readStoredContent() { + try { + const stored = window.localStorage.getItem(contentStorageKey); + if (!stored) return defaultContent; + return normalizeStoredContent(JSON.parse(stored)); + } catch { + return defaultContent; + } +} + +function mergeStepContent(flow, storedSteps = []) { + const mergedBaseSteps = flow.map((step, index) => ({ + ...step, + ...(storedSteps[index] ?? {}) + })); + const addedSteps = storedSteps.slice(flow.length).map((step, index) => ({ + ...step, + id: step.id ?? `added-step-${flow.length + index + 1}`, + icon: step.icon ?? pickStepIcon(step) + })); + return [...mergedBaseSteps, ...addedSteps]; +} + +function pickStepIcon(step) { + const text = `${step.title ?? ''} ${step.feature ?? ''} ${step.note ?? ''}`.toLowerCase(); + + if (/모델|3d|glb|ifc|wbpifc|grasshopper|rhino|객체|형상/.test(text)) return Layers3; + if (/포맷|파일|저장|출력|내보내기|생성|변환/.test(text)) return ClipboardList; + if (/속성|정보|입력|데이터|plugin|플러그인/.test(text)) return Waypoints; + if (/편집|수정|보정|변경|정합/.test(text)) return DraftingCompass; + if (/도로|노선|선형|중심선|경로/.test(text)) return Route; + if (/지도|수치지형도|유역|면적|범위|도면/.test(text)) return Map; + if (/측량|지형|지층|고도|산/.test(text)) return Mountain; + if (/스캔|영상|정사영상|레이어/.test(text)) return ScanLine; + if (/구조물|건물|하천/.test(text)) return Building2; + + return ClipboardList; +} + +function normalizeProgramSteps(program) { + return program.steps.map((step, index) => ({ + id: step.id ?? `${program.id}-step-${index + 1}`, + icon: pickStepIcon(step), + title: step.title, + feature: step.feature, + note: step.note + })); +} + +function createInitialGates(steps) { + return steps.slice(0, Math.max(1, steps.length - 1)).reduce((gates, step, index) => ({ + ...gates, + [`gate${index + 1}`]: 'no' + }), {}); +} + +function buildReviewItems(programId, steps, detailGates) { + const hasStoredDetailGates = Array.isArray(detailGates); + const storedDetailGates = hasStoredDetailGates ? detailGates : []; + + if (programId === 'cheonjiin') { + const count = hasStoredDetailGates ? Math.max(1, storedDetailGates.length) : reviewGates.length; + return Array.from({ length: count }, (_, index) => { + const baseGate = reviewGates[index] ?? { + key: `gate${index + 1}`, + stepId: steps[Math.min(index, Math.max(0, steps.length - 2))]?.id ?? steps[0]?.id, + question: `${index + 1}-${index + 1} 변경?`, + yes: `예: ${index + 1}-${index + 1} 재진입`, + no: index === count - 1 ? '아니오: 변경사항 없음' : '아니오: 다음 검토' + }; + return { + ...baseGate, + ...(storedDetailGates[index] ?? {}), + targetProgramId: storedDetailGates[index] ? storedDetailGates[index].targetProgramId : programId, + key: storedDetailGates[index]?.key ?? baseGate.key ?? `gate${index + 1}` + }; + }); + } + + const defaultCount = Math.max(1, steps.length - 1); + const count = hasStoredDetailGates ? Math.max(1, storedDetailGates.length) : defaultCount; + return Array.from({ length: count }, (_, index) => { + const step = steps[Math.min(index, Math.max(0, steps.length - 2))] ?? steps[0]; + return { + key: storedDetailGates[index]?.key ?? `gate${index + 1}`, + targetProgramId: storedDetailGates[index] ? storedDetailGates[index].targetProgramId : programId, + stepId: storedDetailGates[index]?.stepId ?? step?.id, + question: storedDetailGates[index]?.question ?? `${step?.title ?? `${index + 1}단계`} 변경?`, + yes: storedDetailGates[index]?.yes ?? `예: ${step?.title ?? `${index + 1}단계`} 재진입`, + no: storedDetailGates[index]?.no ?? (index === count - 1 ? '아니오: 변경사항 없음' : '아니오: 다음 검토') + }; + }); +} + +function readStoredProgramStates() { + try { + const stored = window.localStorage.getItem(programStateStorageKey); + return stored ? JSON.parse(stored) : {}; + } catch { + return {}; + } +} + +function publishProgramStates(states) { + try { + window.localStorage.setItem(programStateStorageKey, JSON.stringify(states)); + patchServerState({ programStates: states }); + const channel = new BroadcastChannel(channelName); + channel.postMessage({ states }); + channel.close(); + } catch { + window.localStorage.setItem(programStateStorageKey, JSON.stringify(states)); + patchServerState({ programStates: states }); + } +} + +function saveServerState(payload, method = 'PUT') { + return fetch(serverStateEndpoint, { + method, + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(payload) + }); +} + +function patchServerState(payload) { + return saveServerState(payload, 'PATCH').catch(() => undefined); +} + +function getProgramGates(states, programId, steps) { + return { + ...createInitialGates(steps), + ...(states[programId] ?? {}) + }; +} + +function getActiveGate(gates, reviewItems) { + return reviewItems.find((gate) => gates[gate.key] === 'yes'); +} + +function getActiveStep(gates, reviewItems) { + return getActiveGate(gates, reviewItems)?.stepId ?? 'completed'; +} + +function getReentryContext(programs, programStates, getProgramReviewItems) { + return programs + .map((sourceProgram) => { + const reviewItems = getProgramReviewItems(sourceProgram); + const gates = getProgramGates(programStates, sourceProgram.id, sourceProgram.steps); + const activeGate = getActiveGate(gates, reviewItems); + if (!activeGate) return null; + const targetProgramId = resolveGateTargetProgramId(activeGate, sourceProgram.id, programs); + const targetProgramIndex = programs.findIndex((program) => program.id === targetProgramId); + if (targetProgramIndex < 0) return null; + return { + sourceProgramId: sourceProgram.id, + targetProgramId, + targetProgramIndex, + targetStepId: activeGate.stepId + }; + }) + .find(Boolean); +} + +function resolveGateTargetProgramId(gate, sourceProgramId, allPrograms) { + if (gate?.targetProgramId) return gate.targetProgramId; + return allPrograms.find((program) => program.steps.some((step) => step.id === gate?.stepId))?.id ?? sourceProgramId; +} + +function getStepLabel(program, stepId) { + return program?.steps.find((step) => step.id === stepId)?.title ?? stepId ?? ''; +} + +function moveItem(items, fromIndex, toIndex) { + if (toIndex < 0 || toIndex >= items.length) return items; + const nextItems = [...items]; + const [movedItem] = nextItems.splice(fromIndex, 1); + nextItems.splice(toIndex, 0, movedItem); + return nextItems; +} + +function splitDeliverableText(item) { + return String(item ?? '') + .split(', ') + .map((value) => value.trim()) + .filter(Boolean); +} + +function FlowCard({ step, index, total, accent, status, isEditing, onChange }) { + const Icon = step.icon ?? pickStepIcon(step); + return ( +
+
+
+
+
+ +
+ + {status === 'active' ? '재진입' : status === 'completed' ? '통과' : `${String(index + 1).padStart(2, '0')} / ${String(total).padStart(2, '0')}`} + +
+ {isEditing ? ( +
+ onChange(index, 'title', event.target.value)} + className="w-full rounded-md border border-slate-200 bg-white px-2 py-1.5 text-sm font-extrabold text-slate-950 outline-none focus:border-teal-400" + /> +