Java · Spring Boot 4.1 · Spring AI(Gemini · OpenAI) · PostgreSQL · Redis · Flyway · Playwright
직접 만든 기능
·시세 분석 — 비교 매물 선별, 신뢰도 등급, 판매 · 구매 추천, 감가 예측, 6시간 배치
·AI 상품 등록 — 사진으로 상품 정보 채우기, Gemini 실패 시 GPT 대체
·상품 등록 · 수정 진행 상황 SSE 전송
·알림(시세 변동 · 목표가 도달 · 연동 만료)과 관심상품
·번개장터 · 중고나라 매물 수집, 번개장터 자동 게시
·인증(JWT · 소셜 로그인) · Flyway 마이그레이션 · GitLab CI
화면
배포 서비스(jigeumini.live)의 소개 화면
서비스 소개
시세 근거
판매 · 구매 추천
흐름
상품 등록 진행 흐름 (SSE)
IMAGE_UPLOAD사진 업로드
→IMAGE_ANALYSISAI 사진 분석
→PRODUCT_SAVE상품 저장
→MARKET_ANALYSIS시세 분석
IMAGE_ANALYSIS → GPT 대체Gemini가 실패하면 OpenAI GPT로 한 번 더 — 한도 초과(429) 뒤 5분은 Gemini를 건너뜀
MARKET_ANALYSIS → SKIP90초 안에 끝나지 않으면 이 단계만 건너뛰고 등록은 완료
저장 전 → 취소180초를 넘기거나 연결이 끊기면 저장하지 않고 올린 사진도 지움
저장 중 → 끝까지 저장저장이 시작된 뒤에는 시간 초과여도 저장을 마침
작업 몰림 → 503등록 작업 대기열(20건)이 가득 차면 바로 503으로 알림
단계마다 시작 · 진행 · 완료를 보내고, 15초마다 ping으로 연결을 유지한다.
문제 해결 과정
믿을 수 있는 시세 — 같은 물건만, 같은 규칙으로
문제
중고 매물은 제목 · 상태 · 가격이 제각각이라, 다른 물건이나 구매 글, 극단적인 가격이 섞이면 시세와 추천을 믿을 수 없었다
원인 — 어떻게 찾았나
같은 카테고리 매물을 그대로 평균 내면 부품용 · 액세서리 · 삽니다 글까지 섞였고, 최근 하루치만 쓰면 같은 물건 매물이 너무 적었다
해결 — 무엇을 바꿨나
최근 1주일 매물에서 중복 · 구매 · 대여 글 · 제목에 없는 액세서리를 거르고 키워드 점수로 30개를 고른 뒤 AI가 같은 물건만 확정하게 했다. 4개 이상이면 IQR로 이상값을 빼고, 매물이 모자라면 번개장터를 상품명으로 다시 검색해 채웠다. 신뢰도는 매물 수 비율과 가격 변동계수 중 낮은 등급을 쓰고, 분석 후 24시간이 지나면 한 단계 낮춘다
결과
판매 · 구매 추천은 AI 답과 달라도 가격차 ±5% · 월 추세 ±3% 규칙을 따라, 같은 데이터면 같은 추천이 나온다
AI가 막혀도 등록은 계속 — 한곳에서 대체 호출
문제
AI 사진 분석이 Gemini 한도 초과나 장애로 실패하면 상품 등록 전체가 실패했고, SDK 기본 재시도 때문에 실패까지 오래 기다렸다
해결 — 무엇을 바꿨나
모든 AI 호출을 한 실행기로 모아 Gemini가 실패하면 OpenAI GPT로 한 번 대체 호출하게 했다. 한도 초과(429)는 재시도하지 않고 5분 동안 Gemini를 건너뛰며, 재시도는 408 · 5xx에만 2번으로 줄였다. 사진 분석 프롬프트의 카테고리 목록은 상위 분류별로 묶어 약 14k에서 7k 토큰으로 줄였다
결과
한쪽 AI가 막혀도 상품 등록과 시세 분석이 이어진다
1분 넘게 걸리는 등록 — SSE와 저장 전 취소
문제
사진 업로드 · AI 분석 · 시세 분석까지 등록이 90초를 넘기기도 해, 기다리는 화면은 멈춘 것처럼 보이고 중간에 나가면 반쯤 만든 상품이 남을 수 있었다
해결 — 무엇을 바꿨나
등록 · 수정 API를 SSE로 바꿔 단계마다 진행 상황을 보내고, 시간 초과(180초)나 연결 끊김은 저장 전이면 작업을 취소해 업로드한 사진까지 지웠다. 저장이 시작된 뒤에는 끝까지 마치고, 작업 대기열이 가득 차면 바로 503으로 알린다
결과
사용자는 진행 단계를 보며 기다리고, 중간에 나가도 반쯤 만든 상품이 남지 않는다
설계 결정
사라진 분석 자동 복구
등록 직후 분석 대기열은 메모리에만 있어 재시작하면 사라진다. 30분마다 최근 24시간 안에 등록됐는데 분석 결과도 건너뛴 기록도 없는 상품을 찾아 다시 넣는다.
정기 시세 분석 배치
6시간마다 스레드 3개로 나눠 분석하고, 진행 중인 상품은 건너뛰며 하나가 실패해도 나머지는 계속한다.
번개장터 자동 게시
공개 API가 없어 Playwright로 회원 세션을 넣고 등록 폼을 채워 올린다. 세션 토큰은 AES-GCM으로 암호화해 저장한다.
Redis 쓰임
리프레시 토큰, 차단 회원, 비밀번호 재설정 토큰, 24시간 조회수 중복 제거에 쓴다.
검증
백엔드 테스트 567개
테스트 클래스 65개. 통합 테스트는 Spring 컨텍스트 하나를 공유하고 CI에서 PostgreSQL 17 서비스로 돌린다.
GitLab CI
MR마다 백엔드 빌드(포맷 검사 · 테스트)와 프론트 타입 · 린트 · 테스트 · Playwright e2e를 돌리고, develop · main은 EC2 배포 뒤 헬스 체크까지 한다.
MR 규칙
승인 2명 이상, 직접 push 금지, 기능 브랜치는 develop에 rebase해 올린다.