Featured Project

FinalProject_3

Spring Boot 기반 중고 거래 플랫폼

메인 화면
로그인 화면
마이페이지
채팅 화면
상품 등록
결제 화면
📅 기간
2026.02.24 - 2026.03.31
👥 구성
4인 팀 프로젝트 (KDT 파이널프로젝트)
👤 역할
회원, 마이페이지, 채팅, 챗봇
🔧 주요 기술
Spring Boot, Oracle, WebSocket, Firebase

프로젝트 소개

Spring Boot 기반의 중고 거래 플랫폼으로, 4명의 팀원이 역할을 분담하여 개발한 팀 프로젝트입니다.

MSA(마이크로서비스 아키텍처)로 설계하여 finalProject_3(회원·마이페이지·채팅·챗봇·결제)와 board_service(게시판)를 독립 서비스로 분리하고, API Gateway를 통해 단일 진입점으로 연결했습니다.

회원 인증부터 상품 등록/거래, 실시간 채팅, 결제, AI 챗봇, 관리자 기능까지 실제 서비스 수준의 다양한 기능을 구현하였으며, Spring Security, WebSocket, Firebase, Gemini AI 등 여러 기술을 실무적으로 적용해 보았습니다.

담당 기능

👤 회원 (Member)

  • Spring Security + JWT 기반 로그인/로그아웃, 인증·인가 처리
  • OAuth2 소셜 로그인 구현 (Google, Kakao, Naver)
  • 회원가입 시 이메일·닉네임·휴대폰 중복 확인 API 구현
  • CoolSMS 연동 SMS 인증번호 발송 및 세션 검증 (회원가입 / 계정 찾기)
  • 프로필 이미지 업로드 및 닉네임 수정
  • 아이디·비밀번호 찾기 (SMS 인증 기반)

📋 마이페이지 (MyPage)

  • 마이페이지 메인 (거래 횟수, 안전결제 횟수 등 요약 정보 표시)
  • 내 판매 상품 조회 / 수정 / 삭제 (이미지·배송옵션·직거래 위치 포함)
  • 내 구매 상품 조회 및 구매확정 처리
  • 찜 목록 조회
  • 계좌 정보 관리 (AES-256 암호화 적용)
  • 배송지 관리

💬 채팅 (Chat)

  • WebSocket + STOMP 기반 실시간 1:1 채팅 구현
  • Firebase Realtime Database를 활용한 채팅 메시지 저장 및 조회
  • 채팅방 목록 조회 (Oracle DB에서 방 정보 관리)
  • 채팅 내 신고 기능 구현

🤖 챗봇 (Chatbot)

  • Gemini AI API 연동 챗봇 구현
  • 사용자 질문에 대한 AI 응답 처리

기술적 도전

WebSocket + Firebase 이중 구조로 채팅 구현

실시간 메시지 전송은 WebSocket(STOMP)으로 처리하고, 메시지 영구 저장 및 이전 대화 조회는 Firebase Realtime Database를 활용하는 이중 구조로 설계했습니다. Oracle DB에는 채팅방 정보만 관리하여 DB 부하를 줄이고, 빠른 메시지 조회가 가능하도록 구성했습니다.

Spring Security + JWT + OAuth2 통합 인증 구현

일반 로그인(Spring Security + JWT)과 소셜 로그인(OAuth2 - Google, Kakao, Naver)을 하나의 Security 설정으로 통합하는 것이 복잡했습니다. 각 소셜 로그인의 사용자 정보 형식이 달라 CustomOAuth2UserService에서 공통 처리 로직을 설계하여 해결했습니다.

CoolSMS 연동 SMS 인증 및 세션 관리

회원가입과 계정 찾기 두 가지 흐름에서 각각 다른 세션 키(smsAuthCode, smsFindCode)를 사용하여 인증번호를 관리했습니다. 인증번호 유효 시간을 3분으로 제한하고, 인증 완료 시 세션에서 즉시 제거하는 방식으로 보안을 강화했습니다.

계좌 정보 AES-256 암호화 적용

마이페이지의 계좌 정보는 민감 데이터이기 때문에 AES-256 양방향 암호화를 적용하여 DB에 저장하고, 조회 시 복호화하는 방식으로 처리했습니다.

트러블슈팅

문제

OAuth2 소셜 로그인 - Provider별 사용자 정보 형식 불일치

원인

Google · Kakao · Naver가 각각 다른 필드명으로 이메일·닉네임을 반환하여 공통 처리 로직 적용 불가

해결

Provider별 Service 클래스(NaverOAuth2UserService, GoogleOAuth2UserService 등)로 분리하고, 각각 파싱한 뒤 공통 MemberDTO로 변환하는 방식으로 통합

문제

Firebase 채팅 메시지 조회 시 서버 스레드 무한 대기

원인

Firebase 비동기 응답을 CompletableFuture.get()으로 대기할 때 타임아웃 미설정으로, 연결 불안정 시 스레드가 무한 블로킹 상태에 빠짐

해결

future.get(10, TimeUnit.SECONDS)로 타임아웃을 지정하여 일정 시간 내 응답이 없으면 예외를 발생시키고 사용자에게 오류를 반환하도록 처리

한계 & 개선점

현재

WebSocket 엔드포인트가 permitAll()로 인증 없이 열려 있어, 인증되지 않은 사용자도 채팅 연결 시도 가능

