계획과 워크플로우가 완성됐습니다. 이제 진짜 시작입니다.
빌드 환경을 구축하고, 앱을 처음 실행하고,
서버 알고리즘을 역분석해 Android 코드로 바꿉니다.
구상과 계획이 끝난 뒤 실제 개발에 진입하기까지, 총 4개 Phase를 순서대로 진행했습니다.
Android Studio에서 Medium Phone API 36.1 에뮬레이터를 띄우고 앱을 처음 실행했습니다. 앱이 뜨는 순간은 성공처럼 보였지만, 화면에는 에러가 표시됐습니다.
stg1-en.snaps.com이 DNS 조회에 실패. 회사 내부망에서만 접근 가능한 서버였습니다.백엔드 API 스펙이 Notion에 있었습니다. Claude가 Notion MCP를 통해 직접 문서를 조회하고, 핵심 스펙을 파악해 정리해줬습니다.
[사진 선택]
↓
[Task 1] projectCode 발급
POST /v1/project
↓
[Task 2] 썸네일 업로드 (병렬, 최대 3개 동시)
POST /v1/project/{projectCode}/thumbnailFile
→ 응답: imageYear + imageSequence = imageKey ← 서버가 생성!
↓
[Task 3] AI 추천 API 호출
POST /v1.0/w/api/rcmdsys/design/photobook
→ imageKey, GPS, exifDate, 얼굴인식 데이터 전송
→ 응답: AI가 생성한 포토북 레이아웃 템플릿
↓
[Task 4~7] 템플릿/리소스 다운로드
↓
[편집 화면] SmartRecommendBookMainActivity
SmartRecommendBookMakingActivity)에 이미지 리스트를 넘겨주는 것으로 연결됩니다.
기존 AI 추천 서버의 clustering_story 알고리즘을 Claude가 완전히 분석했습니다. 서버 로직을 이해하고, 모바일 환경에 맞게 재설계했습니다.
서버 알고리즘을 그대로 쓸 수는 없습니다. 모바일 환경(오프라인, 성능, MediaStore API)에 맞게 차이점을 분석하고 재설계했습니다.
| 항목 | 서버 기준 | Android 재설계 |
|---|---|---|
| GPS 처리 | 역지오코딩된 {state, province} 값 사용 | GPS 좌표 거리 계산으로 클러스터링 (오프라인 동작, 10,000장도 빠름). 지역명은 타이틀 표시용으로만 역지오코딩. |
| 최소 사진 수 | 40장 이상 | 10~15장 — 짧은 나들이, 소규모 이벤트도 포함 |
| 날짜 출처 | 파일명에서 날짜 추출 (story_boost) | MediaStore.DATE_TAKEN — 거의 100% 신뢰 가능. 단순화 가능. |
| 노이즈 필터 | 저해상도 제거 | 스크린샷 제거(MIME_TYPE, 파일 경로 기반) + 저해상도 제거 |
| 클러스터링 순서 | GPS 우선 → 시간 보완 | 시간 기반 1차 분리 → GPS 기반 2차 보정 (더 빠름) |
알고리즘 설계가 완성됐습니다. 이제 코드를 작성합니다. Android Clean Architecture 원칙에 따라 가장 먼저 Domain 레이어를 구현했습니다.
PhotoStoryRepositoryImpl 구현입니다. Android MediaStore 쿼리로 사진을 읽어오고, 클러스터링 알고리즘을 Kotlin으로 구현합니다.