절기 미션 추천 아키텍처

희운·2026년 4월 6일

절기별 미션 추천 서비스 - 시스템 아키텍처

1. 시스템 개요

절기가 변경될 때마다 사용자에게 미션을 제공하고 알림을 발송하는 시스템

1.1 미션 유형

유형설명대상
오늘의 미션큐레이터 픽, 관리자가 미리 지정모든 유저 공통
개인화 미션온보딩 데이터 기반 추천유저별 맞춤

1.2 핵심 설계 원칙 (MVP)

  • 오늘의 미션: 관리자가 절기별 15일치 사전 지정 (수동 큐레이션)
  • 개인화 미션: 태그 기반 매칭 (45개 미션 풀)
  • LLM: 미션 생성 보조 (LLM이 리스트 생성 → 관리자가 선별)
  • 날씨 API: MVP 제외 → 2차 고도화

2. 전체 아키텍처

2.1 MVP 아키텍처

┌─────────────────────────────────────────────────────────────────────────────┐
│                                                                             │
│                        ┌─────────────────────┐                              │
│                        │      Client App     │                              │
│                        │   (iOS / Android)   │                              │
│                        └──────────┬──────────┘                              │
│                                   │                                         │
│                                   ▼                                         │
│                        ┌─────────────────────┐                              │
│                        │    Load Balancer    │                              │
│                        │      (Nginx)        │                              │
│                        └──────────┬──────────┘                              │
│                                   │                                         │
│                 ┌─────────────────┼─────────────────┐                       │
│                 ▼                 ▼                 ▼                       │
│       ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                  │
│       │  API Server  │  │  API Server  │  │ Admin Server │                  │
│       │  (Spring)    │  │  (Spring)    │  │  (Spring)    │                  │
│       └───────┬──────┘  └───────┬──────┘  └───────┬──────┘                  │
│               │                 │                 │                         │
│               └─────────────────┼─────────────────┘                         │
│                                 │                                           │
│         ┌───────────────────────┼───────────────────────┐                   │
│         ▼                       ▼                       ▼                   │
│  ┌─────────────┐        ┌─────────────┐        ┌──────────────┐             │
│  │    MySQL    │        │    Redis    │        │   LLM API    │             │
│  │  (Main DB)  │        │  (Cache)    │        │ (Claude/GPT) │             │
│  └─────────────┘        └─────────────┘        └──────────────┘             │
│                                                       ↑                     │
│                                                       │                     │
│                                              Admin Server에서 호출           │
│                                              (미션 생성 보조용)              │
│                                                                             │
│  ┌──────────────────────────────────────────────────────────────┐           │
│  │                      Scheduler (Batch)                       │           │
│  │                                                              │           │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │           │
│  │  │ 오늘의미션  │  │ 절기 체크   │  │ 알림 발송   │          │           │
│  │  │ 활성화 Job  │  │ Job        │  │ Job        │          │           │
│  │  └─────────────┘  └─────────────┘  └─────────────┘          │           │
│  └──────────────────────────────────────────────────────────────┘           │
│                                 │                                           │
│                                 ▼                                           │
│                        ┌──────────────┐                                     │
│                        │  FCM / APNs  │                                     │
│                        │ (Push 알림)  │                                     │
│                        └──────────────┘                                     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

2.2 2차 고도화 아키텍처 (추가 요소)

┌─────────────────────────────────────────────────────────────────┐
│                     2차 고도화 시 추가                           │
│                                                                 │
│   ┌─────────────┐                                               │
│   │ Weather API │                                               │
│   │ (날씨 조회) │                                               │
│   └──────┬──────┘                                               │
│          │                                                      │
│          ▼                                                      │
│   ┌─────────────────────────────────────────┐                  │
│   │            Scheduler 추가 Job            │                  │
│   │  - WeatherCheckJob (06:00)              │                  │
│   │  - 날씨 기반 미션 자동 교체              │                  │
│   └─────────────────────────────────────────┘                  │
└─────────────────────────────────────────────────────────────────┘

3. 핵심 프로세스

3.1 Phase 1: 미션 사전 준비 (관리자 작업)

LLM으로 미션 리스트 생성 → 관리자가 선별/검수 → DB 저장

