Files
vexplor/채번규칙_테이블기반_필터링_구현_완료_보고서.md
kjs 4294fbf608 feat: 채번 규칙 테이블 기반 자동 필터링 구현
- 채번 규칙 scope_type을 table로 단순화
- 화면의 테이블명을 자동으로 감지하여 채번 규칙 필터링
- TextInputConfigPanel에 screenTableName prop 추가
- getAvailableNumberingRulesForScreen API로 테이블 기반 조회
- NumberingRuleDesigner에서 자동으로 테이블명 설정
- webTypeConfigConverter 유틸리티 추가 (기존 화면 호환성)
- AutoGenerationConfig 타입 개선 (enabled, options.numberingRuleId)
- 채번 규칙 선택 UI에서 ID 제거, 설명 추가
- 불필요한 console.log 제거

Backend:
- numberingRuleService: 테이블 기반 필터링 로직 구현
- numberingRuleController: available-for-screen 엔드포인트 수정

Frontend:
- TextInputConfigPanel: 테이블명 기반 채번 규칙 로드
- NumberingRuleDesigner: 적용 범위 UI 제거, 테이블명 자동 설정
- ScreenDesigner: webTypeConfig → autoGeneration 변환 로직 통합
- DetailSettingsPanel: autoGeneration 속성 매핑 개선
2025-11-07 14:27:07 +09:00

12 KiB

채번규칙 테이블 기반 필터링 시스템 구현 완료 보고서

📅 완료 일시

  • 날짜: 2025-11-08
  • 소요 시간: 약 3시간 30분 (마이그레이션 실행 미완료)

🎯 목적

화면관리 시스템에서 채번규칙이 표시되지 않는 문제를 해결하기 위해 메뉴 기반 필터링에서 테이블 기반 필터링으로 전환

기존 문제점

  1. 화면관리에서 menuObjid 정보가 없어 scope_type='menu' 규칙을 볼 수 없음
  2. 메뉴 구조 변경 시 채번규칙 재설정 필요
  3. 같은 테이블을 사용하는 화면인데도 규칙이 보이지 않음

해결 방안

  • 테이블명 기반 자동 매칭: 화면의 테이블과 규칙의 테이블이 같으면 자동으로 표시
  • 하이브리드 접근: scope_type'global', 'table', 'menu' 세 가지로 확장
  • 우선순위 필터링: menu > table > global 순으로 규칙 표시

구현 완료 항목

Phase 1: 데이터베이스 마이그레이션 (준비 완료)

파일 생성

  • /db/migrations/046_update_numbering_rules_scope_type.sql
  • /db/migrations/RUN_046_MIGRATION.md

마이그레이션 내용

  • scope_type 제약조건 확장: 'global', 'table', 'menu'
  • 유효성 검증 제약조건 추가:
    • check_table_scope_requires_table_name: table 타입은 table_name 필수
    • check_global_scope_no_table_name: global 타입은 table_name 없어야 함
    • check_menu_scope_requires_menu_objid: menu 타입은 menu_objid 필수
  • 기존 데이터 자동 마이그레이션: global + table_nametable 타입으로 변경
  • 멀티테넌시 인덱스 최적화:
    • idx_numbering_rules_scope_table (scope_type, table_name, company_code)
    • idx_numbering_rules_scope_menu (scope_type, menu_objid, company_code)

상태

⚠️ 마이그레이션 파일 준비 완료, 실행 대기 중

  • Docker 컨테이너 연결 문제로 수동 실행 필요
  • 실행 가이드는 RUN_046_MIGRATION.md 참고

Phase 2: 백엔드 API 수정

2.1 numberingRuleService.ts

  • getAvailableRulesForScreen() 함수 추가
    • 파라미터: companyCode, tableName (필수), menuObjid (선택)
    • 우선순위 필터링: menu > table > global
    • 멀티테넌시 완벽 지원

주요 SQL 쿼리:

SELECT * FROM numbering_rules
WHERE company_code = $1
  AND (
    (scope_type = 'menu' AND menu_objid = $2)
    OR (scope_type = 'table' AND table_name = $3)
    OR (scope_type = 'global' AND table_name IS NULL)
  )
ORDER BY 
  CASE scope_type
    WHEN 'menu' THEN 1
    WHEN 'table' THEN 2
    WHEN 'global' THEN 3
  END,
  created_at DESC

2.2 numberingRuleController.ts

  • GET /api/numbering-rules/available-for-screen 엔드포인트 추가
    • Query Parameters: tableName (필수), menuObjid (선택)
    • tableName 검증 로직 포함
    • 상세 로그 기록

Phase 3: 프론트엔드 API 클라이언트 수정

lib/api/numberingRule.ts

  • getAvailableNumberingRulesForScreen() 함수 추가
    • 파라미터: tableName (필수), menuObjid (선택)
    • 기존 getAvailableNumberingRules() 유지 (하위 호환성)

사용 예시:

const response = await getAvailableNumberingRulesForScreen(
  "item_info", // 테이블명
  undefined    // menuObjid (선택)
);

