# 한라 WORKS 도메인 분리 및 조직 연동 계획

## 현황 확인

- 로컬 seed 기준 `halla`는 `hanmac-family` 직속 `COMPANY`입니다.
- 로컬 DB 기준 `halla`는 `hanmac-family` 직속이 맞지만, 타입은 현재 `ORGANIZATION`입니다.
- 한라 하위 테넌트는 로컬 DB 기준 전체 43개입니다.
- 한라 직속 하위 조직은 10개입니다.
  - 경영지원본부
  - 기반사업본부
  - 기술영업본부
  - 시공현장
  - 안전관리본부
  - 업무총괄
  - 영업총괄
  - 운영사업소
  - 임원실
  - 환경플랜트사업본부

## 현재 코드의 문제

현재 WORKS 도메인 분류는 다음 네 가지 도메인만 알고 있습니다.

- `SAMAN_DOMAIN_ID`
- `HANMAC_DOMAIN_ID`
- `GPDTDC_DOMAIN_ID`
- `BARONGROUP_DOMAIN_ID`

`HALLA_DOMAIN_ID`가 없기 때문에 `halla`와 `hallasanup.com`은 별도 도메인 루트로 판정되지 않습니다. 이 상태에서 조직 연동을 실행하면 한라 하위 조직이 HALLA 도메인이 아니라 fallback 도메인으로 분류될 수 있습니다.

또한 로컬 DB에서 `halla` 타입이 `ORGANIZATION`이면 “별도 회사 도메인 루트”라는 의미가 약합니다. seed와 실제 DB를 `COMPANY`로 맞추는 마이그레이션이 필요합니다.

## 목표 구조

Baron 내부 구조:

- `hanmac-family`
  - `halla` (`COMPANY`, WORKS domain root, `HALLA_DOMAIN_ID`, `hallasanup.com`)
    - 한라 하위 조직들 (`ORGANIZATION`)

한맥가족 직속 회사/그룹 배치 순서:

1. `gpdtdc` - 총괄기획&기술개발센터
2. `saman` - 삼안
3. `hanmac` - 한맥기술
4. `baron-group` - 바론그룹
5. `halla` - 한라산업개발

WORKS Mobile 구조:

- `HALLA_DOMAIN_ID`
  - 한라 depth 1 조직은 HALLA 도메인의 최상위 org unit으로 생성합니다.
  - 한라 depth 2 이상 조직은 Baron의 부모 조직 external key를 따라 하위 org unit으로 생성합니다.
  - `halla` 회사 테넌트 자체는 WORKS org unit으로 만들지 않습니다. 도메인 루트 분류 기준으로만 사용합니다.

예상 매핑:

- `halla-mgmt-support-hq` -> `HALLA_DOMAIN_ID`, `parentOrgUnitId=""`
- `halla-mgmt-support` -> `HALLA_DOMAIN_ID`, `parentOrgUnitId="externalKey:d656c134-a50b-43b9-8c2d-fb3738dd0f9f"`
- `site-gyeongsan-road` -> `HALLA_DOMAIN_ID`, 실제 Baron parent external key 유지

## 구현 계획

1. 도메인 루트 판정 추가
   - `isWorksmobileDomainRootTenant`에 `halla`, `hallasanup.com`, `한라산업개발`을 추가합니다.
   - `worksmobileTenantDomainIDEnvKey`가 한라 테넌트를 `HALLA_DOMAIN_ID`로 반환하도록 추가합니다.

2. 이메일 도메인 판정 추가
   - `ResolveWorksmobileAccountDomainIDFromEmail`에 `hallasanup.com -> HALLA_DOMAIN_ID`를 추가합니다.
   - `worksmobileDomainIDEnvKeyFromEmail`에도 같은 매핑을 추가합니다.
   - 사용자 주 이메일 또는 alias가 `hallasanup.com`이면 HALLA 계정/조직 이메일로 매핑되도록 검증합니다.

3. WORKS remote 조회 범위 추가
   - `worksmobileDomainEnvMappings`에 `HALLA_DOMAIN_ID`와 label `한라산업개발`을 추가합니다.
   - `WorksmobileDomainIDsFromEnv`가 HALLA 도메인도 remote user/group 조회 대상으로 포함해야 합니다.

