1. 배경(Problem)
서울시 내 버스킹 공연은 매년 꾸준히 운영되고 있지만, 공연자가 어디서 공연이 가능한지, 허가가 필요한지, 어디서 신청해야 하는지를 한눈에 파악하기 어렵다.
1.1 문제 원인
•
공연 허가·운영 기관이 여러 곳으로 분산됨(자치구·문화재단·공공기관 등)
•
때문에 공식 예약/허가 안내가 각 기관 홈페이지에 흩어져 있음
•
기존 서비스는 사용자 제보 기반이거나 업데이트가 늦어서 정보 정확도·최신성 유지가 어려움
1.2 사용자(버스커)의 pain point
지역·기관별로 상이한 예약 방식 → 장소별 허가 여부·신청 조건 확인의 어려움 → 공연 환경(분위기, 후기, 시설 정보 등) 사전 파악 어려움 → 장소를 예약하고 공연을 실행하는데 있어서 초보 버스커에게 높은 진입 장벽 유발
핵심 문제: ‘공연 장소 탐색→조건 이해→예약’의 흐름이 단절되어 실제 공연 실행까지 이어지기 어렵다.
2. 서비스 소개(Solution)
공식 허가 기반 버스킹 공연 장소를 지도에서 한눈에 확인하고, 각 장소의 예약/신청 링크까지 바로 연결하는 지도형 정보 플랫폼
2.1 핵심 제공 가치
•
서울 내 공식 버스킹 장소(공공기관·지자체)만 모아 표준화된 형태로 제공
•
장소별 운영 시간, 허가 조건, 예약 링크를 통합 제공
•
후기 및 북마크 기능을 통해 공연 실행 장벽 완화
2.2 핵심 유저
2.3 핵심 기능
페인포인트 대응 전략
기능명 | 기능 상세 정의 | 목적 | 해결 페인포인트 |
지도 기반 공연 장소 탐색
| 서울시·자치구·산하기관 공식 장소 지도 시각화, 검색/필터를 제공한다. | 분산된 정보 통합, 탐색 비용을 최소화한다. | 반복 사이트 방문 필요 → 탐색 피로, 조건 비교 어려움, 공연 가능성 불확실하다 |
장소 상세 정보 구조화
| 운영 시간, 허가 조건, 제한 사항, 담당자·문의처, 예약 링크 등 통합 | 공연 가능 여부 확신 제공
| 공지 상이 → 이해 어려움, 규정 누락으로 오해를 일으켜 신뢰도가 하락한다. |
공식 예약 연동
| 장소 상세 화면에서 공식 예약 페이지 링크를 제공한다. | 탐색→예약 단절 없는 흐름 | 불확실성 제거, 재검색 과정을 최소화한다. |
공연자 후기 작성 및 조회
| 현장 정보 작성·조회, 신고 기능을 제공한다. | 의사결정 정확도가 향상한다. | 현장 정보 부족, 신규 공연자 불안감 |
관심 장소(북마크)
| 로그인 사용자 대상 장소 저장/관리한다. | 공연 준비 효율화 | 반복 탐색·후보지 비교가 어렵다. |
사용자 인증 및 최소 계정
| 소셜 로그인 기반, 후기 신뢰도 관리, 개인화 기능을 제공한다. | 정보 신뢰성 유지, 개인화 경험을 제공한다. | 익명 후기 신뢰도 저하, 스팸·중복 문제 |
2.4 핵심 기능
핵심 기능(솔루션) 요약
장소 목록 조회
장소 검색
장소 상세 보기
2.5 시연 영상
3. 아키텍처 및 핵심 기능
3.1 시스템 아키텍처
Onset 프로젝트는 거리 공연 장소에 대한 정보를 제공하고, 사용자가 장소를 검색, 리뷰, 북마크할 수 있는 위치 기반 서비스입니다.
1. Auth Service
Google OAuth2 기반 인증 및 사용자 정보를 관리합니다.
sequenceDiagram
participant Client
participant UserController
participant GoogleOAuthService
participant Google OAuth
participant UserRepository
participant HttpSession
Client->>+UserController: POST /api/users/google (credential)
UserController->>+GoogleOAuthService: login(credential)
GoogleOAuthService->>+Google OAuth: ID 토큰 검증 요청
Google OAuth-->>-GoogleOAuthService: 토큰 정보 (sub, email 등)
GoogleOAuthService->>UserRepository: findBySub(sub)
alt 기존 사용자인 경우
UserRepository-->>GoogleOAuthService: User 정보 반환
else 신규 사용자인 경우
GoogleOAuthService->>UserRepository: save(newUser)
UserRepository-->>GoogleOAuthService: 생성된 User 정보 반환
end
GoogleOAuthService-->>-UserController: LoginResponse (userId 포함)
UserController->>+HttpSession: setAttribute("USER_ID", userId)
HttpSession-->>-UserController: 세션 저장 완료
UserController-->>-Client: 200 OK (LoginResponse)Mermaid
복사
사용자 인증 흐름 (User Authentication Flow) - Google 소셜 로그인을 통한 세션 기반 인증을 사용
주요 기능
•
Google OAuth 로그인
•
신규 사용자 자동 가입
•
세션 기반 인증
•
사용자 정보 조회
기술 요소
•
Spring Security
•
Google OAuth2
•
HttpSession
•
PostgreSQL, Redis(세션 캐싱)
2. Place Service
공식 공연 장소 탐색의 핵심 기능을 제공하는 도메인입니다.
sequenceDiagram
participant Client
participant PlaceController
participant PlaceService
participant PlaceRepository
participant ReviewRepository
participant BookmarkRepository
Client->>+PlaceController: GET /api/places/search?keyword=공원
PlaceController->>+PlaceService: searchPlaces("공원", userId, pageable)
Note over PlaceService: 1. 장소 기본 정보 조회 (1번의 쿼리)
PlaceService->>+PlaceRepository: searchByNameOrDistrict("%공원%", pageable)
PlaceRepository-->>-PlaceService: Page<Place> (장소 목록)
Note over PlaceService: 2. 리뷰 개수 일괄 조회 (1번의 쿼리)
PlaceService->>+ReviewRepository: countByPlaces(placeList)
ReviewRepository-->>-PlaceService: List<Object[]> (장소별 리뷰 개수)
Note over PlaceService: 3. 북마크 정보 일괄 조회 (1번의 쿼리)
PlaceService->>+BookmarkRepository: findByUserAndPlaceIn(user, placeList)
BookmarkRepository-->>-PlaceService: List<Bookmark> (사용자의 북마크 목록)
Note over PlaceService: 4. 조회된 데이터를 메모리에서 조합하여 최종 응답 생성
PlaceService-->>-PlaceController: Page<PlaceSearchResponse>
PlaceController-->>-Client: 200 OK (JSON Response)
Mermaid
복사
장소 검색 및 목록 조회 기술 흐름 - 장소 목록/검색 시 발생하는 N+1 문제를 해결하기 위해 'Batch Fetch' (IN절 사용) 방식을 사용함
주요 기능
•
공연 장소 목록 조회
•
키워드 기반 검색
•
장소 상세 정보(허가 조건, 운영 시간, 예약 링크 등)
•
리뷰/북마크 정보와 병합된 응답 제공
기술 요소
•
Spring Boot
•
Spring Data JPA
•
PostgreSQL
•
Batch Fetch 기반 성능 최적화 (N+1 문제 해결)
3. Review Service
공연자 간 정보 공유를 위한 후기 기능을 관리합니다.
주요 기능
•
후기 생성 / 수정 / 삭제
•
장소별 후기 조회
•
후기 신고 처리
기술 요소
•
Spring Boot
•
Spring Data JPA
•
PostgreSQL
4. Bookmark Service
사용자가 관심 장소를 저장하고 관리할 수 있도록 돕는 서비스입니다.
주요 기능
•
북마크 생성 / 삭제
•
사용자 별 북마크 목록 조회
•
장소 목록 조회 시 북마크 여부 함께 반환
기술 요소
•
Spring Boot
•
Spring Data JPA
•
PostgreSQL
3.2 ERD
현 ERD는 소셜 로그인 기반 사용자(Users) 를 중심으로 공연 장소(Place), 후기(Review), 찜(Bookmark) 이 세 가지 핵심 엔티티가 서로 1:N / N:1 관계로 연결되는 구조이다.
3.3 중요 구현 포인트
Backend
•
키워드 기반 장소 검색 조건 구현
◦
사용자가 입력한 keyword를 기준으로 이름(name)·지역구(district) 컬럼에서 LIKE 검색을 수행하는 검색 기능을 구현
◦
PlaceRepository에 전용 JPQL 쿼리를 정의해 Pageable 페이지네이션과 함께 검색결과를 효율적으로 반환하도록 구성
◦
실제 검색은 다음 흐름으로 처리됨:
유저 입력 → Controller → Service → Repository → PageResponse로 변환 → FE 전달
•
Google ID Token 기반 로그인/회원가입 구현
◦
프론트에서 받은 Google ID Token(credential)을 서버로 전달해 로그인/회원가입을 처리하는 소셜 로그인 기능을 구현
◦
GoogleCredentialVerifier에서 JWT 서명, Issuer(iss), Audience(aud), 만료시간(exp)를 검증해 토큰 위변조, 만료 여부를 확인
◦
검증된 토큰에서 sub(고유 식별자), email, picture를 추출해 사용자 식별 및 프로필 정보로 활용
◦
기존 유저면 단순 로그인 처리, 신규 유저면 회원가입 후 로그인 처리
Frontend
•
리뷰 작성·수정·삭제 흐름 + React Query 상태 관리
◦
useMutation과 invalidateQueries를 활용해 후기 CRUD 이후 필요한 데이터만 선택적으로 갱신
◦
createdAt / updatedAt 혼합 정렬 규칙을 적용해 리스트 일관성을 유지하고, 백엔드 응답 구조와 동기화되도록 정렬 로직을 설계
•
장소 상세 페이지 구조 + 바텀시트/페이지 연동 설계
◦
동일한 상세 정보 데이터를 바텀시트 버전과 풀페이지 버전 양쪽에서 재사용할 수 있도록 공통 컴포넌트 기반으로 UI 구조를 계층화
◦
스크롤 위치, topButton, Header/Bottombar 노출 여부 등 레이아웃 요소와 충돌하지 않도록 설계
•
구글 로그인
◦
구글에서 공식적으로 제공하는 react-oauth/google를 이용하여 사용자들이 편하게 이용할 수 있도록 원탭 로그인 구현
◦
윈도우 너비 감지를 통하여 반응형으로 동적 너비 길이 업데이트
◦
useMutation를 활용하여 버튼 클릭 전에 로그인이 되지 않도록 방지함과 동시에, 신규 유저 여부를 구분하여 약관 페이지와 메인 페이지로 이동
4. 활용 라이브러리 및 개발 환경
4.1 주요 사용 기술 스택 요약
•
Backend
◦
Spring Boot, RESTful API
◦
DB: PostgreSQL(운영), H2(테스트), Spring Data JPA
◦
Infra: Docker, Docker compose, AWS EC2, Route 53, ALB, IAM, S3, RDS, GitHub Actions
◦
Logging/Monitoring: Spring Boot Actuator, Prometheus, Grafana
◦
Test: JUnit 5
◦
기타 도구: IntelliJ IDEA, Checkstyle, Postman, Git / GitHub, Swagger / OpenAPI
◦
선택 이유 요약:
▪
검증된 구조로 빠른 개발 가능
▪
확장성·안정성 확보
▪
대규모 장소 조회 시 Batch Fetch 전략으로 성능 최적화
•
Frontend
◦
React(Vite), JS(ES6+), React Router DOM, Zustand, React Query, TailwindCSS, Axios, react-hook-form, react-hot-toast, react-oauth/google
◦
API: Kakao Maps API
◦
선택 이유 요약:
▪
지도 기반·리스트 기반 UI에 최적화
▪
빠른 MVP 구축을 위한 단순하고 안정적인 상태 관리 구조
▪
서버 상태 캐싱으로 API 요청 최소화
•
디자인 및 프로토타입 도구
◦
Figma, Adobe Photoshop, Adobe illustrator
•
커뮤니케이션 및 협업 도구
◦
Notion, Discord, Google Drive, GitHub, Zapier
4.2 주요 기술 스택 선정 이유
Frontend
•
사용 기술: React, JS(ES6+), React Router DOM, Zustand, Tanstack Query, Axios, Vercel
•
선정 이유:
구분 | 기술 | 선정 이유 |
프레임워크 | React (Vite 기반) | 컴포넌트 기반 SPA 구조에 최적화되어 있으며,
Vite 기반으로 빠른 개발/빌드 환경을 제공해 MVP 구축 속도를 높임 |
언어 | JavaScript (ES6+) | 번들링 없이 모든 브라우저에서 동작하며,
React, API 통신, 상태관리 전반에 자연스럽게 적용 가능 |
상태 관리 | Zustand | 코드량이 적고 직관적이며,
전역 UI 상태 관리에 가벼운 선택지 |
서버 상태 관리 | React Query | API 캐싱, 동기화, 리페치 흐름을 자동화하여,
서버 데이터 중심 기능에 안정적인 구조 제공 |
라우팅 | React Router DOM (v7) | 상세 페이지, 탭 이동, Protected Route 구조 등 복잡한 네비게이션 요구를 충족 |
UI 프레임워크 | Tailwind CSS + clsx + CVA | 디자인 토큰 적용, Variant 체계, 화이트라벨 컴포넌트 개발에 효율적이며 재사용성을 높임 |
API 통신 | Axios | 인스턴스에서 공통 헤더, 에러 처리, 토큰 처리 통합 가능해 API 구조를 일관성 있게 유지할 수 있음 |
지도 라이브러리 | Kakao Maps JavaScript SDK | 국내 위치 기반 서비스에 최적화되어 있고,
마커·검색·필터 적용이 용이함 |
배포 | Vercel / S3 + Cloud Front | GitHub 연동 자동 배포 지원 및 Preview URL 제공으로 협업, 테스트 속도 향상
백엔드와 동일한 도메인을 사용함으로써 통신에 필요한 쿠키를 쉽게 전송 |
Backend
•
사용 기술: Spring Boot 3.5.x, PostgreSQL, Spring Data JPA /Hibernate, Spring Security, Docker/Docker Compose, AWS
•
선정 이유
구분 | 기술 | 선정 이유 |
프레임워크 | Java 21, Spring Boot (3.5.x) | 스타터 기반으로 MVP 구현 속도가 매우 빠르고 운영까지 고려한 전체적인 생태계가 갖춰져 있어 추후 확장·관리 용이 |
데이터베이스 | PostgreSQL | 오픈소스 RDB 중에서 운영 사례가 많고, Docker에서 띄우기 편하고, 클라우드 매니지드 서비스도 풍부해서 장기 운영에 유리 |
데이터 접근 | Spring Data JPA + Hibernate | 반복적인 CRUD 코드를 크게 줄여주고, 메서드 이름 기반 쿼리 생성을 지원하여 개발 생산성을 극대화
쿼리들이 대부분 정형 데이터 기반이라, ORM이 다루기 좋고 유지보수성과 코드 가독성 증가 |
인증 · 보안 | Spring Security (OAuth2, Session) | 인증/인가 로직을 안정적으로 구현 OAuth2 Client를 통해 소셜 로그인을 손쉽게 연동하고, 세션 기반 인증으로 상태를 관리하여 사용자의 로그인 흐름을 단순하고 안전하게 처리 |
인프라 | Docker / Docker Compose | 애플리케이션과 그 의존성(DB, Redis 등)을 컨테이너화하여 개발, 테스트, 운영 환경의 일관성을 보장 가능 |
파일 저장소 | AWS S3 | 이미지/정적 파일 저장에 최적화된 안정성, 확장성 제공 |
CI/CD | GitHub Actions + OIDC | 인증키 없이 IAM Role을 이용해 자동배포 |
배포 | AWS CodeDeploy | EC2 기반 배포를 안정적으로 자동화 |
로드 밸런싱 | AWS ALB | HTTPS 종료, 헬스체크, 라우팅 제어를 담당하여 API 서비스의 안정성을 확보 |
운영/접속 | AWS SSM | SSH 포트 개방 없이 접속 가능하여 보안 강화 및 운영 편의성 증 |
4.3 성능 개선·구조 설계·보안 고려사항
Backend
•
통일된 예외 처리 및 오류 응답 구조
→ GlobalExceptionHandler + CustomApiResponse로 모든 에러를 일관된 JSON 형식으로 반환
•
입력 검증 기반의 기본 보안 처리
→ DTO에서 @NotBlank, @Size 등 Jakarta Validation 사용
→ 요청 파라미터 유효성 자동 검증
•
Google ID Token 검증을 통한 소셜 로그인 보안 강화
→ 서명(Signature), Issuer, Audience, Exp 만료시간 모두 검증 수행
•
세션 기반 인증 및 보안 설정 적용
→ HttpOnly 세션 쿠키 사용
→ CORS 정책 명확히 설정(도메인 제한 + Credentials 허용)
•
공통 설정 분리로 구조 안정성 확보
→ ObjectMapperConfig, JpaAuditingConfig, SecurityConfig, AwsS3Config 등
→ 도메인 로직과 공통 기능의 분리
•
멀티 스테이지 Docker 빌드로 배포 안정성 확보
→ 빌드 이미지와 실행 이미지를 분리해 경량 컨테이너 구성
•
정기 배치 작업 기반 데이터 정리 구조
→ UserAgreementCleanupService의 스케줄러로 삭제 이력 관리 자동화
•
DB 무결성 관점 설계
→ users - bookmark - review 사이 FK + ON DELETE CASCADE/SET NULL 로 삭제 전파 및 데이터 정합성 보장
•
AWS 기반 인프라 보안 요소
→ 프라이빗 서브넷 기반의 백엔드 서버 운영(EC2/RDS 외부 노출 차단)
→ ALB → EC2, EC2 → RDS의 최소 권한 트래픽만 허용
→ ACM 기반 HTTPS 적용 및 ALB TLS 종료
Frontend
•
React Query 기반 데이터 캐싱 및 요청 최소화
◦
동일 페이지 재진입 시 서버 재호출 없이 캐시 데이터 우선 사용 → 체감 속도 개선
◦
staleTime, invalidateQueries 기준을 화면 흐름에 맞게 조정하여 불필요한 리페치를 줄임
•
API 실패 대응 및 사용자 피드백 구조
◦
Axios 인스턴스에서 오류를 공통 처리
◦
토스트 알림과 함께 사용자가 요청 실패 원인을 인지하고 재시도 할 수 있도록 UX 설계
•
입력 검증
◦
후기 작성 시 최소/최대 글자 수 제한, 빈 문자열 방지 등 클라이언트 단 입력 검증 적용
◦
프로필 이미지 업로드 시 파일 타입/사이즈 검증을 통해 비정상 파일 업로드 방지
•
UI 구조 설계에 따른 불필요 렌더링 최소화
◦
공통 컴포넌트를 분리하고 하위 도메인 컴포넌트를 계층화
◦
상위 상태 변경 시 불필요한 전체 리렌더를 줄이는 구조로 설계
•
코드 스플리팅
◦
Home / PlaceDetail / Favorite / Mypage 등 페이지 단위로 라우트를 분리하여, 초기 진입 시 필요한 화면만 우선 로드
◦
상세 지도/리뷰 탭 등은 상세 페이지 진입 시점에만 렌더링되도록 구성해 초기 번들 부담을 줄임
5. 트러블 슈팅
5.1 FE 트러블슈팅
1.
지도 렌더링 성능 문제
•
문제: 마커가 많아질수록 지도 렌더링 지연
•
해결: 마커 최소 렌더링, 조건부 렌더링, 메모이제이션 적용
2.
반응형 및 접근성
•
모바일 우선 레이아웃 재정비
•
스크린 리더 지원을 위한 aria-label 정비
3.
무한 요청 버그
•
Tanstack Query 옵션 미설정으로 재요청 반복
•
staleTime 조정으로 해결
5.2 BE 트러블슈팅
1.
N+1 문제
•
문제: 목록 조회 시 리뷰 개수·북마크 정보를 병렬로 불러오며 쿼리 폭증
•
해결: Batch Fetch(IN 절 기반), EntityGraph 적용 → 쿼리 수 70% 감소
2.
이미지 업로드 실패
•
S3 퍼블릭 정책 오류 → IAM 권한 재설정
3.
세션 만료 이슈
•
Google OAuth 로그인 후 세션 유지 문제 → Session TTL 정책 재정비
6. 팀 소개
STOOV는 공연자가 자신의 음악과 에너지를 거리로 옮기는 순간을 함께하며 누구나 공연을 시작할 수 있는 경험을 제공합니다.















