본문으로 건너뛰기

패스 스냅샷 적용 정책

스냅샷 기반 정책 적용 시점과 가격/기능 분리 원칙을 정의한다.

문서 정보


1. 개요

1.1 스냅샷 시스템 구조

1.2 정책 관리 방식

중요: 정책 변경은 어드민 UI가 아닌 코드 재배포를 통해 이루어집니다.

단계작업설명
1PASS-POLICY.yml 수정정책 정의 변경
2/sync-pass-policy 실행코드 자동 동기화
3코드 리뷰 & 배포PR → 머지 → 배포
4pnpm db:cli새 스냅샷 DB에 추가

1.3 핵심 원칙

항목적용 시점근거
가격 (priceInGrains/priceInKrw)구매/구독 시점 고정계약 보호, 법적 안정성
기능 (featurePolicy)구매 시점 고정스냅샷 패턴 일관성
멤버십 혜택 (benefitPolicy)항상 최신 적용구독자 혜택 즉시 반영

2. 스냅샷 생성 플로우

2.1 정책 변경 → 스냅샷 생성

2.2 Upcasters 패턴

기존 스냅샷은 DB에서 수정하지 않고, 조회 시점에 최신 스키마로 변환합니다.

// feature-policy.vo.ts
static fromJson(json: JsonValue, policyVersion?: number): FeaturePolicyVO {
const upcastedData = this.upcastToLatest(json, policyVersion ?? this.currentVersion);
return new FeaturePolicyVO(featurePolicySchema.parse(upcastedData));
}

private static upcastToLatest(data: unknown, version: number): unknown {
let current = data;

// v1 → v2: WORKOUT_CONDITION 추가
if (version < 2) {
current = { ...current, WORKOUT_CONDITION: { enabled: false } };
}

return current;
}

3. 정책 적용 규칙

3.1 일반 패스 (건별 구매)

상황참조 스냅샷고정 값
스케줄 예약해당 패스의 예약 시점 최신 PassSnapshotpriceInGrains, featurePolicy

3.2 멤버십 (구독)

상황가격혜택 (benefitPolicy)
구독 신청구독 시점 고정항상 최신 적용
구독 갱신구독 시점 가격 유지항상 최신 적용

가격 고정 이유:

  • 계약 시점의 합의된 가격 보장
  • 환불, 분쟁 시 증빙 자료
  • 법적 안정성 (소비자 보호)

혜택 최신 적용 이유:

  • 구독자에게 즉시 새 기능 제공
  • 서비스 개선 즉시 반영

3.3 기능 정책 조회 방식

// 일반 패스: 구매 시점 featurePolicy
const passSnapshot = userSchedule.passSnapshot;
const featurePolicy = FeaturePolicyVO.fromJson(passSnapshot.featurePolicy, passSnapshot.policyVersion);

// 멤버십: 최신 benefitPolicy
const latestSnapshot = await getLatestMembershipSnapshot(subscription.sourcePlanId);
const benefitPolicy = BenefitPolicyVO.fromJson(latestSnapshot.benefitPolicy, latestSnapshot.policyVersion);

4. featurePolicy vs benefitPolicy

4.1 구분

정책저장 위치적용 시점용도
featurePolicyPassSnapshot구매 시점 고정패스별 기본 기능 (광고, 품질 등)
benefitPolicyPassMembershipSnapshot항상 최신멤버십 전용 혜택 (콕, 마이콕)

4.2 featurePolicy 구조

{
"AD": { "enabled": false },
"SCHEDULE_ALBUM": { "enabled": true },
"CAMERA_TRANSITION_SPEED": { "speed": "FAST" },
"CAMERA_ACCESS": { "type": "UNLIMITED" },
"STREAMING": { "quality": "4K (3840x2160)", "fps": 30 },
"DOWNLOAD": { "quality": "4K (3840x2160)", "fps": 30 },
"WORKOUT_CONDITION": { "enabled": true }
}

4.3 benefitPolicy 구조

{
"kok": { "limit": 30, "periodType": "SCHEDULE" },
"myKok": { "maxCount": 30, "periodType": "MEMBERSHIP" }
}

Note: v1.2.0에서 KOK_VIEW가 featurePolicy에서 benefitPolicy.kok으로 이동됨. 콕 저장/시청은 멤버십 전용 기능입니다.


5. 예외 케이스

주의: 아래 케이스들은 향후 비즈니스/법무 검토 필요

상황고려사항검토 필요 사항
기능 축소 (다운그레이드)정책적으로 금지 권장불가피한 경우 처리 절차, 환불/보상 정책
기능 변경 (동등 교환)사용자 경험 영향 최소화사전 공지 기간, 동의 필요 여부
기능 삭제법적 리스크 존재법무 검토, 대체 기능 제공 의무

6. 관련 코드

파일역할
PASS-POLICY.yml정책 정의 (SSOT)
feature-policy.vo.tsfeaturePolicy Value Object
benefit-policy.vo.tsbenefitPolicy Value Object
reserve-transaction.util.ts예약 시 최신 스냅샷 조회
pass-snapshot-history.seed.ts스냅샷 시드 데이터

변경 이력

버전날짜변경 내용
v3.0.02026-01-20문서 전면 재작성
- TierFeature 관련 내용 제거 (테이블 없음)
- PASS-POLICY.yml 기반 정책 관리 방식 반영
- KOK_VIEW → benefitPolicy.kok 이동 반영
- featurePolicy vs benefitPolicy 구분 추가
- 멤버십 혜택 "항상 최신" 적용 명시
v2.9.02025-12-29Pass → Pass 마이그레이션
v2.3.02025-12-21기능 정책도 구매 시점 고정으로 변경
v1.0.02025-12-03초기 문서 작성