한마디로
감정 기록과 AI 분석을 제공하는 Zero Gravity의 Spring Boot REST API입니다. 프리티어 클라우드 위에 인프라부터 배포까지 직접 구축하고, 비용 제약 안에서 AI 기능을 설계했습니다.
- 5개 도메인, 14개 엔드포인트: 인증, 감정 기록, 통계, AI 분석을 하나의 API로 설계했습니다.
- OCI + Terraform 6 모듈로 인프라를 직접 구축하고, Build-first 전략으로 Zero-Downtime 배포를 구현했습니다.
- Time Bucket 샘플링으로 Gemini API 전송량을 97% 절감하여, AI 기능을 비용 한도 내에서 운영했습니다.
팀 프로젝트에서 프로덕션까지.
팀 프로젝트로 시작한 Spring Boot 백엔드를 프로덕션 서비스로 전환했습니다. 기본 CRUD API만 존재했던 프로젝트에 인증, 인프라, 배포 파이프라인을 구축하고 AI 분석 기능을 추가했습니다.
- 레이어드 아키텍처를 도메인별 구조로 재구성했습니다.
- NextAuth OAuth → JWT 인증 체계를 구현했습니다.
- OCI 위에 인프라를 직접 구축하고 Zero-Downtime 배포를 구현했습니다.
- Gemini API 기반 감정 분석 기능을 추가했습니다.
API Endpoints
Infrastructure
전부 보내면 한 달도 못 버팁니다.
Gemini API로 감정 기록을 분석하는 기능을 구현하려 했습니다. 1년치 기록을 전부 보내면 요청당 Input 토큰이 ~55K에 달했습니다. 프로젝트 예산으로는 감당할 수 없었습니다.
데이터를 줄이면 분석 품질이 떨어지고, 기능 자체를 포기하기엔 핵심 기능이었습니다.
버킷 하나, 대표 기록 하나.
전체를 보낼 수 없다면, 각 기간을 대표하는 기록만 골라서 보내면 됐습니다. 기간을 균등한 시간 단위(버킷)로 쪼개고, 버킷마다 대표 기록을 1개씩 뽑았습니다. Year 분석이면 월 단위로 12개입니다. 전체에서 한 번에 고르면 기록이 많은 달에 몰려, 1년의 흐름을 담지 못하기 때문입니다.
남은 문제는 "대표"를 어떤 기준으로 고를 것인가였습니다. 기준은 이미 서비스 안에 있었습니다. 차트가 기간별로 집계하던 평균 감정 레벨과 이유 통계로 대표의 조건을 정의했습니다.
- 평균 감정 레벨에 가장 가까울 것
- 가장 자주 등장한 이유를 포함할 것
이유 통계는 버킷 단위로 다시 집계했고, 감정 통계용 집계 쿼리는 그대로 재사용했습니다.
레벨 60% + 이유 40%로 점수를 매겼습니다.
감정 레벨 60% + 이유 매칭 40%의 가중 스코어로 각 버킷의 대표 기록을 선별했습니다.
동점이면 일기가 긴 순, 이유가 많은 순, 최신 순으로 타이브레이크했습니다.
예시: Year 분석의 1월 버킷 (평균 감정 레벨: 4.5, 최빈 이유: "Work")
전송량 97% 절감, 요청당 $0.002
※ AI 분석 결과는 24시간 캐싱하고, 감정 기록이 변경되면 해당 기간 캐시를 무효화했습니다.