Skip to content

S0L-V/flyway

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

945 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

✈️ Flyway

1. Flyway 소개

Flyway는 소비자에게 합리적인 항공권 가격을 제공하기 위해 투명한 동적 가격 모델과 가격 변동 이력 기능을 구현한 실시간 항공권 예매 시스템입니다.

또한 실제 서비스 수준에서 요구되는 핵심 문제인 좌석 점유 동시성 제어, 예약 상태 관리, 결제 안정성 확보를 중심으로 설계 및 구현했습니다.

약 20만 건 규모의 대량 데이터를 직접 생성하여 운영 환경을 가정한 기능 검증과 시스템 테스트까지 수행했습니다.


🚀 배포

🔗 https://flyway.kr


🗓️ 개발 기간

📌 2026.01.07 ~ 진행 중


👥 팀원 소개

👩🏻‍💻 강희민
(@kkhhmm3103)
👩🏻‍💻 김민서
(@minseokim0113)
👩🏻‍💻 박수진
(@cl-o-lc)
  • 좌석 선택 및 상태 관리
  • 데이터 생성 및 성능 테스트
  • 항공편 검색 및 실시간 인기 항공편 조회
  • 데이터 생성 및 성능 테스트
  • AWS S3 구축
  • 가격 변동 배치/스케줄러 및 그래프
  • DB 성능 테스트
🧑🏻‍💻 오찬혁
(@ochanhyeok)
👩🏻‍💻 [팀장] 이가은
(@gaeunnlee)
🧑🏻‍💻 한재훈
(@hjh79gw)
  • 관리자 시스템 및 실시간 대시보드
  • 인프라 구축 및 서비스 배포
  • JWT + Refresh Token Rotation
    기반 회원 인증 시스템
  • 회원 정보·예약 내역 조회 및 수정
  • Jira 기반 협업 프로세스 구축
  • 예약 및 결제
  • 로그인 번호 인증 및 문자 발송
  • 성능 테스트

2. 서비스 기획 배경

✅ 문제 정의

기존 항공권 예매 시장은 가격 산정 기준이 공개되지 않아
사용자가 가격 변동 이유와 현재 가격의 적정성을 판단하기 어렵습니다.
또한 좌석 점유율과 인기 항공편 정보가 명확한 근거 없이 제공되어
사용자 의사결정 과정에서 정보 비대칭 문제가 발생합니다.


✨ Flyway 차별점

Flyway는 항공권 가격이 불투명하게 결정되는 문제를 해결하기 위해
가격 산정 기준을 공개하는 투명한 예매 서비스를 제공합니다.
가격은 다음 요소를 기반으로 산정됩니다.

  • M_time : 출발일까지 남은 시간
  • M_load : 좌석 점유율(수요)
  • alpha : 가격 변동 완화 계수

또한 사용자가 합리적으로 예매할 수 있도록 다음 정보를 제공합니다.

  • 가격 변동 이력 제공 (가격 추세 기반 구매 타이밍 판단)
  • 실시간 인기 여행지/항공편 제공 (수요 급등 항공편 즉시 확인)
  • 정확한 좌석 상태 정보 제공 (실시간 잔여 좌석 기반 의사결정)

3. 주요 화면

메인 검색 가격 변동 그래프
좌석 선택 결제 관리자 대시보드
더보기
메인 메인 - 캘린더 특가
실시간 인기 여행지 항공편 목록 항공편 가격 변동 그래프
약관 동의 탑승자 정보 입력 좌석 선택
부가서비스(1) 부가서비스(2)
결제(1) 결제(2) 결제(3)
예약 완료 예약 내역 관리자 대시보드
접속 기록 시간대별 분포 그래프 항공편 관리
특가 관리 회원 결제 내역

4. 주요 기능

회원 관리자

5. 기술 스택 (Tech Stack)

구분 기술 구분 기술
Backend Spring Framework 5.3.31
MyBatis 3.5.13
Security Spring Security 5.8.13
JWT (jjwt 0.12.6)
BCrypt
Database MariaDB (AWS RDS) Frontend JSP
Tailwind CSS
Chart.js
실시간 Spring WebSocket + SockJS 결제 토스페이먼츠 API
인증 Kakao OAuth 2.0 배포 AWS EC2
Tomcat

6. 시스템 아키텍처