Phase 4: 화면관리 UI 수정

4.1 TextTypeConfigPanel.tsx

  • tableName, menuObjid props 추가
  • 채번 규칙 로드 로직 개선:
    • 테이블명이 있으면 getAvailableNumberingRulesForScreen() 호출
    • 없으면 기존 메뉴 기반 방식 사용 (Fallback)
    • 상세 로그 추가

주요 코드:

useEffect(() => {
  const loadRules = async () => {
    if (tableName) {
      response = await getAvailableNumberingRulesForScreen(tableName, menuObjid);
    } else {
      response = await getAvailableNumberingRules(menuObjid);
    }
  };
}, [localValues.autoValueType, tableName, menuObjid]);

4.2 DetailSettingsPanel.tsx

  • currentTableName을 ConfigPanelComponent에 전달
  • ConfigPanelComponent 타입에 tableName, menuObjid 추가

4.3 getConfigPanelComponent.tsx

  • ConfigPanelComponent 타입 확장: tableName?, menuObjid? 추가

Phase 5: 채번규칙 관리 UI 수정

NumberingRuleDesigner.tsx

  • 적용 범위 선택 UI 추가
    • Global: 모든 화면에서 사용
    • Table: 특정 테이블에서만 사용
    • Menu: 특정 메뉴에서만 사용
  • 조건부 필드 표시:
    • scope_type='table': 테이블명 입력 필드 표시
    • scope_type='menu': 메뉴 선택 드롭다운 표시
    • scope_type='global': 추가 필드 불필요
  • 새 규칙 기본값: scope_type='global'로 변경 (가장 일반적)

UI 구조:

규칙명 | 미리보기
-----------------
적용 범위 [Global/Table/Menu]
└─ (table) 테이블명 입력
└─ (menu) 메뉴 선택

🔄 데이터 흐름

화면관리에서 채번 규칙 조회 시

  1. 화면 로드

    • ScreenDesigner → DetailSettingsPanel
    • currentTableName 전달
  2. TextTypeConfigPanel 렌더링

    • Props: tableName="item_info"
    • autoValueType이 "numbering_rule"일 때 규칙 로드
  3. API 호출

    GET /api/numbering-rules/available-for-screen?tableName=item_info
    
  4. 백엔드 처리

    • numberingRuleService.getAvailableRulesForScreen()
    • SQL 쿼리로 우선순위 필터링
    • 멀티테넌시 적용 (company_code 확인)
  5. 응답 데이터

    {
      "success": true,
      "data": [
        {
          "ruleId": "ITEM_CODE",
          "ruleName": "품목 코드",
          "scopeType": "table",
          "tableName": "item_info"
        },
        {
          "ruleId": "GLOBAL_CODE",
          "ruleName": "전역 코드",
          "scopeType": "global"
        }
      ]
    }
    
  6. UI 표시

    • Select 드롭다운에 규칙 목록 표시
    • 우선순위대로 정렬됨

📊 scope_type 정의 및 우선순위

scope_type 설명 우선순위 사용 케이스
menu 특정 메뉴에서만 사용 1 (최고) 메뉴별로 다른 채번 방식 필요 시
table 특정 테이블에서만 사용 2 (중간) 테이블 기준 채번 (일반적)
global 모든 곳에서 사용 가능 3 (최저) 공통 채번 규칙

필터링 로직

WHERE company_code = $1  -- 멀티테넌시 필수
  AND (
    (scope_type = 'menu' AND menu_objid = $2)     -- 1순위
    OR (scope_type = 'table' AND table_name = $3)  -- 2순위
    OR (scope_type = 'global' AND table_name IS NULL) -- 3순위
  )

🔐 멀티테넌시 보장

데이터베이스 레벨

  • company_code 컬럼 필수 (NOT NULL)
  • 외래키 제약조건 (company_info 참조)
  • 복합 인덱스에 company_code 포함

API 레벨

  • 일반 회사: WHERE company_code = $1
  • 최고 관리자: 모든 데이터 조회 가능 (company_code="*" 제외)
  • 일반 회사는 company_code="*" 데이터를 볼 수 없음

로깅 레벨

  • 모든 로그에 companyCode 포함 (감사 추적)

🧪 테스트 체크리스트

데이터베이스 테스트 (마이그레이션 후 수행)

  • 제약조건 확인

    SELECT conname, pg_get_constraintdef(oid)
    FROM pg_constraint
    WHERE conrelid = 'numbering_rules'::regclass
      AND conname LIKE '%scope%';
    
  • 인덱스 확인

    SELECT indexname, indexdef
    FROM pg_indexes
    WHERE tablename = 'numbering_rules'
      AND indexname LIKE '%scope%';
    
  • 데이터 마이그레이션 확인

    SELECT scope_type, COUNT(*) as count
    FROM numbering_rules
    GROUP BY scope_type;
    

