ERP-node/docs/ycshin-node/MPN[맥락]-품번-수동접두어채번.md

7.0 KiB

[맥락노트] 품번 수동 접두어 채번 - 접두어별 독립 순번 생성

관련 문서: 계획서 | 체크리스트


왜 이 작업을 하는가

  • 기준정보 - 품목정보 등록 모달에서 품번 인풋에 사용자가 값을 입력해도 무시되고 "BULK1"로 저장됨
  • 서로 다른 접두어("ㅁㅁㅁ", "ㅇㅇㅇ")를 입력해도 전부 같은 시퀀스 카운터를 공유함
  • 카테고리 미선택 시 --제발-015-003 처럼 연속 구분자가 발생함
  • 사용자 입력이 반영되고, 접두어별로 독립된 순번이 부여되어야 함

핵심 결정 사항과 근거

1. 수동 값 추출을 buildPrefixKey 전으로 이동

  • 결정: allocateCode 내부에서 수동 값 추출 → buildPrefixKey 순서로 변경
  • 근거: 기존에는 buildPrefixKey(L1306)가 먼저 실행된 후 수동 값 추출(L1332)이 진행됨. 수동 값이 prefix_key에 포함되려면 추출이 먼저 되어야 함
  • 대안 검토: buildPrefixKey 내부에서 직접 추출 → 기각 (역할 분리 위반, previewCode 호출에도 영향)

2. buildPrefixKey에 수동 파트 값 포함

  • 결정: manualValues optional 파라미터 추가, 전달되면 prefix_key에 포함
  • 근거: 기존 continue(L85-87)로 수동 파트가 prefix_key에서 제외되어 모든 접두어가 같은 시퀀스를 공유함
  • 하위호환: optional 파라미터이므로 previewCode(L1091) 등 기존 호출부는 영향 없음

3. 템플릿 파싱 실패 시 userInputCode 전체를 수동 값으로 사용

  • 결정: 수동 파트가 1개이고 템플릿 기반 추출이 실패하면 userInputCode 전체를 수동 값으로 사용
  • 근거: 사용자가 "ㅁㅁㅁ"처럼 접두어 부분만 입력하면 템플릿 "카테고리값-____-XXX"와 불일치. startsWith 조건 실패로 추출이 안 됨. 이 경우 입력 전체가 수동 값임
  • 제한: 수동 파트가 2개 이상이면 이 폴백 불가 (어디서 분리할지 알 수 없음)

4. 코드 조합에서 manualConfig.value 폴백 제거

  • 결정: extractedManualValues[i] || part.manualConfig?.value || ""extractedManualValues[i] || ""
  • 근거: manualConfig.value는 UI에서 입력/편집할 수 없는 유령 필드. ManualConfigPanel.tsxvalue 입력란이 없어 DB에 한번 저장되면 스프레드 연산자로 계속 보존됨
  • 이중 조치: 코드에서 폴백 제거 + DB 마이그레이션으로 기존 "BULK1" 값 정리

5. DB 마이그레이션은 BULK1만 타겟팅

  • 결정: manual_config->>'value' = 'BULK1' 조건으로 한정
  • 근거: 다른 value가 의도적으로 설정된 경우가 있을 수 있음. 확인된 문제("BULK1")만 정리하여 부작용 방지
  • 대안 검토: 전체 manual_config.value 키 제거 → 보류 (운영 판단 필요)

6. extractManualValuesFromInput 헬퍼 분리

  • 결정: 기존 allocateCode 내부의 수동 값 추출 로직(L1332-1442)을 별도 private 메서드로 추출
  • 근거: 추출 로직이 약 110줄로 allocateCode가 과도하게 비대함. 헬퍼로 분리하면 순서 변경도 자연스러움
  • 원칙: 로직 자체는 변경 없음, 위치만 이동 (구조적 변경과 행위적 변경 분리)