image

7. ERD

항공편 공항 관리자 예약(1)
예약(2) 항공편 가격 회원

8. 개발 계획 및 협업

  • WBS 기반 일정 수립을 통해 전체 기능을 도메인 단위로 분해하고, 스프린트 단위로 개발 계획을 구체화
  • 평일 오전 9시 데일리 스크럼 작성 후 9시 30분 대면 회의 진행
  • Jira 이슈 기반 개발 프로세스를 적용하여 기능 단위를 명확히 정의하고, PR 단위로 작업을 관리
  • Notion을 통해 설계 문서, 트러블슈팅, 도메인 지식을 공유하며 팀 전체의 이해도를 통일
  • Discord 알림 연동을 통해 PR/이슈 상황을 실시간 공유하며 협업 속도 개선
WBS(1) WBS(2)
image image
image

9. 핵심 설계

Flyway는 항공권 예매 과정에서 발생하는 인증 보안 문제, 좌석 중복 예약 문제, 불투명한 가격 정책으로 인한 정보 비대칭 문제를 해결하기 위해 다음 4가지 핵심 설계를 중심으로 구현했습니다.

1) 인증/보안 설계 (JWT + Refresh + CSRF + Cookie)

Flyway는 HttpOnly Cookie 기반 JWT 인증 방식을 적용하여 토큰 탈취 위험을 줄였습니다.

또한 Refresh Token 회전(Rotation) 전략을 통해 Access Token 만료 시 자동 재발급이 가능하도록 구현하여 로그인 유지 경험을 개선했습니다.

소셜 로그인 사용자를 고려하여 OAuth 2.0 기반 로그인(Kakao) 흐름을 적용하였으며, OAuth 인증 성공 이후에도 서비스 내부에서는 JWT를 발급하여 인증 방식을 일관되게 통합했습니다.

API 요청은 JWT 기반으로 인증되며, 상태 변경 요청(POST/PUT/PATCH/DELETE)은 CSRF 토큰 검증을 통해 보호합니다.

이를 통해 브라우저 환경에서의 안정성과 보안성을 강화하고, 확장 가능한 인증 구조를 구축했습니다.

JWT 발급 / 회전 시퀀스 다이어그램 auth_web auth_api auth_token rotation
OAuth 시퀀스 다이어그램 kakao_oauth_3 kakao_oauth_2 kakao_oauth_1

2) 좌석 동시성 제어 (HOLD → PAYING → CONFIRMED)/>

Flyway는 동일 좌석에 대한 중복 예약을 방지하기 위해 좌석을 단순 조회 데이터가 아닌

공유 자원(Concurrency Resource) 으로 정의하고, 상태 기반 점유 모델을 설계했습니다.

  • 좌석 선택 시 AVAILABLE → HELD로 변경하여 임시 점유 처리
  • 결제 진행 시 HELD → PAYING → CONFIRMED 상태 전이로 경쟁 상태 방지
  • 일정 시간(10분) 내 결제가 완료되지 않으면 HELD → EXPIRED → AVAILABLE로 복구

이를 통해 결제 중 경쟁 요청이 발생해도 중복 결제가 발생하지 않도록 제어했습니다.

3) 동적 가격 투명성 모델 (M_time, M_load, alpha)

기존 항공권 예매 서비스는 가격 변동 기준이 공개되지 않아 사용자가 가격의 적정성을 판단하기 어렵습니다.

Flyway는 이러한 정보 비대칭 문제를 해결하기 위해 가격 산정 기준을 공개하는 동적 가격 모델을 적용했습니다.

가격은 다음 요소를 기반으로 산정됩니다.

  • M_time : 출발일까지 남은 시간
  • M_load : 좌석 점유율 기반 수요 지표
  • alpha : 가격 변동 완화 계수

또한 사용자에게 가격 변동 이력을 제공하여 합리적인 예매 판단이 가능하도록 설계했습니다.

4) 예약 상태 및 결제 흐름 설계 (예약 세그먼트/승객/부가서비스 + 동시성 연계)

Flyway는 항공권 예매가 단순 결제 처리로 끝나지 않고,

예약 정보 + 탑승자 정보 + 부가서비스 + 결제 상태가 유기적으로 연결되는 복합 도메인임을 고려하여

