# 🎵 MyListBridge

음악 스트리밍 서비스 간 플레이리스트를 손쉽게 이전할 수 있는 웹 애플리케이션입니다.

## ✨ 주요 기능

### VIBE → Spotify 플레이리스트 이전
- 🔐 VIBE 로그인을 통한 플레이리스트 가져오기
- 🔗 VIBE 플레이리스트 URL로 직접 가져오기
- 🎯 트랙 단위 선택 및 이전
- 📝 Spotify 신규 플레이리스트 생성 또는 기존 플레이리스트에 추가
- 🔄 자동 토큰 갱신으로 끊김 없는 사용자 경험

### 보안
- 🔒 AES256 암호화를 통한 안전한 로그인 정보 전송
- 🎫 OAuth 2.0 PKCE 방식의 Spotify 인증
- ⏱️ Access Token 자동 갱신 (만료 5분 전)

### 사용자 경험
- 🎨 모던한 UI/UX (shadcn/ui)
- 🌓 다크 모드 지원
- 📱 반응형 디자인 (모바일/태블릿/데스크톱)
- ⚡ 부드러운 애니메이션 (Framer Motion)
- 🔔 실시간 알림 (Toast)
- 🚫 중복 클릭 방지 및 로딩 상태 표시

## 🛠️ 기술 스택

### Frontend
- **React 18** - UI 라이브러리
- **TypeScript** - 타입 안정성
- **Vite** - 빌드 도구
- **React Router** - 라우팅

### Styling
- **Tailwind CSS** - 유틸리티 CSS 프레임워크
- **shadcn/ui** - UI 컴포넌트 라이브러리
- **Framer Motion** - 애니메이션

### Libraries
- **crypto-js** - AES256 암호화
- **sonner** - Toast 알림
- **Lucide React** - 아이콘

## 📦 설치 및 실행

### 1. 저장소 클론
```bash
git clone https://github.com/yourusername/MyListBridge.git
cd MyListBridge
```

### 2. 의존성 설치
```bash
npm install
```

### 3. 환경 변수 설정
`.env.example` 파일을 `.env`로 복사하고 필요한 값을 설정하세요:

```bash
cp .env.example .env
```

`.env` 파일 내용:
```env
# API Base URL
VITE_API_BASE_URL=http://localhost:9099/api

# Spotify OAuth
VITE_SPOTIFY_CLIENT_ID=your_spotify_client_id_here
# VITE_SPOTIFY_REDIRECT_URI=http://127.0.0.1:3001/callback/spotify
```

### 4. Spotify 앱 설정
1. [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/applications)에서 앱 생성
2. Client ID 복사하여 `.env`에 설정
3. **Redirect URI** 설정:
   - `http://127.0.0.1:3001/callback/spotify` 추가
   - ⚠️ **중요**: Spotify는 `localhost`를 지원하지 않으므로 반드시 `127.0.0.1`을 사용해야 합니다

### 5. 개발 서버 실행
```bash
npm run dev
```

브라우저에서 다음 주소로 접속:
- `http://localhost:3001` (권장)
- `http://127.0.0.1:3001`

### 6. 프로덕션 빌드
```bash
npm run build
```

빌드된 파일은 `build/` 디렉토리에 생성됩니다.

## 📁 프로젝트 구조

```
MyListBridge/
├── src/
│   ├── components/          # React 컴포넌트
│   │   ├── common/         # 공통 컴포넌트
│   │   ├── features/       # 기능별 컴포넌트
│   │   │   ├── playlist/  # 플레이리스트 관련
│   │   │   ├── service/   # 서비스 선택 관련
│   │   │   └── spotify/   # Spotify 관련
│   │   └── ui/            # shadcn/ui 컴포넌트
│   ├── pages/              # 페이지 컴포넌트
│   │   ├── VibePage.tsx   # VIBE 플레이리스트 페이지
│   │   └── SpotifyCallback.tsx  # Spotify OAuth 콜백
│   ├── services/           # API 서비스
│   │   ├── vibeService.ts # VIBE API
│   │   └── spotifyService.ts  # Spotify API
│   ├── utils/              # 유틸리티
│   │   ├── api.ts         # API 클라이언트
│   │   ├── crypto.ts      # AES256 암호화
│   │   └── alert.ts       # 알림 유틸리티
│   ├── types/              # TypeScript 타입 정의
│   │   └── api.ts
│   ├── constants/          # 상수
│   │   └── streamingServices.ts
│   ├── App.tsx            # 메인 앱 컴포넌트
│   └── main.tsx           # 앱 진입점
├── .env.example           # 환경 변수 예시
├── package.json
├── vite.config.ts         # Vite 설정
├── tsconfig.json          # TypeScript 설정
└── tailwind.config.js     # Tailwind CSS 설정
```