┌─────────────────────────────────────────────────────────────────┐
│                      Admin Server Flow                          │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                 1. LLM으로 미션 리스트 생성               │   │
│  │                                                          │   │
│  │   관리자가 절기 + 조건 입력                               │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │ "청명 절기에 맞는 미션 50개 생성해줘"            │   │   │
│  │   │ "조건: 날씨에 덜 민감하고, 감성적인 미션"        │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                          │                               │   │
│  │                          ▼                               │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │              LLM API 호출                        │   │   │
│  │   │         (Claude / GPT 등)                       │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                          │                               │   │
│  │                          ▼                               │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │           미션 후보 리스트 50개 반환             │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│                           ▼                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                  2. 관리자 선별/검수                     │   │
│  │                                                          │   │
│  │   LLM이 생성한 50개 중 45개 선별                         │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │ [✓] 맑은 하늘 아래 심호흡하기                    │   │   │
│  │   │ [✓] 봄 향기 느끼기                              │   │   │
│  │   │ [✗] 벚꽃 축제 가기        ← 날씨 민감, 제외     │   │   │
│  │   │ [✓] 제철 음식 먹어보기                          │   │   │
│  │   │ ...                                             │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                          │   │
│  │   - 부적절한 미션 삭제                                   │   │
│  │   - 미션 문구 수정                                       │   │
│  │   - 태그 부여 (장소/활동/강도)                           │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│                           ▼                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │               3. 오늘의 미션 스케줄 지정                 │   │
│  │                                                          │   │
│  │   선별된 45개 중 15개를 오늘의 미션으로 지정             │   │
│  │   ┌──────┬─────────────────────────┐                    │   │
│  │   │ 날짜 │ 오늘의 미션              │                    │   │
│  │   ├──────┼─────────────────────────┤                    │   │
│  │   │ 4/4  │ 맑은 하늘 아래 심호흡    │                    │   │
│  │   │ 4/5  │ 봄 향기 느끼기           │                    │   │
│  │   │ ...  │ ...                     │                    │   │
│  │   └──────┴─────────────────────────┘                    │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│                           ▼                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                     4. DB 저장                           │   │
│  │                                                          │   │
│  │   - Mission 테이블: 미션 풀 (45개)                       │   │
│  │   - MissionTag 테이블: 태그 정보                         │   │
│  │   - DailyMissionSchedule 테이블: 오늘의 미션 스케줄      │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

미션 선별 가이드라인:

원칙설명예시
날씨 무관실내/실외 모두 가능"봄 향기 느끼기" (창문 열어도 OK)
감성 중심행위보다 감각/경험"초록색 찾아 사진 찍기"
재사용 가능매년 사용 가능한 형태"제철 음식 먹어보기"

3.2 Phase 2: 오늘의 미션 활성화 (매일 00:00)

┌─────────────────────────────────────────────────────────────────┐
│                  Daily Mission Scheduler Flow                   │
│                                                                 │
│  ┌───────────────┐                                              │
│  │ 매일 00:00    │                                              │
│  │ DailyMission  │                                              │
│  │ ActivateJob   │                                              │
│  └───────┬───────┘                                              │
│          │                                                      │
│          ▼                                                      │
│  ┌───────────────────────────────────────────┐                  │
│  │ 1. DailyMissionSchedule에서 오늘 날짜 조회 │                  │
│  │ 2. 해당 미션을 "오늘의 미션"으로 활성화    │                  │
│  │ 3. Redis 캐시 갱신                        │                  │
│  └───────────────────────────────────────────┘                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

3.3 Phase 3: 절기 변경 감지 및 알림 발송

┌─────────────────────────────────────────────────────────────────┐
│                   Solar Term Scheduler Flow                     │
│                                                                 │
│  ┌───────────────┐                                              │
│  │ 매일 00:00    │                                              │
│  │ SolarTermCheck│                                              │
│  │ Job           │                                              │
│  └───────┬───────┘                                              │
│          │                                                      │
│          ▼                                                      │
│  ┌───────────────┐     NO                                       │
│  │ 오늘 = 절기   │ ──────────→ 종료                             │
│  │ 시작일?      │                                               │
│  └───────┬───────┘                                              │
│          │ YES                                                  │
│          ▼                                                      │
│  ┌───────────────────────────────────────────┐                  │
│  │ 절기 변경 알림 발송                        │                  │
│  │                                           │                  │
│  │ "청명이 시작됐어요! 새로운 미션을 확인하세요" │                  │
│  └───────────────────────────────────────────┘                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