7. 프론트엔드 변경 불필요

  • 결정: 프론트엔드 코드 수정 없음
  • 근거: _numberingRuleId가 사용자 입력 시에도 유지되고 있음 확인. buttonActions.ts가 정상적으로 allocateCode를 호출함. 문제는 백엔드 로직에만 있음

8. joinPartsWithSeparators 연속 구분자 방지

  • 결정: 빈 파트 뒤에 이미 같은 구분자가 있으면 중복 추가하지 않음
  • 근거: 카테고리가 비면 파트 값 "" + 구분자 -가 반복되어 -- 발생. 구분자 구조(-ㅁㅁㅁ-001)는 유지하되 연속(--)만 방지
  • 조건: if (val || !result.endsWith(sep)) — 값이 있으면 항상 추가, 값이 없으면 이미 같은 구분자로 끝나면 스킵

9. 템플릿 카테고리/참조 플레이스홀더를 실제값으로 변경

  • 결정: extractManualValuesFromInput 내부의 카테고리/참조 빈 값 반환을 "CATEGORY"/"REF"""로 변경
  • 근거: 실제 코드 생성에서 빈 카테고리는 ""인데 템플릿에서 "CATEGORY"를 쓰면 구조 불일치로 추출 실패. 로그로 확인: userInputCode=-제발-015, previewTemplate=CATEGORY-____-XXX, extractedManualValues=[]
  • 카테고리 있을 때: catMapping2?.format 반환은 수정 전후 동일하여 영향 없음

관련 파일 위치

구분 파일 경로 설명
수정 대상 backend-node/src/services/numberingRuleService.ts joinPartsWithSeparators(L36), buildPrefixKey(L75), extractManualValuesFromInput(신규), allocateCode(L1296)
신규 생성 db/migrations/1053_remove_bulk1_manual_config_value.sql BULK1 유령 값 정리 마이그레이션
변경 없음 frontend/components/screen/widgets/TextInputComponent.tsx _numberingRuleId 유지 확인 완료
변경 없음 frontend/lib/registry/components/numbering-rule/config.ts 채번 설정 레지스트리
변경 없음 frontend/components/screen/config-panels/NumberConfigPanel.tsx 채번 규칙 설정 패널
참고 backend-node/src/controllers/numberingRuleController.ts allocateNumberingCode 컨트롤러

기술 참고

allocateCode 실행 순서 (변경 전 → 후)

변경 전: buildPrefixKey(L1306) → 시퀀스 할당 → 수동 값 추출(L1332) → 코드 조합
변경 후: 수동 값 추출 → buildPrefixKey(수동 값 포함) → 시퀀스 할당 → 코드 조합

prefix_key 구성 (변경 전 → 후)

변경 전: "카테고리값"        (수동 파트 무시, 모든 접두어가 같은 키)
변경 후: "카테고리값|ㅁㅁㅁ"  (수동 파트 포함, 접두어별 독립 키)

폴백 체인 (변경 전 → 후)

변경 전: extractedManualValues[i] || manualConfig.value || ""
변경 후: extractedManualValues[i] || ""

joinPartsWithSeparators 연속 구분자 방지 (변경 전 → 후)

변경 전: "" + "-" + "" + "-" + "ㅁㅁㅁ" → "--ㅁㅁㅁ"
변경 후: "" + "-" (이미 "-"로 끝남, 스킵) + "ㅁㅁㅁ" → "-ㅁㅁㅁ"

템플릿 정합성 (변경 전 → 후)

변경 전: 카테고리 비었을 때 템플릿 = "CATEGORY-____-XXX" / 입력 = "-제발-015" → 불일치 → 추출 실패
변경 후: 카테고리 비었을 때 템플릿 = "-____-XXX"        / 입력 = "-제발-015" → 일치 → 추출 성공

BULK1이 DB에 남아있는 이유

ManualConfigPanel.tsx: placeholder 입력란만 존재 (value 입력란 없음)
플레이스홀더 수정 시: { ...existingConfig, placeholder: newValue }
→ 기존 config에 value: "BULK1"이 있으면 스프레드로 계속 보존됨
→ UI에서 제거 불가능한 유령 값