tdc114plus/tdc114plus 프로필 이미지 관리 정책 및 단계별 진행안.md 추가

This commit is contained in:
2026-07-15 11:00:08 +09:00
parent 8b85942b70
commit 5be5d19db4
@@ -0,0 +1,328 @@
# tdc114plus 프로필 이미지 관리 정책 및 단계별 진행안
작성일: 2026-07-14
최종 개정일: 2026-07-15
상태: draft
관련 Phase: `Phase 7-C`
## 1. 목적
신규앱의 직원 프로필 이미지를 어떤 우선순위와 어떤 저장/조회 구조로 운영할지 정리한다.
본 문서의 목적은 아래 네 가지다.
- 프로필 이미지 노출 우선순위를 고정한다.
- 네이버웍스, 114 중계서버 내부 DB, R2 버킷의 역할을 분리한다.
- 중계서버 내부에 둘 매핑 테이블의 권고 컬럼을 정리한다.
- 실제 구현을 위한 단계별 진행작업을 타임테이블 형식으로 정리한다.
## 2. 현재까지 확인된 사실
### 2-1. 이미지 노출 우선순위
현재 정리된 우선순위는 아래와 같다.
1. 네이버웍스 프로필 사진
2. 114 중계서버 내부 매핑 DB + R2 버킷 fallback 이미지
3. 신규앱 기본 아바타
즉, R2 버킷 기반 이미지는 기본 경로가 아니라 `2차 fallback` 경로다.
### 2-2. 네이버웍스 문서 검토 결과
2026-07-15 기준 네이버웍스 개발자 문서 `구성원 프로필 조회` 화면에서 아래는 확인했다.
- Endpoint: `GET /users/{userId}`
- Scope: `user.profile.read`
- `userId`에는 구성원 ID, 메일, 리소스 ID, `externalKey:{externalKey}` 형식 사용 가능
- 응답 예시 기준 확인 필드:
- `email`
- `userId`
- `userExternalKey`
- 이름, 전화번호, 조직 정보
아직 추가 확인이 필요한 사항:
- 프로필 사진 URL 필드 존재 여부
- 프로필 사진 바이너리 직접 응답 여부
- `사진 조회` API의 endpoint, scope, 응답 형식
- 사진이 없는 사용자의 판별 방식
### 2-3. 현재 준비된 외부 자산
현재 다른 개발자가 준비한 자산은 아래와 같다.
- 프로필 이미지 파일은 Cloudflare R2 Object Storage 버킷에 업로드되어 있다.
- 현재 확인된 버킷/도메인 구조는 아래와 같다.
- 공개 도메인 prefix: `https://baroncs.co.kr/employee_img/TDC/`
- 파일명 suffix: 해시 기반 `.jpg`
- 즉, 최종 URL은 아래 구조로 해석할 수 있다.
```text
https://baroncs.co.kr/employee_img/TDC/{hash_filename}.jpg
```
- 현재 파일 경로 앞부분 `https://baroncs.co.kr/employee_img/TDC/` 는 고정값으로 간주하고 진행한다.
### 2-4. 현재 준비된 매핑 테이블
현재 다른 서버에 `mapping_profile_img` 테이블이 이미 생성되어 있다.
확인된 컬럼은 아래와 같다.
- `id`
- `comp`
- `old_name`
- `new_name`
- `status`
- `name`
- `email`
- `hash_name`
- `hash_status`
- `created_at`
현재 테이블은 `파일명 변경/해시 매핑 결과 관리` 용도로는 유효하지만, 신규앱 런타임 조회를 직접 담당하는 `114 중계서버 운영 테이블`로 쓰기에는 일부 컬럼이 더 필요하다.
### 2-5. 목표 운영 위치
현재 DB는 다른 서버에 있으나, 목표 방향은 `114 신규어플 중계서버 내부`에 매핑 DB를 두는 것이다.
핵심 이유는 아래와 같다.
- 해시/매핑 테이블을 114 시스템 내부에 두어 외부 노출을 줄이기 위함
- 신규앱이 직접 파일명 규칙, 해시 규칙, 외부 DB를 알지 않게 하기 위함
- 중계서버가 사용자 식별과 최종 이미지 경로를 내부에서만 매핑하도록 만들기 위함
## 3. 현재 기준 정책
### 3-1. 기본 정책
- 신규앱은 직접 파일명을 만들지 않는다.
- 신규앱은 직접 R2 객체 경로를 계산하지 않는다.
- 신규앱은 먼저 네이버웍스 프로필 사진을 사용한다.
- 네이버웍스 사진이 없을 때만 114 중계서버 fallback 경로를 사용한다.
- 114 중계서버는 내부 매핑 DB를 조회해 R2 버킷의 이미지와 사용자를 연결한다.
- 그마저도 실패하면 앱은 기본 아바타를 사용한다.
### 3-2. 권장 조회 흐름
```text
신규앱
-> 네이버웍스 사진 확인
-> 없으면 114 중계서버에 직원 식별값 전달
-> 114 중계서버가 내부 매핑 DB 조회
-> R2 객체 경로 또는 최종 이미지 응답 반환
-> 실패 시 기본 아바타
```
### 3-3. 신규앱이 직접 하지 않아야 하는 일
- `이메일 @ 앞부분.jpg` 직접 조합
- 해시 파일명 직접 계산
- R2 저장 경로 직접 추론
- 외부 DB 직접 접근
## 4. 현재 테이블 구조 해석
현재 `mapping_profile_img` 테이블의 의미는 아래처럼 해석할 수 있다.
- `comp`
- 한글명: `회사구분`
- 의미: 계열사/회사 코드
- `old_name`
- 한글명: `기존 파일명`
- 의미: 기존 프로필 파일명
- `new_name`
- 한글명: `변경 파일명`
- 의미: 1차 치환 또는 정리 후 파일명
- `status`
- 한글명: `변환 상태`
- 의미: 파일명 변경 상태
- `name`
- 한글명: `직원명`
- 의미: 직원 실명
- `email`
- 한글명: `직원 이메일`
- 의미: 직원의 전체 이메일 주소
- `hash_name`
- 한글명: `해시 파일명`
- 의미: 최종 해시 기반 이미지 파일명
- `hash_status`
- 한글명: `해시 매핑 상태`
- 의미: 해시 파일명 매핑 처리 상태
- `created_at`
- 한글명: `생성일시`
- 의미: 매핑 행 생성 시각
## 5. 중계서버 내부 테이블에 추가 권장되는 컬럼
현재 테이블은 변환 이력 관리에는 도움이 되지만, 신규앱 조회 운영을 위해서는 아래 컬럼을 추가하는 편이 좋다.
### 5-1. 핵심 추가 권장 컬럼
- `employee_email`
- 한글명: `직원 이메일`
- 설명: 직원 전체 이메일 주소
- 비고: 현재 테이블의 `email`이 사실상 같은 역할을 하므로, 이름만 정리해도 된다.
- `employee_email_local_part`
- 한글명: `이메일 @앞부분`
- 설명: 이메일의 `@` 앞부분
- 예: `khkang@samaneng.com` -> `khkang`
- 비고: 기존 자산 규칙과 직접 연결할 때 유용하다.
- `object_key`
- 한글명: `버킷 내부 파일경로`
- 설명: R2 버킷 안의 실제 저장 경로
- 예: `employee_img/TDC/81f931388c85da0ec18cac730231827f58e5338cb1bf4751d472af413d5c557e.jpg`
- 비고: 현재 `hash_name`만으로도 조합은 가능하지만, 운영 테이블에는 전체 경로를 저장하는 편이 낫다.
### 5-2. 운영용 추가 권장 컬럼
- `is_active`
- 한글명: `사용 여부`
- 설명: 현재 앱 fallback 이미지로 사용할 수 있는 행인지 표시
- `updated_at`
- 한글명: `수정일시`
- 설명: 최근 변경 시각
- `deleted_at`
- 한글명: `삭제일시`
- 설명: soft delete 관리용
- `profile_source`
- 한글명: `프로필 이미지 출처`
- 설명: `NAVER_WORKS`, `R2_FALLBACK`, `DEFAULT` 같은 출처 관리
- `object_bucket`
- 한글명: `버킷명`
- 설명: 예: `baron-hompage`
- `public_base_url`
- 한글명: `공개 URL 기준경로`
- 설명: 예: `https://baroncs.co.kr/employee_img/TDC/`
- 비고: 현재는 고정값이지만 환경 분리를 고려하면 설정 또는 컬럼화 검토 가능
- `last_verified_at`
- 한글명: `객체 확인일시`
- 설명: 실제 버킷 객체 존재 여부를 마지막으로 확인한 시각
### 5-3. 현재 구조 대비 최소 권장안
중계서버 내부에 최소 구성으로 새 테이블을 만든다면 아래는 반드시 권장한다.
- `comp`
- `employee_email`
- `employee_email_local_part`
- `name`
- `object_key`
- `hash_name`
- `is_active`
- `created_at`
- `updated_at`
## 6. object_key와 hash_name의 차이
현재 고정 경로 prefix는 아래와 같다.
```text
https://baroncs.co.kr/employee_img/TDC/
```
따라서 두 컬럼의 차이는 아래처럼 정리된다.
- `hash_name`
- 한글명: `해시 파일명`
- 예: `81f931388c85da0ec18cac730231827f58e5338cb1bf4751d472af413d5c557e.jpg`
- `object_key`
- 한글명: `버킷 내부 파일경로`
- 예: `employee_img/TDC/81f931388c85da0ec18cac730231827f58e5338cb1bf4751d472af413d5c557e.jpg`
- 최종 URL
- 한글명: `프로필 이미지 URL`
- 예: `https://baroncs.co.kr/employee_img/TDC/81f931388c85da0ec18cac730231827f58e5338cb1bf4751d472af413d5c557e.jpg`
운영 편의성 기준으로는 `hash_name`만 보관하기보다 `object_key`를 같이 두는 편이 더 낫다.
## 7. 114 중계서버 운영 기준 권장 스키마
현재 테이블을 그대로 쓰기보다, 중계서버 내부 운영용 테이블은 아래 같은 형태를 권장한다.
| 컬럼명 | 한글명 | 용도 |
| --- | --- | --- |
| `id` | 식별자 | PK |
| `comp` | 회사구분 | 회사/계열사 구분 |
| `employee_email` | 직원 이메일 | 신규앱/직원 API 매핑 기준 |
| `employee_email_local_part` | 이메일 @앞부분 | 기존 자산 규칙 연결용 |
| `employee_name` | 직원명 | 운영 확인용 |
| `object_bucket` | 버킷명 | 저장 버킷 식별 |
| `object_key` | 버킷 내부 파일경로 | 실제 이미지 객체 경로 |
| `hash_name` | 해시 파일명 | 파일명 원본 보관용 |
| `profile_source` | 프로필 이미지 출처 | `R2_FALLBACK` 등 출처 구분 |
| `is_active` | 사용 여부 | fallback 사용 가능 여부 |
| `created_at` | 생성일시 | 생성 시각 |
| `updated_at` | 수정일시 | 수정 시각 |
| `deleted_at` | 삭제일시 | soft delete 용 |
## 8. 단계별 진행작업 타임테이블
아래 타임테이블은 현재까지 확보된 정보 기준의 권장 순서다.
| 단계 | 상태 | 작업 구분 | 작업 내용 | 완료 기준 |
| --- | --- | --- | --- | --- |
| Step 1 | 진행 중 | 문서/정책 | 프로필 이미지 우선순위, R2 구조, 중계서버 내부 DB 방향을 문서에 정리 | 본 문서와 타임테이블 반영 완료 |
| Step 2 | 대기 | 네이버웍스 검증 | `사진 조회` API endpoint, scope, 응답 형식, 무사진 응답 규칙 확인 | 네이버웍스 사진 연동 가능/불가 기준 확정 |
| Step 3 | 대기 | 현행 자산 점검 | 현재 R2 버킷 구조, 고정 prefix, 해시 파일명 규칙, 공개 URL 정책 확인 | 버킷/경로/공개정책 확정 |
| Step 4 | 대기 | 현행 DB 점검 | 현재 `mapping_profile_img` 실제 데이터 의미와 컬럼 용도 재확인 | 현행 테이블 해석표 확정 |
| Step 5 | 대기 | 중계서버 DB 설계 | 114 내부 운영용 테이블 컬럼, 인덱스, 활성여부, 수정일시 설계 | 운영용 스키마 초안 확정 |
| Step 6 | 대기 | 데이터 이관 설계 | 외부 서버 DB -> 114 내부 DB 이관 방식과 컬럼 매핑 정리 | 이관 계획서 확정 |
| Step 7 | 대기 | 중계 API 설계 | 신규앱이 중계서버에 어떤 식별값을 보내고 어떤 응답을 받을지 정리 | API 요청/응답 계약 초안 확정 |
| Step 8 | 대기 | 앱 연동 설계 | `네이버웍스 -> 중계서버 fallback -> 기본 아바타` 구현 순서 정리 | 앱 연동 시나리오 확정 |
| Step 9 | 대기 | 검증/테스트 | 정상 이미지, 무사진, 매핑 누락, 404, timeout, 비활성 이미지 테스트 | 테스트 케이스 확정 |
| Step 10 | 대기 | 구현 착수 | 중계서버 DB 생성, 데이터 이관, API 구현, 앱 연결 순차 진행 | 실제 구현 시작 가능 상태 |
## 9. 단계별 상세 진행 순서
### 9-1. 문서 정리 단계
1. 프로필 이미지 정책 문서를 최신 사실 기준으로 정리한다.
2. R2 버킷 구조와 매핑 테이블 컬럼 의미를 고정한다.
3. 중계서버 내부 DB 이전 방향을 정책으로 명시한다.
### 9-2. 중계서버 DB 설계 단계
1. 현재 `mapping_profile_img`의 재사용 범위를 결정한다.
2. 운영용 테이블을 별도로 둘지, 기존 테이블을 확장할지 결정한다.
3. `employee_email`, `employee_email_local_part`, `object_key` 포함 여부를 확정한다.
4. `is_active`, `updated_at`, `deleted_at` 같은 운영 컬럼을 확정한다.
### 9-3. API 및 앱 연동 단계
1. 신규앱이 중계서버로 어떤 식별값을 보내는지 결정한다.
2. 중계서버가 어떤 컬럼으로 이미지를 조회할지 결정한다.
3. 중계서버가 URL을 반환할지, 이미지 바이너리를 프록시할지 결정한다.
4. 앱에서 네이버웍스 실패 시에만 fallback 호출하도록 연결한다.
## 10. 현재 시점 우선 결론
- 프로필 이미지 1순위는 네이버웍스다.
- fallback 이미지는 R2 버킷을 사용하되, 조회 책임은 114 중계서버 내부로 가져오는 방향이 적절하다.
- 현재 다른 서버의 `mapping_profile_img`는 참고 소스/이관 원본으로 보고, 114 내부 운영용 테이블은 별도 정리하는 쪽이 안전하다.
- 최소 추가 권장 컬럼은 `employee_email_local_part`, `object_key`, `is_active`, `updated_at` 이다.
- 현재 단계에서는 구현보다 문서/정책/스키마 정리를 먼저 완료하는 것이 맞다.
## 11. 관련 문서
- `docs/00_guide_tdc114plus_work_progress_timetable_2026-07-02.md`
- `docs/00_contract_tdc114plus_api_2026-07-02.md`
- `docs/00_guide_tdc114plus_org_context_mapping_2026-07-08.md`