# 05. 마스터 데이터 매핑 (wace_plm → vexplor_rps)

> 도메인 테이블(견적/주문/판매/매출)이 참조하는 마스터를 vexplor_rps 기존 마스터와 어떻게 연결할지 정의.

## 1. 매핑 정책

**하이브리드 정책** (사용자 확정):
- **공용 마스터** (거래처, 품목, 사용자, 부서 등): vexplor_rps 기존 테이블(`customer_mng`, `item_info`, `user_info` 등) 사용
- **도메인 테이블** (`contract_mgmt`, `estimate_mgmt`, `sales_registration` 등): wace_plm 스키마 그대로 이식

→ 도메인 테이블의 외래 컬럼이 wace_plm objid를 가리키는 문자열이므로, **매핑 테이블** 또는 **마이그레이션 시 inline 변환** 둘 중 하나의 전략 필요.

## 2. 핵심 매핑 표 (2026-05-07 vexplor_rps DB 실측 반영)

| wace_plm 테이블 | wace_plm PK | wace_plm 키 컬럼 | vexplor_rps 테이블 | vexplor_rps PK | 매핑 방식 |
|---|---|---|---|---|---|
| `SUPPLY_MNG` | `objid` (numeric) | `customer_objid` (varchar) | `customer_mng` | `id` (**integer** auto seq) | 매핑 테이블 필수 |
| `CLIENT_MNG` | `objid` (numeric) | `customer_objid` = `'C_'` + objid | `customer_mng` | `id` (integer) | 매핑 테이블 (prefix로 분기) |
| `PART_MGMT` | `objid` (varchar) | `part_objid` 등 | `item_info` | `id` (**varchar 500**) | **objid 그대로 사용 가능** (매핑 테이블 불필요) |
| `PRODUCT_MGMT` | `objid` | (별도 컬럼) | `item_info` 또는 별도 | `id` (varchar) | 검토 필요 |
| `USER_INFO` | `user_id` (varchar) | `writer`, `pm_user_id`, `salesman` 등 | `user_info` | `user_id` (varchar 1024) | 동일 키 사용 가능 (사용자 매핑 검증 필요) |
| `DEPT_INFO` | `dept_code` | `deptcd` | `user_info.dept_code` (별도 부서 마스터 미확인) | — | 일단 dept_code 그대로 가져오고 부서 마스터는 추후 |
| `COMM_CODE` | `code_id` + `code_value` | 다양한 `*_cd` 컬럼 | (vexplor_rps `code_master*` 추정) | (별도 확인 필요) | 코드 시드 작업 |
| `ATTACH_FILE_INFO` | `objid` | `target_objid` + `doc_type` | (vexplor_rps 파일 시스템) | (별도 확인 필요) | TBD |
| `OEM_MNG` | `objid` | (차량 정보) | — | — | RPS에 불필요 |

### 실측한 vexplor_rps 마스터 핵심 컬럼

#### `customer_mng` (PK `id` integer)
주요 컬럼: `customer_code(varchar 20)`, `customer_name(varchar 100)`, `division(varchar 50)`, `business_number(varchar 20)`, `ceo_name(varchar 120)`, `address(text)`, `phone`, `fax_no(varchar 40)`, `hp_no(varchar 40)`, `charge_name(varchar 120)`, `charge_tel(varchar 40)`, `charge_email(varchar 200)`, `nation_code(varchar 20)`, `currency_code(varchar 20)`, `bank_name`, `bank_account`, `account_owner`, `corp_number(varchar 32)`, `short_name(varchar 120)`, `biz_condition`, `biz_item`, `zip_code`, `address_detail`, `customer_type(varchar 20)`, `internal_manager(varchar 500)`, `delivery_location(varchar 500)`, `use_yn(varchar 1, default 'Y')`, `company_code(varchar 20)`, `created_at`, `updated_at`

#### `item_info` (PK `id` **varchar 500**)
주요 컬럼: `id(varchar 500)`, `item_name(varchar 500)`, `item_number(varchar 500)`, `division(varchar 500)`, `type(varchar 500)`, `unit(varchar 500)`, `inventory_unit`, `material`, `size`, `weight`, `volum`, `specific_gravity`, `selling_price`, `standard_price`, `currency_code`, `lead_time`, `width(numeric)`, `height(numeric)`, `thickness(numeric)`, `area(numeric)`, `mold_number`, `use_packaging`, `use_insert`, `image`, `image_path`, `drawing_path`, `expiry_years`, `expiry_months`, `expiry_days`, `meno(text 500, 오타: memo가 아님)`, `status`, `writer`, `company_code`, `created_date`, `updated_date`

