# Celery + Redis 정기구독 자동 스케줄 구조

## 개요

Celery와 Redis를 사용하여 Toss API 기반 정기구독 자동 갱신 시스템을 구현했습니다.

## 주요 기능

1. **정기구독 갱신 체크**: 매시간 `next_billing_date`가 오늘인 구독을 찾아 결제 링크 생성
2. **결제 링크 생성**: Toss API를 사용한 단건결제 링크 생성
3. **이메일 발송**: 결제 링크를 포함한 이메일 자동 발송
4. **만료 구독 정리**: 매일 자정에 만료된 구독 자동 정리

## 파일 구조

```
mlink-backend/
├── src/
│   ├── celery_app.py          # Celery 앱 초기화
│   ├── tasks.py                # Celery 태스크 정의
│   └── utils/
│       └── email_service.py    # 이메일 발송 유틸리티
├── celery_worker.py            # Celery Worker 실행 스크립트
└── celery_beat.py              # Celery Beat 실행 스크립트
```

## 환경 변수 설정

`.env` 파일에 다음 환경 변수를 설정하세요:

```bash
# Redis 설정
REDIS_URL=redis://localhost:6379/0

# SMTP 설정 (이메일 발송용)
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password

# Toss API 설정
TOSS_API_KEY=your-toss-api-key
TOSS_SECRET_KEY=your-toss-secret-key

# URL 설정
FRONT_URL=http://localhost:3001
BACK_URL=http://localhost:8011
```

## 실행 방법

### 1. Redis 서버 실행

```bash
# Redis가 설치되어 있지 않은 경우
sudo apt-get install redis-server

# Redis 서버 시작
redis-server
```

### 2. Celery Worker 실행

별도 터미널에서:

```bash
cd /home/kdj-ubuntu1/mlink_AI_Server/mlink-backend
celery -A src.celery_app.celery worker --loglevel=info
```

또는:

```bash
python celery_worker.py
```

### 3. Celery Beat (스케줄러) 실행

별도 터미널에서:

```bash
cd /home/kdj-ubuntu1/mlink_AI_Server/mlink-backend
celery -A src.celery_app.celery beat --loglevel=info
```

또는:

```bash
python celery_beat.py
```

### 4. Flask 애플리케이션 실행

```bash
python src/main.py
```

## 스케줄 설정

`src/celery_app.py`의 `beat_schedule`에서 스케줄을 관리합니다:

- **정기구독 갱신 체크**: 매시간 실행 (`check_subscription_renewals`)
- **만료 구독 정리**: 매일 자정 실행 (`cleanup_expired_subscriptions`)

## 태스크 설명

### 1. check_subscription_renewals

- **실행 주기**: 매시간
- **기능**: `next_billing_date`가 오늘인 활성 구독을 찾아 결제 링크 생성 및 이메일 발송

### 2. create_payment_link_and_send_email

- **트리거**: `check_subscription_renewals`에서 호출
- **기능**:
  - Toss API를 사용한 결제 링크 생성
  - PaymentHistory 레코드 생성 (PENDING 상태)
  - 사용자에게 결제 링크 이메일 발송

### 3. cleanup_expired_subscriptions

- **실행 주기**: 매일 자정
- **기능**: `end_date`가 지난 활성 구독을 만료 상태로 변경

## 이메일 템플릿

결제 링크 이메일은 HTML 형식으로 발송되며, 다음 정보를 포함합니다:

- 사용자 이름
- 구독 상품명
- 결제 예정일
- 결제 금액
- 결제 링크 버튼

## 모니터링

Celery 태스크 실행 상태는 로그를 통해 확인할 수 있습니다:

```bash
# Worker 로그 확인
tail -f celery_worker.log

# Beat 로그 확인
tail -f celery_beat.log
```

## 문제 해결

### Redis 연결 오류

```bash
# Redis 서버 상태 확인
redis-cli ping
# 응답: PONG

# Redis 서버 재시작
sudo systemctl restart redis
```

### Celery Worker가 태스크를 받지 못하는 경우

1. Redis 연결 확인
2. Celery Worker 재시작
3. `celery_app.py`의 설정 확인

### 이메일 발송 실패

1. SMTP 설정 확인 (환경 변수)
2. Gmail의 경우 "앱 비밀번호" 사용 필요
3. 방화벽 설정 확인 (포트 587)

## 프로덕션 배포

프로덕션 환경에서는 systemd 서비스로 등록하는 것을 권장합니다:

### 1. systemd 서비스 파일 복사

```bash
# 서비스 파일 복사
sudo cp systemd/celery-worker.service /etc/systemd/system/
sudo cp systemd/celery-beat.service /etc/systemd/system/

# 사용자 이름 확인 및 수정 (필요시)
sudo nano /etc/systemd/system/celery-worker.service
sudo nano /etc/systemd/system/celery-beat.service
```

### 2. 서비스 활성화 및 시작

```bash
# systemd 데몬 재로드
sudo systemctl daemon-reload

# Celery Worker 시작
sudo systemctl enable celery-worker.service
sudo systemctl start celery-worker.service

# Celery Beat 시작
sudo systemctl enable celery-beat.service
sudo systemctl start celery-beat.service
```

### 3. 서비스 상태 확인

```bash
# Worker 상태 확인
sudo systemctl status celery-worker.service

# Beat 상태 확인
sudo systemctl status celery-beat.service

# 로그 확인
sudo journalctl -u celery-worker.service -f
sudo journalctl -u celery-beat.service -f
```

### 4. 서비스 중지/재시작

```bash
# Worker 중지
sudo systemctl stop celery-worker.service

# Worker 재시작
sudo systemctl restart celery-worker.service

# Beat 중지
sudo systemctl stop celery-beat.service

# Beat 재시작
sudo systemctl restart celery-beat.service
```

## 참고 사항

- 결제 링크는 Toss API를 통해 생성되며, 사용자가 링크를 클릭하여 결제를 완료합니다.
- 결제 완료 후 Toss 콜백을 통해 `PaymentHistory` 상태가 업데이트됩니다.
- 결제 실패 시 구독은 자동으로 만료되지 않으며, 관리자가 수동으로 처리해야 합니다.

