제3장 — 구독 분리 + ★ G9 PASSED
RLS 정책 + 마감 D-1 알림 + 인증 흐름 5 시나리오 + 첫 구독자 환경 완전 준비
📋 이 챕터의 목차
권4 제2장에서 ★ ⭐ E5 8 규칙 모두 완성. 누적 286.5h, 2주 누적 (1+2주차) 45h. 이번 챕터 = 구독 상태별 RLS 분리 + 마감 D-1 알림 시스템 + ★ G9 PASSED.
작업 (4h)
[Claude Code, Sonnet + medium]
"구독 상태별 콘텐츠 분리 — RLS (Row Level Security) 정책 적용.
요구사항:
1. supabase/migrations/0012_rls_subscriptions.sql:
- articles 테이블 RLS 정책:
· STAT·OBSERVER: 모든 사용자 SELECT 가능
· COACH·INSIDER: 활성 구독자만 SELECT 가능
- subscriptions 테이블 RLS:
· 자기 user_id 의 subscription만 SELECT
- 정책 함수: is_active_subscriber(user_id UUID)
2. ⚖️ Position C 보호 (구독 상태와 무관 일관):
- 모든 사용자 (무료·구독자) 에게 4자리 동일 노출
- 구독 유도 페이지에도 ⚖️ E1 메시지 일관
3. Next.js API routes 정책:
- GET /api/articles — 구독 상태 확인 후 페르소나 필터
- GET /api/match/{id} — 구독자: 4 페르소나, 무료: 2 페르소나
- 무료 사용자 COACH·INSIDER 접근 시 → 401 + 구독 유도 redirect
4. tests/rls-isolation.test.ts (130줄):
- 무료 사용자 → STAT·OBSERVER 접근 PASS
- 무료 사용자 → COACH 접근 → 401 차단
- 구독자 → 4 페르소나 모두 PASS
- 다른 사용자의 subscription 접근 → 차단"- 0012_rls_subscriptions.sql 적용 ✅
- articles 테이블 RLS 정책 (구독 상태별) ✅
- rls-isolation.test.ts 4 시나리오 통과 ✅
- 시뮬 사용자 5명 (무료 3 + 구독자 2):
- 무료 → STAT·OBSERVER 노출 ✅
- 무료 → COACH·INSIDER 차단 ✅
- 구독자 → 4 페르소나 모두 노출 ✅
근거: API route 우회 시 (예: 다른 클라이언트로 직접 DB 호출) 보안 빈틈 가능. RLS = DB 보장 = 모든 entry point 일관 차단
대안: 애플리케이션 레벨 차단만 — 우회 위험
결과: RLS 정책 복잡도 증가 (검수 부담), 그러나 보안 가치 큼
작업 (4h)
[Claude Code, Sonnet + medium]
"마감 D-1 알림 시스템 — 구독자 혜택.
요구사항:
1. 알림 시스템 설계:
- 무료 사용자: 마감 D-1 알림 X (또는 일 1건 제한)
- 구독자: 마감 D-1 알림 무제한 + 신규 매칭 즉시 알림 + 상세 통계 알림
2. 알림 채널 (3 옵션):
- 이메일 (모든 사용자)
- 브라우저 push notification (Phase 1.2 시점, 옵션)
- 모바일 앱 push (Phase 2.0 옵션)
→ Phase 1.2 = 이메일 + 브라우저 push
3. workers/src/notifications.rs (90줄):
- 매일 03:30 UTC cron (cron 발행 후 30분 후)
- 다음 24시간 안 경기 → 구독자 user_id 별 알림 발송
- 발송 이력 notifications 테이블 INSERT
4. supabase/migrations/0013_notifications.sql:
- notifications 테이블:
· id, user_id, match_id, channel, sent_at, status
5. ⚖️ E1 알림 메시지 일관:
- "EPL 맨시티 vs 첼시 D-1 — TSV 4 페르소나 분석 보기"
- 베팅·픽 추천 표현 제외 (Position C 일관)"근거: 구독 가치 차별화 의무. 무료 알림 = 구독 가치 약화 = 전환율 하락. Phase 1.2 KPI 5% 전환율 목표 달성 위해 의식적 차별화.
대안: 무료 사용자 알림 일 1건 — 구독 가치 약화 위험 (Day 121 G9 시점 검토)
결과: 무료 사용자 "알림 없음" 인식 → 구독 유도 페이지 "알림" 강조 메시지
작업 (4h)
[Claude Code, Sonnet + medium]
"사용자 인증 흐름 최종 종합 검증.
요구사항:
1. 가입 → 구독 → 콘텐츠 노출 → 결제 실패 → 갱신 → 취소 시나리오 종합 검증:
[시나리오 1] 첫 가입
- 이메일 OAuth → users INSERT → 첫 사용자 페이지 노출 (STAT·OBSERVER)
[시나리오 2] 구독 결제
- Stripe Checkout → subscriptions INSERT (active) → 4 페르소나 노출
+ 광고 제거 + 알림 활성화
[시나리오 3] 결제 실패
- 다음 달 결제 카드 만료 → invoice.payment_failed → 알림 + 7일 유예
- 7일 후 status canceled → 4 페르소나 잠금
[시나리오 4] 갱신
- Stripe 자동 갱신 → invoice.payment_succeeded → 활성 유지
[시나리오 5] 자발적 취소
- 구독자 취소 → 현재 기간 끝까지 노출 → period_end 후 잠금
2. tests/auth-flow-end-to-end.test.ts (180줄, 5 시나리오)
3. 인증 흐름 자동화 cron (Day 113 작업):
- 매일 03:45 UTC subscriptions status 점검
- period_end < NOW + 7d 인 active → 갱신 알림"- tests/auth-flow-end-to-end.test.ts (180줄) 작성 ✅
- 5 시나리오 모두 통과 ✅
- 인증 흐름 자동화 cron 등록 (Day 113 작업) ✅
근거: 카드 만료·일시적 결제 실패 = 실제 자주 발생. 즉시 차단 시 의도하지 않은 이탈 증가. 7일 유예 + 갱신 알림 = 구독자 신뢰 보호
대안: 즉시 차단 — 운영자 관점 단순, 사용자 관점 손상
결과: 7일 동안 결제 없는 사용자 무료 노출 (수용 가능)
## Phase 1.2 Day 112 — ★ 토요일 작업 X ★ [E2 의식] - 토요일 X (권4 3주차) - cron 결과 5분 점검만 [자동 cron Day 102~112 누적 결과] ✓ 4 페르소나 일 평균 76 articles 발행 ✓ 자동 일관성 100% (5 차원 검증, 11일 무사고) ✓ supremacy 차단 hit 0건 ✓ ⚖️ Position C 다층 보호 62일 무사고 ✓ Sentry crash-free 100%
G9 통과 조건 (PLAN v4.0)
[기능 통과 조건] [ ] Stripe 통합 5 시나리오 통과 ✅ Day 100 [ ] 4 페르소나 시스템 완성 ✅ Day 102 [ ] 4 페르소나 자동 일관성 5 차원 검증 ✅ Day 104 [ ] ⭐ E5 [8] supremacy 차단 ✅ Day 105 [ ] RLS 정책 (구독 상태별) ✅ Day 109 [ ] 마감 D-1 알림 시스템 ✅ Day 110 [ ] 사용자 인증 흐름 최종 5 시나리오 ✅ Day 111 [ ] 첫 구독자 환경 완전 prep ✅ [★ 페이스 점검 (E2)] [ ] 3주 누적: 24+21+21.5 = 66.5h ⚠️ R4 60h 트리거 6.5h 초과 [ ] 토요일 X (Day 99·106·112 모두) ✅ [ ] 매주 회고 (3주 모두) ✅ [ ] 4주차 (Day 116~121) 휴식 + ★ Day 121 12개월 강화 의무 [★ 통과 의식 (E2)] [ ] git tag v0.3-G9-passed [ ] Day 116~120 휴식 + Day 121 12개월 강화 (★ 세 번째)
Day 113 점검: 8/8 기능 통과 조건 모두 PASS ✅ + 페이스 ⚠️ → 4주차 휴식 + 페이스 보호 결정
Day 114 점검 보강: 4 페르소나 통합 7일 운영 검증 (Day 102~108):
- 일 평균 76 articles ✅
- 자동 일관성 100% ✅
- supremacy 차단 hit 0건 ✅
- ⚖️ Position C 다층 보호 7일 추가 무사고 (누적 64일) ✅
- Sonnet 비용 7일: $13.65 (월 추정 $58.50) ✅
근거: G9 통과 (Day 115) + 4주 누적 R4 트리거 + 12개월 강화 (Day 121 = 매월 마지막 주 1일) = 5일 휴식 (R4 안전 회복)
대안: 1일 휴식만 — R4 누적 위험
결과: 권4 4주차 (Day 116~121) 산출물 거의 없음 (수용)
G9 통과 의식
git tag v0.3-G9-passed git push origin v0.3-G9-passed
## Phase 1.2 Day 115 — ★ G9 PASSED ★ [기능 통과 조건] 8/8 PASS ✅ [페이스 점검] 3주 누적 66.5h ⚠️ → 4주차 휴식 보호 [git tag] v0.3-G9-passed ✅ ### 산출물 (Day 109·110·111·113·114, 5일 작업) 1. 0012_rls_subscriptions.sql (80줄, RLS 정책) 2. workers/src/notifications.rs (90줄, 마감 D-1 알림) 3. 0013_notifications.sql (40줄) 4. tests/rls-isolation.test.ts (130줄, 4 시나리오) 5. tests/auth-flow-end-to-end.test.ts (180줄, 5 시나리오) 총: 5 파일 + 2 SQL migration + 9 시나리오 자동 검증 ### Phase 1.2 첫 구독자 환경 완전 prep ✅ | 영역 | 상태 | |------|------| | Stripe 통합 (5 시나리오) | ✅ | | 4 페르소나 시스템 (8 규칙) | ✅ | | RLS 정책 (DB 레벨 보장) | ✅ | | 마감 D-1 알림 (구독자 혜택) | ✅ | | 인증 흐름 (5 시나리오) | ✅ | | ⚖️ Position C 일관 (모든 자리) | ✅ | | 자동 일관성 5 차원 + supremacy | ✅ | [누적] 306.5h + Day 115 (1.5h G9 의식 + 회고) = 308h [E2] 4주차 휴식 + Day 121 12개월 강화
| 영역 | 상태 |
|---|---|
| Stripe 통합 (5 시나리오) | ✅ |
| 4 페르소나 시스템 (8 규칙) | ✅ |
| RLS 정책 (DB 레벨 보장) | ✅ |
| 마감 D-1 알림 (구독자 혜택) | ✅ |
| 인증 흐름 (5 시나리오) | ✅ |
| ⚖️ Position C 일관 (모든 자리) | ✅ |
| 자동 일관성 5 차원 + supremacy 차단 | ✅ |
git add SPEC.md PLAN.md \ supabase/migrations/0012_rls_subscriptions.sql 0013_notifications.sql \ workers/src/notifications.rs \ tests/rls-isolation.test.ts tests/auth-flow-end-to-end.test.ts git commit -m "Phase 1.2 Day 109~115: ★ G9 PASSED + RLS + 알림 + 인증 + 첫 구독자 환경 완전 prep"
이번 챕터까지 누적 자동 검증 시나리오:
| 영역 | 시나리오 수 | 작동 시점 |
|---|---|---|
| Stripe 통합 | 5 | Day 100 |
| 자동 일관성 (4 페르소나) | 5 | Day 104 |
| supremacy 차단 | 5 | Day 105 |
| RLS 정책 | 4 | Day 109 |
| 인증 흐름 | 5 | Day 111 |
| 합계 | 24 시나리오 | — |
★ 24 시나리오 자동 검증 = 첫 구독자 도달 시점 사고 방지 깊이 보장 ✅
| 자리 | 줍줍 (Phase 2 시점) | TSV (3탄 권4 3주차, 본 장) |
|---|---|---|
| 3주차 핵심 | 구독 분리 (RLS) + Stripe webhook | 구독 분리 (RLS) + 알림 + 첫 구독자 prep |
| RLS 적용 시점 | Phase 2 도입 | ★ Phase 1.2 (TSV 더 빠름) |
| 알림 시스템 | (Phase 2 이후 검토) | ★ 마감 D-1 알림 (Phase 1.2) |
| 자동 검증 시나리오 | 약 12~15 | 24 (TSV 더 깊음) |
구조 일관 ✅ + TSV 특수 (Phase 1.2 시점에 모든 prep 완성).
📘 권4 제3장 정리
핵심 한 줄: Day 109~115 = RLS + 알림 + 인증 + ★ G9 PASSED + 첫 구독자 환경 완전 prep ✅.
- 3주차 산출물 (5 파일 + 2 SQL): RLS 정책 / 마감 D-1 알림 시스템 / 인증 흐름 5 시나리오 / 14 시나리오 자동 검증 (총 24 누적)
- ★ G9 PASSED — Phase 1.2 첫 게이트: 8/8 기능 통과 + 첫 구독자 환경 완전 prep ✅
- ★ 누적 자동 검증 24 시나리오: Stripe 5 + 자동 일관성 5 + supremacy 5 + RLS 4 + 인증 5
- 누적: 308h / 3주 누적 66.5h ⚠️ → 4주차 5일 휴식
- 다음 장: 권4 제4장 — Day 116~121 (★ 5일 휴식 + Day 121 12개월 강화 세 번째)
★ G9 PASSED — Phase 1.2 첫 게이트 통과.
★ 24 시나리오 자동 검증 = 시리즈 누적 안전망 깊이 ✅. 1탄 v2 메타 원칙 "한 안전망 부족, 두 개 결합" 이 "12개 결합" 의 입증. Stripe 5 + 자동 일관성 5 + supremacy 5 + RLS 4 + 인증 5 = 첫 구독자 도달 시점 사고 방지 깊이 보장.
★ RLS DB 레벨 보장 = 권1 제3장 ⚖️ E1 결정 ② 의 "코드 + DB 이중 보장" 본문 입증. 애플리케이션 우회 시도가 DB 레벨에서 차단됩니다.
★ 마감 D-1 알림 = 구독 가치의 차별화. SPEC v5.0 §6 의 5% 전환율 가설 보호.
다음 장에서 4주차 (Day 116~121) — 5일 휴식 + ★ Day 121 12개월 강화 의식 세 번째. R4 자동 회복 사이클 + 12개월 강화 누적 의식의 안정성 깊이 입증.