기능 테스트

  • 회사 A로 로그인

    • 채번규칙 관리에서 새 규칙 생성 (scope_type='table', tableName='item_info')
    • 저장 성공 확인
    • 화면관리에서 item_info 테이블 화면 생성
    • 텍스트 필드에서 "자동 입력 > 채번 규칙" 선택
    • 방금 생성한 규칙이 목록에 표시되는지 확인
  • 회사 B로 로그인

    • 화면관리에서 item_info 테이블 화면 접속
    • 텍스트 필드에서 "자동 입력 > 채번 규칙" 선택
    • 회사 A의 규칙이 보이지 않는지 확인
  • 최고 관리자로 로그인

    • 채번규칙 관리에서 모든 회사 규칙이 보이는지 확인
    • 화면관리에서는 일반 회사 규칙만 보이는지 확인

우선순위 테스트

  • 같은 테이블(item_info)에 대해 3가지 scope_type 규칙 생성

    • scope_type='global', table_name=NULL, ruleName="전역규칙"
    • scope_type='table', table_name='item_info', ruleName="테이블규칙"
    • scope_type='menu', menu_objid=123, tableName='item_info', ruleName="메뉴규칙"
  • 화면관리에서 item_info 화면 접속 (menuObjid=123)

    • 규칙 목록에서 순서 확인:
      1. 메뉴규칙 (menu, 우선순위 1)
      2. 테이블규칙 (table, 우선순위 2)
      3. 전역규칙 (global, 우선순위 3)

📁 수정된 파일 목록

데이터베이스 (준비 완료, 실행 대기)

  • db/migrations/046_update_numbering_rules_scope_type.sql
  • db/migrations/RUN_046_MIGRATION.md

백엔드

  • backend-node/src/services/numberingRuleService.ts
  • backend-node/src/controllers/numberingRuleController.ts

프론트엔드 API

  • frontend/lib/api/numberingRule.ts

프론트엔드 UI

  • frontend/components/screen/panels/webtype-configs/TextTypeConfigPanel.tsx
  • frontend/components/screen/panels/DetailSettingsPanel.tsx
  • frontend/lib/utils/getConfigPanelComponent.tsx
  • frontend/components/numbering-rule/NumberingRuleDesigner.tsx

🚀 배포 가이드

1단계: 데이터베이스 마이그레이션

# Docker 환경
docker exec -i erp-node-db-1 psql -U postgres -d ilshin < db/migrations/046_update_numbering_rules_scope_type.sql

# 로컬 PostgreSQL
psql -h localhost -U postgres -d ilshin -f db/migrations/046_update_numbering_rules_scope_type.sql

2단계: 백엔드 재시작

# Docker 환경
docker-compose restart backend

# 로컬 개발
npm run dev

3단계: 프론트엔드 재빌드

# Docker 환경
docker-compose restart frontend

# 로컬 개발
npm run dev

4단계: 검증

  1. 개발자 도구 콘솔 열기
  2. 화면관리 접속
  3. 텍스트 필드 추가 → 자동 입력 → 채번 규칙 선택
  4. 콘솔에서 다음 로그 확인:
    📋 테이블 기반 채번 규칙 조회: { tableName: "xxx", menuObjid: undefined }
    ✅ 채번 규칙 로드 성공: N개
    

🎉 주요 개선 사항

사용자 경험

  • 화면관리에서 채번규칙이 자동으로 표시
  • 메뉴 구조를 몰라도 규칙 설정 가능
  • 같은 테이블 화면에 규칙 재사용 자동

유지보수성

  • 메뉴 구조 변경 시 규칙 재설정 불필요
  • 테이블 중심 설계로 직관적
  • 코드 복잡도 감소

확장성

  • 향후 scope_type 추가 가능
  • 다중 테이블 지원 가능
  • 멀티테넌시 완벽 지원

⚠️ 알려진 제약사항

  1. 메뉴 목록 로드 미구현

    • NumberingRuleDesigner에서 scope_type='menu' 선택 시 메뉴 목록 로드 필요
    • TODO: 메뉴 API 연동
  2. 마이그레이션 실행 대기

    • Docker 컨테이너 연결 문제로 수동 실행 필요
    • 배포 시 반드시 실행 필요

📝 다음 단계

  1. 마이그레이션 실행

    • DB 접속 정보 확인 후 마이그레이션 실행
    • 검증 쿼리로 정상 동작 확인
  2. 통합 테스트

    • 전체 워크플로우 테스트
    • 회사별 데이터 격리 확인
    • 우선순위 필터링 확인
  3. 메뉴 API 연동

    • NumberingRuleDesigner에서 메뉴 목록 로드 구현
  4. 사용자 가이드 작성

    • 채번규칙 사용 방법 문서화
    • scope_type별 사용 예시 추가

📞 문의 및 지원

  • 작성자: AI 개발팀
  • 작성일: 2025-11-08
  • 관련 문서: 채번규칙_테이블기반_필터링_구현_계획서.md

구현 완료! 🎊

마이그레이션 실행 후 바로 사용 가능합니다.