#### `user_info` (PK `user_id` varchar 1024)
주요 컬럼: `user_id`, `sabun`, `user_password`, `user_name`, `user_name_eng`, `user_name_cn`, `dept_code`, `dept_name`, `position_code`, `position_name`, `rank_code`, `rank_name`, `email`, `out_email`, `tel`, `cell_phone`, `fax_no`, `user_type`, `user_type_name`, `data_type`, `signup_type`, `branch_name`, `department_history`, `gender_fg`, `join_date`, `retire_date`, `work_status`, `partner_objid`, `license_number`, `vehicle_number`, `emp_seq`, `status`, `end_date`, `locale`, `company_code`, `regdate`, `token_version`

## 3. 매핑 테이블 설계 (제안)

```sql
-- wace_plm objid → vexplor_rps id 변환
CREATE TABLE legacy_id_map (
    legacy_table   VARCHAR(50)  NOT NULL,   -- 'supply_mng', 'client_mng', 'part_mgmt', ...
    legacy_objid   VARCHAR(100) NOT NULL,   -- 'C_' prefix 포함 가능
    target_table   VARCHAR(50)  NOT NULL,   -- 'customer_mng', 'item_info'
    target_id      INTEGER      NOT NULL,
    company_code   VARCHAR(20)  DEFAULT 'COMPANY_16',
    migrated_at    TIMESTAMP    DEFAULT NOW(),
    note           TEXT,
    PRIMARY KEY (legacy_table, legacy_objid)
);
CREATE INDEX idx_legacy_id_map_target ON legacy_id_map(target_table, target_id);
```

## 4. 마이그레이션 절차

### 4.1 마스터 이주 (도메인 이주 전 선행 필수)

#### 거래처 (`SUPPLY_MNG` + `CLIENT_MNG` → `customer_mng`)

```sql
-- 1. SUPPLY_MNG → customer_mng (공급/일반 고객사)
INSERT INTO customer_mng (
    customer_code, customer_name, division, business_number,
    address, contact_person, contact_phone, email,
    company_code, writer, created_date
)
SELECT
    'CUST-' || lpad(objid::text, 6, '0'),     -- 임시 코드, 추후 채번 룰로 대체
    supply_name,
    code_name(area_cd),                       -- 또는 별도 코드 매핑
    bus_reg_no,
    address,
    charge_user_name,
    charge_phone,                             -- 컬럼명 확인 필요
    charge_email,
    'COMPANY_16',
    'migration',
    CURRENT_TIMESTAMP
FROM wace_plm_dump.supply_mng
ON CONFLICT DO NOTHING;

-- 2. 매핑 테이블 기록
INSERT INTO legacy_id_map (legacy_table, legacy_objid, target_table, target_id)
SELECT 'supply_mng', s.objid::text, 'customer_mng', c.id
FROM wace_plm_dump.supply_mng s
JOIN customer_mng c ON c.customer_name = s.supply_name AND c.business_number = s.bus_reg_no;

-- 3. CLIENT_MNG → customer_mng (일반 거래처)
INSERT INTO customer_mng (
    customer_code, customer_name, division, business_number,
    address, contact_person, contact_phone, email,
    company_code, writer, created_date
)
SELECT
    'CUST-' || lpad((objid + 1000000)::text, 7, '0'),  -- supply와 충돌 방지
    client_nm,
    'general_client',
    bus_reg_no,
    address,                                   -- 컬럼명 확인
    ceo_nm,
    NULL, NULL,
    'COMPANY_16',
    'migration',
    CURRENT_TIMESTAMP
FROM wace_plm_dump.client_mng;

-- 4. CLIENT_MNG 매핑 (legacy_objid는 'C_' prefix)
INSERT INTO legacy_id_map (legacy_table, legacy_objid, target_table, target_id)
SELECT 'client_mng', 'C_' || cl.objid::text, 'customer_mng', cn.id
FROM wace_plm_dump.client_mng cl
JOIN customer_mng cn ON cn.customer_name = cl.client_nm
                    AND cn.division = 'general_client';
```

#### 품목 (`PART_MGMT` → `item_info`)

vexplor_rps `item_info` 스키마 확인 후 동일 패턴 적용. PRODUCT_MGMT가 별도 도메인이면 합치거나 분리.

### 4.2 도메인 이주 시 변환 패턴

