Files
invyone/db/migrations/RUN_085_MIGRATION.md
johngreen 68c1cb5b14 fix(부서관리): 25개 버그 일괄 수정 + 데이터 무결성 강화
CRITICAL:
- searchUsers 회사/role 격리 가드 추가 (멀티테넌시 침해 차단)
- setPrimaryDept 멤버십 검증 추가 (주부서 데이터 손상 방지)
- parent_dept_code cross-tenant 검증 (validateParent 헬퍼)

HIGH:
- updateDepartment SQL WHERE 에 DELETED_AT IS NULL 추가 (silent corruption 방지)
- update/restore 부서명 중복 검증 추가
- 글로벌 부서 (*) write 작업 SUPER_ADMIN 전용 가드
- 부서코드 자동 생성으로 강제 (사용자 입력 받지 않음)
- 회사 변경 시 상세 패널 초기화
- handleMove 부분 실패 시 화면 동기화
- 검색 시 부모 체인 자동 포함 (broken tree 수정)
- start_date 기본값 today 강제 제거

MEDIUM:
- 멤버 fetch cancellation flag
- 삭제 다이얼로그 dept_code 클로저 캡처
- isDirty 시 X 버튼 폼 초기화 경고
- 변경이력 버튼 disabled (백엔드 API 미구현)
- 일괄등록 실패 상세 모달 (라인 + 사유)
- LIKE 와일드카드 ESCAPE 적용
- nullIfBlank 에 trim 통합

LOW + 새 기능:
- 부서원 추가/제거 UI 신규 구현 (UserSearchModal)
- selectDeptMembers LEFT JOIN 으로 변경
- DepartmentPicker allowRoot 옵션 (최상위로 이동)
- expandAll 전체 departments 사용
- dead code 정리

DB:
- RUN_085 마이그레이션: DEPT_INFO partial UNIQUE + USER_DEPT UNIQUE
- 모든 active 테넌트 DB (siflex/test01/test02_invyone) 적용 완료

Breaking changes:
- 일괄등록 CSV 4컬럼 → 3컬럼 (부서명,상위부서,유형)
- 부서코드 입력란 제거 (자동 부여 DEPT_n)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:08:03 +09:00

2.0 KiB

085 마이그레이션 — 부서관리 데이터 무결성 제약 추가

작성일: 2026-05-08 작성자: johngreen 관련: 부서관리 페이지 버그 수정 (notes/johngreen/2026-05-08-부서관리-버그-정리.md)

목적

부서명/부서원 중복을 DB 레벨에서 방어. race condition 시에도 데이터 무결성 보장.

추가 제약

제약 대상 용도
idx_dept_info_company_name_unique DEPT_INFO (COMPANY_CODE, LOWER(TRIM(DEPT_NAME))) WHERE DELETED_AT IS NULL 회사 내 동일 이름 active 부서 중복 방지
idx_user_dept_user_dept_unique USER_DEPT (USER_ID, DEPT_CODE) 동일 사용자가 같은 부서 중복 등록 방지

(USER_DEPT 에 이미 PK 또는 UNIQUE 가 있으면 IF NOT EXISTS 로 안전 적용)

SQL

-- 085: 부서관리 무결성 제약
CREATE UNIQUE INDEX IF NOT EXISTS idx_dept_info_company_name_unique
  ON DEPT_INFO (COMPANY_CODE, LOWER(TRIM(DEPT_NAME)))
  WHERE DELETED_AT IS NULL;

CREATE UNIQUE INDEX IF NOT EXISTS idx_user_dept_user_dept_unique
  ON USER_DEPT (USER_ID, DEPT_CODE);

실행

각 테넌트 DB 에 적용 필요. 운영 DB 와 모든 회사 DB 에 한 번씩.

# 메타 DB
psql -h <host> -U postgres -d invyone -f RUN_085.sql

# 각 테넌트 DB (예시)
for db in $(psql -tA -c "SELECT db_name FROM company_mng WHERE db_status='active'"); do
  psql -h <host> -U postgres -d "$db" -f RUN_085.sql
done

사전 점검

기존 데이터에 중복이 있으면 인덱스 생성이 실패합니다. 사전 확인:

-- 부서명 중복 확인
SELECT COMPANY_CODE, LOWER(TRIM(DEPT_NAME)), COUNT(*)
FROM DEPT_INFO
WHERE DELETED_AT IS NULL
GROUP BY COMPANY_CODE, LOWER(TRIM(DEPT_NAME))
HAVING COUNT(*) > 1;

-- USER_DEPT 중복 확인
SELECT USER_ID, DEPT_CODE, COUNT(*)
FROM USER_DEPT
GROUP BY USER_ID, DEPT_CODE
HAVING COUNT(*) > 1;

중복이 있다면 수동 정리 후 인덱스 생성.

롤백

DROP INDEX IF EXISTS idx_dept_info_company_name_unique;
DROP INDEX IF EXISTS idx_user_dept_user_dept_unique;