4. 로컬 데이터 마이그레이션
   - `halla`가 `hanmac-family` 직속인지 확인합니다.
   - `halla` 타입을 `COMPANY`로 맞춥니다.
   - `halla` 도메인을 `hallasanup.com`으로 유지합니다.
   - 필요한 경우 `halla` 관련 기존 WORKS outbox pending 작업을 정리하거나 재등록합니다.

5. 조직 연동 순서
   - 먼저 comparison dry-run으로 HALLA 도메인 예상값을 확인합니다.
   - 한라 하위 조직만 대상으로 org unit upsert를 등록합니다.
   - WORKS에서 같은 external key가 다른 도메인에 이미 붙어 있으면 기존 도메인 external key를 clear한 뒤 HALLA 도메인에 재등록합니다.
   - 조직 연동 성공 후 사용자 연동을 진행합니다.

6. 사용자 연동 기준
   - Baron representative/primary가 `halla` 또는 한라 하위 조직이면 `HALLA_DOMAIN_ID` 조직 membership을 생성합니다.
   - 주 이메일이 `hallasanup.com`이면 HALLA domain account로 생성합니다.
   - 다른 회사 주 이메일을 가진 겸직 사용자는 계정 domain은 주 이메일 기준으로 유지하고, HALLA 조직은 `organizations[]`의 추가 조직으로 매핑합니다.

## 테스트 계획

- `worksmobile_mapper_test.go`
  - `halla`와 `hallasanup.com`이 `HALLA_DOMAIN_ID`로 resolve되는지 검증합니다.
  - `hallasanup.com` 이메일이 HALLA account domain으로 resolve되는지 검증합니다.
  - `WorksmobileDomainIDsFromEnv`에 HALLA 도메인이 포함되는지 검증합니다.

- `worksmobile_sync_service_test.go`
  - 한맥가족 직속 회사 `halla`를 domain root로 판정하는 테스트를 추가합니다.
  - 한라 depth 1 조직은 `parentOrgUnitId=""`로 생성되는지 검증합니다.
  - 한라 depth 2 조직은 `parentOrgUnitId="externalKey:<parent>"`로 생성되는지 검증합니다.
  - comparison에서 같은 external key가 다른 domain에 있으면 HALLA domain 기준으로 update/rekey 대상이 되는지 검증합니다.

- live/E2E
  - `HALLA_DOMAIN_ID`가 설정된 환경에서 한라 하위 조직 org unit provisioning dry-run을 실행합니다.
  - 실제 upsert 후 worksmobile 메뉴의 최근 작업에서 processed/failed 및 실패 사유를 확인합니다.

## 운영 순서 제안

1. `HALLA_DOMAIN_ID` 환경값을 dev/local에 먼저 설정합니다.
2. 코드에 HALLA 도메인 분류를 추가하고 테스트를 통과시킵니다.
3. 로컬 DB의 `halla` 타입을 `COMPANY`로 마이그레이션합니다.
4. worksmobile comparison에서 한라 하위 조직만 필터링해 예상 도메인과 parent를 확인합니다.
5. 조직 upsert를 먼저 수행합니다.
6. 실패 작업이 있으면 최근 작업 이력에서 원인을 확인하고 external key 충돌부터 해소합니다.
7. 조직이 모두 정상 처리된 뒤 사용자 sync를 진행합니다.

## 주의점

- `halla` 회사 테넌트 자체를 org unit으로 만들면 HALLA 도메인 최상위에 “한라산업개발” 조직이 중복으로 생길 수 있습니다.
- 기존에 한라 하위 조직 external key가 `BARONGROUP_DOMAIN_ID`에 생성되어 있으면, WORKS API가 같은 external key의 다른 domain 중복을 허용하지 않을 수 있습니다.
- 사용자 sync는 조직 upsert가 끝난 뒤 진행해야 `organizations[].orgUnits[].orgUnitId` 참조 실패를 줄일 수 있습니다.
- 로컬 DB 타입과 seed 타입이 다르면 이후 seed/마이그레이션 테스트가 계속 흔들릴 수 있으므로 DB 보정이 먼저 필요합니다.
