영업관리 PartSelect·JOIN을 part_mng 전용 테이블로 분리 (item_info 혼재 데이터 해소)

배경:
  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>
This commit is contained in:
hjjeong
2026-05-11 09:56:45 +09:00
parent d23b305990
commit f34eddb9fc
5 changed files with 113 additions and 24 deletions
+45
View File
@@ -0,0 +1,45 @@
-- ============================================================
-- part_mng 분리 검증 — wace 도메인 메뉴가 part_mng를 참조하는지 정합성 확인
-- ============================================================
\echo ''
\echo '[1] 카운트'
SELECT 'item_info numeric id (wace)' AS kind, COUNT(*) FROM item_info WHERE id ~ '^-?[0-9]+$'
UNION ALL SELECT 'part_mng total', COUNT(*) FROM part_mng
UNION ALL SELECT 'part_mng status active/release/활성', COUNT(*) FROM part_mng WHERE LOWER(COALESCE(status,'')) IN ('active','release','활성');
\echo ''
\echo '[2] 견적관리 라인 JOIN — 26C-0801'
SELECT CI.seq, CI.part_objid,
COALESCE(PM.part_no, CI.part_no) AS master_part_no,
COALESCE(PM.part_name, CI.part_name) AS master_part_name
FROM contract_item CI
LEFT JOIN part_mng PM ON PM.objid::varchar = CI.part_objid
WHERE CI.contract_objid='-1778190592' AND CI.status='ACTIVE'
ORDER BY CI.seq;
\echo ''
\echo '[3] /sales/parts 호출 결과 — 8,173건 기대'
SELECT COUNT(*) AS cnt FROM part_mng
WHERE LOWER(COALESCE(status, '')) IN ('active', 'release', '활성')
AND part_no IS NOT NULL AND part_no <> ''
AND part_name IS NOT NULL AND part_name <> '';
\echo ''
\echo '[4] 영업관리 4개 메뉴 그리드 SQL 정합성 (라인 JOIN)'
\echo ' - 견적관리 26C-0801 ITEM_SUMMARY'
SELECT T.contract_no,
CASE WHEN COUNT(*) = 1 THEN MIN(COALESCE(PM.part_name, CI.part_name))
WHEN COUNT(*) > 1 THEN MIN(COALESCE(PM.part_name, CI.part_name)) || '' || (COUNT(*) - 1) || ''
ELSE '' END AS item_summary
FROM contract_mgmt T
JOIN contract_item CI ON CI.contract_objid = T.objid AND CI.status='ACTIVE'
LEFT JOIN part_mng PM ON PM.objid::varchar = CI.part_objid
WHERE T.contract_no IN ('26C-0801','26C-0797','26C-0796')
GROUP BY T.contract_no
ORDER BY T.contract_no DESC;
\echo ''
\echo '[5] 잡 데이터 제거 확인 (item_info에 있는 -20260126-, 0 등은 part_mng에 없어야)'
SELECT 'item_info garbage' AS kind, COUNT(*) FROM item_info WHERE item_number IN ('-20260126-', '-20260126-____')
UNION ALL SELECT 'part_mng garbage (0건 기대)', COUNT(*) FROM part_mng WHERE part_no IN ('-20260126-', '-20260126-____');