예약 흐름을 상태 기반으로 관리했습니다. 트랜잭션과 상태 기반 관리를 통한 동시성 제어로 오버 부킹 상황을 사전에 방지했습니다.

  • 예약 상태 변경 과정에서 좌석 동시성 제어 로직(HOLD/PAYING/CONFIRMED) 이 함께 적용되어 동일 좌석 중복 예약이 발생하지 않도록 설계했습니다.
  • 예약은 해당 항공편을 선택하여 동의 페이지로 이동하기 전 트랜잭션과 잔여석 행에 대한 비관적 락을 통해 잔여석을 인원수 만큼 차감하고 예약자의 상태 칼럼을 HELD로 변경합니다. 정보 입력 후 결제를 완료하면 HELD → CONFIRMED 흐름으로 상태가 변경되며, 결제 확정 처리됩니다.
  • 예약 세그먼트(왕복/경유) 구조를 반영하여 다구간 예약을 관리할 수 있도록 설계했습니다.
  • 탑승자(Passenger) 정보와 좌석(Seat) 선택이 예약과 강하게 연결되도록 구성했습니다.
  • 수하물/기내식 등 부가서비스는 Passenger 단위로 연결되어 확장 가능하도록 구현했습니다.

5) 관리자 실시간 대시보드 (WebSocket + SockJS)

Flyway는 관리자가 서비스 현황을 실시간으로 모니터링할 수 있도록 WebSocket 기반 실시간 대시보드를 구현했습니다.

  • WebSocket + SockJS를 활용하여 서버에서 클라이언트로 실시간 데이터를 푸시합니다.
  • 통계 데이터(매출, 예약, 방문자)는 15초 주기로 자동 브로드캐스트되어 새로고침 없이 최신 현황을 확인할 수 있습니다.
  • WebSocket 연결 실패 시 REST API 폴백을 통해 데이터 조회가 가능하도록 설계하여 안정성을 확보했습니다.
  • 알림 시스템을 통해 신규 예약, 결제 완료, 취소 요청 등 주요 이벤트를 실시간으로 전달합니다.

또한 관리자 시스템은 일반 사용자 시스템과 완전히 분리된 Security FilterChain으로 구성하여, 한쪽 시스템이 침해되더라도 다른 시스템에 영향을 주지 않도록 보안을 격리했습니다.


10. 회고

  • 강희민
    어려운 일들이 많았지만 하나씩 해결해 가면서 많이 성장할 수 있었습니다! 이번 프로젝트를 통해 단순히 기능이 동작하는 것보다 현실적인 운영 구조를 데이터 모델에 어떻게 녹여내는지가 훨씬 중요하다는 점을 배웠습니다!
  • 김민서
    다양한 변수로 일정이 지연되었으나, Jira로 계획의 우선순위를 조정하며 단계적으로 해결하였습니다. 이를 통해 계획의 유연성과 일정 관리의 중요성을 배웠습니다.
  • 박수진
    초기에 시행착오를 겪으며, 우리 팀에게 필요한 소통 방식을 찾아가던 과정이 인상 깊습니다. 매일 9:30 데일리 스크럼을 진행한 것이 큰 도움이 되었습니다.
  • 오찬혁
    처음엔 막막했지만, 하나씩 해결하면서 자신감을 얻었고 개발 과정에서 겪은 문제들을 팀원들과 공유하고 함께 해결해 나갔습니다. 이를 통해 Spring Legacy 환경에서의 경험과 AWS 인프라 운영 역량을 키울 수 있었습니다.
  • 이가은
    이번 프로젝트에서 설계 의도와 코드 구조를 꾸준히 기록하여, 중간에 구조 변경이 발생했을 때도 빠르게 대응할 수 있었습니다. 또한 Jira를 통해 팀원들의 작업 현황과 전체 진행도를 한눈에 파악할 수 있어 효율이 좋았고, 다음 프로젝트에서도 적극적으로 활용하고 싶습니다.
  • 한재훈
    api 명세서를 작성하며 팀원과 코드를 맞춰가는 게 어려웠지만 협업과 소통하는 법을 배울 수 있었습니다. 데일리 스크럼을 통해 담당기능이 아니더라도 진행사항을 파악하고 코드 리뷰를 할 수 있어 프로젝트 진행에 많은 도움이 됐습니다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 6