숨은 사진 스팟을 지도에서 발견하고 공유하는 위치 기반 커뮤니티 서비스
이 저장소는 PATATA
서비스의 백엔드 서버 코드입니다.
PATATA는 사용자가 직접 발견한 포토 스팟을 지도 위에 공유하고,
다른 사용자들과 함께 숨겨진 장소를 발견할 수 있는 위치 기반 서비스입니다.
- 서버 URL
- API 문서 (Swagger)
분류 | 기술 |
---|---|
Language | Java 17 |
Framework | Spring Boot 3.2.1 |
DB | MySQL (RDS) |
Auth | OAuth2 (Google, Apple), JWT |
Infra | AWS EC2, S3, Lambda |
CI/CD | GitHub Actions + Docker |
기타 | JTS GeometryFactory, ST_Distance_Sphere |
- Spring Security + OAuth2를 이용하여 Google/Apple 로그인을 구현하였고, 로그인 후에는 자체 JWT 토큰을 발급합니다.
- 클라이언트는 발급받은 JWT를 헤더에 포함하여 인증된 요청을 보낼 수 있으며, 토큰 만료 시 Refresh Token을 이용한 재발급이 가능합니다.
- 탈퇴 시 해당 계정의 리프레시 토큰을 무효화하고, 소셜 계정 연동도 해제합니다.
- 탈퇴한 사용자의 닉네임은 "알 수 없음"으로 변경되며, 등록한 스팟은 삭제되지 않는다.
- 사용자가 업로드한 이미지는 AWS S3 버킷에 저장됩니다.(이때 클라이언트에서 이미지 한 장당 5MB 이하, 전체 10MB 이하로 리사이징 후 업로드하도록 제한되어 있습니다.)
- S3에 업로드될 때 S3 이벤트 트리거가 동작하여 AWS Lambda 함수가 실행되고,
- 원본 이미지를 기반으로 400/800/1200px 리사이징된 이미지를 생성해 다시 S3에 저장합니다.
- 각 해상도는 용도에 맞게 다음값이 기본값으로 적용됩니다.
1200px
: 스팟 상세 조회용800px
: 스팟 목록 썸네일용400px
: 사용자 프로필 이미지용
- DB에는 각각의 리사이징 이미지 URL이 함께 저장되어 클라이언트에서 다양한 해상도로 불러올 수 있습니다.
PATATA의 핵심은 지도 중심의 위치 기반 탐색 기능입니다. 사용자는 지도 상에서 자연스럽게 스팟을 탐색하고, 조건에 맞는 스팟을 시각적으로 빠르게 확인할 수 있습니다.
- 사용자의 현재 위치 또는 지도를 이동한 위치 기준으로, 현재 화면에 보이는 지도 영역 내 스팟을 조회합니다.
- 클라이언트로부터 전달받은 남서쪽 좌표(lat1, lng1) 와 북동쪽 좌표(lat2, lng2) 를 기반으로, MBR(Minimum Bounding Rectangle) 내 포함 여부로 스팟을 필터링합니다.
- 각 스팟의 좌표는
JTS GeometryFactory
를 사용해 Point 타입으로 저장되며, MySQL 공간 함수ST_Distance_Sphere()
를 활용해 각 스팟과 사용자의 현재 위치와의 직선 거리도 함께 표시한다. - 카테고리 필터링도 함께 지원하여, 최대 30개의 스팟만 조회되도록 제한하여 서버 부하를 줄이고 성능을 향상시켰습니다.
- 목록으로 조회 시, 추천(스크랩)순/거리순으로 해당 스팟들을 조회 가능합니다.
- 사용자가 검색어를 입력하면, 해당 키워드를 제목에 포함한 스팟 중 스크랩 수가 가장 많은 스팟의 위치로 지도를 자동 이동시킵니다.
- 이후 지도를 이동하면, 이동된 영역 내에서 해당 키워드에 해당하는 스팟만 필터링하여 지도에 표시됩니다.
- 목록으로 조회 시, 스크랩 순/거리 순으로 검색어에 해당하는 스팟들을 조회 가능합니다.
- 오늘의 추천 스팟(메인 화면): 매일 랜덤으로 5개의 스팟 추천
- 스팟에 대한 리뷰 작성 및 삭제
- 사용자의 스팟 스크랩 등록/취소
- 사용자/스팟/리뷰 신고 기능
- 프로필 이미지 업로드 및 닉네임 변경(닉네임은 중복 불가)
src/
├── main/
│ ├── java/
│ │ └── PATATA/
│ │ ├── auth/
│ │ │ ├── jwt/
│ │ │ └── oauth/
│ │ ├── domain/
│ │ │ ├── member/
│ │ │ ├── report/
│ │ │ └── spot/
│ │ ├── global/
│ │ ├── infra/
│ │ └── PatataApplication.java
│ └── resources/
│ └── application.yml
PATATA 서비스의 주요 엔티티 구조입니다. 👉 ERD 보러가기 (ERDCloud)
main
: 실제 배포용 브랜치 (운영 환경)develop
: 개발 브랜치 (테스트 환경 및 통합 개발)feature/기능명
: 새로운 기능 개발 시 사용
예:feature/spotCRUD
,feature/withdraw
모든 기능 개발은
feature/*
브랜치에서 작업한 뒤develop
브랜치로 Pull Request를 생성하고,
코드 리뷰 및 테스트를 거쳐 병합합니다. 운영 배포 전에는develop → main
으로 머지합니다.
태그 | 설명 |
---|---|
feat: |
새로운 기능 추가 |
fix: |
버그 수정 |
docs: |
문서 수정 (README 등) |
style: |
코드 포맷팅, 세미콜론 누락 등 기능에 영향 없는 변경 |
refactor: |
코드 리팩토링 |
test: |
테스트 코드 추가 |
chore: |
기타 변경사항 (빌드 설정, 패키지 설치 등) |
예시
feat: 지도 기반 스팟 필터링 기능 구현
fix: JWT 토큰 만료 오류 수정
docs: README에 ERD 링크 추가
개발 및 운영 중 발생했던 이슈와 해결 과정을 정리했습니다.