워킹홀리데이·교환학생·인턴십을 준비하는 모든 사람을 위한 AI 기반 해외 생활 정보 플랫폼
말하면 찾아주고, 고르면 준비된다.
OMO는 해외 체류를 준비하는 사용자가 자연어 AI 검색을 통해 자신에게 맞는 도시를 찾고, 도시 비교, 예산 확인, 서류 준비 로드맵까지 한 번에 관리할 수 있도록 돕는 해외 준비 플랫폼입니다.
| 핵심 기능 |
설명 |
| 🏙️ 도시 탐색 |
워킹홀리데이·교환학생·인턴십별 추천 도시 탐색 |
| 🤖 AI 도시 리포트 |
도시별 생활비·치안·선호도 점수, 장단점, 실제 후기 제공 |
| ⚖️ 도시 비교 |
여러 도시의 지표를 나란히 비교 |
| 🗺️ 로드맵 |
비자·숙소·항공권 등 준비 단계별 타임라인 및 예산 관리 |
| ⚙️ 설정 |
프로필 관리, 알림·동기화 설정 |
| 팀원 |
역할 |
| 김성연 |
탐색 탭, 필터, 문의하기, 배포 |
| 유승지 |
내 홈 탭, 로드맵, 태스크·서류, 예산 계획, 위시리스트 |
| 이지우 |
회원가입, 로그인, 메인 탐색 홈, AI 스마트 브리핑, 글로벌 검색 |
| 이지현 |
도시 비교, AI 탐색 리포트, 설정 |
| 분류 |
기술 |
| Framework |
React 19 |
| Language |
TypeScript |
| Build Tool |
Vite |
| Styling |
Tailwind CSS v4 |
| 상태 관리 |
Zustand, TanStack Query |
| Linter |
ESLint |
| Formatter |
Prettier |
src/
├── features/ # 도메인별 기능 모듈
│ ├── auth/ # 로그인·회원가입·소셜 로그인
│ │ ├── api/ # 인증 API
│ │ ├── components/ # 로그인·회원가입 모달
│ │ ├── constants/
│ │ ├── hooks/
│ │ ├── pages/ # 이메일 인증·OAuth 콜백 라우트
│ │ ├── store/ # Zustand 스토어
│ │ └── types/
│ ├── chat/ # AI 채팅
│ │ ├── api/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── types/
│ │ └── utils/
│ ├── city-ai-report/ # AI 도시 리포트 (모달)
│ │ ├── api/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── mocks/
│ │ ├── types/
│ │ ├── utils/
│ │ └── index.ts # public API
│ ├── city-insight/ # 도시 인사이트
│ │ ├── components/
│ │ ├── constants/
│ │ ├── hooks/
│ │ ├── mocks/
│ │ ├── pages/
│ │ ├── types/
│ │ └── utils/
│ ├── compare/ # 도시 비교 (모달)
│ │ ├── api/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── store/
│ │ ├── types/
│ │ └── utils/
│ ├── contact/ # 문의하기
│ │ ├── components/
│ │ ├── constants/
│ │ ├── hooks/
│ │ ├── pages/
│ │ └── types/
│ ├── home/ # 메인 홈
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── pages/
│ │ └── types/
│ ├── roadmap/ # 로드맵·태스크·예산·위시리스트
│ │ ├── api/ # 로드맵/태스크/예산/위시리스트 API
│ │ ├── components/
│ │ │ └── icons/ # 로드맵 전용 아이콘
│ │ ├── mocks/
│ │ ├── pages/ # 로드맵 목록·상세
│ │ ├── store/
│ │ ├── types/
│ │ └── utils/ # API 응답 → 화면 데이터 변환
│ ├── search/ # 검색 모달
│ │ └── components/
│ └── settings/ # 설정
│ ├── api/
│ ├── components/
│ ├── pages/
│ └── types/
│
├── shared/ # 여러 feature에서 공통으로 사용하는 리소스
│ ├── components/ # 공통 컴포넌트 (Header, Footer, Chip 등)
│ ├── constants/
│ ├── hooks/
│ ├── layouts/ # MainLayout 등 레이아웃
│ ├── pages/ # 약관·정책 페이지
│ └── types/
│
├── lib/ # 외부 라이브러리 설정
│ └── axios.ts # 인스턴스·토큰 인터셉터
│
├── assets/ # 이미지, 아이콘 등 정적 파일
│ ├── icons/
│ └── images/
│
├── App.tsx
├── main.tsx
├── router.tsx # 라우트 정의
└── index.css
패키지 매니저는 pnpm으로 통일합니다. npm install을 쓰면 package-lock.json이
다시 생겨 팀원 간 의존성 버전이 갈릴 수 있습니다.
# 저장소 클론
git clone https://github.com/OMO-team/OMO-FE.git
cd OMO-FE
# 패키지 설치
pnpm install
# 개발 서버 실행
pnpm dev
pnpm dev # 개발 서버 실행 (http://localhost:5173)
pnpm build # 프로덕션 빌드 (tsc -b && vite build)
pnpm preview # 빌드 결과 로컬 미리보기
pnpm lint # ESLint 검사
pnpm format # Prettier 자동 포맷
pnpm format:check # Prettier 포맷 위반 여부 확인 (CI용)
| 화면 |
경로 |
설명 |
| 메인 홈 |
/ |
카테고리별 추천 도시, AI 프롬프트 검색 |
| 도시 인사이트 |
/city-insight |
도시 상세 정보 카드 |
| 내 홈 (로드맵·위시리스트) |
/myhome |
국가별 로드맵과 위시리스트 탭 |
| 로드맵 상세 |
/myhome/dashboard/:roadmapId |
타임라인·예산·AI 리포트 |
| 태스크 상세 |
/myhome/dashboard/:roadmapId/task-detail/:taskId |
단계별 준비 서류 체크 |
| 문의하기 |
/contact |
문의 폼 |
| 약관·정책 |
/support/terms |
이용약관·개인정보처리방침 |
| 설정 |
/setting |
프로필·알림·계정 설정 |
AI 도시 리포트와 도시 비교는 별도 라우트가 아니라 모달로 열립니다.
| 경로 |
설명 |
/auth/email-verify |
이메일 인증 링크 진입 |
/auth/password-reset/verify |
비밀번호 재설정 링크 진입 |
/oauth/callback |
구글 OAuth 콜백 |
/settings/account |
구글 계정 연동 콜백 |
[메인 홈]
│
├─ 카테고리 선택 (워킹홀리데이 / 교환학생 / 인턴십)
│ └─ 도시 카드 탐색
│ └─ [도시 인사이트]
│ └─ [AI 도시 리포트]
│ ├─ 점수 · 요약 · 장단점 확인
│ ├─ 브이로그 · 실제 후기 확인
│ └─ AI 검색으로 추가 질문
│
├─ AI 프롬프트 입력
│ └─ 맞춤 도시 추천 결과
│
└─ 도시 비교 [Compare Bar]
└─ [도시 비교 모달]
└─ 두 도시 지표 비교
[내 홈]
├─ 나라별 로드맵 탭
│ └─ 국가별로 묶인 도시 로드맵 카드
│ ├─ [로드맵 상세]
│ │ ├─ 타임라인 (비자 · 보험 · 서류 · 항공권 · 숙소 · 재정)
│ │ │ └─ [태스크 상세] 준비 서류 체크
│ │ ├─ 예산 계획 (체류 기간 선택 → 초기 정착금 · 월 생활비 합산)
│ │ └─ AI 리포트 카드 → [AI 도시 리포트 모달]
│
└─ 위시 리스트 탭
└─ 목적별로 담은 도시 카드
└─ [AI 도시 리포트 모달]
└─ 로드맵에 추가하기
[설정]
├─ 프로필 확인 · 수정
├─ 푸시 알림 · 자동 동기화 토글
├─ 비밀번호 변경 · 이용약관
└─ 로그아웃 · 계정 탈퇴
| 브랜치 |
역할 |
main |
항상 배포 가능한 상태. PR로만 merge |
dev |
다음 배포를 준비하는 통합 브랜치 |
feat/* |
기능 개발 브랜치. 완료 후 dev로 PR |
구조: Prefix/#이슈번호-설명 (kebab-case)
| Prefix |
설명 |
예시 |
feat |
새로운 기능 추가 |
feat/#10-login-api |
fix |
버그 수정 |
fix/#23-header-layout |
docs |
문서 수정 |
docs/#5-update-readme |
style |
코드 포맷팅 (로직 변경 없음) |
style/#12-format-code |
refactor |
코드 리팩토링 |
refactor/#30-user-service |
test |
테스트 코드 |
test/#15-login-test |
chore |
설정 파일, 패키지 매니저 등 |
chore/#2-setting-eslint |
hotfix |
운영 긴급 버그 수정 |
hotfix/#99-payment-error |
type: Subject (#이슈번호)
Body (선택: 무엇을, 왜 변경했는지 상세 설명)
Footer (선택: Closes #이슈번호)
| 태그 |
설명 |
예시 |
feat |
새로운 기능 추가 |
feat: 회원가입 API 구현 (#10) |
fix |
버그 수정 |
fix: 로그인 토큰 만료 오류 수정 (#23) |
docs |
문서 수정 |
docs: API 명세서 업데이트 (#5) |
style |
코드 스타일 변경 |
style: 코드 포맷팅 적용 (#12) |
refactor |
리팩토링 (기능 변경 없음) |
refactor: 사용자 조회 로직 개선 (#30) |
test |
테스트 코드 |
test: 회원가입 성공 테스트 작성 (#15) |
chore |
빌드·패키지 설정 |
chore: 라이브러리 버전 업데이트 (#2) |
rename |
파일·폴더 이동/이름 변경 |
rename: 이미지 경로 변경 (#8) |
remove |
파일 삭제 |
remove: 사용하지 않는 로고 삭제 (#9) |
| 항목 |
작성 방법 |
| 제목 |
[Prefix] 작업 내용 요약 (예: [Feat] 소셜 로그인 기능 구현) |
| 설명 |
작업의 배경 및 목적 |
| 할 일 |
체크박스 Task List |
| 참고 |
디자인 시안, 참고 문서 링크 등 |
| 항목 |
작성 방법 |
| 제목 |
[Prefix] 작업 내용 요약 |
| 관련 이슈 |
Closes #이슈번호 |
| 작업 내용 |
변경 사항 핵심 요약 |
| 스크린샷 |
UI 변경 시 이미지 첨부 |
| 특이사항 |
리뷰어가 집중해서 봐줬으면 하는 부분 |
PR은 최소 1명 Approve 후 merge 가능
| 대상 |
규칙 |
예시 |
| 폴더명 |
camelCase |
profileSetup, onBoarding |
| 컴포넌트 파일명 |
PascalCase |
MyComponent, ToggleSwitch |
| 변수명 |
camelCase |
const [isLoading, setIsLoading] = useState(false) |