Stabilize auth flow and profile images
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
# tdc114plus org-context 응답 매핑 판단서
|
||||
|
||||
작성일: 2026-07-08
|
||||
상태: v1.0
|
||||
|
||||
목적: Baron Swagger의 `GET /api/v1/integrations/org-context` 설명과 예시 응답을 기준으로, 현재 `tdc114plus` 앱 화면 요소에 어떤 필드를 직접 매핑할 수 있는지와 어떤 부분은 추가 가공이 필요한지 판단한다.
|
||||
|
||||
관련 문서:
|
||||
|
||||
- `docs/00_contract_tdc114plus_api_2026-07-02.md`
|
||||
- `docs/00_guide_tdc114plus_external_api_usage_2026-07-03.md`
|
||||
- `docs/00_policy_tdc114plus_screen_feature_2026-07-07.md`
|
||||
|
||||
## 1. 결론
|
||||
|
||||
- `org-context`는 현재 기준으로 `조직도/직원 데이터 원형 API`로 매우 유력하다.
|
||||
- 특히 `tenantSlug` 기준 subtree, `tree`, `tenants`, `members` 구조는 `전체 > 회사 > 하위조직 > 개인` 탐색 정책과 잘 맞는다.
|
||||
- 다만 이 API는 `Integrations` 영역이며 `API Key`가 필요하므로, 모바일 앱이 운영 Key를 직접 넣고 호출하는 구조는 기본안으로 채택하면 안 된다.
|
||||
- 따라서 `데이터 구조 기준 API`로는 채택 가능하지만, `실기기 앱 직접 호출 방식`은 보안 검토가 끝나기 전까지 확정하지 않는다.
|
||||
|
||||
## 2. Swagger에서 확인된 사실
|
||||
|
||||
대상 API:
|
||||
|
||||
```http
|
||||
GET /api/v1/integrations/org-context
|
||||
```
|
||||
|
||||
특징:
|
||||
|
||||
- 계정 세션 없이 `API Key`로 조회
|
||||
- `tenantSlug`가 없으면 기본 `hanmac-family` subtree 반환
|
||||
- `includeUsers=false`이면 tenant members는 빈 배열
|
||||
- `includeUserIds=true`이면 `members[].id`, `members[].phone` 추가
|
||||
|
||||
주요 응답 구조:
|
||||
|
||||
- `scope.tenantId`
|
||||
- `scope.tenantSlug`
|
||||
- `tree`
|
||||
- `tenants[]`
|
||||
- `tenant.members[]`
|
||||
|
||||
즉, 조직 트리와 조직별 직접 소속 구성원 목록을 함께 주는 구조다.
|
||||
여기서 `tenant.members[]`와 `tenant.memberCount`는 해당 조직에 직접 붙어 있는 구성원 기준으로 해석한다.
|
||||
화면의 하위조직 카드에 표시하는 인원 수는 직접 소속 수가 아니라, 해당 조직과 모든 descendant 조직의 직접 소속 인원을 합산한 `subtree 인원 수`로 앱에서 계산한다.
|
||||
|
||||
## 3. 현재 앱 기능과의 적합도 판단
|
||||
|
||||
### 3.1 매우 잘 맞는 부분
|
||||
|
||||
1. 회사/가족사 칩
|
||||
- `tree.name`, `tree.slug`, `tenants[].name`, `tenants[].slug`, `parentId`
|
||||
- 현재 상단 칩 구조와 직접 연결 가능
|
||||
|
||||
2. 하위조직 drilldown
|
||||
- `tree.children[]`
|
||||
- `tenant.parentId`
|
||||
- 현재 정책의 `전체 > 회사 > 하위조직 > 개인` 탐색 구조와 잘 맞음
|
||||
|
||||
3. 조직별 소속 인원 표시
|
||||
- `tenant.members[]`
|
||||
- leaf 조직에서 직원 목록으로 진입하는 정책과 맞음
|
||||
- 비-leaf 조직의 `members[]`는 직접 소속 인원이므로, 하위조직 목록과 한 화면에 섞어 표시하지 않는다
|
||||
|
||||
4. 직원 상세 기본 텍스트
|
||||
- `members[].name`
|
||||
- `members[].email`
|
||||
- `members[].department`
|
||||
- `members[].grade`
|
||||
- `members[].position`
|
||||
- `members[].jobTitle`
|
||||
|
||||
5. 조직도 정렬 힌트
|
||||
- `members[].isOwner`
|
||||
- `members[].isLeader`
|
||||
- `members[].isPrimary`
|
||||
- 현재 `팀장 우선` 정렬 정책에 보조 신호로 활용 가능
|
||||
|
||||
### 3.2 조건부로 맞는 부분
|
||||
|
||||
1. 전화/문자 기능
|
||||
- `members[].phone`
|
||||
- 하지만 Swagger 설명상 `includeUserIds=true`일 때만 포함
|
||||
- 즉, 전화/문자 기능까지 쓰려면 `includeUserIds=true`가 사실상 필요
|
||||
|
||||
2. 직원 식별자 기반 상세/즐겨찾기
|
||||
- `members[].id`
|
||||
- 이것도 `includeUserIds=true`일 때만 포함
|
||||
- 즐겨찾기/상세/프로필 이미지 매핑 안정성을 높이려면 필요
|
||||
- 2026-07-15 실조회 기준 이 값은 실제 UUID 형식으로 내려오는 것을 확인했다
|
||||
|
||||
3. 초기 내 팀 뱃지 계산
|
||||
- `members[].department`와 `tenant.name` 매칭으로 어느 정도 가능
|
||||
- 다만 `department` 문자열과 tenant 이름이 항상 1:1 대응하는지 추가 확인 필요
|
||||
|
||||
### 3.3 그대로는 부족한 부분
|
||||
|
||||
1. 앱 현재 `Employee` 모델의 `tenantId`, `tenantName`, `tenantSlug`
|
||||
- `OrgContextMember` 안에는 tenant 정보가 직접 들어있지 않음
|
||||
- 따라서 `tenant.members[]`를 순회하며 `상위 tenant 정보`를 멤버에 주입하는 앱 내부 flatten 가공이 필요
|
||||
|
||||
2. 현재 `EmployeeListResponse.items` 형태
|
||||
- `org-context`는 `items[]` 응답이 아니라 `tree + tenants[] + tenant.members[]` 구조
|
||||
- 즉, 직원검색용 평탄 목록은 앱 내부에서 별도 생성해야 함
|
||||
|
||||
3. 현재 `TenantListResponse.items`
|
||||
- `org-context`는 `items[]` 래퍼가 아님
|
||||
- `tenants[]` 또는 `tree.children[]`를 `TenantSummary` 형태로 바꾸는 adapter 필요
|
||||
|
||||
4. `totalMemberCount`
|
||||
- Swagger 예시에는 `memberCount`는 보이지만 `totalMemberCount`는 보장되지 않음
|
||||
- 현재 앱 모델의 `totalMemberCount`는 앱 내부에서 descendant 포함 합산 계산이 필요
|
||||
- 예: `CM본부` 자체 직접 소속이 0명이라도 하위 `CM사업부`에 511명이 있으면 `CM본부` 카드에는 511명으로 표시한다
|
||||
- 반대로 leaf 조직의 직접 소속이 0명이면 leaf 진입 시 `검색 결과 없음` 표시가 정상일 수 있다
|
||||
|
||||
5. 프로필 사진 URL
|
||||
- `profileImageUrl` 필드는 없음
|
||||
- 사번/이미지 URL 직접 연결은 불가
|
||||
|
||||
## 4. 현재 Flutter 모델 기준 매핑 판단
|
||||
|
||||
### 4.1 `TenantSummary`
|
||||
|
||||
현재 필드:
|
||||
|
||||
- `id`
|
||||
- `name`
|
||||
- `slug`
|
||||
- `type`
|
||||
- `parentId`
|
||||
- `memberCount`
|
||||
- `totalMemberCount`
|
||||
|
||||
매핑 판단:
|
||||
|
||||
| 앱 필드 | org-context 소스 | 판단 |
|
||||
| --- | --- | --- |
|
||||
| `id` | `tenant.id` | 직접 가능 |
|
||||
| `name` | `tenant.name` | 직접 가능 |
|
||||
| `slug` | `tenant.slug` | 직접 가능 |
|
||||
| `type` | `tenant.type` | 직접 가능 |
|
||||
| `parentId` | `tenant.parentId` | 직접 가능 |
|
||||
| `memberCount` | `tenant.memberCount` 또는 `tenant.members.length` | 직접 소속 수로 사용 |
|
||||
| `totalMemberCount` | 없음 | 앱 내부에서 subtree 합산 계산 필요 |
|
||||
|
||||
### 4.2 `Employee`
|
||||
|
||||
현재 필드:
|
||||
|
||||
- `id`
|
||||
- `name`
|
||||
- `phoneNumber`
|
||||
- `email`
|
||||
- `tenantId`
|
||||
- `tenantName`
|
||||
- `tenantSlug`
|
||||
- `department`
|
||||
- `grade`
|
||||
- `position`
|
||||
- `jobTitle`
|
||||
- `status`
|
||||
- `profileImageUrl`
|
||||
|
||||
매핑 판단:
|
||||
|
||||
| 앱 필드 | org-context 소스 | 판단 |
|
||||
| --- | --- | --- |
|
||||
| `id` | `member.id` | `includeUserIds=true` 필요 |
|
||||
| `name` | `member.name` | 직접 가능 |
|
||||
| `phoneNumber` | `member.phone` | `includeUserIds=true` 필요 |
|
||||
| `email` | `member.email` | 직접 가능 |
|
||||
| `tenantId` | 상위 `tenant.id` | 가공 필요 |
|
||||
| `tenantName` | 상위 `tenant.name` | 가공 필요 |
|
||||
| `tenantSlug` | 상위 `tenant.slug` | 가공 필요 |
|
||||
| `department` | `member.department` | 직접 가능 |
|
||||
| `grade` | `member.grade` | 직접 가능 |
|
||||
| `position` | `member.position` | 직접 가능 |
|
||||
| `jobTitle` | `member.jobTitle` | 직접 가능 |
|
||||
| `status` | 없음 또는 tenant status와 혼동 가능 | 재정의 필요 |
|
||||
| `profileImageUrl` | 없음 | 별도 정책 필요 |
|
||||
|
||||
## 5. 화면 정책 기준 판단
|
||||
|
||||
### 5.1 바로 충족 가능한 정책
|
||||
|
||||
- 회사급 초기 범위
|
||||
- 전체 > 회사 > 하위조직 > 개인 drilldown
|
||||
- breadcrumb 유지
|
||||
- leaf 조직 진입 후 직원 목록 표시
|
||||
- 하위조직 카드의 subtree 인원 수 표시
|
||||
- 조직도 그룹 내 리더 우선 정렬 보조
|
||||
|
||||
### 5.2 추가 가공 후 충족 가능한 정책
|
||||
|
||||
- 본인 팀 뱃지 고정 노출
|
||||
- 선택 scope 기준 직원검색
|
||||
- 즐겨찾기 로컬 저장
|
||||
- 상세 화면 tenant/부서/직급/직위 표시
|
||||
- 프로필 이미지 2순위 UUID 파일명 연결
|
||||
|
||||
### 5.3 현재 구조만으로는 바로 어려운 정책
|
||||
|
||||
- 프로필 사진 URL 표시
|
||||
- 안정적인 직원 상세 단건 조회
|
||||
- 서버 기반 즐겨찾기 동기화
|
||||
|
||||
## 6. 최종 판단
|
||||
|
||||
`org-context`는 다음 의미에서 채택 가치가 높다.
|
||||
|
||||
1. 조직도와 직원검색의 데이터 원형으로 충분히 쓸 수 있다.
|
||||
2. 현재 앱이 원하는 조직 탐색 UX와 구조적으로 잘 맞는다.
|
||||
3. 현재 코드의 `tdc114plus 전용 DTO`는 상당 부분 이 응답을 flatten/adapter 한 결과로 재해석할 수 있다.
|
||||
|
||||
하지만 아래 2가지는 분리해서 봐야 한다.
|
||||
|
||||
1. `데이터 구조 기준으로 채택할 것인가`
|
||||
- 예
|
||||
2. `모바일 앱이 운영 Key를 넣고 직접 호출할 것인가`
|
||||
- 현재 기준으로는 보안 검토 전까지 아니오
|
||||
|
||||
### 6.1 2026-07-15 추가 확인
|
||||
|
||||
- 가족사 전체 `org-context` 응답과 기존 프로필 파일 CSV를 대조한 결과, 기존 `2457`건이 `members[].id`와 전건 매핑됐다.
|
||||
- 따라서 현재 기준으로 `members[].id`는 프로필 이미지 2순위 식별자로 실사용 가능한 후보가 아니라, 사실상 채택 가능한 기준값으로 본다.
|
||||
|
||||
## 7. 다음 작업 권장 순서
|
||||
|
||||
1. `org-context`를 기준 데이터 구조로 채택한다고 문서에 명시
|
||||
2. 현재 `Employee`, `TenantSummary`, `OrgChartSnapshot`를 `org-context adapter` 기준으로 재설계
|
||||
3. `includeUserIds=true`를 전제로 해야 하는 기능과 아닌 기능을 분리
|
||||
4. 운영 Key 보호 방식을 확정
|
||||
5. 그 다음 실제 코드 변경
|
||||
Reference in New Issue
Block a user