ManalGak (만날각)
목적 기반 공정한 중간 만남 장소 추천 서비스
여러 참여자의 출발지를 고려해 가장 공정한 중간 지점과 장소를 추천합니다.
프로젝트 개요
•
프로젝트명: ManalGak (만날각)
•
개발 기간: 2026년 1월 ~ 2026년 2월 (약 4주)
•
팀명: MagicDev
•
팀 구성: 백엔드 3명, 프론트엔드 2명 (총 5명)
•
•
GitHub: https://github.com/CHOSSEANG/ManalGak-magicDev
•
시연 영상
프로젝트 배경
문제 정의
여러 명이 약속을 잡을 때 항상 반복되는 질문이 있습니다. “어디서 만날까?”
겉으로는 단순한 질문처럼 보이지만, 실제로는 다음과 같은 문제들이 존재합니다.
•
중간 지점 찾기의 어려움: 수동으로 지도 앱을 번갈아가며 검색해야 하는 번거로움이 있고, 단순 평균으로 계산하면 지구의 곡률을 고려하지 못해 부정확한 결과가 나옵니다.
•
이동 시간의 불균형: 특정 인원에게만 유리한 장소가 선정되는 경우가 많습니다. 어떤 사람은 20분이면 도착하지만, 다른 사람은 90분이 걸리는 불공평한 상황이 발생합니다.
•
장소 선택의 번거로움: 중간 지점을 찾아도 주변 맛집이나 카페를 다시 검색해야 하는 이중 수고가 필요합니다.
•
의견 취합의 어려움: 메신저 투표 기능은 한계가 있어 의견이 메시지에 묻히거나 결정이 지연되는 문제가 있습니다.
해결 방안
ManalGak은 이러한 문제들을 기술적으로 해결합니다.
•
3D 지구 모델 기반 중심점 계산: 단순 평균이 아닌 위경도 좌표계와 지구 곡률을 고려한 정확한 기하학적 중심점을 계산합니다.
•
이동 시간 데이터 시각화: 모든 참여자의 이동 시간을 분석하여 표준편차를 최소화한 공정한 장소를 추천합니다.
•
목적 맞춤 원스톱 추천: 중간 지점 선정 후 Kakao Local API를 활용해 목적(회식/데이트 등)에 맞는 장소를 즉시 추천합니다.
•
실시간 WebSocket 투표: STOMP 프로토콜 기반으로 실시간 반영되는 투표 시스템을 제공하여 빠르고 명확한 의사결정을 지원합니다.
핵심 가치
ManalGak은 4가지 핵심 가치를 바탕으로 설계되었습니다.
•
공정성: 참여자 간 이동시간 편차를 최소화하여 누구에게나 공평한 장소를 선정합니다. 한 사람에게만 유리한 장소가 아닌, 모두가 비슷한 시간을 투자하는 진정한 ‘중간’을 찾아줍니다.
•
정확성: 3D 지구 모델 및 실시간 교통 데이터를 기반으로 정밀한 위치를 계산합니다. 지구의 곡률을 고려한 벡터 연산으로 평면 좌표계의 오차를 제거했습니다.
•
편의성: 복잡한 중간지점 계산과 장소 검색 과정을 원스톱으로 자동화합니다. 사용자는 출발지만 입력하면 계산부터 추천까지 모든 과정이 자동으로 진행됩니다.
•
실시간성: WebSocket 기술을 활용하여 투표 현황과 의사결정을 실시간으로 동기화합니다. 모든 참여자가 동시에 같은 화면을 보며 지연 없이 결정할 수 있습니다.
시연 영상
서비스 플로우
사용자 여정 (User Journey)
Step 1: 모임 생성
↓
Step 2: 참여자 추가
↓
Step 3: 중간지점 확인
↓
Step 4: 장소 투표
↓
Step 5: 결과 공유
Plain Text
복사
상세 플로우
Step 1: 모임 생성
•
모임 이름과 목적(음식점/카페 등) 선택
•
참여자 수 설정
•
고유 링크 생성
Step 2: 참여자 추가
•
참여자 리스트 작성
•
Kakao Maps에서 출발지 선택
•
이동 수단 설정 (대중교통/자동차)
Step 3: 중간지점 확인
•
3D 벡터 기반 중간 지점 계산
•
참여자별 이동 시간 시각화
•
최적 지하철역 표시
Step 4: 최종 결과 및 공유
•
확정된 장소 정보 (주소, 전화번호)
•
카카오톡 공유 버튼
•
링크 복사 기능
시스템 아키텍처
주요 특징
Redis Caching Layer
•
목적: API 호출 비용 절감 및 응답 속도 개선
•
전략: 장소/경로 검색 결과를 1시간 TTL로 캐싱
•
효과: 응답 속도 95% 개선 (1200ms → 60ms)
WebSocket (STOMP)
•
목적: 실시간 투표 및 상태 동기화
•
구현: Spring Boot + SockJS + STOMP
•
효과: 모든 참여자가 지연 없이 투표 결과 확인
External API Integration
•
구조: Service Layer에서 API 호출 격리
•
장점: 유지보수성 향상 및 테스트 용이성 확보
ERD (데이터베이스 설계)
주요 엔티티
데이터베이스는 5개의 핵심 테이블로 구성되어 있습니다.
•
Meeting (모임 정보): 모임의 기본 정보를 저장합니다. 모임 제목, 목적, 생성 시간, 계산된 중간 지점의 위경도 좌표 등을 포함합니다.
•
Participant (참여자 정보): 각 모임에 참여하는 사용자의 정보를 관리합니다. 참여자 이름, 출발지 주소 및 좌표, 이동 수단 등을 저장합니다.
•
Station (지하철역 마스터): 자주 조회되는 지하철역 정보를 미리 DB에 저장하여 외부 API 호출을 줄였습니다. 역 이름, 노선, 참여자들의 총 이동시간 등을 관리합니다.
•
Place (추천 장소): Kakao Local API를 통해 추천된 장소 정보를 캐싱합니다. 장소명, 카테고리, 주소, Kakao Place ID 등을 저장합니다.
•
Vote (투표 이력): 실시간 투표 시스템의 데이터를 저장합니다. 누가 어떤 장소에 투표했는지, 언제 투표했는지 기록하여 투표 변경 이력도 추적할 수 있습니다.
설계 포인트
•
모임 & 참여자: Meeting(1) : Participant(N) 관계로 설계하여 한 모임에 여러 참여자가 속할 수 있도록 했습니다. 참여자별로 출발지 좌표와 이동 수단 정보를 포함하여 중간 지점 계산의 기초 데이터로 활용합니다.
•
투표 시스템: 투표 안건, 선택지, 이력을 분리하여 확장성을 확보했습니다. 사용자가 투표를 변경하더라도 이력이 남아 추후 분석이 가능합니다.
•
장소 & 지하철역: 외부 API 호출 비용을 절감하기 위해 자주 조회되는 지하철역 정보를 내부 DB에 저장했습니다. 이를 통해 반복적인 역 검색 시 API 호출 없이 즉시 응답할 수 있습니다.
기술 스택
Backend
백엔드는 Spring Boot 기반으로 구축했습니다.
•
Spring Boot: REST API 서버의 핵심 프레임워크로 사용했습니다. 최신 버전을 도입하여 성능과 보안을 강화했습니다.
•
JPA (Hibernate): ORM을 통해 객체 지향적인 데이터 접근 계층을 구현했습니다. 복잡한 SQL 작성 없이도 효율적인 데이터 관리가 가능합니다.
•
MySQL: 관계형 데이터베이스로 모임, 참여자, 투표 등 핵심 데이터를 안정적으로 저장합니다.
•
Redis: 캐싱 레이어로 외부 API 응답을 1시간 동안 저장하여 응답 속도를 95% 개선했습니다.
•
Swagger: API 문서를 자동 생성하여 프론트엔드 팀과의 협업을 원활하게 했습니다.
Frontend
프론트엔드는 Next.js 15를 기반으로 웹 애플리케이션을 구현했습니다.
•
Next.js: App Router를 활용해 직관적인 라우팅을 구현했습니다. SSR로 초기 로딩을 개선했습니다.
•
React: 컴포넌트 기반 UI를 구성했습니다.
•
TypeScript: 타입 안정성을 확보하여 런타임 에러를 사전에 방지했습니다.
•
Tailwind CSS: 빠르고 일관된 스타일링을 구현했습니다.
•
Zustand: 가볍고 직관적인 전역 상태 관리를 적용했습니다.
Infra & DevOps
안정적인 운영을 위한 인프라를 구축했습니다.
•
AWS EC2: 애플리케이션 서버 운영
•
AWS RDS: 관리형 MySQL 운영(백업/스냅샷/복구)
•
Docker: 개발/운영 환경 일관성 확보 및 배포 자동화 기반
•
GitHub Actions: develop/main 브랜치 기반 자동 빌드/배포
•
Nginx: Reverse Proxy 및 80/443 라우팅
External APIs
•
Kakao Maps API: 지도 표시, 출발지/중간지점 마커 시각화
•
Kakao Local API: 카테고리 기반 주변 장소 검색
•
Kakao Mobility API: 자동차 기준 경로/이동시간 산출
•
Kakao Login API: OAuth 2.0 기반 소셜 로그인
•
ODsay API: 대중교통 이동 시간 및 경로 정보 제공
핵심 기능
1. 모임 생성 및 참여자 관리
사용자는 간단한 단계로 모임을 생성하고 참여자를 추가할 수 있습니다.
•
모임 정보 입력: 모임 이름과 목적(회식, 카페, 문화시설, 관광명소)을 선택합니다. 목적에 따라 추천 카테고리가 자동 적용됩니다.
•
참여자 추가: 참여자 이름을 입력하고 지도에서 출발지를 선택합니다. 주소 검색 또는 지도 클릭으로 위치 지정이 가능합니다.
•
고유 링크 생성: 모임 생성 시 UUID 기반 고유 링크가 발급되어 공유가 가능합니다.
주요 구현 코드
Frontend - 지도 컴포넌트
// Kakao Maps SDK 활용
<Map center={center}>
<CustomOverlayMap position={midPoint} />
{participants.map((p) => (
<MapMarker key={p.id} position={{ lat: p.lat, lng: p.lng }} />
))}
</Map>
Plain Text
복사
2. 3D 지구 모델 기반 중간지점 계산
왜 3D 모델이 필요한가?
•
위경도 산술 평균은 평면 좌표계 기준이어서 정확하지 않습니다. 지구는 구형이므로 참여자 간 거리가 멀어질수록 실제 지리적 중심과 오차가 발생할 수 있습니다.
3. 최적 지하철역 선택
•
중간 지점이 강/산 등 접근 불가능한 위치일 수 있어, 실제 만남을 위해 접근성 좋은 지하철역을 최종 선택합니다.
•
표준편차(이동시간 편차) 최소화 기준으로 최적 역을 선정합니다.
4. 목적 기반 장소 추천
•
Kakao Local API를 활용해 목적에 맞는 장소를 자동 추천합니다.
•
목적별 카테고리 자동 매핑 예시:
◦
회식 → 음식점(FD6)
◦
카페/스터디 → 카페(CE7)
◦
문화 → 문화시설(CT1)
◦
관광 → 관광명소(AT4)
5. 실시간 투표 시스템 (WebSocket)
•
WebSocket(STOMP) 기반으로 투표 결과를 실시간 동기화합니다.
•
모든 참여자가 동일한 투표 상태를 동시에 확인할 수 있습니다.
6. 결과 공유
•
고유 링크 생성 및 공유
•
카카오톡 공유(장소 정보 포함)
기술적 도전과 해결
Challenge 1: API 호출 최적화
참여자 수(N) × 후보 역 수(M)에 따라 API 호출이 폭증하여 Rate Limit 문제가 발생할 수 있습니다.
필터링과 요청 제어(딜레이/재시도), 그리고 캐싱 전략으로 안정적인 응답 속도를 확보했습니다.
Challenge 2: Redis 캐싱 전략
•
반복되는 장소/경로 요청을 캐싱하여 외부 API 호출을 줄이고, 응답 속도를 개선했습니다.
•
예시 키: search:{lat}:{lng}:{category}
•
TTL: 1시간
Challenge 3: Dev/Prod 환경 분리 배포 자동화
GitHub Actions + Docker + GHCR + EC2 기반으로 자동 배포를 구성했습니다.
•
develop → DEV 서버
•
main → PROD 서버
Challenge 4: 운영 서버 장애 대응 (502 Bad Gateway)
•
배포 직후 502 장애 발생, 원인 분석 결과 AWS 보안 정책에 의해 Outbound 80/443이 차단된 것을 확인했습니다.
•
Next.js 취약점 대응(15.1.9 업그레이드) 및 인스턴스 재구성을 통해 서비스 정상화했습니다.
•
향후 Private Subnet + ALB 구조로 개선할 계획입니다.
팀 소개 & 역할 분담
Team MagicDev
“기술을 마법처럼 연결한다”는 의미에서 시작된 이름입니다.
각자의 역할을 명확히 나누되, 서로의 영역을 이해하며 협업하는 것을 목표로 했습니다.
팀 구성
•
Backend (팀장) - 외부 API 연동(Kakao, ODsay) 및 추천 장소 로직 구현, 응답 최적화 및 캐싱 전략 수립
•
Backend - 중간지점/지하철역 알고리즘 구현, 인프라 구축 및 Docker/CI-CD 담당
•
Backend - DB 설계 및 인증/보안(JWT), 도메인(모임/투표) 설계 담당
•
Frontend - 핵심 화면 구현, 상태 관리, API 연동 담당
•
Frontend - UI/UX 디자인, 지도 컴포넌트 및 모바일 최적화 담당
성과 및 배운 점
구현 완료 기능
•
3D 중심점 알고리즘(지구 곡률 반영)
•
이동시간 조회(ODsay + Kakao Mobility)
•
목적별 장소 추천(Kakao Local API)
•
실시간 투표(WebSocket - STOMP)
•
결과 공유(링크 및 카카오톡)
기술적 성과
•
Kakao API 4종 활용
•
Deep Dive 기술 스택 전면 적용(Spring Boot, Next.js, Redis)
•
GitHub Actions + Docker 기반 CI/CD 자동화 구축
향후 개선 계획
•
보안 강화: Private Subnet + ALB 구조 전환, WAF 도입 검토
•
성능 최적화: CDN 도입, DB 인덱싱 최적화, API 응답 압축
•
기능 확장: AI 기반 추천 고도화, 추가 외부 데이터 연동
•
모니터링: CloudWatch 알림, 에러 추적(Sentry) 등















