# Baron OrgChart (바론 조직도 서비스)

Baron SSO 시스템과 연동되는 독립적인 **조직도 시각화(Organization Chart) 웹 애플리케이션**입니다. 기존 관리자 시스템(Adminfront)에 종속되어 있던 기능을 별도의 서비스(RP: Relying Party)로 분리하여 구축했습니다.

## 🌟 주요 기능

*   **독립된 SSO 인증 (Ory Hydra):** Baron SSO(Ory 기반)를 통한 안전한 OAuth2/OIDC 로그인 지원
*   **딥링크(Deep Link) 지원:** 특정 부서의 조직도로 바로 접근 가능한 공유 링크 (`/chart/:tenantId` 또는 `/chart/:slug`) 지원
*   **고급 트리뷰 디자인:** 밝은 테마 기반의 직관적인 계층형 트리뷰 제공
*   **Keto ReBAC 권한 연동 (예정):** 사용자의 소속 부서 및 권한 레벨에 따라 열람 가능한 조직도가 동적으로 제어됩니다.

## 🛠️ 기술 스택

*   **프레임워크:** React 19 + Vite + TypeScript
*   **스타일링:** Tailwind CSS
*   **인증 연동:** `react-oidc-context`, `oidc-client-ts`
*   **상태 관리:** React Query (`@tanstack/react-query`)
*   **아이콘:** Lucide React

## 🧩 조직도 데이터 연동 구조

조직도 화면은 Baron Admin에서 관리한 **테넌트(Tenant)**와 **사용자(User)** 정보를 Backend API로 받아와 프론트에서 트리 구조로 조립합니다. Adminfront 화면에 직접 의존하지 않고, 동일한 Admin API 데이터를 사용하는 독립 RP로 동작합니다.

### 인증 및 API 호출

*   모든 인증 화면은 `react-oidc-context`를 통해 OIDC Access Token을 얻고, API 요청 시 `Authorization: Bearer <access_token>` 헤더를 붙입니다.
*   사용자가 작업 테넌트를 선택한 경우 `localStorage.dev_tenant_id` 값을 `X-Tenant-ID` 헤더로 함께 전달합니다.
*   API Base URL은 `VITE_DEV_API_BASE`, `VITE_ADMIN_API_BASE`, `/api` 순서로 결정됩니다.

### 일반 조직도 화면

`/chart`와 `/chart/:tenantId`는 로그인된 사용자를 대상으로 다음 API를 호출합니다.

| 용도 | API | 주요 사용 필드 |
| --- | --- | --- |
| 테넌트 목록 | `GET /v1/admin/tenants?limit=10000&offset=0` | `id`, `type`, `name`, `slug`, `parentId`, `memberCount`, `status` |
| 사용자 목록 | `GET /v1/admin/users?limit=5000&offset=0` | `id`, `email`, `name`, `status`, `tenantSlug`, `companyCode`, `joinedTenants`, `position`, `jobTitle` |

테넌트는 Baron Admin에서 입력한 `parentId` 관계를 기준으로 트리로 변환합니다. 현재 루트 후보는 `type === "COMPANY_GROUP"`인 테넌트를 우선 사용하고, 없으면 최상위 테넌트를 사용합니다. 회사 필터는 루트 하위의 `type === "COMPANY"` 테넌트로 구성됩니다.

사용자는 다음 순서로 조직도 노드에 매핑됩니다.

1. `status === "active"`인 사용자만 사용합니다.
2. `@hanmac.kr` 이메일은 현재 조직도 표시 대상에서 제외합니다.
3. 사용자의 `companyCode`가 있으면 해당 값을 테넌트 `slug`와 매칭합니다.
4. `companyCode`가 없으면 `tenantSlug`를 사용합니다.
5. `joinedTenants`가 있으면 각 joined tenant의 `slug`에도 같은 사용자를 추가합니다.
6. 같은 테넌트 노드 안에서 동일 사용자 `id`는 중복 추가하지 않습니다.

각 조직도 노드는 테넌트명(`name`)을 헤더로 사용하고, 해당 테넌트 `slug`에 매핑된 사용자를 구성원 목록으로 표시합니다. 구성원은 `position`/`jobTitle` 기준으로 정렬되며, 표시 직무는 `jobTitle || position || "사원"` 순서로 결정됩니다.

### 공유 조직도 화면

`/chart?token=<share-token>` 형태의 공유 링크는 인증 체크를 건너뛰고 다음 공개 API만 호출합니다.

| 용도 | API | 주요 사용 필드 |
| --- | --- | --- |
| 공유 조직도 | `GET /v1/public/orgchart?token=<share-token>` | `tenants`, `users`, `sharedWith` |

공개 API 응답의 `tenants`와 `users`는 일반 조직도와 같은 방식으로 트리 및 구성원 목록에 매핑됩니다. 단, 공개 응답은 서버가 공유 범위에 맞게 이미 필터링한 데이터로 간주합니다.

### 조직 선택기

`/picker`와 `/embed/picker`도 Baron Admin의 테넌트/사용자 데이터를 사용합니다.

*   `GET /v1/admin/tenants`
*   `GET /v1/admin/users`

선택기는 테넌트 노드와 사용자 노드를 함께 보여주며, 사용자는 `companyCode || tenantSlug`와 테넌트 `slug`를 기준으로 배치합니다. 임베딩 모드에서는 선택 결과를 `postMessage`로 부모 화면에 전달합니다.

## 🚀 로컬 환경 실행 가이드

### 1. 저장소 복제 및 의존성 설치
```bash
git clone https://gitea.hmac.kr/baron/baron-orgchart.git
cd baron-orgchart
npm install
```

### 2. 환경 변수 설정
프로젝트 루트에 `.env.local` 파일을 생성하고 아래 환경 변수를 설정합니다. (개발 환경 기준)

```env
# Baron SSO(Gateway)의 OIDC 엔드포인트
VITE_OIDC_AUTHORITY=http://localhost:5000/oidc

# Hydra에 등록된 Client ID
VITE_OIDC_CLIENT_ID=orgfront

# Backend API 주소
VITE_ADMIN_API_BASE=http://localhost:5000/api
```

### 3. 개발 서버 실행
```bash
npm run dev
```
기본적으로 `http://localhost:5175` 에서 실행됩니다.

## 🔗 관련 문서 및 이슈
*   [조직도 임베딩 토큰 설계](docs/orgchart-embedding-token-design.md)
*   [Issue #544: 조직도 탭 분리 및 스타일 변경](https://gitea.hmac.kr/baron/baron-sso/issues/544)
*   [Issue #545: 조직도 권한 설정](https://gitea.hmac.kr/baron/baron-sso/issues/545)

---
*Powered by Baron SSO*
