You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
인덱스: (user_id, mission_id), (user_id, mission_id, attempt_date) 로 조회 최적화
제약조건: reward_ledger에 UNIQUE(user_id, mission_id) → 미션당 중복 보상 방지
AI Integration
영수증 판독(M3)과 상품 이미지 비교(M4)에 AI Vision을 활용합니다.
모델: gemini-2.5-flash (Elice Cloud ML API 경유)
선택 이유: 빠른 응답 속도와 충분한 정확도를 위해 gemini-2.5-flash를 채택하였습니다. 실시간 사용자 경험을 해치지 않으면서도 영수증 OCR 및 이미지 비교에 필요한 멀티모달 성능을 제공합니다.
호출 방식: Spring Boot에서 RestClient로 OpenAI 호환 API를 직접 호출 (별도 AI 서버 없음)
영수증 분석 (M3): 이미지에서 문자를 직접 읽어 대상 상품명과 글자 형태 유사도로 매칭, 공백 차이 무시
인벤토리 비교 (M4): 사용자 촬영 사진과 기준 상품 이미지를 비교, 브랜드·이름·패키징 기준 동일 상품 판별
응답 형식: { match, confidence, retryHint, reason } JSON → confidence threshold 초과 시 성공 처리
에러 처리: AI 응답 파싱 실패 시 안전하게 match=false 반환, 네트워크 타임아웃 60초
Tech Points
1. AI Vision 기반 실시간 미션 검증
gemini-2.5-flash 모델을 통한 빠른 멀티모달 분석으로 사용자 대기 시간 최소화
영수증 OCR에서 공백/줄바꿈을 무시하는 유연한 문자열 매칭 프롬프트 설계
AI 응답 실패 시에도 서비스가 중단되지 않는 방어적 에러 핸들링
2. Stateless JWT 인증 + 역할 기반 접근 제어
Spring Security 필터 체인에 JWT 인증 필터를 통합한 무상태 아키텍처
USER / OWNER 역할 분리로 매장 관리와 미션 참여를 분리
3. Flyway 기반 DB 마이그레이션
V1~V8의 순차적 스키마 마이그레이션으로 안전한 DB 스키마 변경 관리
서버 시작 시 자동 실행되어 배포 파이프라인 단순화
4. 거리 기반 매장 정렬 (Haversine Formula)
사용자 좌표 기반 매장 거리 계산 및 가까운 순 정렬
Kakao Geocoding API 연동으로 주소 → 좌표 자동 변환
5. S3 Presigned URL을 활용한 이미지 업로드
서버 부하 없이 클라이언트에서 S3에 직접 업로드
10분 만료 URL로 보안 확보
6. Soft Delete & 중복 보상 방지
미션 삭제 시 is_active 플래그를 사용한 논리적 삭제로 데이터 보존
reward_ledger UNIQUE 제약조건으로 미션당 1회만 보상 지급
Getting Started
Prerequisites
Java 21+
Docker & Docker Compose
1. 인프라 실행 (MySQL + Redis)
docker-compose up -d
2. 환경변수 설정
export INVENTORY_API_URL=<Elice API URL>export INVENTORY_API_KEY=<Elice API Key>export KAKAO_API_KEY=<Kakao REST API Key>export JWT_SECRET=<최소 32바이트 시크릿 키>