3.4 Phase 4: 개인화 미션 조회 (실시간)

┌─────────────────────────────────────────────────────────────────┐
│              Personalized Mission Recommendation                │
│                                                                 │
│  ┌─────────┐         ┌─────────────────────────────────────┐   │
│  │ Client  │ ──────→ │           API Server                │   │
│  │ 요청    │ GET     │                                     │   │
│  │         │/missions│  1. 사용자 온보딩 태그 조회          │   │
│  └─────────┘         │  2. 현재 절기 미션 풀 조회           │   │
│                      │  3. 태그 매칭 점수 계산              │   │
│                      │  4. 이미 완료/스킵한 미션 제외       │   │
│                      │  5. 상위 N개 반환                   │   │
│                      └─────────────────────────────────────┘   │
│                                                                 │
│  [태그 매칭 로직]                                               │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ score = 0                                               │   │
│  │ if (user.location == mission.location) score += 2       │   │
│  │ if (user.activity == mission.activity) score += 3       │   │
│  │ if (user.intensity == mission.intensity) score += 1     │   │
│  │ return missions.sortByScore().limit(N)                  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4. 미션 제공 구조

4.1 화면별 미션 구성

┌─────────────────────────────────────────────────────────────────┐
│                        메인 화면                                │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              오늘의 미션 (큐레이터 픽)                    │   │
│  │                                                          │   │
│  │   "맑은 하늘 아래 심호흡하기"                             │   │
│  │                                                          │   │
│  │   - 모든 유저 동일                                       │   │
│  │   - 관리자가 미리 지정한 미션                            │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              개인화 미션 (A/B 테스트)                     │   │
│  │                                                          │   │
│  │   [A안] 리스트로 여러 개                                  │   │
│  │   ┌─────────────────────────────────────┐               │   │
│  │   │ - 봄나물 비빔밥 만들기               │               │   │
│  │   │ - 창문 열고 환기하기                 │               │   │
│  │   │ - 산책하며 새소리 듣기               │               │   │
│  │   └─────────────────────────────────────┘               │   │
│  │                                                          │   │
│  │   [B안] 1개 + 새로고침                                   │   │
│  │   ┌─────────────────────────────────────┐               │   │
│  │   │ 봄나물 비빔밥 만들기          🔄    │               │   │
│  │   └─────────────────────────────────────┘               │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.2 미션 데이터 흐름

┌───────────────────────────────────────────────────────────────────────────┐
│                           미션 데이터 흐름                                 │
│                                                                           │
│  [사전 준비]                              [실시간]                         │
│                                                                           │
│  ┌──────────┐                                                            │
│  │  LLM     │                                                            │
│  │  API     │                                                            │
│  └────┬─────┘                                                            │
│       │ 미션 후보 50개 생성                                               │
│       ▼                                                                   │
│  ┌──────────┐                                                            │
│  │ 관리자   │                                                            │
│  │ 선별/검수│                                                            │
│  └────┬─────┘                                                            │
│       │ 45개 선정 + 태그 부여                                             │
│       ▼                                                                   │
│  ┌──────────┐                                                            │
│  │ Mission  │                                                            │
│  │ 테이블   │                                                            │
│  │ (풀)     │                                                            │
│  └────┬─────┘                                                            │
│       │                                                                   │
│       ├────────────────┐                                                  │
│       │                ▼                                                  │
│       │         ┌───────────────┐                                        │
│       │         │ DailyMission  │                                        │
│       │         │ Schedule      │                                        │
│       │         │ (15일치 지정) │                                        │
│       │         └───────┬───────┘                                        │
│       │                 │                                                 │
│       │                 │ 매일 00:00                                      │
│       │                 ▼                                                 │
│       │         ┌───────────────┐      ┌──────────┐                      │
│       │         │ 오늘의 미션   │ ───→ │ 모든유저 │                      │
│       │         │ 활성화        │      └──────────┘                      │
│       │         └───────────────┘                                        │
│       │                                                                   │
│       │ 사용자 요청 시                                                    │
│       ▼                                                                   │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────┐                    │
│  │ 태그 매칭    │ ─→ │ 개인화 미션  │ ─→ │ 해당유저 │                    │
│  │ (실시간)     │    │ 추천         │    └──────────┘                    │
│  └──────────────┘    └──────────────┘                                    │
│                                                                           │
└───────────────────────────────────────────────────────────────────────────┘