개선

ChannelInterceptor를 구현하여 STOMP 연결 헤더에서 JWT를 추출·검증하면 WebSocket 단계에서도 인증 적용 가능

현재

AccessToken 만료 시 자동 재발급 엔드포인트가 없어 토큰이 만료되면 사용자가 다시 로그인해야 함

개선

/api/auth/refresh 엔드포인트를 구현하여 RefreshToken으로 AccessToken을 자동 갱신하면 UX 개선 및 토큰 만료 시간 단축으로 보안 강화 가능

설계 문서

시퀀스 다이어그램 (회원 인증)

회원 인증 시퀀스

시퀀스 다이어그램 (채팅)

채팅 시퀀스

유스케이스 다이어그램

유스케이스

클래스 다이어그램

클래스 다이어그램

DevOps / 인프라

🔍 SonarCloud 코드 품질 개선

SonarCloud 정적 분석을 도입하여 코드 품질 이슈를 체계적으로 개선했습니다. Claude Code를 활용하여 다수의 이슈를 분석하고 일괄 제거했습니다.
주요 개선 사항: 접근성(aria 속성, alt 텍스트), 보안(전역 변수 → globalThis), 코드 스멜(for-of, 함수 스코프), 중복 코드(sell.html·share.html 통합, SQL 중복 제거)

Before

SonarCloud 개선 전

Issues ~1,900 · Duplications 2.5% · Quality Gate Not computed

After

SonarCloud 개선 후

New Issues 2 · Duplications 1.26% · Quality Gate Passed

이슈 유형 발견된 문제 해결 방법
보안 SmartEditor에 포함된 미사용 샘플 파일(file_uploader.php 등 14개)이 임의 파일 업로드 취약점으로 탐지 sample/photo_uploader/ 디렉터리 전체 삭제 (14개 파일, 14,073줄 제거)
접근성 이미지 alt 누락, 버튼·입력 필드 aria-label 미적용, <label for> 연결 누락, 빈 <h*> 태그, <title> 없는 페이지 전체 템플릿에 alt·aria-label·aria-hidden 추가, label for-input id 연결, 빈 heading 제거, <title> 일괄 추가 (17개 배치에 걸쳐 수정)
JS 품질 getAttribute()data-* 접근, parseFloat/parseInt/isNaN 전역 함수 사용, window 직접 참조, for 인덱스 순회, 중첩 삼항·template literal getAttributedataset.* 교체, 전역 함수 → Number.parseFloat/Number.isNaN 등으로 변경, windowglobalThis, for-of 루프 적용, 중첩 표현식 단순화
인지 복잡도 product_detail.js·product_form.js·chat_popup.html 등에서 함수 중첩 깊이 초과, 복잡한 분기 로직으로 SonarCloud 임계값 위반 긴 함수를 역할별로 분리, 조건 로직을 early return 패턴으로 단순화, 중첩 콜백을 외부 함수로 이동
CSS 품질 색상 대비 불충분 (#22c55e, #ff6a00 등이 WCAG 기준 미달), CSS 파일 내 중복 선택자 저대비 색상을 #15803d·#a84400 등 진한 색으로 교체, 중복 선택자 병합 (product_form.css, product_list.css 등)
중복 코드 SQL 파일에 CREATE TABLE REPORTS 블록 2회 정의, sell.html·share.html이 거의 동일한 HTML 구조를 중복 보유 SQL 중복 블록 63줄 제거, sell.html·share.htmlproduct_form.html 하나로 통합 (duplication 2.5% → 1.26%)
SQL 품질 SELECT * 사용으로 불필요한 컬럼 전체 조회, CHAR 타입 사용으로 공백 패딩 발생 가능성 SELECT *를 필요한 컬럼 명시로 교체, CHARVARCHAR2로 변경

📊 Grafana 모니터링

Spring Boot Actuator + Prometheus + Grafana를 연동하여 서버 상태(CPU, Memory, HTTP 요청 수 등)를 대시보드로 실시간 모니터링했습니다.

Grafana 대시보드

📄 Swagger API 문서

SpringDoc OpenAPI(Swagger UI)를 적용하여 REST API 명세를 자동으로 문서화하고, 브라우저에서 직접 API를 테스트할 수 있도록 했습니다.

Swagger UI

🔄 Jenkins 자동 배포 파이프라인

GitHub에 git push하면 Webhook이 Jenkins를 트리거하여 자동으로 빌드·테스트·Docker 이미지 빌드·푸시·배포까지 이어지는 CI/CD 파이프라인을 구축했습니다.
finalProject_3board_service 각 서비스별로 독립적인 파이프라인을 구성하여 서비스 단위 배포가 가능하도록 했습니다.

🐳 Portainer.io 컨테이너 관리

Jenkins 파이프라인으로 빌드된 Docker 이미지를 Portainer.io를 통해 배포하고, 각 서비스 컨테이너 상태를 GUI로 모니터링했습니다.

Portainer 컨테이너 관리

기술 스택

Java 17 Spring Boot 3.5 Spring Security OAuth2 JWT MyBatis Oracle WebSocket (STOMP) Firebase Gemini AI CoolSMS Thymeleaf AES-256 SonarCloud Grafana Swagger MSA API Gateway Docker Jenkins Portainer