Files
reloop-v2/README.md
reloop 420610a41d docs: ALGORITHM/README/report 최신 상태 반영
- 가격 2,900원 통일, 기능 게이트 문서화
- 코드 규모 45,641줄/71 API/15 모델/26 페이지
- 실현가능성/시장성 섹션 전면 재작성
- 2022 교육과정 프리셋, 학교 관리 4대 기능 반영

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 19:39:35 +09:00

214 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ReLoop v2
**잊기 전에 다시 만나는 학습법.** 에빙하우스 망각곡선 + SM-2 알고리즘으로 개인화된 복습 간격을 자동 계산하는 학습 플랫폼.
> 운영 서버: https://reloop.nabomhalang.co.kr
## 핵심 기능
| 기능 | 설명 |
|------|------|
| **적응형 복습 스케줄링** | 4가지 학습자 페르소나 + 3단계 자기평가로 최적의 복습 시점을 자동 계산 |
| **복습 캘린더 + Quick Add** | 월간 달력에서 날짜별 복습 현황 확인, "+" 버튼으로 바로 학습 기록 등록 |
| **3종 문제집** | B2B 프리미엄 ebook, PDF 자동 변환 문제집, 샘플 문제집 12권 |
| **PDF 문제 분리** | 모의고사 PDF + 해설지 업로드 → 30초 만에 디지털 문제집 생성 |
| **모의고사 모드** | 사용자 설정 타이머 + OMR 답안 선택 + 자동 채점 + 집중 모드 |
| **3단계 자기평가** | 어려움/보통/쉬움 → SM-2 기반 간격 배정 |
| **필기모드** | Canvas 오버레이, 펜 3색, 문제별 localStorage 저장 |
| **B2B QR 등록** | 종이 문제집 QR 코드 → 앱 ebook 자동 등록 |
| **학교/학원 관리** | 학급 생성, 일괄/개인 과제, 복습 과제, 풀이 상세 확인, 선생님 해설 공유 |
| **2022 교육과정 프리셋** | 중1~고3 과목 생성 시 단원 자동 배치 |
| **마스터리 경로** | 단원별 예상 정답률 + 마스터까지 남은 일수 예측 |
| **Freemium 구독** | Free(과목 3개, 복습 10개) / Pro(월 2,900원) / School(학생당 월 2,900원) |
## 알고리즘
ReLoop은 두 가지 복습 경로를 제공합니다. 상세 설명은 [ALGORITHM.md](./ALGORITHM.md) 참조.
### 1. SM-2 하이브리드 (메인)
사용자가 "어려웠어/괜찮았어/쉬웠어"를 선택하면 SM-2 알고리즘이 적용됩니다.
- **어려웠어** → 1일 후 재복습, EF -0.3
- **괜찮았어** → 기본 간격 × 페르소나 배율
- **쉬웠어** → 간격 확대, EF +0.15
- 간격에 페르소나 배율 + 학습 강도 배율이 곱해짐 (최대 60일 cap)
- 망각곡선 안전장치: SM-2 간격 후 예상 P < 30%이면 자동 축소
### 2. 에빙하우스 망각곡선 (Legacy)
```
S(t) = S₀ × exp(-λ × t) 기억 감쇄
P = sigmoid(k × (S(t) - D)) 정답 확률
```
| 페르소나 | λ (망각속도) | 간격 배율 |
|---------|-------------|----------|
| 상위권 (senior) | 0.1 | ×1.3 |
| 중위권 (mid) | 0.2 | ×1.0 |
| 하위권 (junior) | 0.4 | ×0.8 |
| 벼락치기형 (crammer) | 0.6 | ×0.6 |
## 수익 모델
| | Free | Pro | School |
|--|------|-----|--------|
| 가격 | 0원 | 월 2,900원 / 연 24,900원 | 학생당 월 2,900원 |
| 복습 큐 | 일일 10개 | 무제한 | 무제한 |
| 과목 | 3개 | 무제한 | 무제한 |
| PDF 업로드 | 월 1회 | 무제한 | 무제한 |
| 기출 문제집 | 샘플만 | 전체 | 전체 |
| 마스터리 경로 | 미리보기 | 전체 | 전체 |
| 학교/학원 관리 | - | - | 전체 |
## 기술 스택
| 영역 | 기술 |
|------|------|
| Backend | NestJS 10, Prisma 5, MariaDB |
| Frontend | Next.js 14 (App Router), React 18, styled-components 6 |
| 인증 | JWT (passport-jwt) |
| 차트 | Recharts |
| 아이콘 | Phosphor React |
| 폰트 | Pretendard + Inter + JetBrains Mono |
| PDF 파싱 | poppler-utils (pdftotext, pdftoppm, pdfinfo) |
| 배포 | PM2, nginx reverse proxy |
## 프로젝트 구조
```
reloop-v2/
├── backend/
│ └── src/
│ ├── auth/ # JWT 인증
│ ├── dashboard/ # 대시보드 요약
│ ├── forget/ # 망각곡선 + SM-2 엔진
│ ├── me/ # 프로필 + 티어 전환
│ ├── problem-sets/ # 문제집 + PDF 파싱
│ │ └── parsing/ # pdftotext 기반 파서 + OCR fallback
│ ├── reviews/ # 복습 큐 (자동 이월 + Free 10개 제한)
│ ├── stats/ # 통계 + 마스터리 경로 (Pro 전용)
│ ├── study-logs/ # 학습 기록 + PDF 문제 분리
│ ├── subjects/ # 과목 + 교육과정 프리셋 + Free 3개 제한
│ ├── tags/ # 태그 (CRUD + 이름 변경)
│ ├── organizations/ # 학교/학원
│ ├── classes/ # 학급
│ └── assignments/ # 과제 (일괄/개인/복습 + 풀이상세 + 선생님 노트)
├── frontend/
│ └── src/
│ ├── app/
│ │ ├── dashboard/ # 대시보드 (캘린더, 숙련도)
│ │ ├── review/ # 복습 세션 (키보드 단축키)
│ │ ├── exams/ # 문제집 카탈로그 (프리미엄/내 문제집/샘플)
│ │ ├── study/
│ │ │ ├── exam/ # 모의고사 화면 (타이머 + 집중모드)
│ │ │ ├── import-pdf/# PDF 문제 분리
│ │ │ └── history/ # 학습 기록
│ │ ├── subjects/ # 과목/태그 관리 + 색상 피커
│ │ ├── pricing/ # 요금제 (Free/Pro/School)
│ │ ├── profile/ # 프로필 + 학습설정 + 티어 전환
│ │ └── school/ # 학교 관리
│ ├── components/
│ │ ├── ui/ # 공통 UI 컴포넌트
│ │ ├── layout/ # AppShell, SideNav, BottomNav
│ │ ├── review/ # ReviewCalendar + Quick Add
│ │ └── charts/ # 망각곡선, 숙련도 차트
│ └── lib/ # API 클라이언트, 상수, 인증
└── prisma/
└── schema.prisma # DB 스키마 (15 모델)
```
## 규모
| 항목 | 수치 |
|------|------|
| 프로덕션 코드 | 45,641줄 |
| API 엔드포인트 | 71개 |
| DB 모델 | 15개 |
| 프론트엔드 페이지 | 26개 |
| 샘플 문제집 | 12권 |
## 빠른 시작
### 필수 조건
- Node.js 20+, pnpm 9+
- MariaDB/MySQL 8+
- poppler-utils (`apt install poppler-utils`)
### 설치
```bash
git clone ssh://git@your-gitea:2222/hanarang/reloop-v2.git
cd reloop-v2
# 백엔드
cd backend
pnpm install
cp .env.example .env # DATABASE_URL, JWT_SECRET 편집
pnpm prisma migrate dev
pnpm prisma:seed
pnpm dev # :3001
# 프론트엔드
cd ../frontend
pnpm install
cp .env.example .env.local # NEXT_PUBLIC_API_URL 편집
pnpm dev # :3000
```
### 환경 변수
**Backend** (`backend/.env`)
| 변수 | 필수 | 설명 |
|------|------|------|
| `DATABASE_URL` | O | `mysql://user:pass@host:3306/reloop_v2` |
| `JWT_SECRET` | O | 32자+ 랜덤 문자열 |
| `JWT_EXPIRES_IN` | - | 기본 `7d` |
| `CORS_ORIGINS` | - | 허용 도메인 (쉼표 구분) |
| `PORT` | - | 기본 `3001` |
**Frontend** (`frontend/.env.local`)
| 변수 | 설명 |
|------|------|
| `NEXT_PUBLIC_API_URL` | 기본 `http://localhost:3001/api` |
## 배포
```bash
cd /path/to/reloop-v2
# 풀 배포 (백엔드 + 프론트엔드)
cd backend && npx prisma generate && npx prisma migrate deploy && rm -f *.tsbuildinfo && pnpm build && pm2 restart reloop-api
cd ../frontend && pnpm build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/ && pm2 restart reloop-web
```
## 주요 API 엔드포인트
| Method | Endpoint | 설명 |
|--------|----------|------|
| POST | `/api/auth/register` | 회원가입 |
| POST | `/api/auth/login` | 로그인 |
| GET | `/api/auth/me` | 내 정보 |
| PATCH | `/api/me/profile` | 프로필 수정 (페르소나 변경 시 스케줄 재계산) |
| PATCH | `/api/me/subscription-tier` | 구독 티어 전환 (Free/Pro/School) |
| GET | `/api/dashboard/summary` | 대시보드 요약 |
| GET | `/api/reviews/queue` | 복습 큐 (Free 10개 제한, 밀린 복습 자동 이월) |
| POST | `/api/reviews/:id/submit` | 복습 결과 제출 |
| GET | `/api/reviews/calendar` | 월간 복습 캘린더 |
| GET | `/api/reviews/day` | 일별 복습 상세 |
| POST | `/api/study-logs` | 학습 기록 생성 |
| POST | `/api/study-logs/from-problem-set` | 모의고사 일괄 제출 |
| POST | `/api/study-logs/parse-pdf` | PDF 문제 분리 |
| GET | `/api/problem-sets` | 문제집 목록 |
| GET | `/api/subjects` | 과목 목록 (Free 3개 제한) |
| GET | `/api/stats/mastery-path` | 마스터리 경로 (Pro 전용) |
| POST | `/api/assignments` | 과제 생성 (일괄/개인/복습) |
| GET | `/api/assignments/:id/submissions/:userId/details` | 학생 풀이 상세 |
## 라이선스
UNLICENSED (비공개)