활동 보상 시스템 (Activity Reward System)
문서 정보
- 작성일: 2026-02-27
- 최종 업데이트: 2026-02-27
- 버전: v1.0.0
TL;DR
사용자의 활동(콕 시청, 운동 컨디션 기록, 광고 시청)에 대해 Rules Engine이 DB에 저장된 규칙을 평가하여 보상(리워드 적립, 카메라 잠금 해제)을 자동 지급하는 시스템입니다. 규칙 변경 시 코드 수정 없이 DB만 수정하면 됩니다.
목차
- 핵심 개념
- 활동 유형과 보상
- Rules Engine 아키텍처
- 자격 조건 (Eligibility)
- 제한 설정 (Limits)
- MembershipRewardCounter
- 활동별 상세 플로우
- Google AdMob SSV 연동
- 카메라 잠금 해제
- 데이터 모델
- FAQ
핵심 개념
한 줄 요약
사용자가 활동을 하면, Rules Engine이 규칙을 평가하여 보상을 지급한다.
핵심 용어
| 용어 | 설명 |
|---|---|
| 활동 (Activity) | 사용자의 행동. 콕 시청, 운동 컨디션 기록, 광고 시청 등 |
| 규칙 (Rule) | "누가, 무엇을 하면, 어떤 보상을, 얼마나 받을 수 있는지" 정의한 설정 |
| Rules Engine | 규칙을 평가하고 보상 지급을 결정하는 핵심 엔진 |
| 리워드 | 활동 보상으로 적립되는 포인 트 (서비스 내 재화) |
| 카메라 잠금 해제 | FREE 사용자가 광고 시청 후 PLUS 전용 카메라에 접근하는 것 |
| 멱등성 (Idempotency) | 같은 활동을 여러 번 요청해도 보상이 한 번만 지급되는 안전장치 |
설계 철학
- 분리된 구조: 콕, 운동 컨디션 등 핵심 서비스는 보상 로직을 모릅니다. 이벤트만 발행하고, 보상 시스템이 처리합니다.
- 유연한 규칙: 자격 조건, 보상 금액, 제한 등을 코드 수정 없이 DB 설정으로 변경할 수 있습니다.
- 감사 추적: 모든 활동과 보상 결과가 기록되어 추적이 가능합니다.
활동 유형과 보상
시스템이 지원하는 4가지 활동과 해당 보상입니다.
| 활동 유형 | 트리거 | 보상 | 대상 | 제한 |
|---|---|---|---|---|
| 콕 시청 (KOK_WATCH) | 콕 시청 완료 시 | 리워드 5 적립 | PLUS 구독자 | 50% 확률, 구독 주기당 240회 |
| 운동 컨디션 (WORKOUT_CONDITION) | 컨디션 기록 시 | 리워드 5 적립 | PLUS 패스 보유자 | 스케줄당 1회 |
| 광고 시청 (AD_WATCH) | 광고 시청 완료 시 | 카메라 잠금 해제 | FREE 사용자 | 제한 없음 |
| Google 광고 (GOOGLE_AD) | Google 리워드 광고 시청 시 | 리워드 5 적립 | PLUS 구독자 | 일 50회, 쿨다운 7분 |
콕 시청의 확률 적용 시점
콕 시청 보상의 50% 확률은 콕 생성 시점에 미리 결정됩니다 (isPointEligible 필드). 시청 시점이 아닌 생성 시점에 결정하여, 어떤 콕이 보상 대상인지 사전에 공정하게 배분합니다.
Rules Engine 아키텍처
Rules Engine은 사용자 활동이 발생할 때 다음 순서로 보상 여부를 판별합니다.
각 단계 설명
| 단계 | 이름 | 설명 |
|---|---|---|
| 1 | 규칙 매칭 | 활동 유형에 맞는 활성화된 규칙을 DB에서 조회합 니다 |
| 2 | 멱등성 체크 | 동일 활동에 대한 중복 보상을 방지합니다 (멱등성 키 기반) |
| 3 | 자격 검증 | 사용자의 멤버십, 패스 타입이 규칙의 자격 조건을 만족하는지 확인합니다 |
| 4 | 제한 확인 | 일별, 구독 주기별 등 보상 횟수 제한을 초과하지 않았는지 확인합니다 |
| 5 | 확률 검사 | 확률 기반 보상인 경우 랜덤 체크를 수행합니다 (기본값 100%) |
| 6 | 보상 지급 | 리워드 적립 또는 카메라 잠금 해제를 실행합니다 |
모든 결과는 기록됩니다
보상이 지급되든 거부되든, 모든 결과는 ActivityRecord에 기록됩니다. 이를 통해 "왜 보상을 못 받았는지" 추적이 가능합니다.
자격 조건 (Eligibility)
규칙마다 누가 보상을 받을 수 있는지 자격 조건이 JSON으로 정의되어 있습니다.
자격 조건 필드
| 필드 | 설명 | 예시 |
|---|---|---|
membershipTypes | 필요한 멤버십 타입 | ["PLUS"] |
passTypes | 허용되는 패스 타입 | ["PLUS"] 또는 ["FREE"] |
requiresActiveSubscription | 보상 청구 시점에 활성 구독 필요 여부 | true / false |
규칙별 자격 조건
| 규칙 | 멤버십 필요? | 패스 타입 | 설명 |
|---|---|---|---|
| 콕 시청 리워드 | PLUS 구독 필수 | PLUS | 구독 중인 PLUS 멤버십 사용자만 |
| 운동 컨디션 리워드 | 불필요 | PLUS | PLUS 패스(단건 구매 포함) 보유자 |
| 광고 카메라 해제 | 불필요 | FREE | FREE 사용자만 (PLUS는 이미 전체 접근 가능) |
| Google 광고 리워드 | PLUS 구독 필수 | - | PLUS 구독 중인 사용자만 |
패스 타입별 접근 권한 요약
| 기능 | FREE | PLUS 패스 (단건) | PLUS 멤버십 (구독) |
|---|---|---|---|
| 카메라 접근 | 일부만 (광고 시청으로 해제) | 전체 | 전체 |
| 콕 시청 리워드 | X | X | O (50%, 240회/주기) |
| 운동 컨디션 리워드 | X | O | O |
| Google 광고 리워드 | X | X | O (일 50회) |
제한 설정 (Limits)
보상의 과도한 지급을 막기 위해 규칙별로 제한이 설정됩니다.
제한 유형
| 제한 유형 | 설명 | 사용 예시 |
|---|---|---|
daily | 하루 최대 보상 횟수 | Google 광고: 일 50회 |
monthly | 월 최대 보상 횟수 | (현재 미사용) |
perMembershipCycle | 구독 주기당 최대 보상 횟수 | 콕 시청: 주기당 240회 |
perSchedule | 스케줄당 최대 보상 횟수 | 운동 컨디션: 스케줄당 1회 |
cooldownSeconds | 보상 간 최소 대기 시간(초) | Google 광고: 420초 (7분) |
현재 규칙별 제한 설정
| 규칙 | 제한 | 값 |
|---|---|---|
| 콕 시청 리워드 | 구독 주기당 | 240회 |
| 운동 컨디션 리워드 | 스케줄당 | 1회 (멱등성으로 보장) |
| 광고 카메라 해제 | 없음 | - |
| Google 광고 리워드 | 일일 + 쿨다운 | 50회/일 + 420초 간격 |
MembershipRewardCounter
구독 주기(Billing Cycle) 기반으로 보상 횟수를 추적하는 카운터입니다. 콕 시청 리워드의 "주기당 240회" 제한을 관리합니다.
동작 방식
카운터 주요 필드
| 필드 | 설명 |
|---|---|
currentCount | 현재 주기 내 보상 횟수 |
maxCount | 최대 허용 횟수 (240) |
accumulatedAmount | 현재 주기 내 누적 리워드 금액 |
cycleStartDate / cycleEndDate | 구독 주기 시작/종료일 |
subscriptionId | 연결된 구독 ID |
주기 관리 규칙
- 새 구독 주기 시작 시:
currentCount와accumulatedAmount가 0으로 초기화됩니다 - 구독 환불 시: 카운터가 삭제됩니다 (Hard Delete)
- 카운터는 기존 레코드를 업데이트: 주기별로 새 레코드를 만들지 않고, 기존 레코드의 주기 정보를 갱신합니다
예상 결제 금액 계산
콕 시청 리워드 응답에는 cycleSummary가 포함됩니다. 여기에는 estimatedPayment (예상 결제 금액)이 있으며, 이는 구독 가격 - 적립된 리워드 잔액으로 계산됩니다. 사용자에게 "리워드를 더 모으면 결제 금액이 줄어든다"는 동기부여를 제공합니다.