## 🔐 보안 설정

### AES256 암호화
VIBE 로그인 시 아이디와 비밀번호가 AES256으로 암호화되어 전송됩니다.

```typescript
// src/utils/crypto.ts
const SECRET_KEY = 'MyListBridgeSecretKey1234567890';
```

**⚠️ 중요**: 프로덕션 환경에서는 환경 변수로 관리하세요!

### Spotify OAuth 2.0 (PKCE)
- PKCE (Proof Key for Code Exchange) 방식 사용
- Code Verifier 및 Code Challenge 자동 생성
- Refresh Token을 통한 자동 갱신

## 🚀 사용 방법

### 1. VIBE 플레이리스트 가져오기
1. 메인 페이지에서 **VIBE** 서비스 선택
2. 두 가지 방법 중 선택:
   - **로그인**: VIBE 계정으로 로그인하여 모든 플레이리스트 가져오기
   - **URL 입력**: 특정 플레이리스트 URL 입력

### 2. 트랙 선택
1. 플레이리스트를 펼쳐 트랙 확인
2. 이전할 트랙 선택 (개별 선택 또는 플레이리스트 전체 선택)
3. **다음** 버튼 클릭

### 3. Spotify로 이전
1. **Spotify** 서비스 선택
2. Spotify 로그인 (OAuth 팝업)
3. 대상 플레이리스트 선택:
   - **새 플레이리스트 생성**: 이름과 설명 입력
   - **기존 플레이리스트**: 목록에서 선택
4. 이전 완료 후 자동으로 메인 페이지로 이동

## 🎯 API 명세

### Backend API 엔드포인트

#### VIBE
```typescript
// 로그인 및 플레이리스트 목록 조회
POST /api/v2/vibe/playlists
Body: { id: string (encrypted), password: string (encrypted) }

// 플레이리스트 트랙 조회
GET /api/v2/vibe/playlists/:playlistId/tracks
Headers: { X-Session-Id: string }
```

#### Spotify
```typescript
// 플레이리스트 목록 조회
POST /api/v2/spotify/playlists
Body: { access_token: string }

// 트랙 추가
POST /api/v2/spotify/playlists/tracks
Body: {
  access_token: string,
  playlist_id?: string,
  playlist_name?: string,
  playlist_description?: string,
  is_public?: boolean,
  tracks: TrackInfo[]
}
```

## 🐛 문제 해결

### Spotify 로그인 오류: "INVALID_CLIENT: Invalid redirect URI"
- Spotify Dashboard의 Redirect URI를 `127.0.0.1`로 설정했는지 확인
- `localhost` 대신 `127.0.0.1`을 사용해야 합니다

### 연결 거부 (ERR_CONNECTION_REFUSED)
- 개발 서버가 포트 3001에서 실행 중인지 확인
- Spotify Dashboard의 Redirect URI 포트가 일치하는지 확인

### Alert가 표시되지 않음
- `<Toaster />` 컴포넌트가 `main.tsx`에 추가되어 있는지 확인

### 토큰 만료 오류
- Access Token은 1시간 후 자동으로 갱신됩니다
- Refresh Token이 없을 경우 다시 로그인하세요

## 📝 개발 가이드

### 코드 작성 규칙
- ✅ **타입 안정성**: TypeScript 엄격 모드 준수
- ✅ **실제 구현**: Mock 데이터 사용 금지
- ✅ **컴포넌트 네이밍**: PascalCase 사용
- ✅ **파일 구조**: `.types.ts`, `.constants.ts`, `.utils.ts` 분리

### 금지 사항
- ❌ `any` 타입 사용
- ❌ 직접적인 DOM 조작
- ❌ 프로덕션 코드에 `console.log` 남기기
- ❌ Mock 데이터나 가짜 구현

## 🤝 기여하기

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## 📄 라이선스

이 프로젝트는 MIT 라이선스 하에 배포됩니다.

## 🙏 감사의 말

- [shadcn/ui](https://ui.shadcn.com/) - 아름다운 UI 컴포넌트
- [Lucide Icons](https://lucide.dev/) - 아이콘 세트
- [Spotify Web API](https://developer.spotify.com/documentation/web-api) - Spotify 통합

## 📞 문의

프로젝트에 대한 질문이나 제안사항이 있으시면 이슈를 등록해주세요.

---

Made with ❤️ by MyListBridge Team
