# 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

```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 에 한 번씩.

```bash
# 메타 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
```

## 사전 점검

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

```sql
-- 부서명 중복 확인
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;
```

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

## 롤백

```sql
DROP INDEX IF EXISTS idx_dept_info_company_name_unique;
DROP INDEX IF EXISTS idx_user_dept_user_dept_unique;
```
