Projects
Local Up (진행 중)
- 개요
- 지역 및 공공 데이터와 외부 API를 결합해 지역 정보 분석과 시각화를 제공하는 서비스
- 서로 다른 주기의 공공데이터와 외부 API를 일관성 있게 다루기 위해 데이터 모델링 원칙을 정의하고, 캐싱·API 연동·운영 전략을 정리
- 기간: 2025년 ~ 진행 중
- 기술 스택
- 백엔드: Kotlin, Spring Boot, Spring Data MongoDB, Spring Cache, RestClient
- DB/인프라: MongoDB, Redis, Docker, GitHub Actions, Testcontainers, Cloudflare Tunnel
- 외부 API: Tour API, 공공데이터포털, OpenAI API
- 역할
- MongoDB 문서 모델링 원칙 수립: 임베디드/참조 기준과 인덱싱 전략을 확립하여 조회 성능을 개선하고 데이터 일관성을 확보
- 외부 API 전용 RestClient 구성, 인증/타임아웃/에러 처리 정책 분리
- 캐싱 전략 설계(TTL, sync, 캐시 스탬피드 방지) 및 Redis 기반 구현
- 운영 환경 제약 대응: VPN(WireGuard) 실험 및 실제 환경에서는 Cloudflare Tunnel 도입
- 첫 오픈소스 기여 경험(wg-easy 한글화 Pull Request 반영)
- 기술적 도전 및 해결
- MongoDB & Kotlin data class:
data class
와@DocumentReference(lazy = true)
가 충돌했으며,open class
적용과 단방향 참조 모델링으로 문제를 해결 - 외부 API 연동: RestTemplate/WebClient를 검토했으며, 동기 처리 선호 및 팀 러닝 커브를 고려해 RestClient를 채택
- API별 특성 차이: 공공데이터포털은 ServiceKey 인증을 사용하고 OpenAI는 Bearer Token을 사용함. 이에 따라 전용 RestClient를 분리하고 타임아웃을 최적화
- 사용량 제한과 비용: RateLimit AOP/Interceptor로 사용자별 호출 제어, Redis TTL 캐시로 비용 절감
- 장애 격리: 외부 API 실패가 전체 서비스 장애로 이어지지 않도록, 캐시 데이터나 기본 응답을 반환하는 Graceful Degradation 개념을 고려하고 설계 방향을 탐색
- MongoDB & Kotlin data class:
- 성과/배운 점
- 팀 공통 기준(데이터 모델링, HTTP 클라이언트 선택, 캐싱/RateLimit 원칙)을 문서화하여 재논의 비용을 감소시킴
- 외부 API 사용량 제한과 과금 문제를 서비스 설계 단계에서 고려하여, 운영 비용 절감 관점의 설계 경험을 축적
- Redis 캐시 도입 과정에서 TTL, sync, 분산 환경을 고려하며 운영 수준의 설계 포인트를 학습
- 네트워크 접근 대안 검토(WireGuard vs Cloudflare Tunnel) 및 오픈소스 기여 경험을 통해 개발 외적 역량 확장
- 링크
전화대장군 (해커톤)
- 개요
- 노년층 보이스피싱 피해 방지 서비스
- 통화 음성을 텍스트로 변환하고 AI 모델로 분석한 결과를 비동기 알림으로 전달하여 위험도를 고지
- 위험 수준에 따라 사용자에게 FCM 푸시 알림을 보내고, 보호자에게 SMS를 전송
- 기간: 2024년 10월 ~ 2024년 11월 (K-디지털 트레이닝 해커톤)
- 기술 스택
- 백엔드: Java 17, Spring Boot, Spring Data JPA, OpenFeign
- 비동기 처리:
@Async
,CompletableFuture
- DB/인프라: Redis (TTL 기반 상태 관리), Docker, GitHub Actions (CI/CD)
- 외부 API: OpenAI Whisper, GPT-4o, FCM, SMS API
- 역할
- 백엔드 및 DevOps를 담당
- 음성 텍스트 변환 및 분석 API 연동과 비동기 처리 구조 설계
- Redis를 활용한 임시 사용자 세션 관리 구현
- CI/CD 파이프라인 구축 및 팀 개발 환경 세팅
- 기술적 도전 및 해결
- Whisper 응답에 약 7.4초, GPT-4o 분석에 약 1.2초가 소요되어 총 8.6초 지연이 발생함. 실시간성이 저하되었고 이를 해결하기 위해 비동기 파이프라인을 적용
- 오픈소스 모델을 직접 구축했으나 성능이 부족하여, 개발 일정과 서비스 요구사항을 고려해 OpenAI 상용 API를 선택
- 프로토타입 단계에서는 인증을 생략하고 Redis TTL 기반 UUID 세션으로 상태를 관리
- 외부 API 장애 발생 시 Discord 알림과 기본 안전 메시지를 전송하도록 예외 처리를 강화
- 성과/배운 점
- K-디지털 트레이닝 해커톤에서 최우수상을 수상
- 외부 API 연동, 비동기 설계, Redis TTL 활용 등 실무와 유사한 문제를 해결하며 경험을 축적
- 기술 선택에서 이상과 현실의 균형을 고려하는 실용적인 관점을 학습
- 팀 협업 과정에서 명확한 API 스펙 정의와 소통의 중요성을 체감
- 링크
Connectrip
- 개요
- 동행 내 실시간 채팅과 위치 공유를 지원하는 국내 여행 커뮤니티 서비스
- 여행 동행자 모집, 실시간 채팅, 위치 공유 기능을 통해 안전하고 소통이 활발한 동행 여행 경험을 제공
- 처음으로 팀장 역할을 맡아 5명의 팀원과 함께 기획부터 배포까지 전 과정을 주도
- 기간: 2024년 8월 ~ 2024년 10월 (2개월)
- 기술 스택
- 백엔드: Java 17, Spring Boot, Spring Data JPA, Spring Security, WebSocket
- 프론트엔드: React, TypeScript, Vite
- DB/인프라: AWS RDS(MariaDB), MongoDB, Redis, Docker, GitHub Actions
- 배포: AWS EC2, ALB, Nginx, S3, CloudFront
- 역할
- 팀장으로서 프로젝트 기획, 일정 관리, 팀원 갈등 해결
- API 명세 문서화(Swagger) 도입 및 "API 선문서화 후 작업" 프로세스 정립
- AWS 인프라 구축 및 블루/그린 배포 방식 적용
- 채팅 기능 구현 (MongoDB + WebSocket)
- 기술적 도전 및 해결
- 팀 협업 문제: API 명세 부족으로 5일 일정 지연 발생. Swagger 도입과 1:1 미팅을 통해 해결하여 개발 속도 40% 향상
- 인프라 구축: t2.micro → t2.small 업그레이드, ALB + 2개 EC2로 서버 분리, Docker를 활용한 무중단 배포 환경 구축
- 채팅 구현: MongoDB Room/Message 엔티티 분리 구조로 구현했으나, 소규모 서비스에서는 RDB로도 충분했을 것이라는 회고
- 성능 최적화: 동행 게시물 생성 API 중복 조회 문제 해결로 처리 시간 22.6% 단축, RPS 30.6% 향상
- 성과/배운 점
- 목표 12개 API를 넘어 17개 추가 개발하여 1개월 2주 만에 MVP 출시
- Disquiet에서 첫 서비스 홍보 및 사용자 피드백 수집 경험
- 팀 리더십과 제한된 자원으로 목표 달성하는 법 학습
- 단순한 코딩을 넘어 제품을 만드는 과정에 대한 깊은 고민과 성찰
- 링크
MOVE
- 개요
- 위치 기반 게이미피케이션 요소를 결합한 러닝 기록 서비스
- 사용자의 걸음 수와 GPS 기반 위치 데이터를 실시간으로 수집하여 특정 장소 방문 시 포인트를 지급하고, 기록된 데이터를 시각화하여 운동 성취도를 확인할 수 있도록 기획
- 단순 만보기 앱을 넘어, “위치 방문 보상 + 친구와 경로 공유”라는 차별화를 목표
- 기간: 2023년 9월 ~ 2023년 12월 (대학교 졸업작품)
- 기술 스택
- 백엔드: Java 11, Spring Boot 2.x, Spring Data JPA, Spring Security, JWT
- 클라이언트: Android(Java, MVVM, Retrofit2, Hilt)
- 인프라/DB: PostgreSQL 10, Redis 6.x (캐싱), Firebase (푸시 알림/로그인)
- 역할
- Android UI 및 실시간 걸음 수, 위치 동기화 기능 개발
- 운동, 위치 데이터 저장/조회 API 설계 및 도메인 로직 구현
- JWT 기반 인증/인가 및 사용자 관리 기능 구축
- 위치 방문 보상(포인트 적립) 핵심 비즈니스 로직 설계 및 테스트
- 기술적 도전 및 해결
- JPA 지연 로딩 문제: 컨트롤러 단에서
LazyInitializationException
이 발생했으며, 서비스 계층에서 DTO 변환을 수행하고 fetch join을 도입하여 문제를 해결 - 위치 데이터 폭주: 0.3초 간격으로 위치 데이터를 전송하면서 서버에 과부하가 발생함. 이후 전송 주기를 조정하고 이중 검증 로직과 캐싱을 활용하여 안정성을 확보
- 안드로이드 구조 개선: 초기에는 Fragment가 과도한 책임을 지고 있었으며, MVVM 패턴을 도입하고
BroadcastReceiver
와ServiceConnection
을 분리하여 관심사를 명확히 구분하고 테스트 용이성을 확보
- JPA 지연 로딩 문제: 컨트롤러 단에서
- 성과/배운 점
- 새로운 기술 스택(Spring Boot, Android, JPA)을 단기간 습득하여 실제 프로젝트에 적용
- 무리한 아키텍처 적용(헥사고날 전환 시도) 경험을 통해 상황에 맞는 기술 선택의 중요성을 학습
- 위치 기반 데이터 처리, 동시성 이슈, 클라이언트-서버 데이터 동기화 등 여러 과제를 경험
- 실제 사용자 배포에는 이르지 못했으나, 배포 과정에서 필요한 안정성 확보와 데이터 동기화 전략을 사전에 고민하는 경험을 얻음
- 링크: 프로젝트 상세 회고