# AI Service 데이터베이스 설계서

## 📋 데이터설계 요약

### 서비스 특성
- **서비스명**: AI Service
- **아키텍처**: Clean Architecture
- **데이터 저장소**: Redis Cache Only (PostgreSQL 미사용)
- **특징**: Stateless 서비스, AI API 결과 캐싱 전략

### 데이터 구조 개요
AI Service는 외부 AI API(Claude)와 연동하여 이벤트 추천을 생성하는 서비스로, 영속적인 데이터 저장이 필요하지 않습니다. 모든 데이터는 Redis 캐시를 통해 임시 저장되며, TTL 만료 시 자동 삭제됩니다.

| 캐시 키 패턴 | 용도 | TTL | 데이터 형식 |
|------------|------|-----|-----------|
| `ai:recommendation:{eventId}` | AI 추천 결과 | 1시간 | JSON (AIRecommendationResult) |
| `ai:job:status:{jobId}` | AI 작업 상태 | 24시간 | JSON (JobStatusResponse) |
| `ai:trend:{industry}:{region}` | 트렌드 분석 결과 | 24시간 | JSON (TrendAnalysis) |

### 설계 근거
1. **Stateless 설계**: AI 추천은 요청 시마다 실시간 생성되므로 영속화 불필요
2. **성능 최적화**: 동일한 조건의 반복 요청에 대한 캐시 히트율 향상
3. **비용 절감**: AI API 호출 비용 절감을 위한 캐싱 전략
4. **TTL 관리**: 추천의 시의성 유지를 위한 적절한 TTL 설정

---

## 1. 캐시 데이터베이스 설계 (Redis)

### 1.1 AI 추천 결과 캐시

**캐시 키**: `ai:recommendation:{eventId}`

**TTL**: 3600초 (1시간)

**데이터 구조**:
```json
{
  "eventId": "uuid-string",
  "trendAnalysis": {
    "industryTrends": [
      {
        "keyword": "string",
        "relevance": 0.95,
        "description": "string"
      }
    ],
    "regionalTrends": [...],
    "seasonalTrends": [...]
  },
  "recommendations": [
    {
      "optionNumber": 1,
      "concept": "string",
      "title": "string",
      "description": "string",
      "targetAudience": "string",
      "duration": {
        "recommendedDays": 7,
        "recommendedPeriod": "주중"
      },
      "mechanics": {
        "type": "DISCOUNT",
        "details": "string"
      },
      "promotionChannels": ["string"],
      "estimatedCost": {
        "min": 500000,
        "max": 1000000,
        "breakdown": {
          "promotion": 300000,
          "gift": 500000
        }
      },
      "expectedMetrics": {
        "newCustomers": {
          "min": 50.0,
          "max": 100.0
        },
        "revenueIncrease": {
          "min": 10.0,
          "max": 20.0
        },
        "roi": {
          "min": 150.0,
          "max": 250.0
        }
      },
      "differentiator": "string"
    }
  ],
  "generatedAt": "2025-10-29T10:00:00",
  "expiresAt": "2025-10-29T11:00:00",
  "aiProvider": "CLAUDE"
}
```

**용도**: AI 추천 결과를 캐싱하여 동일한 이벤트에 대한 반복 요청 시 AI API 호출 생략

**캐싱 전략**:
- Cache-Aside 패턴
- 캐시 미스 시 AI API 호출 후 결과 저장
- TTL 만료 시 자동 삭제하여 최신 트렌드 반영

---

### 1.2 작업 상태 캐시

**캐시 키**: `ai:job:status:{jobId}`

**TTL**: 86400초 (24시간)

**데이터 구조**:
```json
{
  "jobId": "uuid-string",
  "status": "PROCESSING",
  "progress": 50,
  "message": "트렌드 분석 중...",
  "createdAt": "2025-10-29T10:00:00"
}
```

**상태 값**:
- `PENDING`: 작업 대기 중
- `PROCESSING`: 작업 진행 중
- `COMPLETED`: 작업 완료
- `FAILED`: 작업 실패

**용도**: 비동기 AI 작업의 상태를 추적하여 클라이언트가 진행 상황 확인

**캐싱 전략**:
- Write-Through 패턴
- 상태 변경 시 즉시 캐시 업데이트
- 완료/실패 후 24시간 동안 상태 조회 가능

---

### 1.3 트렌드 분석 캐시

**캐시 키**: `ai:trend:{industry}:{region}`

**TTL**: 86400초 (24시간)

**데이터 구조**:
```json
{
  "industryTrends": [
    {
      "keyword": "친환경",
      "relevance": 0.95,
      "description": "지속가능성과 환경 보호에 대한 관심 증가"
    }
  ],
  "regionalTrends": [
    {
      "keyword": "로컬 맛집",
      "relevance": 0.88,
      "description": "지역 특산물과 전통 음식에 대한 관심"
    }
  ],
  "seasonalTrends": [
    {
      "keyword": "겨울 따뜻함",
      "relevance": 0.82,
      "description": "추운 날씨에 따뜻한 음식 선호"
    }
  ]
}
```

**용도**: 업종 및 지역별 트렌드 분석 결과를 캐싱하여 AI API 호출 최소화

