Stabilize auth flow and profile images

This commit is contained in:
Codex
2026-07-20 13:38:39 +09:00
parent 57caca8dc8
commit 5d3eee7a16
128 changed files with 28860 additions and 1468 deletions
@@ -0,0 +1,238 @@
# 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` 소스로 완전히 통일할지는 후속 판단이 필요하다.