```sql
-- contract_mgmt 이주 예시
INSERT INTO contract_mgmt (
    objid, contract_no,
    customer_objid_legacy,                    -- 원본 보존
    customer_id,                              -- vexplor_rps 매핑된 customer_mng.id
    category_cd, area_cd, ...
)
SELECT
    cm.objid,
    cm.contract_no,
    cm.customer_objid,                        -- 원본
    m.target_id,                              -- 매핑된 id
    cm.category_cd, cm.area_cd, ...
FROM wace_plm_dump.contract_mgmt cm
LEFT JOIN legacy_id_map m
       ON m.legacy_objid = cm.customer_objid
      AND m.legacy_table = CASE WHEN cm.customer_objid LIKE 'C_%' THEN 'client_mng' ELSE 'supply_mng' END
      AND m.target_table = 'customer_mng';
```

> 권장: 원본 컬럼(`customer_objid`)을 그대로 남기고 + 신규 `customer_id` 컬럼을 추가해서 디버깅·역추적 쉽게 함. SQL 조회 시엔 `customer_id` 사용.

### 4.3 코드 마스터 매핑

wace_plm `COMM_CODE`는 `(code_id, code_value, code_name)` 구조.
vexplor_rps의 코드 시스템 확인 후:
- 동일 키로 매핑 가능하면 그대로 INSERT
- 다르면 코드 매핑 시드 작성

자주 쓰는 그룹:
- `category_cd` (주문유형)
- `area_cd` (지역/국내해외)
- `paid_type` (유/무상)
- `contract_currency` (환종)
- `contract_result` (수주상태)
- `appr_status` (결재상태)
- `est_status` (견적상태)

### 4.4 첨부파일

`attach_file_info`는 파일 메타. 실제 파일은 `/data_storage` 등 디스크에 있음.
이주 시:
1. 메타데이터 INSERT (target_objid는 그대로 유지)
2. 실제 파일 복사 (또는 vexplor_rps 파일 시스템에 맞게 경로 변환)

## 5. 사용자(USER_INFO) 매핑

wace_plm `USER_INFO.user_id` 와 vexplor_rps `user_info.user_id`가 동일 사람을 가리킨다는 보장이 없음.

**확인 사항**:
- 두 시스템 사용자 ID 체계가 통합되어 있는가?
- 통합되어 있지 않다면, `legacy_user_map (legacy_user_id, target_user_id)` 별도 필요

**확인 방법**: 양쪽 USER_INFO 테이블의 user_id, user_name, dept_code, email 비교.

## 6. 마이그레이션 실행 체크리스트

- [ ] vexplor_rps `customer_mng`, `item_info`, `user_info`, `code_*` 스키마 확인 후 본 문서 컬럼명 보정
- [ ] wace_plm 운영 DB에서 마스터 4종 (`supply_mng`, `client_mng`, `part_mgmt`, `user_info`) schema-only dump 추출
- [ ] 데이터 dump 추출 (또는 staging DB에 운영 데이터 복제)
- [ ] `legacy_id_map` 테이블 생성
- [ ] 거래처 이주 + 매핑 기록
- [ ] 품목 이주 + 매핑 기록
- [ ] 사용자 매핑 검토 (이주 또는 별도 매핑)
- [ ] 코드 마스터 매핑 (시드 SQL)
- [ ] 도메인 테이블 이주 (각 메뉴별 01–04 문서 순서로)
- [ ] 검증 SQL: 도메인 테이블 행 수, NULL 매핑 행 (legacy_id_map JOIN 실패) 카운트

## 7. 주의 / 결정 보류

- **vexplor_rps 마스터 컬럼명** 본 문서 추정치임. 실제 컬럼명/타입은 `customer_mng` 정의([docs/customer-management-tables.md](../../customer-management-tables.md)) 와 `item_info`, `user_info` 정의 보고 보정.
- **PRODUCT_MGMT** vs PART_MGMT: wace_plm에서 둘 다 사용되며 다른 도메인일 가능성. 추후 분석 필요.
- **OEM_MNG**: 자동차 OEM 정보. RPS 도메인에선 불필요해 보이지만 contract_mgmt에 일부 컬럼이 참조할 수 있음 — 확인 필요.
- **운영 데이터 vs 신규 데이터**: 기존 운영 데이터를 모두 이주할 것인지, 신규 데이터만 RPS에 쌓을 것인지 결정 필요. 전자라면 본 문서대로, 후자라면 매핑 테이블 없이 단순 도메인 스키마 이식만으로 충분.