**캐싱 전략**:
- Cache-Aside 패턴
- 동일 업종/지역 조합에 대한 반복 분석 방지
- 하루 단위 TTL로 최신 트렌드 유지

---

## 2. Redis 데이터 구조 설계

### 2.1 Redis 키 명명 규칙

```
ai:recommendation:{eventId}        # AI 추천 결과
ai:job:status:{jobId}              # 작업 상태
ai:trend:{industry}:{region}       # 트렌드 분석
```

### 2.2 Redis 설정

```yaml
# application.yml
spring:
  redis:
    host: ${REDIS_HOST:localhost}
    port: ${REDIS_PORT:6379}
    password: ${REDIS_PASSWORD:}
    timeout: 3000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 2
        max-wait: -1ms

# 캐시 TTL 설정
cache:
  ttl:
    recommendation: 3600    # 1시간
    job-status: 86400      # 24시간
    trend: 86400           # 24시간
```

### 2.3 캐시 동시성 제어

**Distributed Lock**:
- Redis의 SETNX 명령을 사용한 분산 락
- 동일한 이벤트에 대한 중복 AI 호출 방지

```java
// 예시: Redisson을 사용한 분산 락
RLock lock = redisson.getLock("ai:lock:event:" + eventId);
try {
    if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
        // AI API 호출 및 캐시 저장
    }
} finally {
    lock.unlock();
}
```

---

## 3. 캐시 무효화 전략

### 3.1 TTL 기반 자동 만료

| 캐시 타입 | TTL | 만료 이유 |
|----------|-----|----------|
| 추천 결과 | 1시간 | 트렌드 변화 반영 필요 |
| 작업 상태 | 24시간 | 작업 완료 후 장기 보관 불필요 |
| 트렌드 분석 | 24시간 | 일간 트렌드 변화 반영 |

### 3.2 수동 무효화 트리거

- **이벤트 삭제 시**: 해당 이벤트의 추천 캐시 삭제
- **시스템 업데이트 시**: 전체 캐시 초기화 (관리자 기능)

---

## 4. 성능 최적화 전략

### 4.1 캐시 히트율 최적화

**목표 캐시 히트율**: 70% 이상

**최적화 방안**:
1. **프리페칭**: 인기 업종/지역 조합의 트렌드를 사전 캐싱
2. **지능형 TTL**: 접근 빈도에 따른 동적 TTL 조정
3. **Warm-up**: 서비스 시작 시 주요 데이터 사전 로딩

### 4.2 메모리 효율성

**예상 메모리 사용량**:
- 추천 결과: ~50KB/건
- 작업 상태: ~1KB/건
- 트렌드 분석: ~10KB/건

**메모리 관리**:
- 최대 메모리 제한: 1GB
- 만료 정책: volatile-lru (TTL이 있는 키만 LRU 제거)

---

## 5. 모니터링 지표

### 5.1 캐시 성능 지표

| 지표 | 목표 | 측정 방법 |
|------|------|----------|
| 캐시 히트율 | ≥70% | (hits / (hits + misses)) × 100 |
| 평균 응답 시간 | <50ms | Redis 명령 실행 시간 측정 |
| 메모리 사용률 | <80% | used_memory / maxmemory |
| 키 개수 | <100,000 | DBSIZE 명령 |

### 5.2 알림 임계값

- 캐시 히트율 < 50%: 경고
- 메모리 사용률 > 80%: 경고
- 평균 응답 시간 > 100ms: 경고
- Redis 연결 실패: 심각

---

## 6. 재해 복구 전략

### 6.1 데이터 손실 대응

**특성**: 캐시 데이터는 손실되어도 서비스 정상 동작
- Redis 장애 시 AI API 직접 호출로 대체
- Circuit Breaker 패턴으로 장애 격리
- Fallback 메커니즘으로 기본 추천 제공

### 6.2 Redis 고가용성

**구성**: Redis Sentinel 또는 Cluster
- Master-Slave 복제
- 자동 Failover
- 읽기 부하 분산

---

## 7. 보안 고려사항

### 7.1 데이터 보호

- **네트워크 암호화**: TLS/SSL 연결
- **인증**: Redis PASSWORD 설정
- **접근 제어**: Redis ACL을 통한 명령 제한

### 7.2 민감 정보 처리

- AI API 키: 환경 변수로 관리 (캐시 저장 금지)
- 개인정보: 캐시에 저장하지 않음 (이벤트 ID만 사용)

---

## 8. 결론

AI Service는 **완전한 Stateless 아키텍처**를 채택하여 Redis 캐시만을 사용합니다. 이는 다음과 같은 장점을 제공합니다:

✅ **확장성**: 서버 인스턴스 추가 시 상태 동기화 불필요
✅ **성능**: AI API 호출 비용 절감 및 응답 시간 단축
✅ **단순성**: 데이터베이스 스키마 관리 부담 제거
✅ **유연성**: 캐시 정책 변경 시 서비스 재시작 불필요

**PostgreSQL 미사용 이유**:
- AI 추천은 실시간 생성 데이터로 영속화 가치 낮음
- 이력 관리는 Analytics Service에서 담당
- 캐시 TTL로 데이터 신선도 보장

**다음 단계**: Redis 클러스터 구성 및 모니터링 대시보드 설정
