- NumberInput 공용 컴포넌트: blur 시 콤마+소수점 자릿수 강제,
focus 시 raw 숫자로 전환되어 자유 편집, 잘못된 입력은 이전 값 유지.
- 다이얼로그 수량/단가 input → NumberInput 으로 교체.
- 백엔드 정규화 — M-BOM/detail/proposal-targets:
qty=FLOOR()::INTEGER, unit_price/partner_price/total_price=NUMERIC(18,2)
(운영 sales_request_part 는 정수 String 이지만 M-BOM production_qty
NUMERIC(15,4) 가 흘러들어와 '4.0000' 노출되던 문제 차단).
- ProposalCreateDialog fmt: Math.floor 후 ko-KR toLocaleString.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
스키마 재정합 (docs/migration/quality/03_waceplm_quality_sync.sql):
- waceplm.esgrin.com 운영(211.115.91.141:11133/waceplm) 스키마 그대로 이식
- 기존 bigserial PK 5개 테이블 DROP 후 varchar(50) PK 로 재생성
- customer_cs, pms_quality_ecr 신규 추가
데이터 복사 (waceplm → vexplor_rps, 126행):
- customer_cs 24
- process_inspection_master 3
- process_inspection_detail 13
- incoming_inspection_detail 1
- pms_quality_semi_product_inspection 84
- pms_quality_ecr 1
backend qualityRoutes.ts:
- incoming-mgmt 의 inspection_yn='검사' 하드코딩 필터를 1=1 로 완화.
'스킵' 행도 검사 진행 화면에 노출. 완료 건만 보려면 search_inspection_status='완료'.
5개 메뉴 1:1 검증(Agent 5병렬) 후 발견된 mbom 메인 그리드 [BOM 복사] 누락 보완.
저장 매퍼는 PR-B5 saveBomAssignment 재사용 — 백엔드는 EBOM/MBOM 분기 이미 지원,
이번에 MBOM UI 진입점도 첫 노출.
신규 컴포넌트:
- BomCopyDialog.tsx — 품번/품명 readonly + E-BOM/M-BOM 셀렉트 상호배타 +
트리 미리보기 + AttachFileDropZone (docType=MBOM_DRAWING, accept=.stp,.step,.dwg,.dxf,.pdf)
- 메인 page.tsx [BOM 복사] 버튼 추가 + 체크 단건 검증 +
Machine(0000928) 외 동일 partNo 최신 M-BOM 자동 추천
신규 백엔드 (mbomService/Controller/Routes):
- searchAssignableMboms — 매퍼 productionplanning.getMbomListForSelect2 (4007~4014) 1:1
- previewMbomTree — getStructureOnly + finalize("ASSIGNED_MBOM")
- getLatestMbomByPartNo — 매퍼 getLatestMbomByPartNo (3426~3445) 1:1, Machine 외 자동 검색
- 라우트: GET /assignable-mboms, GET /mbom-preview/:objid, GET /latest-mbom-by-partno/:partNo
도면 업로드 차이: 운영 fn_uploadDrawingFiles 는 placeholder("구현 예정"). RPS 는
공용 AttachFileDropZone 재사용해 실구현 (target_objid=projectObjid).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
신규 4개 메뉴 (PageHeader + CompactFilterBar + DataGrid 통일):
- 품질관리/수입검사 요청 (/quality/incoming-request)
- 품질관리/수입검사 관리 (/quality/incoming-mgmt)
- 품질관리/공정검사 관리 (/quality/process-inspection)
- 품질관리/반제품검사 관리 (/quality/semi-product-inspection)
DB 마이그레이션 (docs/migration/quality/):
- 01_quality_tables_from_ilshin.sql — ilshin 운영 5개 테이블 vexplor_rps 정합
(customer_service_mgmt/part/workingtime, inspection_mgmt, delivery_history_defect)
+ ecr_mng 7개 컬럼 동기화 (project_no, customer_cd, equip_name,
design_dept, unit_cd, memo, check_result)
- 02_wace_plm_quality_tables.sql — wace_plm quality.xml 매퍼 호환 신규 5개 테이블
(incoming_inspection_detail/defect, process_inspection_master/detail,
pms_quality_semi_product_inspection) + 인덱스 정의
백엔드:
- qualityRoutes.ts — 4개 메뉴 list 엔드포인트 (실 테이블 조회)
- ecrMngService SELECT_BASE 에 ilshin 신규 7컬럼 노출
- app.ts 라우팅 등록 (/api/quality/*)
프론트:
- DataGrid 4개 신규 페이지 + 그리드 툴바 (차트/엑셀/새로고침/컬럼설정/페이지사이즈)
- customer-cs/cs, ecr/ecr — 견적관리와 동일한 PageHeader + CompactFilterBar
+ DataGrid 패턴으로 리팩토링 (다이얼로그/기존 API 유지)
- ECR 그리드에 신규 6개 컬럼 추가 (설비명/프로젝트번호/고객사/설계부서/조치결과 등)
- AdminPageRenderer 4개 라우트 등록
데이터 복사: ilshin → vexplor_rps (workingtime 5건, inspection_mgmt 1건,
ecr_mng 1건). 나머지 ilshin 운영 테이블은 0건이므로 스키마만 정합.
디렉토리 rename (menu_info 등록 URL 일치)
- prod-plan-result → plan-result
- prod-plan-result-equip → plan-result-equip
- semi-product-requirement → semi-product-req
- raw-material-requirement → raw-material-req
- menu_info objid 100033~100036 이 가리키는 URL 과 1:1 매칭 + gridId 동기화
DataGrid 헤더 잘림/한 글자 깨짐 수정
- 헤더 라벨 span: whitespace-nowrap + title (이전 break-words 가 한글 단어를 글자 단위로 wrap 시키던 문제 제거)
- 부모 컨테이너 overflow-hidden 도 제거 — 좁은 컬럼에서도 글자가 한 줄로 자연스럽게 표시
- plan-result / plan-result-equip 좁은 컬럼 너비 보정 (수주/추가생산/총생산/완조립/등록자/진척율)
반제품/원자재 소요량 numeric 캐스팅 에러 수정
- RPS DB mbom_detail.qty/required_qty 는 numeric(15,4) — wace_plm 의 varchar 패턴(NULLIF 후 ::INTEGER) 적용 시 invalid input syntax 발생
- COALESCE(MD.QTY, 1)::INTEGER / COALESCE(MD.REQUIRED_QTY, 0)::NUMERIC 으로 교체
행 추가: MbomAddPartDialog 신설 (devPartApi.list 재사용)
· 품번/품명 검색 + 체크박스 multi-select + 페이지네이션
· 선택 행 1개면 그 자식으로 추가, 없으면 root (level=1)
편집 모드 확장 (MbomDetailDialog):
· 체크박스 컬럼(맨 왼쪽) + 전체 선택 토글
· 선택 행 파란 배경, 새 행 초록 배경 (temp- prefix 식별)
· toolbar [+ 행 추가] / [선택 삭제] 버튼 추가
· 선택 삭제 — cascade(선택 + 하위) + 확인창
backend save() UPDATE 분기:
· client temp- child_objid → 서버 발급 createObjId 매핑
(객체 ID 안정성 + DB 에 임시 ID 잔존 방지 + 충돌 회피)
· parent_objid 가 temp- 참조면 신규 ID 로 remap
운영판은 좌(M-BOM)+중앙(<<,>>,변경)+우(소스 트리) 3분할이지만
좌측 19컬럼이 좁아져 가로스크롤 강제되는 약점. 팝업 방식이
트리 풀너비 확보 + 모바일 친화 → 사용자 결정으로 팝업 채택.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
운영 productionplanning.getMbomHistory (3448~3470) 1:1 이식:
· backend mbomService.getHistory(projectObjid) — project 단위 mbom_header 변경이력
시간순 최신 우선, USER_INFO join 으로 변경자명 함께
· GET /api/production/mbom/history/:projectObjid
· frontend MbomHistoryDialog — 5컬럼 그리드(변경일시/유형/내용/변경자/M-BOM품번)
CREATE=파란 뱃지, UPDATE=황색 뱃지, max-w-900px
· MbomDetailDialog toolbar 에 "변경이력" 버튼 (편집 모드 아닐 때만 노출)
PR-B1 의 history 저장 결과를 사용자가 직접 확인할 수 있도록 보는 화면 마무리.
부수: production/mbom/page 그리드 컬럼 폭 정돈 + summaryStats(전체/페이지/수주합/M-BOM 비율).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(1) 정전개 트리 화면 운영판 wace structureAscendingList.jsp 1:1 정정:
- L1..LMaxLevel 컬럼 — row.lev 와 일치하는 컬럼에만 "*" 표시 (이전엔 품번 표시)
- 별도 품번 컬럼 1개 (모든 행 part_no)
- 3D/2D/PDF — renderType: "folder" (wace fnc_getFolderIcon 1:1)
- 컬럼 운영판 1:1 : 품번/품명/수량/항목수량/3D/2D/PDF/재료/열처리경도/열처리방법/표면처리/메이커/범주이름/비고
- 제거 : 변경일/REV/규격/중량 (운영판 미사용)
(2) 토글 -/+ 버튼 추가 (wace 트리 1:1):
- 첫 컬럼 __toggle — 자식 있는 행만 − / + 표시, 클릭 시 자식 숨김/표시
- collapsedChildIds Set<string> 상태로 접힘 관리
- ancestor 체인: parent_objid → 부모 행 child_objid 추적 (cycle guard)
- 가시 행 필터: ancestor 중 하나라도 collapsed Set 에 있으면 hide → 자손 전체 숨김
- 새 조회 시 collapsed Set 초기화 (모두 펼침)
(3) 품번 셀 클릭 → PartDetailDialog (wace partMngDetailPopUp 1:1):
- row.part_no = part_mng.objid::varchar 이므로 그대로 detail dialog 의 objid 로 전달
- ebom-search 페이지에 PartDetailDialog 임포트 + state
(4) 검색 필터 anchor 정정 (사용자 검증: 1행만 나오고 자식 안 풀림):
- 이전: search_part_no/search_part_name 을 결과 단계 WHERE PM.part_no LIKE ... 로 적용
→ 매칭 행 1개만 살아남고 자식 잘림
- 정정: anchor 단계에서 매칭된 PART 가 들어있는 bom_report_objid 전체를 startWhere 로
→ 재귀 CTE 가 자식 모두 풀어냄 (운영판 1:1)
- search_level (1~5) 은 결과 단계 유지 (트리 깊이 제한)
- ascending / ascendingForExcel 양쪽 동일 패턴
(5) ascending SELECT 풀 컬럼 보강:
- 추가 : item_qty(p_qty), heat_treatment_hardness/method, surface_treatment,
maker, part_type, part_type_title (comm_code.code_name)
- TREE CTE 컬럼에 item_qty 추가
- BomTreeRow 타입 동기 (lib/api/devBom.ts)
(6) 상태변경 시 확정일(DEPLOY_DATE) 처리 — 사용자 요청:
- status = 'Y' 변경 시 DEPLOY_DATE = TO_CHAR(NOW(), 'YYYY-MM-DD') 채움 (varchar)
- 'N' 변경 시 기존 DEPLOY_DATE 보존
- $5 prepared statement 타입 추론 충돌 (varchar vs unknown) → $5::varchar 명시 캐스팅
- STATUS_TITLE 매핑은 운영판 1:1 — CREATE/CHANGEDESIGN/DEPLOY 만 라벨, Y/N 등은 raw 표시
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
사용자 검증으로 발견된 5가지 함정 일괄 정정.
(1) ebom-search 검색폼 운영판 1:1 — wace structureAscendingList.jsp 노출 필드만:
- 제거: 프로젝트 OBJID (raw input), UNIT_CODE (raw input)
운영판도 고객사/프로젝트번호/유닛명 모두 주석 처리되어 노출 안 됨
- 유지: 품번 / 품명 / 표시 레벨 (1~5 select)
- BomTreeFilter.search_level 추가 + ascending/descending CTE 에 T.lev <= $search_level::int
(2) 품번/품명 자동완성 (wace select2-part 1:1):
- 영업관리 PartSelect 는 item_info 마스터 기반 → 개발관리(part_mng)용 별도 컴포넌트 신설
- backend GET /api/development/part/options : IS_LAST='1' part_mng 전체 (영업관리 sales/parts 패턴)
- frontend DevPartSelect.tsx : SmartSelect 캐시 + mode partNo/partName 분리
- ebom-search 페이지 단순 Input → DevPartSelect 교체
- 품번 선택 시 품명 자동 채움 / 품명 선택 시 품번 자동 채움 (운영판 select2-part 1:1)
(3) BomReportStatusDialog 운영판 1:1 재작성 — wace structureStatusChangePopup.jsp:
- 잘못된 점: read-only 박스 + 상태 select(create/changeDesign/deploy 3옵션)
- 정정: 5필드 모두 편집 가능 (CommCodeSelect 제품구분 / 품번 input / 품명 input /
Version input / 상태 Y/N 라디오) — 운영 매퍼 updateStructureStatus 5컬럼 UPDATE 1:1
- 헤더 파란 바 + 4컬럼 테이블(25%/75%) + 저장/닫기 중앙 배치 (운영판 스타일 1:1)
(4) DataGrid id 매핑 — 체크박스 ID 키 불일치 함정:
- DataGrid 는 row.id 로 체크박스 ID 관리, 백엔드 응답은 row.objid (postgres lowercase)
- 결과: checkedIds[0] 가 undefined → 상태변경/수정/삭제 다이얼로그가 objid=undefined 로 열려
detail 호출 안 됨 → 빈 폼 표시 (사용자 지적 "기본 정보 표시 안됨")
- 일괄 수정 (3 페이지) : ebom-regist / part-regist / part-search
gridRows = useMemo(() => rows.map(r => ({ ...r, id: r.objid })), [rows])
영업관리 페이지 동일 패턴 1:1
(5) STATUS_TITLE 매핑 운영판 1:1 — 운영 그리드는 'Y'/'N' 글자 그대로 표시:
CASE UPPER(T.STATUS)
WHEN 'CREATE' THEN '등록중'
WHEN 'CHANGEDESIGN' THEN '설계변경미배포'
WHEN 'DEPLOY' THEN '배포완료'
ELSE COALESCE(T.STATUS, '') END AS STATUS_TITLE
- 운영 매퍼는 ELSE '' 이지만 RPS 는 raw fallback (사용자 화면에서 식별 가능)
- 'Y'/'N' 매핑 라벨 추가 → 운영 스크린샷 확인 후 제거 (운영판은 raw)
미해결 (별 작업):
- 확정일 (DEPLOY_DATE) 표시 — 운영판은 별도 "배포" 액션 (deployBomReport 매퍼) 으로 채움.
RPS ebom-regist 에 배포 버튼 미구현 → 신규 BOM 확정일 빈값. 별 PR.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CSV 파싱 함정 정정:
사용자 검증 중 운영판 wace 에서 3건만 파싱되는 CSV 가 RPS 에서 4건으로 파싱되며 4번째
행이 깨진 채 들어가는 문제 발견. 단순 line.split(",") 로는 RFC4180 따옴표 처리 실패.
backend-node:
- csv-parse ^6.2.1 추가
- devBomExcelImportService.parseAndValidate :
text.split(/\r\n|\r|\n/).map(line => line.split(",")) 단순 split →
parseCsvSync(text, { relax_quotes, relax_column_count, skip_empty_lines: false })
· 따옴표 내부 콤마/줄바꿈, "" 이스케이프 모두 안전 처리
· 운영판 사용자가 만든 비정형 quote 도 relax_quotes 로 관대 처리
· 1차 스캔(자품번 수집) 도 동일 allRows 재사용
- getCsvValue 헬퍼는 보존 (csv-parse 후에도 안전 trim/quote-strip 으로 유지)
시퀀스 누락 (별 함정):
저장 시 "relation seq_bom_qty does not exist" 에러 발생. wace 매퍼에서 사용하는
nextval('seq_*') 시퀀스 5종 중 RPS DB 에 seq_ecr_no 만 존재. 나머지 4종 신규 생성.
02_sequences.sql (data-sync 디렉토리에 보존):
- seq_bom_qty 200,000 (운영 179,258 + 여유)
- seq_as_no 1,000 (운영 109 + 여유)
- seq_comm_code 10,000 (운영 1,839 + 여유)
- seq_eo_no 1,000 (운영 62 + 여유)
- seq_ecr_no (RPS 기존 보존, 운영 33)
운영 last_value 보다 충분히 큰 값으로 setval — 향후 운영 데이터 sync 시 PK 충돌 방지.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
운영판 wace 재확인 결과 BOM 등록은 XLSX가 아니라 CSV 가 진짜 입력 포맷이었음.
근거:
· openBomReportExcelImportPopUp.jsp : 제목 "PART 및 구조등록 CSV upload",
Drop Zone "Drag & Drop CSV 템플릿", fnc_setFileDropZone(..., "csv") 로 CSV 만 허용
· /partMng/parsingExcelFile.do 가 .csv 분기에서 별도 함수 parsingCsvFile() 호출
· CSV 11컬럼 : 수준 / 품번 / 품명 / 수량 / 항목수량 / 재료 / 열처리경도 / 열처리방법 /
표면처리 / 공급업체(MAKER) / 범주이름(PART_TYPE)
· CSV 는 PARENT_PART_NO 컬럼이 없고 "수준" 으로 부모-자식 자동 결정
· 숫자("1","2","3"): 깊이 D 의 부모 = D-1 의 최신 품번
· 점 표기법("1","1.1","1.4.1"): 마지막 점 이전 수준이 부모
backend (devBomExcelImportService.ts):
· XLSX(xlsx 라이브러리) 파싱 → CSV(iconv-lite) 파싱으로 완전 재작성
· 인코딩 자동 감지 1:1 — CP949 → UTF-8 → EUC-KR → MS949 순서, � 카운트로 베스트 선택,
UTF-8 BOM() 자동 제거
· CSV 영문 범주명 자동 변환 — Assy/ASSY→조립품, Buy/BUY→구매품, Make/MAKE→부품
· 범주별 ACCTFG/ODRFG 자동 설정 — 조립품(0001813)·부품(0001812) → ACCTFG=4·ODRFG=1,
구매품(0000063) → ACCTFG=7·ODRFG=0
· 기본값 일괄 — UNIT_DC=0001400(EA) · UNITMANG_DC=0001400 · UNITCHNG_NB=1 ·
LOT_FG=1 · USE_YN=1 · QC_FG=0 · SETITEM_FG=0 · REQ_FG=0
· 검증 1:1 — rowIndex > 2 에서만 모품번 자품번 목록 존재 검사, NOTE 누적
· 저장 로직(savePartBomMaster)은 동일 유지 — 자식 PART updatePartInfoFromCsv UPDATE /
insertpartInfo INSERT, 부모 PART 존재 시 lookup·없으면 "" (INSERT 안 함),
bom_part_qty INSERT 시 ACCTFG/ODRFG/UNIT_DC/UNITCHNG_NB 등 모든 컬럼 동기
frontend:
· BomExcelRow → BomCsvRow (LEVEL 컬럼 + ACCTFG/ODRFG/UNIT_DC/UNITCHNG_NB/LOT_FG/USE_YN/
QC_FG/SETITEM_FG/REQ_FG 자동 채움 필드 추가). BomExcelRow 는 호환 type alias 로 보존
· BomReportExcelImportDialog : 제목 "PART 및 구조등록 CSV upload", accept=".csv", Drop Zone
안내 텍스트 변경, 그리드 컬럼 — 결과/수준/모품번(자동)/품번/품명/수량/항목수량/재료/
열처리경도/열처리방법/표면처리/공급업체/범주/계정구분(자동)/조달구분(자동)
· 파싱 결과의 encoding 정보 표시 (CP949/UTF-8 등)
정적 자산:
· 운영 BOM_REPORT_EXCEL_IMPORT_TEMPLATE.xlsx 제거 (운영판도 실제 사용 안 함)
· 신규 BOM_REPORT_CSV_IMPORT_TEMPLATE.csv 추가 (11컬럼 헤더 + 4행 샘플)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
· wace fn_openSaleRegPopup(PROJECT_NO, "detail") 의도 재해석 — read-only 상세 조회 모드
· 행 전체 클릭(onRowClick) → PROJECT_NO 컬럼 셀 클릭(cellClick)으로 좁힘 (wace 1:1)
· 판매관리 페이지 라우팅 폐기 → ProjectInfoDialog 신설 (같은 탭, list row 직접 사용, 추가 API 호출 0)
· 표시 항목: 프로젝트번호/영업번호/주문유형/제품구분/국내해외/고객사/유무상/품번/품명/S/N/수주수량/접수일/요청납기/발주일/프로젝트명/작성자
· 영업관리 변경 롤백 (SaleListFilter.project_no, useSearchParams 자동 선택, 초기화 핸들러)
· 01-progress / 01-progress-verify 문서 갱신
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 시스템 관리 > 시퀀스 관리 신규 메뉴 + 페이지(채번 룰 빌더)
- ensureSequenceMngMenu 부팅 시드
- 테이블 타입관리 → 채번 룰 드롭다운 + 의존성 자동 검증
- 표시명/코멘트 UX 개선
- 설계 문서 추가
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
- salesOrderMgmtService에 assertNoProjectExists(client, contractObjid) 신설. wace 매퍼 getProjectListBycontractObjid:3909와 동일하게 SELECT 1 FROM project_mgmt WHERE contract_objid=$1 LIMIT 1 (status 필터 없음).
- salesEstimateService.remove + salesOrderMgmtService.remove 둘 다 BEGIN 직후 가드 호출. 차단 시 AppError("프로젝트가 생성된 건은 삭제할 수 없습니다.", 409) throw.
- 컨트롤러 remove 두 곳에서 error.statusCode ?? 500으로 응답 → 409 정확히 전달.
- DB 검증: 26C-0698(project 11건) 차단, project 없는 contract 통과.
G7(contract_item UPSERT)는 사실상 이미 구현 — upsertItems 두 서비스 모두 INSERT ... ON CONFLICT (objid) DO UPDATE 패턴으로 OBJID 유지 보장 중. 별도 코드 변경 없음.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ECR 관리: wace 의 ecrList/Form/Detail JSP 와 동일하게 5개 필터(연도/기종/요청/작성자/상태),
변경전/후 2분할 모달, 작성중(0000100)만 삭제·수정 허용, 컬럼 순서/라벨 wace 일치
- ECR 스키마 wace 풀세트 동기화: ecr_mng 컬럼폭 확장, product_mgmt 16컬럼, part_mng 52컬럼,
user_info 22컬럼, comm_code 보강(id/code_cd/ext_val), code_name(varchar) 함수,
seq_ecr_no setval(33) 정렬
- wace_plm public.comm_code 733행 시드: src/seed/wace_comm_code.sql 추출 + 부팅 시 자동 적재
(writer='system-seed' placeholder 자동 정리, 무중단 재적재 엔드포인트 /comm-code-seed)
- wace_plm 데이터 import 풀스키마: PRODUCT(7→16), PART(6→52), USER_INFO·COMM_CODE 신규
- 공통코드 관리 화면: 제목/설명 축소, 카테고리·코드 카드 → 컴팩트 리스트, 활성 토글 점,
계층 배지 톤다운, hover 시 액션 노출
- 테이블 타입 관리 — 좌측: 한 줄 리스트 + 알파벳 인덱스 sticky 헤더
- 테이블 타입 관리 — 우측: 타입 카드 그리드 → 그룹 셀렉트(기본/참조/자동/첨부/표시변형),
표시이름 제거 + 코멘트(description) Textarea 신설(화면관리에서 기본 라벨로 활용),
시스템 자동 생성 컬럼(id/company_code/writer/created_date/updated_date) 잠금,
표시옵션/고급설정(필수·읽기·기본값·최대길이) 제거 — 화면관리로 이관
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1) getById 응답 구조 fix
- salesEstimateService.getById는 { ...contract_mgmt 헤더, items } 평면 객체 반환
- 페이지가 contractInfo.header.customer_objid로 잘못 접근해 고객사·환율·통화 자동 채움이 안 됐던 버그
- contractInfo.customer_objid 직접 접근으로 수정 (template1·template2 동일)
2) /auth/me 응답에 cellPhone/tel 추가
- AuthService.getUserInfo는 이미 두 필드 반환하나 authController가 응답에서 누락
- 견적서 연락처가 wace MailUtil 패턴(cell_phone 우선 → tel 폴백)으로 자동 채워지도록 노출
3) 시행일자 picker 표시 형식 정정
- input[type="date"]는 한국 Chrome이 "YYYY. MM. DD." 강제 (CSS 변경 불가)
- text input + hidden type=date 조합: 표시는 YYYY-MM-DD, 클릭 시 hidden picker showPicker() 트리거
- template1 executor + template2 executor_date 모두 적용
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
배경:
item_info에 wace 마이그레이션(numeric id 8,179건) + RPS 자체 등록(UUID 21k건)이 섞여 있어
PartSelect/그리드 JOIN에서 잡 데이터(-20260126-, 00 등)와 RPS 자체 등록 데이터가 노출됨.
wace 도메인 메뉴는 part_mng만 참조하도록 분리. 개발관리 등 다른 wace 메뉴도 동일 테이블 활용.
변경:
- DDL: docs/migration/sales/ddl-extracted/105_create_part_mng.sql
(item_info의 numeric id 데이터를 part_mng로 컬럼 매핑 INSERT, 8,176건 적재)
- backend service JOIN 6곳 교체: item_info IT → part_mng PM (PM.objid::varchar = CI.part_objid)
· salesEstimateService.ts (getList LATERAL JOIN, getById 라인 조회 — 2곳)
· salesOrderMgmtService.ts (getList, getById, getOrderFormView, createProjectsFromContract — 4곳)
- /sales/parts endpoint: part_mng SELECT + status active/release/활성 필터.
반환 키는 기존 호환을 위해 id/item_number/item_name으로 alias (objid::varchar/part_no/part_name).
- 자동 검증: scripts/verify-part-mng.sql (카운트·JOIN·그리드 SQL·잡 데이터 제거 검증)
영향:
- item_info는 그대로 — RPS 자체 메뉴(/sales/sales-item 등) 전용으로 유지
- ecrMngService, wacePlmDataImportService 등 RPS 다른 모듈은 이미 part_mng 사용 가정 → 자연 활성화
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>