# 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. 그 다음 실제 코드 변경