5. 서버 구성

5.1 API Server

역할설명
사용자 인증JWT 기반 인증/인가
오늘의 미션 조회당일 활성화된 미션 반환
개인화 미션 조회태그 매칭 기반 실시간 추천
미션 완료/스킵상태 업데이트
알림 조회인앱 알림 목록

5.2 Admin Server

역할설명
LLM 연동미션 후보 리스트 생성 요청
미션 관리미션 선별/검수, CRUD
태그 관리미션별 태그 설정
스케줄 관리오늘의 미션 일정 지정
통계 조회미션 완료율 등

5.3 Scheduler (Batch Server)

Job실행 시점역할
DailyMissionActivateJob매일 00:00오늘의 미션 활성화
SolarTermCheckJob매일 00:00절기 변경 여부 확인
NotificationJob절기 변경 시절기 시작 알림 발송
MissionReminderJob매일 09:00미완료 미션 리마인드 (선택)

6. 데이터 모델

6.1 핵심 테이블

-- 미션 풀
CREATE TABLE mission (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    description TEXT,
    solar_term VARCHAR(20),          -- 절기 (청명, 곡우 등)
    season VARCHAR(20),              -- 계절 (봄, 여름 등)
    status ENUM('DRAFT', 'ACTIVE') DEFAULT 'DRAFT',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 미션 태그 (개인화 매칭용)
CREATE TABLE mission_tag (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    mission_id BIGINT NOT NULL,
    tag_category VARCHAR(50),        -- location, activity, intensity
    tag_value VARCHAR(50),           -- indoor/outdoor, cooking/exercise, light/active
    FOREIGN KEY (mission_id) REFERENCES mission(id)
);

-- 오늘의 미션 스케줄 (관리자 지정)
CREATE TABLE daily_mission_schedule (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    solar_term VARCHAR(20) NOT NULL,
    target_date DATE NOT NULL,       -- 노출 날짜
    mission_id BIGINT NOT NULL,
    created_by BIGINT,               -- 지정한 관리자
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (mission_id) REFERENCES mission(id),
    UNIQUE KEY (target_date)
);

-- 사용자 온보딩 프로필
CREATE TABLE user_profile (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    location_pref VARCHAR(20),       -- indoor / outdoor / both
    activity_pref VARCHAR(50),       -- cooking / exercise / culture / rest
    intensity_pref VARCHAR(20),      -- light / moderate / active
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES user(id)
);

-- 사용자 미션 이력
CREATE TABLE user_mission (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    mission_id BIGINT NOT NULL,
    mission_type ENUM('DAILY', 'PERSONALIZED'),
    status ENUM('RECOMMENDED', 'COMPLETED', 'SKIPPED'),
    recommended_at TIMESTAMP,
    completed_at TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES user(id),
    FOREIGN KEY (mission_id) REFERENCES mission(id)
);

-- 절기 정보
CREATE TABLE solar_term (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,       -- 청명, 곡우 등
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    season VARCHAR(20),              -- 봄, 여름 등
    year INT NOT NULL
);

6.2 태그 체계

카테고리설명
locationindoor실내
outdoor실외
both무관
activityfood음식/요리
nature자연/산책
culture문화/감상
exercise운동
rest휴식
intensitylight가벼움
moderate보통
active활발

7. API 목록

7.1 Client API

MethodEndpoint설명
GET/api/missions/today오늘의 미션 조회
GET/api/missions/personalized개인화 미션 목록
GET/api/missions/personalized/refresh개인화 미션 새로고침 (B안)
POST/api/missions/{id}/complete미션 완료
POST/api/missions/{id}/skip미션 스킵
GET/api/solar-terms/current현재 절기 정보
GET/api/notifications알림 목록

7.2 Admin API

MethodEndpoint설명
POST/admin/missions/generateLLM으로 미션 후보 생성
GET/admin/missions/candidates생성된 미션 후보 목록
POST/admin/missions/approve미션 선별/승인
PUT/admin/missions/{id}미션 수정
DELETE/admin/missions/{id}미션 삭제
POST/admin/daily-schedule오늘의 미션 스케줄 지정

8. 타임라인

┌───────────────────────────────────────────────────────────────────────────┐
│                              운영 타임라인                                 │
│                                                                           │
│  [절기 시작 전 - 관리자 작업]                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐ │
│  │ 1. Admin에서 LLM 호출 → 미션 후보 50개 생성                         │ │
│  │ 2. 관리자가 선별/검수 → 45개 확정                                   │ │
│  │ 3. 태그 부여 (장소/활동/강도)                                       │ │
│  │ 4. 오늘의 미션 15일치 스케줄 지정                                   │ │
│  │                                                                     │ │
│  │ ※ 1년치 한번에 작업 가능 (24절기 × 45개 = 1,080개)                 │ │
│  │ ※ 이후 매년 재사용 (필요시 일부 수정)                               │ │
│  └─────────────────────────────────────────────────────────────────────┘ │
│                                                                           │
│  [매일 00:00]                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐ │
│  │ 1. 오늘의 미션 활성화 (DailyMissionActivateJob)                     │ │
│  │ 2. 절기 변경 체크 (SolarTermCheckJob)                               │ │
│  │    → 변경 시 푸시 알림 발송                                         │ │
│  └─────────────────────────────────────────────────────────────────────┘ │
│                                                                           │
│  [사용자 앱 실행 시]                                                      │
│  ┌─────────────────────────────────────────────────────────────────────┐ │
│  │ 1. 오늘의 미션 조회 (캐시)                                          │ │
│  │ 2. 개인화 미션 조회 (실시간 태그 매칭)                               │ │
│  └─────────────────────────────────────────────────────────────────────┘ │
│                                                                           │
└───────────────────────────────────────────────────────────────────────────┘

9. 기술 스택

영역기술용도
API ServerSpring Boot 3.xREST API
Admin ServerSpring Boot 3.x관리자 기능
SchedulerSpring Scheduler배치 처리
DatabaseMySQL 8.0메인 데이터 저장
CacheRedis오늘의 미션 캐싱, 세션
LLMClaude API / OpenAI미션 생성 보조 (Admin에서 사용)
PushFCM / APNs모바일 푸시 알림
InfraAWS (EC2, RDS, ElastiCache)클라우드
CI/CDGitHub Actions + Docker배포 자동화
MonitoringGrafana + Prometheus + Loki모니터링

10. 장애 대응

상황대응 방안
스케줄러 장애오늘의 미션 활성화 안 됨 → 수동 트리거 API 제공
오늘의 미션 없음스케줄 미지정 → 전날 미션 유지 or 기본 미션
LLM API 장애미션 생성 불가 → 이전 절기 미션 복사 후 수정
FCM 장애실패 건 별도 저장 → 재발송 배치
DB 장애Read Replica 활용, Redis 캐시

11. 2차 고도화 계획

기능설명우선순위
날씨 API 연동비 오면 실내 미션으로 자동 교체높음
A/B 테스트 결과 반영개인화 미션 노출 방식 확정높음
미션 이력 기반 추천완료/스킵 패턴 학습낮음

11.1 날씨 연동 시 변경 사항

┌─────────────────────────────────────────────────────────────────┐
│                      날씨 연동 추가 시                           │
│                                                                 │
│  [테이블 추가]                                                   │
│  - mission_tag에 weather 카테고리 추가 (sunny/rainy/all)        │
│  - daily_mission_schedule에 fallback_mission_id 추가           │
│                                                                 │
│  [스케줄러 추가]                                                 │
│  - WeatherCheckJob (06:00)                                     │
│    → 날씨 API 조회 → Redis 캐싱                                 │
│    → 비 예보 시 오늘의 미션 자동 교체                            │
│                                                                 │
│  [개인화 미션 로직 수정]                                         │
│  - 태그 매칭 시 날씨 태그도 고려                                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

12. 결정된 사항

항목결정
오늘의 미션 방식LLM 생성 → 관리자 선별 (수동 큐레이션)
LLM 활용MVP에서 사용 (미션 생성 보조)
날씨 APIMVP 제외 → 2차
개인화 미션 노출A/B 테스트로 결정
미션 풀 크기절기당 45개 (LLM 50개 생성 → 45개 선별)

13. 미결 사항 (TBD)

항목선택지현재 상태
예상 사용자 수1천 / 1만 / 10만+미정
알림 발송 시점오전 / 점심 / 사용자 설정미정
개인화 미션 개수A안 3~5개 / B안 1개A/B 테스트
A/B 테스트 비율50:50 / 70:30미정
LLM 서비스 선택Claude / GPT / 기타미정
profile
기록하는 공간

0개의 댓글