TODO: 여행 추천 플랫폼
[개요]
- 삼성청년소프트웨어아카데미 1학기 최종 프로젝트
- 관광지를 검색하고 주변의 숙박업소를 쉽게 찾을 수 있는 커뮤니티
- 관광지 주변 숙박업자들이 커뮤니티에 홍보 및 예약을 받을 수 있도록 구현
- 유저, 셀러, 관리자의 권한 구현
- AI 기반 관광지 추천 및 검색 기능 제공
[사용 기술 스택]
- Infra
- AWS : EC2, S3
- Docker
- Vite
- Nginx, DNS
- GitLab CI/CD
- BE
- 개발 환경 : IntelliJ IDEA
- 빌드 도구 : Maven
- 프레임워크 : Spring Boot (3.4.5)
- 언어 : Java (17)
- DB : MySQL
- 데이터 접근 : MyBatis
- 캐싱 : Redis (Redis Cloud)
- AI : Spring AI (1.0.0-M6), OpenAI GPT-4o
- 실시간 통신 : WebSocket (STOMP)
- 인증/보안 : Spring Security, JWT
- 모니터링 : Prometheus, Micrometer, Loki
- 이메일 : Spring Mail (SMTP)
- 기타 : Lombok, JSP/JSTL
- FE
- 개발 환경 : VS Code
- 빌드 도구 : Node.js, Vite (6.2.4)
- 프레임워크 : Vue (3.5.13)
- 언어 : TypeScript
- 상태 관리 : Pinia (3.0.1)
- 라우팅 : Vue Router (4.5.0)
- HTTP 클라이언트 : Axios (1.9.0)
- UI 프레임워크 : Tailwind CSS (4.1.5), DaisyUI (5.0.35), Vuetify (3.8.4)
- 실시간 통신 : STOMP.js, SockJS
- 지도 : vue3-kakao-maps (2.3.10)
- 기타 : vue-daum-postcode (주소 검색)
[주요 담당 기능]
- BE
- 인증 및 보안
- JWT 기반 인증 시스템 구현
- 토큰 발급 및 검증
- 10분 유효 기간 설정
- Spring Security를 통한 인증/인가 처리
- 회원가입 시 이메일 인증 기능
- SMTP를 통한 인증 메일 발송
- reCAPTCHA 설정
- JWT 기반 인증 시스템 구현
- 게시판
- 게시글 CRUD 기능
- 게시글 작성, 수정, 삭제, 조회
- 조회수 증가 기능
- 페이징 처리
- 댓글 시스템
- 댓글 작성, 수정, 삭제
- JWT 기반 작성자 인증
- 게시판 타입별 분류
- BoardType 컬럼을 통한 게시판 구분
- 메인 페이지 최근 5개 글 미리보기
- 게시글 CRUD 기능
- 관리자 기능
- 회원 관리
- 회원 목록 조회 (페이징)
- 회원 상세 정보 조회
- 검색 기능 (이름, 이메일)
- 셀러 요청 관리
- 셀러 등록 요청 승인/거절
- 대기 중인 요청 수 조회
- 회원 관리
- 인증 및 보안
- FE
- 사용자 인터페이스
- 반응형 웹 디자인
- Tailwind CSS, DaisyUI, Vuetify를 활용한 모던한 UI
- 라우팅 및 네비게이션
- Vue Router를 통한 SPA 구현
- 인증이 필요한 페이지 보호
- 상태 관리
- Pinia를 통한 전역 상태 관리
- 사용자 정보 및 인증 상태 관리
- 반응형 웹 디자인
- 관광지 검색
- 지도 기반 관광지 검색
- Kakao Maps API 연동
- 필터 검색 (시/도, 시/군/구, 타입)
- 키워드 검색
- 결과 내 검색 기능
- 지도 기반 관광지 검색
- 게시판
- 게시글 목록, 상세, 작성, 수정 화면
- 댓글 기능
- 추천/비추천 기능
- 회원 관리
- 회원가입 (이메일 인증)
- 로그인 (JWT 토큰 저장)
- 마이페이지
- 회원 정보 수정
- 관리자 기능
- 회원 관리 화면
- 셀러 요청 관리 화면
- 권한 관리
- 사용자 인터페이스
[트러블슈팅 & 문제 해결]
- BE
- JWT 검증 문제
- 프론트엔드에서 토큰을 전송했으나 백엔드에서 검증 실패
- Authorization 헤더에서 “Bearer ” 접두사 제거 로직 추가
- 토큰 검증 로직 개선
- CORS 설정 보완
- MyBatis 페이징 처리
- 복잡한 검색 조건에서 페이징 처리 어려움
- SearchCondition DTO를 통한 검색 조건 관리
- Page DTO를 통한 페이징 정보 전달
- 동적 쿼리 활용
- JWT 검증 문제
- FE
- CORS 문제
- 프론트엔드에서 백엔드 API 호출 시 CORS 에러 발생
- 백엔드 CORS 설정 추가
- Axios 인터셉터 설정
- 상태 관리 문제
- 페이지 새로고침 시 인증 상태 유실
- localStorage에 JWT 토큰 저장
- Pinia store 초기화 시 토큰 확인
- 라우터 가드에서 토큰 검증
- CORS 문제
[성과]
- JWT 기반 인증 시스템 및 권한 관리 시스템 구축
- RESTful API 설계 및 프론트엔드-백엔드 분리 아키텍처 구현
[주요 화면]
- 관광지 검색
- 지도 기반 관광지 검색 화면
- 필터 검색 (시/도, 시/군/구, 타입)
- 키워드 검색
- 결과 내 검색
- 게시판
- 게시글 목록 화면
- 게시글 상세 화면
- 게시글 작성/수정 화면
- 댓글 기능
- 회원 관리
- 로그인 화면
- 회원가입 화면
- 마이페이지
- 회원 목록 (관리자)
- 채팅
- 채팅방 목록
- 실시간 채팅 화면
- 셀러 기능
- 상품 등록 화면
- 상품 상세 화면
- 셀러 상품 목록
- 관리자 기능
- 회원 관리 화면
- 셀러 요청 관리 화면
[아키텍처 구조]
┌─────────────┐
│ Frontend │ Vue 3 + TypeScript + Vite
│ (Vue.js) │
└──────┬──────┘
│ HTTP/REST API
│ WebSocket (STOMP)
┌──────▼──────┐
│ Backend │ Spring Boot 3.4.5
│ (Java 17) │
└──────┬──────┘
│
┌───┴───┐
│ │
┌──▼──┐ ┌──▼──┐
│MySQL│ │Redis│
│ │ │ │
│ │ │Vector│
│ │ │Store │
└─────┘ └─────┘
[ERD]
- 주요 테이블
- member: 회원 정보
- post: 게시글
- comment: 댓글
- attraction: 관광지 정보
- product: 상품 (숙박업소)
- seller: 셀러 정보
- seller_request: 셀러 등록 요청
- reservation: 예약 정보
- chat_room: 채팅방
- chat_message: 채팅 메시지
- address: 주소 정보
- sido, gugun: 시/도, 시/군/구 정보
- content_type: 관광지 타입
[회고]
- Best Practice (배운 점)
- JWT 기반 인증 시스템 구현 및 이해
- RESTful API 설계 원칙 학습 및 적용
- 프론트엔드와 백엔드 분리 아키텍처 경험
- Vue 3 Composition API 활용 경험
- TypeScript를 통한 타입 안정성 확보 및 개발 생산성 향상
- 계층형 아키텍처(Controller-Service-DAO)를 통한 코드 구조화
- DTO 패턴을 통한 데이터 전달 객체 분리
- MyBatis 동적 쿼리를 활용한 유연한 데이터 조회
- Redis를 활용한 토큰 관리 및 캐싱
- Lesson Learned
- 프론트엔드와 백엔드 분리 시 API 설계의 중요성
- 모니터링 시스템 구축의 필요성
- RESTful API 설계 원칙 준수의 필요성