# tdc114plus 프로필 사진 식별자 매핑 및 소스 우선순위 검토안 작성일: 2026-07-14 상태: draft 관련 Phase: `Phase 7-C` ## 1. 목적 신규앱에서 직원 프로필 사진을 노출할 때, 어떤 이미지 소스를 어떤 우선순위로 사용할지 정하고, 기존 이미지 파일명 규칙을 앱이 직접 사용하지 않도록 외부서버와 신규앱의 역할을 정리한다. 본 문서는 아래를 결정하기 위한 검토 초안이다. - 기존 `이메일 @ 앞부분.jpg` 자산을 어떻게 안전하게 재사용할지 - 네이버웍스 사진, 외부서버 매핑 사진, 앱 기본 아바타의 우선순위를 어떻게 정할지 - 외부서버에서 어떤 테이블과 조회 인터페이스를 제공해야 하는지 - 신규앱에서 어떤 식별값으로 프로필 이미지를 표현해야 하는지 - DTO 또는 계약에 어떤 보강이 필요한지 ## 2. 현재 상황 - 신규앱은 프로필 사진 파일을 자체 저장하거나 자체 파일명 규칙으로 관리하지 않는다. - Baron SSO는 현재 네이버웍스와 강하게 연결되어 있으며, 팀장 방향은 네이버웍스 사진을 우선 활용하는 것이다. - 팀장은 네이버웍스 프로필 사진 연동 검토를 위해 사용할 개발자계정을 별도로 공유해주기로 한 상태다. - 현재 프로필 이미지는 특정 외부서버에 있는 파일 링크 또는 이미지 URL을 통해 표현하는 방향이다. - 기존 이미지 파일명은 `직원 이메일 @ 앞부분.jpg` 규칙을 따른다. - `이메일 @ 앞부분`은 사내 개인 고유키 성격을 가지므로, 팀장 권고에 따라 신규앱이 이 값을 직접 파일명으로 사용하거나 URL 규칙으로 유추하는 방식은 피해야 한다. 팀장 권고 기준의 1차 방향은 아래와 같다. 1. 네이버웍스에 해당 직원 사진이 있으면 그 사진을 먼저 표현한다. 2. 네이버웍스 사진이 없으면, 외부서버의 `photoLookupKey` 기반 매핑 구조로 사진을 조회한다. 3. 그마저도 사진이 없거나 조회에 실패하면, 신규앱이 현재 제공하는 기본 프로필 이미지를 사용한다. ## 3. 기본 판단 - 앱의 최우선 사진 소스는 네이버웍스여야 한다. - 앱이 `이메일 @ 앞부분.jpg`를 직접 조합하는 방식은 보안 권고와 충돌하므로 장기 유지안으로 보기 어렵다. - 외부서버는 이미지 원본 파일명과 분리된 별도 조회 키를 제공해야 한다. - 신규앱은 네이버웍스 사진이 없는 경우에만 `photoLookupKey` 같은 대체 식별자로 외부서버 이미지를 조회해야 한다. - 가능하면 앱이 원본 식별값으로 해시를 직접 계산하기보다, 서버 또는 DTO가 `photoLookupKey`를 직접 제공하는 구조가 더 안전하고 단순하다. ## 4. 목표 - 네이버웍스 사진을 1순위 소스로 사용한다. - 내부 파일명 규칙을 앱과 외부 URL에 직접 노출하지 않는다. - 기존 이미지 자산을 전면 재가공하지 않고 재사용 가능하게 만든다. - 직원검색, 조직도, 직원 상세 화면에서 동일한 규칙으로 프로필 사진을 노출한다. - 이미지가 없거나 매핑이 실패해도 기본 아바타 fallback을 유지한다. ## 5. 권장 구조 ### 5-1. 핵심 구조 1. 신규앱은 먼저 네이버웍스 사진을 조회하거나 네이버웍스 사진 URL/식별값을 우선 사용한다. 2. 네이버웍스 사진이 없을 때만 외부서버 기반 fallback 경로로 내려간다. 3. 외부서버는 기존 이미지 파일과 사용자 정보를 기준으로 매핑 테이블을 만든다. 4. 외부서버는 원본 파일명 대신 `photoLookupKey`를 생성해 저장한다. 5. 신규앱은 직원 DTO 또는 별도 응답에서 `photoLookupKey`를 받는다. 6. 신규앱은 `photoLookupKey`를 이용해 외부서버의 이미지 조회 endpoint만 호출한다. 7. 외부서버는 내부적으로 실제 파일을 찾아 이미지를 응답한다. 8. 네이버웍스 사진도 없고 외부서버 사진도 없으면 앱 기본 아바타를 표시한다. ### 5-2. 프로필 사진 소스 우선순위 신규앱의 프로필 사진 노출 우선순위는 아래와 같이 본다. 1. 네이버웍스 사진 2. 외부서버 `photoLookupKey` 기반 이미지 3. 신규앱 기본 아바타 즉, 이번 문서에서 정리한 외부서버 매핑 구조는 기본 경로가 아니라 `2차 fallback 경로`다. ### 5-3. 쉽게 설명한 구조 쉽게 말하면 앱은 사진을 아래 순서로 찾는다. - 먼저 네이버웍스에서 사진이 있는지 본다 - 없으면 외부서버에 `photoLookupKey`로 사진이 있는지 본다 - 그것도 없으면 앱 기본 이미지를 보여준다 그리고 외부서버 fallback을 사용할 때도, 기존 방식처럼 앱이 직접 파일명을 만들어 찾지는 않는다. 기존 방식은 앱이 직접 파일명을 만들어 창고 물건 이름을 바로 찾아가는 방식에 가깝다. - 앱이 이메일을 안다 - 앱이 `@` 앞부분을 뽑는다 - 앱이 `kimss.jpg` 같은 파일명을 만든다 - 앱이 그 파일명을 URL에 붙여 직접 호출한다 권장 방식은 앱이 파일명을 모르고, 보관증 번호만 내는 방식이다. - 앱은 `photoLookupKey`만 안다 - 앱은 `GET /profile-images/{photoLookupKey}` 같은 주소만 호출한다 - 외부서버가 내부 테이블을 조회한다 - 외부서버가 실제 파일을 찾아 이미지로 응답한다 이렇게 하면 앱이 내부 파일명 규칙을 알 필요가 없다. ## 6. 외부서버(테이블) 측 단계별 작업 ### 6-1. 원본 기준값 확정 기존 이미지 파일명이 `이메일 @ 앞부분.jpg` 규칙을 사용하므로, 외부서버 내부 기준값은 우선 `email local-part`를 원본 식별값으로 사용한다. ### 6-2. 대체 식별자 생성 규칙 확정 원본 식별값을 외부에 직접 노출하지 않도록 `photoLookupKey`를 생성한다. 권고 방향: - 단순 평문 재사용 금지 - 단순 파일명 재사용 금지 - 서버 비밀값 기반의 `HMAC(email local-part)` 또는 이에 준하는 결정적 식별자 우선 검토 ### 6-3. 매핑 테이블 설계 최소 컬럼 초안: - `photo_lookup_key` - `image_path` 또는 `image_url` - `employee_name` - `phone_number` - `email` - `status` - `updated_at` 운영상 필요하면 원본 `email local-part`를 내부 관리용으로 둘 수 있으나, 접근 권한은 제한하고 앱이나 공개 URL에는 직접 노출하지 않는다. ### 6-4. 기존 이미지와 사용자 정보 적재 기존 `이메일 @ 앞부분.jpg` 파일 목록과 Baron SSO 사용자 정보를 대조해 초기 매핑 데이터를 적재한다. 이때 함께 점검할 항목: - 누락 파일 - 중복 매핑 - 퇴사자 데이터 - 이메일 변경 이력 ### 6-5. 조회 인터페이스 설계 신규앱이 파일명을 직접 조합하지 않도록 조회 endpoint를 `photoLookupKey` 기준으로 고정한다. 후보: - `GET /profile-images/{photo_lookup_key}` - `GET /profile-image?key=...` 둘 다 의미는 비슷하지만, 경로형인 `GET /profile-images/{photo_lookup_key}`가 더 읽기 쉽고 관리가 단순하므로 우선안으로 본다. ### 6-6. 조회 인터페이스를 쉽게 설명하면 앱은 더 이상 `"kimss.jpg"` 같은 실제 파일명을 만들지 않는다. 대신 아래처럼 `photoLookupKey`만 전달한다. ```http GET /profile-images/a8f3x91k... ``` 또는 ```http GET /profile-image?key=a8f3x91k... ``` 그러면 외부서버가 내부적으로: 1. 전달받은 key를 테이블에서 찾고 2. 그 key에 연결된 실제 이미지 파일을 찾고 3. 그 이미지를 앱에 대신 내려준다 즉, 앱은 파일명을 모르고도 이미지를 볼 수 있다. ### 6-7. 이미지 응답 방식 결정 응답 방식은 아래 두 가지가 있다. 1. 이미지 바이너리 직접 응답 외부서버가 JPEG 또는 PNG 자체를 바로 응답한다. 2. CDN 또는 실제 파일 URL로 redirect 외부서버가 내부 검증 후 다른 이미지 주소로 이동시키는 방식이다. 1차 구현 우선안: - `GET /profile-images/{photo_lookup_key}` - 이미지 바이너리 직접 응답 이유: - 구조가 단순하다 - 파일 실제 위치를 숨기기 쉽다 - 앱 쪽 구현이 단순하다 ### 6-8. 접근 통제와 운영 정책 `photoLookupKey`만 알면 누구나 무제한 조회되는 구조는 피해야 한다. 정리 필요 항목: - 앱 또는 API gateway 기준 인증 필요 여부 - rate limit - 캐시 헤더 - 만료 정책 - 비정상 대량 조회 탐지 ### 6-9. 갱신 절차 정의 아래 이벤트 발생 시 테이블과 이미지 자산이 어떻게 갱신되는지 운영 절차를 정리한다. - 입사 - 퇴사 - 이메일 변경 - 사진 교체 - 사용자 정보 정정 ## 7. 신규앱 측 단계별 작업 ### 7-1. 현재 DTO 식별 필드 점검 직원검색, 조직도, 직원 상세 응답에서 어떤 식별값을 안정적으로 받을 수 있는지 먼저 확인한다. 최소 확인 대상: - 네이버웍스 사진 URL 또는 네이버웍스 사진 존재 여부를 나타내는 필드 - `email` - `emailLocalPart` - `photoLookupKey` 추가 전제: - 팀장이 전달 예정인 네이버웍스 연동용 개발자계정으로 실제 프로필 사진 조회 가능 여부와 응답 구조를 먼저 확인한다. ### 7-2. 계약 보강 포인트 정리 현재 DTO에 프로필 사진 매핑용 안정 식별자가 없으면 아래 중 하나를 계약 보강 후보로 요청한다. - `naverWorksPhotoUrl` 또는 이에 준하는 사진 필드 - `email` - `emailLocalPart` - `photoLookupKey` 우선 확인안은 `네이버웍스 사진 식별/URL 제공 가능 여부`이고, 외부서버 fallback용으로는 `photoLookupKey` 직접 제공이 권고안이다. ### 7-3. 앱 내부 매핑 전략 확정 가능한 방식은 두 가지다. 1. 서버/DTO가 `photoLookupKey`를 직접 내려주고 앱은 그 값만 사용 2. 앱이 직원 식별값을 받아 직접 `photoLookupKey`를 계산 권고안은 1번이다. 이유: - 앱이 원본 식별값을 덜 알게 된다 - 해시/HMAC 규칙을 앱에 넣지 않아도 된다 - 보안 검토 범위가 줄어든다 - 앱 구현이 단순해진다 ### 7-4. 이미지 조회 규칙 반영 앱은 아래 우선순위 규칙으로 이미지를 선택한다. 1. 네이버웍스 사진이 있으면 그것을 사용 2. 네이버웍스 사진이 없으면 외부서버 `photoLookupKey` 기반 이미지 조회 3. 둘 다 없으면 앱 기본 아바타 사용 앱은 외부서버 fallback 단계에서도 더 이상 `이메일 @ 앞부분.jpg`를 붙여 이미지 URL을 만들지 않는다. 대신 아래와 같은 고정 규칙만 사용한다. ```text /profile-images/{photo_lookup_key} ``` ### 7-5. fallback 처리 아래 상황에서는 기본 아바타를 노출한다. - 네이버웍스 사진 없음 - `photoLookupKey` 없음 - 외부서버 404 - timeout - 기타 이미지 로드 실패 중요 원칙: - 프로필 사진 실패 때문에 직원검색/조직도 본문 로딩이 깨지지 않도록 분리 처리한다 ### 7-6. 캐시와 placeholder 정책 동일 이미지가 목록에서 반복 노출될 수 있으므로 앱 이미지 캐시 정책과 placeholder 표현을 함께 정리한다. ### 7-7. 테스트 시나리오 - 네이버웍스 사진이 있으면 외부서버 조회 없이 우선 노출되는지 확인 - 네이버웍스 사진이 없고 `photoLookupKey`가 있으면 외부서버 사진이 노출되는지 확인 - 네이버웍스 사진도 없고 `photoLookupKey`도 없으면 기본 이미지가 노출되는지 확인 - `photoLookupKey`가 있을 때 정상 이미지 노출 - `photoLookupKey`가 없을 때 기본 이미지 노출 - 외부서버 404 시 fallback 유지 - 응답 지연 또는 timeout 시 본문 기능 유지 - 잘못된 이미지가 다른 직원에게 매핑되지 않는지 확인 ## 8. 현재 권고안 현재 시점의 우선 권고안은 아래와 같다. 1. 신규앱의 프로필 사진 1순위 소스는 네이버웍스로 둔다. 2. 네이버웍스 사진이 없을 때만 외부서버 `photoLookupKey -> 실제 이미지` 매핑 테이블을 사용하는 fallback 경로로 내려간다. 3. 외부서버는 `GET /profile-images/{photo_lookup_key}` 형태의 조회 endpoint를 제공한다. 4. 1차 구현은 외부서버가 이미지를 직접 응답하는 방식으로 시작한다. 5. 신규앱은 파일명을 직접 만들지 않는다. 6. 팀장이 공유할 네이버웍스 개발자계정으로 연동 가능성과 필요한 API/권한 범위를 먼저 확인한다. 7. 직원 DTO 또는 별도 프로필 응답에 `네이버웍스 사진 필드`와 `photoLookupKey`를 함께 포함시킬 수 있는지 우선 검토한다. ## 9. 후속 확인 필요 항목 - 팀장이 공유할 네이버웍스 개발자계정의 권한 범위가 프로필 사진 조회에 충분한지 - 네이버웍스 연동 시 앱이 직접 API를 호출하는지, Baron SSO 또는 중간 서버가 사진 URL/바이너리를 전달하는지 - Baron SSO 연계 응답 또는 직원 API에서 네이버웍스 사진 URL/식별값을 받을 수 있는지 - 네이버웍스 사진이 없는 사용자를 어떤 기준으로 판별할 수 있는지 - Baron SSO 또는 직원 API 응답에 `email`이 항상 존재하는지 - `email local-part`가 전사적으로 유일하고 장기적으로 안정적인지 - 이메일 변경 시 파일명과 매핑 테이블을 어떻게 갱신할지 - 외부서버가 앱 전용 이미지 조회 endpoint를 제공할 수 있는지 - 이미지 직접 응답과 CDN redirect 중 어느 운영 방식이 더 적합한지 - 직원 DTO에 `photoLookupKey`를 직접 추가할 수 있는지 ## 10. 관련 문서 - `docs/00_guide_tdc114plus_work_progress_timetable_2026-07-02.md` - `docs/00_guide_tdc114plus_org_context_mapping_2026-07-08.md` - `docs/00_contract_tdc114plus_api_2026-07-02.md`