InPick Project
InPick — AI 기반 여행 일정 생성 및 추천 시스템
사용자의 취향과 위치 정보를 분석하여 개인화된 여행 코스를 설계해주는 올인원 여행 플랫폼입니다.
1. 시스템 아키텍처 (System Architecture)
FastAPI를 중심으로 다양한 AI 모델과 3종류의 데이터베이스(RDB, NoSQL, Vector DB)가 유기적으로 연결된 구조입니다.
flowchart TB
%%{init: {"flowchart": {"nodeSpacing": 25, "rankSpacing": 35}}}%%
user["사용자"]
subgraph INPICK["INPICK"]
direction TB
subgraph Browser["Browser"]
direction TB
spa["SPA
React 19 · Vite 7
TypeScript"]
end
subgraph Server["학원 서버 (Docker Host)"]
direction TB
nginx["Nginx
Reverse Proxy · Static"]
api["FastAPI
(Gunicorn/Uvicorn)"]
end
end
user -->|"HTTPS"| nginx
nginx -->|"Static"| spa
nginx -->|"Proxy /api"| api
spa -->|"Session Cookie"| api
%% =========================
%% Data / Models (Hub)
%% =========================
dataHub["Data / Models"]
api --> dataHub
subgraph Data["Data / Models"]
direction TB
pg["PostgreSQL
RDB"]
mongo["MongoDB
Session TTL"]
faiss["FAISS
Vector Index"]
ml["PyTorch
Model (.pt)"]
end
dataHub -->|"SQL"| pg
dataHub -->|"Session"| mongo
dataHub -->|"Vector Search"| faiss
dataHub -->|"Load/Run"| ml
%% =========================
%% OAuth (Hub)
%% =========================
oauthHub["OAuth"]
api --> oauthHub
subgraph OAuth["OAuth Providers"]
direction TB
google["Google"]
naver["Naver"]
kakaoOAuth["Kakao"]
end
oauthHub -->|"Redirect"| google
oauthHub -->|"Redirect"| naver
oauthHub -->|"Redirect"| kakaoOAuth
%% =========================
%% LLM (Hub)
%% =========================
llmHub["LLM"]
api --> llmHub
subgraph LLM["LLM APIs"]
direction TB
openai["OpenAI"]
claude["Claude
(LangChain)"]
end
llmHub -->|"Call"| openai
llmHub -->|"Call"| claude
%% =========================
%% Maps / Routing (Hub)
%% =========================
mapsHub["Maps / Routing"]
spa --> mapsHub
api --> mapsHub
subgraph Maps["Maps / Routing"]
direction TB
kakaoMaps["Kakao Maps
JS SDK"]
ncpMap["NCP Map
Directions"]
tmap["TMAP"]
end
mapsHub -->|"UI"| kakaoMaps
mapsHub -->|"Route/POI"| ncpMap
mapsHub -->|"Route"| tmap
%% =========================
%% CI/CD
%% =========================
jenkins["Jenkins
CI/CD"]
jenkins -.->|"Deploy"| nginx
jenkins -.->|"Deploy"| api
%% =========================
%% Styles
%% =========================
classDef person fill:#F3E8FF,stroke:#7C3AED,stroke-width:2px;
classDef c_container fill:#E8F1FF,stroke:#2563EB,stroke-width:2px;
classDef external fill:#FFF4E5,stroke:#F59E0B,stroke-width:2px;
classDef datastore fill:#E9FBF0,stroke:#16A34A,stroke-width:2px;
class user person;
class spa,nginx,api,dataHub,oauthHub,llmHub,mapsHub c_container;
class google,naver,kakaoOAuth,openai,claude,kakaoMaps,ncpMap,tmap,jenkins external;
class pg,mongo,faiss,ml datastore;
▲ React, FastAPI 및 다중 DB/AI 모델 연동 구조
2. 주요 기능 및 화면 (UI/UX)
맞춤 장소 추천
지역, 기간, 동행자, 테마를 단계별로 입력받아 CBF, CF 추천 알고리즘을 통해 최적의 장소를 제안합니다.
시퀀스 추천 + 지도 기반 경로 확인
시퀀스 추천을 통해 생성된 일정의 동선을 Kakao Map과 TMAP API로 시각화하여 보여줍니다.
3. 4단계 여행 일정 생성 UI Flow
지역·기간·동행·테마 입력 후, AI 추천 모델을 선택해 일정 초안을 만들고 지도에서 편집한 뒤 저장합니다.
sequenceDiagram
participant U as User
participant S1 as Step1(조건 입력)
participant S2 as Step2(장소/지도/AI생성)
participant S3 as Step3(숙소 선택)
participant S4 as Step4(최종 저장)
participant BE as FastAPI
U->>S1: 1. 지역/기간/동행/테마 입력
S1->>BE: 2. GET /region/list (지역 목록)
S1-->>U: 3. 기본 추천 후보/좌표 확보
U->>S2: 4. 추천 모델 선택 후 "AI 생성"
S2->>BE: 5. POST /itinerary/generate {model_name, base_itinerary}
BE-->>S2: 6. ItineraryResponse(일정 초안)
S2-->>U: 7. 지도(카카오맵)에서 동선 확인/장소 수정
U->>S3: 8. 숙소 선택(지도/리스트)
S3->>BE: 9. GET /accommodation/list
BE-->>S3: 10. 숙소 후보 반환
U->>S4: 11. 최종 확정/시간 미세조정
S4->>BE: 12. POST /itinerary/createItinerary (DB 저장)
BE-->>U: 13. 저장 완료 + 내 일정 리스트 갱신
4. 데이터베이스 설계 (ERD)
사용자 정보와 장소 데이터는 관계형 DB에, 세션과 로그는 NoSQL에 분산 저장합니다.
▲ PostgreSQL 핵심 엔티티 관계도
5. 기술 스택 (Tech Stack)
Frontend
React 19 TypeScript Vite 7 Tailwind CSS 4 Kakao Maps SDK shadcn/uiBackend & AI
FastAPI Python PyTorch FAISS (Vector) LangChain OAuth 2.0Data & Infra
PostgreSQL MongoDB Docker Jenkins Nginx6. 트러블 슈팅
개발/배포 과정에서 발생한 이슈를 증상 → 원인 → 해결 흐름으로 정리했습니다.
-
[CORS] 프론트 API 호출 실패 (CORS 에러)
증상브라우저에서 API 요청이 차단되며 호출이 실패(CORS 오류 발생)원인FastAPI에서 허용 Origin/자격 증명(쿠키) 설정이 누락되어 브라우저가 요청을 막음해결CORSMiddleware적용 후allow_origins에 프론트 URL 추가,allow_credentials활성화로 세션 기반 인증이 동작하도록 수정 -
[Auth] 로그인 후 간헐적 401 / 사용자 정보 조회 실패
증상로그인 이후 간헐적으로 인증이 풀리거나(401), 사용자 정보 조회 API가 실패원인요청 시 세션/쿠키 전송 누락 또는 인증 헤더/쿠키 흐름이 불안정하여 서버가 비인증 요청으로 판단해결Axios 인스턴스에 요청/응답 로깅 + 인터셉터 적용,withCredentials포함 여부를 점검해 쿠키 전송/인증 흐름을 안정화 -
[ML] 추천 API 호출 시 500 (FileNotFoundError)
증상추천 기능 호출 시 서버가500으로 종료되며FileNotFoundError발생원인모델 파일(nextpoi_gru4rec.pt)이 배포 환경에 포함되지 않거나 로딩 경로가 잘못되어 ML artifact를 찾지 못함해결app/ml/artifacts/디렉토리 구성 및 배포 포함 여부를 점검하고, 모델 파일 배치를 재정리하여 로딩 실패를 제거 -
[Config] .env 누락/필수 값 미설정 (pydantic field required)
증상개발/배포 환경에서 실행 시pydantic field required에러로 서버 기동 실패원인.env가 누락되거나 필수 환경변수가 비어 있어 Settings 로딩 단계에서 검증에 실패해결Settings 기준 필수 환경변수 목록을 재정리하고, 실행 전 환경변수 검증(체크리스트/검증 단계)을 추가하여 재발 방지 -
[Session] MongoDB TTL 인덱스로 인한 예기치 못한 로그아웃
증상사용 중 갑자기 로그아웃되거나, 세션이 만료되어 인증이 끊기는 현상이 발생원인MongoDB 세션이 TTL 인덱스 정책에 의해 만료되며, 사용자 활동과 무관하게 세션이 삭제될 수 있음해결세션(쿠키) 만료 정책(TTL)과 갱신(refresh) 흐름을 점검하고, 갱신 타이밍/유효기간을 조정하여 사용자 경험을 개선
▲ GoogleDrive를 통한 기획, 문서화, 협업 및 트러블 슈팅 관리