- Plans.md: 203행 → 140행. Phase 0-6 완료 이력을 .claude/archive/plans-phase0-6.md 로 분리 - Phase 7 title 에서 'Tailwind' 제거 - 7A 재작성: pdf-parse + 정규식 텍스트 파싱 파이프라인 (국어/영어/한국사/생활과윤리 4과목) + Passage 모델(공통지문), needsReview flag, 8 ProblemSet × ~240문항 MVP - 7C 재작성: Tailwind 도입 취소. theme.ts 토큰 확장 + styled-components primitives 증축 + Phosphor React + Inter/JetBrains Mono next/font + Toast 컴포넌트 - 기술 결정 D1/D2/D3 확정 반영 (사용자 컨펌) - 수학/과탐은 Phase 8 별도 트랙 (이미지 crop 또는 Vision API)
6.3 KiB
6.3 KiB
ReLoop v2 — QA Plan
Harness v3 Breezing 모드로 전체 QA를 실행한다. 구현 자체는 이전 세션에서 완료됐고, 이 Plans.md는 검증 태스크만 다룬다. 각 QA 태스크는 정적 분석/리포트 작성이며 파일 수정은 원칙적으로 하지 않는다 (findings 수집 단계). Critical/major finding은 Phase C에서 별도 fix 태스크로 재티켓화한다.
Context
- Repo:
/home/erang/reloop-v2(backend: NestJS+Prisma, frontend: Next.js 14 + styled-components) - Plan 원본:
/home/erang/reloop-v2-plan/PLAN.md - Deploy target:
reloop.nabomhalang.co.kr/reloop-api.nabomhalang.co.kr(Dev VM PM2) - Persona forgetting curve:
S(t)=S₀·exp(-λt),P=σ(k(S(t)−D)), λ∈{0.1,0.2,0.4,0.6} - Node modules 미설치 — runtime 검증은 Phase C에서 Dev VM에서만 가능
Tasks
| Task | 내용 | DoD | Depends | Status |
|---|---|---|---|---|
| QA-1 | Backend API contract audit | APPROVE (minor 2) | - | cc:완료 [40232af] |
| QA-2 | Persona forget algorithm verification | APPROVE (minor 2) | - | cc:완료 [40232af] |
| QA-3 | Auth & security review | REQUEST_CHANGES (crit 2, maj 2) | - | cc:완료 [40232af] |
| QA-4 | Frontend runtime bug scan | REQUEST_CHANGES (crit 2, maj 2) | - | cc:완료 [40232af] |
| QA-5 | Prisma schema & transaction integrity | REQUEST_CHANGES (crit 2, maj 2) | - | cc:완료 [40232af] |
| QA-6 | Build & deploy readiness | REQUEST_CHANGES (crit 4, maj 3) | - | cc:완료 [40232af] |
Fix tasks (QA follow-up — Breezing Wave 2)
QA 리포트의 critical/major를 5개 Cluster로 묶어 병렬 Worker로 수정했다. 각 Cluster는 독립 commit.
| Cluster | 내용 | DoD | Depends | Status |
|---|---|---|---|---|
| A | QA-5.C1 reviews.submit() 전체 tx + QA-5.M1 iteration in tx + QA-5 skip() race + QA-4.C1 review page per-item lock | 동일 reviewId 동시 submit/skip 시 ConflictException. iteration 경쟁 제거. 프론트 버튼 per-review 잠금 | C | cc:완료 [bc5e14e] |
| B | QA-3.C1 email normalize + QA-3.C2 JwtStrategy DB re-fetch + QA-3.M1 JWT_SECRET required + QA-3.M2 forbidNonWhitelisted=true | register/login email trim().toLowerCase(). validate()가 DB 조회. env 누락 시 bootstrap 실패. unknown DTO 필드 거부 | - | cc:완료 [7495416] |
| C | QA-5.C2 SkillSnapshot.tag SetNull + QA-5.M2 StudyLog.tag SetNull + DashboardService null-tag 필터 | Tag 삭제 시 s0 데이터 보존. 고아 snapshot은 UI에서 제외 | - | cc:완료 [e8121e5] |
| D | QA-4.C2 subjects/[id] NaN 가드 + QA-4.M1 history 에러 상태 + QA-4.M2 ConfirmDialog/ToastBar로 native confirm/alert 교체 | 잘못된 URL에 InvalidWrap 표시. 500 시 ErrorBlock + 재시도. 네이티브 다이얼로그 제거 | - | cc:완료 [e0974b8] |
| E | QA-6.C2 postinstall + QA-6.C4 ecosystem.config.js + QA-6.M1 next standalone + QA-6.M2 README/env.example + engines/packageManager pin | Fresh pnpm install로 Prisma client 생성. PM2 reloop-api/reloop-web 프로세스 정의. standalone 빌드. 배포 가이드 문서화 | - | cc:완료 [3d7866b] |
| F | QA-6.C1 migrations (Dev VM 에서 prisma migrate dev 실행) + QA-6.C3 pnpm lockfile (Dev VM pnpm install) | README 배포 가이드에 실행 순서 포함됨. 실제 생성은 Dev VM에서 | C, E | cc:완료 [3d7866b] (README 편입) |
Phase 6 — 사업 레이어 + 통계 재설계 + 기출 데이터 + UX (소급 기록)
Phase 6 구현은 harness 규칙 없이 직선 실행됐고, 그 뒤 harness-review --base e0ac7a4 로 사후 감사했다. 아래는 실제 commit hash 와 감사 결과 기록.
| Task | 내용 | DoD | Status |
|---|---|---|---|
| P6-T1 | Pretendard Variable CDN 로드 + theme.font.sans 우선순위 | layout.tsx 에 link 주입, 실제 HTML 응답에 포함 확인 | cc:완료 [9939f29] |
| P6-T3 | masteryPath API + stats UI 재설계 (마스터리/망각 토글, ceilingP/effectiveTarget) | GET /api/stats/mastery-path 동작. 프론트 토글 + 회차 표 + 카피 | cc:완료 [9939f29, f22f837] |
| P6-T5 | 전역 드래그 방지 + data-selectable 예외 | body user-select:none, input/textarea/[data-selectable] 만 허용, review/study 제목·메모에 attr 부여 | cc:완료 [9939f29] |
| P6-T2 | SubscriptionTier + Landing + Pricing + /profile 구독 섹션 | Landing(히어로~FAQ), /pricing 3티어+비교+FAQ, User.subscriptionTier 필드 | cc:완료 [871ca89] |
| P6-T4 | ProblemSet/Problem 모델 + 2024 수능 수학 데모 10문제 + /study 탭 | GET /api/problem-sets CRUD, study 페이지 탭 + 자동 채움 + problemId | cc:완료 [871ca89] |
| P6-R | harness-review 감사 (base=e0ac7a4 head=871ca89) | REQUEST_CHANGES (major 1) | cc:완료 — .claude/state/review-result.json |
감사 결과: critical 0, major 1, minor 4, recommendation 5. AI residuals clean.
Major (수정 필요): backend/src/study-logs/study-logs.service.ts 의 create() 가 problemId 서버 검증 없이 INSERT 시도. FK 위반 시 500.
Phase 6 follow-up fix cluster
| Task | 내용 | DoD | Depends | Status |
|---|---|---|---|---|
| P6-F1 | [major] study-logs 의 problemId 존재 검증 + NotFoundException | input.problemId 가 있으면 prisma.problem.findUnique 후 null 이면 404 | - | cc:완료 [779e2cf] |
| P6-F2 | [minor] 마스터리 이미 도달 특수 분기 | iterationsToTarget === 0 일 때 '이미 목표 P 에 도달' 카피 | - | cc:완료 [74c05a5] |
| P6-F3 | [minor] 토글들에 aria-pressed | stats viewMode, pricing cycle, study mode 토글 전부 | - | cc:완료 [26cfec0] |
| P6-F4 | [minor] 데모 credential 공개 경고 | Landing <HeroNote> + seed log 에 TODO 주석 |
- | cc:완료 [9887586] |
| P6-F5 | [minor] Subscription tier enforcement TODO 주석 | mastery-path + problem-sets 컨트롤러에 'Phase 7 tier gating' TODO | - | cc:완료 [ddce6c9] |
Recommendation 5건 (pagination cap, dynamic import, pricing CTA 문구, mailto 난독화, Landing SSR 플래시) 은 별도 tracking 으로 Phase 7 이후.
Phase 6 2nd-pass 감사 결과
- base
6d8deef→ head71cf469(fix cluster 5 commit) - verdict: APPROVE
- finding resolution: major 1 + minor 4 전부 해결, 회귀 없음
- 새 recommendation 2건 (iterationsToTarget null 가드, Problem IDOR 방지) — Phase 7 확장 시 주의사항
- review-result:
.claude/state/review-result.json(2nd pass),.1st.json(1st pass) - AI Residuals: clean (0/0/0)