📑 이 챕터에서 다룰 내용
- 들어가며 — Phase 1.0 마무리 직전
- 5-1. Day 22 — SEO 구조 (canonical + 페르소나별 키워드)
- 5-2. Day 23 — Sentry 통합 + crash-free rate 측정
- 5-3. Day 24 — ⚖️ Position C 콘텐츠 면책 (E1 1차)
- 5-4. Day 25 — ⚖️ Cloudflare WAF 5룰
- 5-5. Day 26 — 토요일 작업 X 의식
- 5-6. Day 27 — G4 점검
- 5-7. Day 28 — G4 PASSED + 12개월 강화 의식
- 5-8. 두 도메인 권2 4주차 비교
- 📌 챕터 정리
권2 제4장에서 ★ R4 자동 회복 사이클 + G3 PASSED를 달성했습니다. 누적 72.5h. 이번 챕터는 G4 통과 + ⚖️ E1 외부 노출 1차 + ★ 12개월 강화 1 의식 (TSV 신규)를 다룹니다.
권1 제6장 R4에서 "줍줍 5 의식 + TSV 12개월 강화 1 의식 = 매월 마지막 주 1일 추가 휴식"이라고 박혔어요.
Day 28 (4주차 끝)이 첫 적용 자리입니다. 줍줍 (73일)에는 없는 TSV (12개월) 특유의 안전망이에요.
| 사전 지식 체크 | 이 장의 목적 | 완료 후 결과물 |
|---|---|---|
| Day 15~21 / G3 PASSED / 페이스 정상 복귀 4h/일 / SPEC v4.1 §4 [3] Sentry + ⚖️ Position C 외부 노출 4자리 | Day 22 (SEO) → Day 28 G4 PASSED + 12개월 강화 1 의식. ⚖️ E1 콘텐츠 면책 1차 + Cloudflare WAF + Sentry 7일 관측 | SEO 구조 + Sentry + Footer + ContentDisclaimer + WAF 5룰 + git tag v0.1-G4-passed + 12개월 강화 휴식 |
작업 (4h, 페이스 정상 복귀)
[Claude Code, Sonnet + medium]
"SEO 구조 — canonical URL + 페르소나별 키워드 분리.
요구사항:
1. Next.js 동적 라우트:
- /matches/{match_id} (메인 — 두 페르소나 link)
- /matches/{match_id}/stat (STAT 글)
- /matches/{match_id}/observer (OBSERVER 글)
2. canonical URL 메타 태그:
- 각 페르소나 페이지에 <link rel='canonical' href='...stat'> 명시
- 같은 경기 두 페르소나 글이 SEO 카니발리제이션 X 보장
3. 페르소나별 SEO 키워드 분리 (articles.seo_keywords):
- STAT 키워드: '통계 분석', '데이터로 보는', 'xG 분석'
- OBSERVER 키워드: '경기 관전 포인트', '한 시각으로'
4. sitemap.xml 자동 생성 (articles 누적 100건+ 시점)"
- ✓ Next.js 라우트 3종 (메인 / stat / observer)
- ✓ canonical URL 메타 자동 생성 (각 페이지)
- ✓ 페르소나별 SEO 키워드 분리 (Day 17~ v2 articles 적용)
- ✓ sitemap.xml 첫 생성 (110건 articles)
## Phase 1.0 Day 22
[실행]
- Next.js 동적 라우트 3종
- canonical URL 메타 태그
- 페르소나별 SEO 키워드 분리 (Day 17~ v2 적용)
- sitemap.xml 자동 생성 (110건)
[LogOnTable 트레이스 — canonical URL의 SEO 보호]
> 결정: 각 페르소나 페이지가 자기 자신을 canonical 명시
> 근거: 권1 제2장 Gemini 발견 4 (SEO 카니발리제이션 방지). 같은
경기 두 페르소나 글이 같은 키워드 경쟁 시 둘 다 순위 ↓ →
키워드 분리 + canonical 분리 = SEO 의도 보호.
> 대안: 메인 페이지 canonical — 두 페르소나 글이 검색 노출 X
> 부작용: 두 페르소나 글이 다른 SEO 키워드로 분리 노출 → SEO 효율 ×2
[누적] 72.5h + Day 22 (4h) = 76.5h
[E2] 4주차 페이스 정상 복귀 (4h/일)
작업 (4h)
[Claude Code] "Sentry 통합 — REVIEW 75분 패치 P2 + Day 14 PLAN 보강 적용. 요구사항: 1. Rust workers — sentry crate 통합 2. Next.js — @sentry/nextjs SDK 3. Sentry 그룹화 룰 4개: - 'llm-classification' (Sonnet 호출 실패) - 'db-error' (DB INSERT/UPDATE 실패) - 'api-fetch' (TheSportsDB 호출 실패) - 'cron-pause' (cron_pause 발동 시 자동 보고) 4. Slack 통합 (Critical 에러) 5. crash-free rate 측정 시작 (Day 23~ 7일 관측) 6. SENTRY_DSN .env.local"
## Phase 1.0 Day 23
[실행]
- workers Cargo.toml: sentry = "0.34" 추가
- Next.js: @sentry/nextjs 설치
- Sentry 그룹화 룰 4개
- Slack alert webhook 통합
- ★ Day 23 자정부터 7일 관측 시작 (Day 30 까지)
[LogOnTable 트레이스 — crash-free rate 측정 분모]
> 결정: cron 실행 + LLM 호출 + DB INSERT 합산 (Critical 에러만)
> 근거: 권1 제4장 G-5 발견. SPEC v4.1 §5 KPI 명시:
"crash = 사용자 영향이 있는 에러". cron_pause 자동 회복 X일 때.
> 대안: 모든 에러 (warning 포함) — crash-free rate 99% 달성 어려움
> 부작용: warning 추세 모니터링 의무 (증가 시 critical 신호)
[누적] 76.5h + Day 23 (4h) = 80.5h
권1 제3장에서 박힌 Position C 5 차원 결정의 외부 노출 4자리 중 첫 번째입니다.
- About 페이지 — 권3 (Phase 1.1) 출시 직전
- 약관 §3 — 권3
- Footer (모든 페이지) — ★ 이번 일자 (Day 24) 1차
- 콘텐츠 면책 (각 페르소나 글 하단) — ★ 이번 일자 (Day 24) 1차
작업 (4h)
[Claude Code, Sonnet + medium]
"⚖️ E1 Position C 외부 노출 1차 — Footer + 콘텐츠 면책.
요구사항:
1. components/Footer.tsx (모든 페이지 하단):
본 메시지 (CLAUDE.md §5 [5] 일관):
'본 서비스는 분석 콘텐츠 미디어. 베팅·픽 추천 X.
| About | 약관 | 개인정보'
(About·약관·개인정보 placeholder만, 권3 본격)
2. components/ContentDisclaimer.tsx (각 페르소나 글 하단):
'본 분석은 통계·전술적 시각이며, 베팅·픽 추천 X.
승리 단정 X / 외부 베팅 사이트 link X.'
3. CLAUDE.md §5 [5] 절대 준수 — 모든 자리 같은 메시지
4. CLAUDE.md §3 절대 준수 — '픽' / '확률 N%' / '승리 단정' 표현 X
5. About·약관·개인정보 placeholder 첫 줄 일관 메시지"
Claude (Sonnet)가 작성한 components/Footer.tsx
// components/Footer.tsx — ⚖️ E1 [5] Position C 1차
import Link from 'next/link';
export function Footer() {
return (
<footer className="px-4 py-3 border-t border-gray-200 bg-gray-50">
<p className="text-xs text-gray-500 text-center mb-2">
본 서비스는 분석 콘텐츠 미디어. 베팅·픽 추천 X.
</p>
<div className="flex justify-center gap-4">
<Link href="/about" className="text-xs text-gray-600 underline">
About
</Link>
<Link href="/terms" className="text-xs text-gray-600 underline">
약관
</Link>
<Link href="/privacy" className="text-xs text-gray-600 underline">
개인정보
</Link>
</div>
</footer>
);
}
components/ContentDisclaimer.tsx
// components/ContentDisclaimer.tsx — ⚖️ E1 [5] 콘텐츠 면책
export function ContentDisclaimer() {
return (
<div className="mt-8 p-3 bg-yellow-50 border border-yellow-200
rounded text-xs text-gray-600">
⚠️ 본 분석은 통계·전술적 시각이며, 베팅·픽 추천이 아닙니다.
승리 단정·외부 베팅 사이트 link·배당률 변환을 하지 않습니다.
각 페르소나의 분석 시각이 모두 유효하며, 다관점 = 본 서비스 본질입니다.
</div>
);
}
## Phase 1.0 Day 24
[실행]
- components/Footer.tsx (50줄)
- components/ContentDisclaimer.tsx (40줄)
- src/app/(legal)/about·terms·privacy.tsx (placeholder 3종)
- 모든 페이지 자동 적용 (RootLayout)
- 각 페르소나 글 하단 ContentDisclaimer 자동
[LogOnTable 트레이스 — ⚖️ E1 외부 노출 1차의 본질]
> 결정: Day 24 = Footer + ContentDisclaimer. About·약관·개인정보
placeholder 첫 줄 일관 메시지. 본격 페이지는 권3 (Phase 1.1)
> 근거: 사용자가 화면 첫 만지는 시점부터 ⚖️ Position C 노출 의무.
권1 제3장 단계 ④ 변호 논리 사실 성립을 위해 4자리 일관 시작.
> 대안: Phase 1.1 본격까지 미적용 — 사용자 노출 시점부터 미적용 = 위험
> 부작용: About·약관·개인정보 placeholder 미완성 (Day 32 본격) →
사용자 클릭 시 "준비 중" 노출. 그러나 핵심 메시지 박혔음.
[누적] 80.5h + Day 24 (4h) = 84.5h
작업 (4h)
[룰 1] DDoS 방어 (rate limit per IP) - 1분당 60 req 초과 시 차단 - 정상 사용자 분당 10 req 미만 → 영향 X [룰 2] 악성 봇 차단 - User-Agent 빈 또는 악성 패턴 차단 - 정상 봇 (Googlebot·Bingbot) 허용 [룰 3] ⚖️ Position C 보호 — query parameter 주입 차단 - URL에 'odds=' 'pick=' 'bet=' parameter 포함 시 차단 - 외부에서 의도적 우회 시도 차단 [룰 4] 베팅 referrer 차단 - Referrer가 베팅 사이트 도메인일 때 차단 (대표 30개 도메인) - TSV가 베팅 사이트 트래픽 우회 X 보호 [룰 5] SQL injection 패턴 차단 - URL/body에 'OR 1=1' 'UNION SELECT' 등 패턴 차단
- ✓ /matches/123?odds=1.5 → 차단 ✅ (룰 3)
- ✓ 봇 User-Agent 'python-requests/2.x' → 차단 ✅ (룰 2)
- ✓ /api/search?q=' OR 1=1-- → 차단 ✅ (룰 5)
- ✓ 정상 사용자 영향 X (3 시나리오 시뮬 통과)
권1 제3장 단계 ② 배제 5가지의 코드 보장입니다. 외부 사이트가 odds=1.5 parameter로 우회 시도할 때 차단 = 변호 논리 사실 성립이에요.
정확한 정규식 (?<=^|&|\?)(odds|pick|bet)=으로 parameter 형식만 차단하여 글 본문의 "odds 분석" 같은 표현은 영향을 받지 않습니다.
## Phase 1.0 Day 25 [실행] - Cloudflare 대시보드 5 룰 적용 - 각 룰 trigger Slack 알림 통합 - 3 시뮬 테스트 모두 통과 [누적] 84.5h + Day 25 (4h) = 88.5h
## Phase 1.0 Day 26 — ★ 토요일 작업 X ★ [E2 의식] - 토요일 작업 X (Day 5·12·19·26 일관) - 자동 cron 5분 점검만 [자동 cron 4주차 누적 검증] ✓ Day 23~25 cron 무사고 (cron_pause 0회) ✓ Sentry 4일 관측 (Day 23~26): Critical 0건, Warning 1건 (자동 retry) ✓ articles 누적: Day 14 70 + Day 17~25 90 = 160건 [누적] 88.5h (Day 26 변동 없음)
G4 통과 조건 (PLAN v2.2)
[기능 통과 조건]
- SEO 구조 (canonical + 페르소나별 키워드) ✅ Day 22
- Sentry 통합 + crash-free rate 측정 ✅ Day 23
- ⚖️ Position C 콘텐츠 면책 (Footer + Disclaimer) ✅ Day 24
- Cloudflare WAF 5 룰 ✅ Day 25
- Sentry 7일 무장애 관측 (Day 23~Day 29) — Day 27 시점 5일째 진행
- 자동 일관성 + 톤 키워드 이중 검증 4주 무사고 ✅ Day 8~26
[페이스 점검 (E2)]
- 4주 누적 (1+2+3+4): 18+23.5+11+~21 = 73.5h ⚠️ 60h 초과 13.5h
- 토요일 X (4주 모두) ✅
- 매주 회고 (4주 모두) ✅
- R4 자동 회복 사이클 작동 (Day 14 트리거) ✅
4주 누적 73.5h는 R4 60h 트리거를 13.5h 초과했어요.
권1 제6장 R4 12개월 강화 (매월 마지막 주 1일 추가) 발동 조건 충족 → Day 28~29 1.5일 휴식 의무
줍줍 R4 5 의식 + TSV 12개월 강화 = 6 의식. Day 28이 12개월 강화 첫 본격 등장 자리입니다.
## Phase 1.0 Day 27
[실행]
- G4 기능 5/6 PASS (Sentry 7일 자연 진행)
- 4주 누적 73.5h ⚠️ → ★ Day 28~29 1.5일 휴식 의무
[LogOnTable 트레이스 — ★ 12개월 강화 의식 첫 적용]
> 결정: Day 28~29 1.5일 휴식 (G4 의식 + 12개월 강화 의식 통합)
> 근거: 권1 제6장 R4 12개월 강화 (매월 마지막 주 1일 추가). Day 28
(4주차 끝) = 첫 적용 자리. 4주 누적 73.5h 초과도 보호.
> 대안: G4 의식 1일만 — 4주 누적 13.5h 초과 미해결 위험
> 부작용: 5주차 (Day 30~36) 페이스 보호 의무 (3.5h/일 검토)
[줍줍에 없는 TSV 신규 의식]
- 줍줍 R4: 5 의식
- TSV R4: 5 의식 + 12개월 강화 1 의식 = 6 의식
- Day 28 = 12개월 강화 첫 등장 자리
[누적] 88.5h + Day 27 (4h) = 92.5h
git tag v0.1-G4-passed git push origin v0.1-G4-passed
4주 회고 + 12개월 강화 의식
## Phase 1.0 Day 28 — ★ G4 PASSED + ★ 12개월 강화 의식 ★ [기능 통과 조건] 5/6 PASS + 1 자연 진행 [페이스 점검] 4주 누적 73.5h ⚠️ → ★ 1.5일 휴식 의무 [git tag] v0.1-G4-passed ✅ --- ## 4주 회고 (Day 22~28) ### 산출물 (Day 22~25, 4 파일) 1. SEO 구조 (Next.js 동적 라우트 + canonical) — 부수 변경 2. Sentry 통합 (workers + Next.js) 3. components/Footer.tsx (50줄) 4. components/ContentDisclaimer.tsx (40줄) 5. src/app/(legal)/ 3 placeholder 6. Cloudflare WAF 5룰 ### 5확장 운영 단계 (이번 4주차) - ⚖️ E1: ★ 외부 노출 1차 (Footer + ContentDisclaimer) - ★ E2: ★ 12개월 강화 1 의식 (Day 28~29 1.5일 휴식) - E3: G-5 (Sentry 측정 분모) + G-6 (WAF 룰) - E4: 4주차 = 7 트레이스 → 누적 ~39 - E5 [5] 1차 시작 (Footer + Disclaimer + placeholder 일관) [누적] 92.5h + Day 28 (1.5h G4 의식 + 회고) = 94h [E2] R4 12개월 강화 첫 본격 → 5주차 페이스 보호
E2 12개월 강화 의식 — 줍줍 vs TSV 비교
| 의식 | 줍줍 (5 의식) | TSV (6 의식) |
|---|---|---|
| 1. 게이트 통과 휴식 | ✅ | ✅ |
| 2. 60h+/4주 추가 휴식 | ✅ | ✅ |
| 3. 토요일 X | ✅ | ✅ |
| 4. 일요일 회고 | ✅ | ✅ |
| 5. "피곤하다" 트리거 | ✅ | ✅ |
| 6. 12개월 강화 | (없음) | ★ Day 28 첫 등장 |
git add BUILD.md git commit -m "Phase 1.0 Day 28: ★ G4 PASSED + ★ 12개월 강화 1 의식 (TSV 신규)"
| 항목 | 줍줍 (2탄 v2 권2 4주차) | TSV (3탄 v2 권2 4주차) |
|---|---|---|
| 4주차 핵심 | 통합 테스트 + G2 통과 | SEO + Sentry + ⚖️ E1 1차 + G4 |
| ⚖️ E1 외부 노출 | (Phase 1.0 절반 시점, 미적용) | ★ Day 24 1차 |
| 페이스 의식 | 60h 트리거 보호 | ★ 12개월 강화 1 의식 (TSV 신규) |
| 4주 누적 | 약 70h | 73.5h |
| 4주차 LogOnTable | ~7 트레이스 | ~7 트레이스 |
구조적 일관성 ✅ — 두 도메인 모두 4주차에 7 LogOnTable 트레이스, 게이트 통과 의식, 토요일 X 일관 유지.
TSV 특수성 — ⚖️ E1 외부 노출 1차가 더 빠르게 등장하고, 12개월 강화 의식이 신규 추가됩니다.
- 1️⃣ 핵심 한 줄: Day 22~28 = SEO + Sentry + ⚖️ E1 1차 + Cloudflare WAF + G4 PASSED + 12개월 강화 1 의식
- 2️⃣ 4주차 산출물: SEO 구조 / Sentry 통합 / Footer.tsx + ContentDisclaimer.tsx / legal placeholder 3종 / WAF 5룰
- 3️⃣ ⚖️ E1 외부 노출 1차: Footer (모든 페이지) + ContentDisclaimer (각 페르소나 글) — 변호 논리 사실 성립 토대
- 4️⃣ ★ 12개월 강화 의식: Day 28 (4주차 끝) 첫 등장 — 줍줍 5 의식 → TSV 6 의식 (12개월 강화 추가)
- 5️⃣ 누적: 94h / 4주 누적 73.5h ⚠️ 12개월 강화 자동 보호
- 6️⃣ 다음 장: 권2 제6장 — Day 29~36 (G5 FINAL + Phase 1.0 종합 회고 + Phase 1.1 진입 결정)
권1 제6장에서 박힌 "12개월 운영 보호"가 코드 + 운영 데이터로 입증됩니다.
⚖️ E1 외부 노출 1차도 의미 있는 자리 — 권1 제3장 Position C 5 차원 결정이 Footer + ContentDisclaimer에 일관 메시지로 박혔어요.
다음 장: 권2 제6장 — Phase 1.0 마지막 (G5 FINAL + Phase 1.0 종합 회고 + Phase 1.1 진입 결정)