# Baron Org Context API 연동 참고

작성일: 2026-07-03

목적: `tdc114plus` 개발 중 Baron SSO 계열 조직/사용자 데이터를 어떤 API로 조회하는지, 인증 방식은 무엇인지, 실제 호출 예시와 응답 구조는 어떠한지 빠르게 참고할 수 있도록 정리한다.

## 1. 결론

`tdc114plus`에서 참고할 Baron 조직도 API는 아래 둘 중 하나처럼 보일 수 있다.

- 공개 공유링크 방식: `GET /api/v1/public/orgchart?token=...`
- API Key 방식: `GET /api/v1/integrations/org-context`

실제 확인 결과, 팀에서 전달받은 값은 `public/orgchart`용 `token`이 아니라 `integrations/org-context`용 `X-Baron-Key-ID`, `X-Baron-Key-Secret` 조합이다.

즉 현재 기준의 실제 연동 대상은 아래 API다.

```http
GET https://sadmin.hmac.kr/api/v1/integrations/org-context
X-Baron-Key-ID: {key id}
X-Baron-Key-Secret: {key secret}
```

2026-07-10 기준:

- 실제 배포 전까지 Baron SSO API 참고 기준은 staging `https://sadmin.hmac.kr/api/docs#/`다.
- Baron SSO가 로그인 성공 후 조직도 API 호출용 ID/Secret을 내려주는 기능은 아직 미개발이다.
- 앱은 향후 이 값을 받을 준비를 하되, 현재 개발/검증은 로컬 비추적 env/Dart define에 설정한 staging 고정 키 fallback으로 진행한다.

## 2. 확인 결과

실제 테스트 결과:

- `GET /api/v1/public/orgchart?token={ID}`: `401 Unauthorized`
- `GET /api/v1/public/orgchart?token={SECRET}`: `401 Unauthorized`
- 응답 body:

```json
{
  "error": "invalid or expired share link",
  "code": "invalid_session"
}
```

- `GET /api/v1/integrations/org-context`에 `X-Baron-Key-ID`, `X-Baron-Key-Secret` header 사용: `200 OK`

따라서 현재 `tdc114plus`는 공유 링크 token 방식이 아니라 API Key 방식의 `org-context`를 원본 조직/사용자 데이터 소스로 본다.

## 3. Swagger 문서 위치

Swagger UI:

```text
https://sadmin.hmac.kr/api/docs#/Integrations/get_api_v1_integrations_org_context
```

OpenAPI YAML:

```text
https://sadmin.hmac.kr/api/openapi.yaml
```

Swagger에서 직접 확인할 때는 우측 상단 `Authorize`에 아래 값을 입력한다.

- `X-Baron-Key-ID`
- `X-Baron-Key-Secret`

## 4. 호출 방식

기본 호출 예시:

```bash
curl "https://sadmin.hmac.kr/api/v1/integrations/org-context?tenantSlug=hanmac-family&includeUsers=true&includeUserIds=true" \
  -H "X-Baron-Key-ID: {KEY_ID}" \
  -H "X-Baron-Key-Secret: {KEY_SECRET}"
```

주요 query parameter:

| 이름 | 필수 | 기본값 | 설명 |
| --- | --- | --- | --- |
| `tenantSlug` | N | `hanmac-family` | 조회할 subtree root tenant slug |
| `includeUsers` | N | `true` | `false`이면 사용자 목록 없이 조직만 반환 |
| `includeUserIds` | N | `false` | `true`이면 사용자 `id`, `phone` 포함 |

## 5. 응답 구조

응답 최상위 구조:

```json
{
  "schemaVersion": "baron.org-context.v1",
  "issuedAt": "2026-07-03T02:31:37Z",
  "scope": {
    "tenantId": "tenant-uuid",
    "tenantSlug": "hanmac-family"
  },
  "tree": {
    "id": "tenant-uuid",
    "type": "COMPANY_GROUP",
    "name": "한맥가족",
    "slug": "hanmac-family",
    "members": [],
    "children": []
  },
  "tenants": [
    {
      "id": "tenant-uuid",
      "type": "ORGANIZATION",
      "name": "플랫폼팀",
      "slug": "platform-team",
      "parentId": "root-uuid",
      "status": "active",
      "memberCount": 3,
      "members": []
    }
  ]
}
```

사용자 필드 예시:

```json
{
  "id": "user-uuid",
  "email": "user@example.com",
  "name": "홍길동",
  "phone": "+821012345678",
  "department": "플랫폼팀",
  "grade": "책임",
  "position": "팀장",
  "jobTitle": "개발",
  "isOwner": false,
  "isLeader": true,
  "isPrimary": true
}
```

핵심 해석:

- `tree`: 실제 조직 트리 구조
- `tenants`: flatten된 조직 목록
- `members`: 각 조직에 직접 소속된 사용자 목록
- `memberCount`: 각 조직의 직접 소속 인원 수로 해석
- `totalMemberCount`: 응답에서 보장되는 값이 아니므로 앱에서 descendant를 포함해 계산
- `scope.tenantSlug`: 이번 조회의 기준 루트 slug

화면 표시 규칙:

- 하위조직 카드의 `n명`은 `memberCount`가 아니라 앱이 계산한 `totalMemberCount`를 사용한다.
- `totalMemberCount`는 해당 조직 직접 소속 인원과 모든 하위조직 직접 소속 인원을 합산한다.
- 자식 조직이 있는 비-leaf 조직에서는 직원 목록보다 하위조직 목록을 우선 표시한다.
- 자식 조직이 없는 leaf 조직에 도달했을 때만 해당 leaf의 직접 소속 직원 목록을 표시한다.
- leaf 조직의 직접 소속 인원이 0명이면 `검색 결과 없음`이 정상일 수 있다.

## 6. 보안 및 저장 위치

이 API는 query parameter가 아니라 header 인증을 사용한다.

```http
X-Baron-Key-ID
X-Baron-Key-Secret
```

따라서 다음 원칙을 지킨다.

- tracked 모바일 Flutter 앱 소스와 tracked 문서에 실제 키를 넣지 않는다.
- 브라우저 주소창 query string으로 시크릿을 넣지 않는다.
- Baron SSO backend, 별도 서버, 또는 개발자 로컬 비추적 env/Dart define에만 저장한다.
- 실제 키 값은 저장소 tracked 파일에 커밋하지 않는다.
- 운영 배포 전에는 로그인 성공 후 받은 session credential 또는 안전한 서버 중계 구조로 전환한다.

현재 로컬 Baron SSO worktree에서는 아래 환경변수 이름으로 정리했다.

```env
TDC114PLUS_ORG_CONTEXT_BASE_URL=https://sadmin.hmac.kr
TDC114PLUS_ORG_CONTEXT_KEY_ID=
TDC114PLUS_ORG_CONTEXT_KEY_SECRET=
TDC114PLUS_ORG_CONTEXT_TENANT_SLUG=hanmac-family
TDC114PLUS_ORG_CONTEXT_INCLUDE_USERS=true
TDC114PLUS_ORG_CONTEXT_INCLUDE_USER_IDS=true
```

로컬 반영 위치:

- Baron SSO API worktree: `/home/ubuntu/workspace/baron-sso-tdc114plus-api/.env`

## 7. tdc114plus 반영 상태

2026-07-03 기준 반영 상태:

- 이 문서의 기준 API는 Baron 원본 `org-context`다.
- 앱 코드와 문서에 남아 있는 `tdc114plus` 전용 endpoint 가정은 레거시 흔적이며, 신규 정책의 공식 기준이 아니다.

현재 구현 동작:

- 외부 `org-context` 호출 성공 시: 외부 조직/사용자 응답을 앱 내부 DTO로 매핑
- 환경변수 미설정 시: 기존 로컬 fallback 동작이 남아 있을 수 있으므로 단계적 제거 대상이다

현재 매핑 결과:

- `tenants`는 `org-context`의 tenant 목록 기준
- `employees`는 각 tenant `members` 기준
- 중복 사용자는 `id`, `email`, `phone`, `name` 순으로 dedupe
- `cache.source`는 외부 연동일 때 `org-context`

## 8. 브라우저 확인 방법

브라우저 주소창만으로는 header를 넣을 수 없으므로 직접 호출은 불가능하다.

확인 방법:

1. Swagger UI에서 `Authorize` 사용
2. 브라우저 개발자도구 console에서 `fetch` 사용
3. 터미널에서 `curl` 사용

예시 `fetch`:

```js
fetch("https://sadmin.hmac.kr/api/v1/integrations/org-context?tenantSlug=hanmac-family&includeUsers=true&includeUserIds=true", {
  headers: {
    "X-Baron-Key-ID": "YOUR_KEY_ID",
    "X-Baron-Key-Secret": "YOUR_KEY_SECRET"
  }
}).then(r => r.json()).then(console.log)
```

## 10. 운영 전환 메모

- 2026-07-10부터 팀장 지시에 따라 신규 앱 개발 시 Baron 원본 참고 API는 production host가 아니라 staging host `https://sadmin.hmac.kr/` 기준으로 다시 본다.
- 운영 키(`CLIENT ID`, `X-Baron-Key-Secret`)는 회전될 수 있으므로 tracked 문서에 박아두지 않고 로컬 비추적 `.env`에만 보관한다.

## 9. 후속 작업 메모

- 앱 내부 직원검색 모델
- 앱 내부 직원상세 모델

현재 이 두 경로는 기존 로컬 DB 기반이며, 조직도와 동일한 외부 `org-context` 소스로 완전히 통일할지는 후속 판단이 필요하다.
