플래시카드 암기 트레이너 - 간격 반복 학습 시스템
flashcard-spaced-repetition-trainer
문제 설명
📚 플래시카드 암기 트레이너
간격 반복 학습(Spaced Repetition) 원리를 활용한 효율적인 암기 도구입니다. 사용자가 직접 플래시카드를 만들고, 학습 진도에 따라 자동으로 복습 주기를 조절하여 장기 기억을 돕습니다.
핵심 기능
-
카드 덱 관리
- 주제별 덱(영어 단어, 역사 연표, 프로그래밍 개념 등) 생성
- 각 덱에 플래시카드 추가/수정/삭제
- 앞면(질문)과 뒷면(답변) 텍스트 입력
-
학습 모드
- 카드를 한 장씩 보여주고 "알았어요" / "몰랐어요" 버튼으로 평가
- 정답률에 따라 다음 복습 시점 자동 계산 (간격 반복 알고리즘)
- 학습 진행률 표시 (오늘 학습할 카드 수 / 전체 카드 수)
-
복습 스케줄링
- "몰랐어요" 클릭 시 → 1일 후 재출제
- "알았어요" 클릭 시 → 3일 후 재출제
- 연속 정답 시 → 7일, 14일, 30일 등 간격 증가
- 오늘 복습할 카드만 필터링하여 표시
-
통계 대시보드
- 총 학습 카드 수
- 오늘 학습 완료한 카드 수
- 덱별 숙달도 (정답률 %)
필수 기능
- ✅ 덱 생성/삭제 (SQLite에 저장)
- ✅ 플래시카드 CRUD (앞면/뒷면 텍스트)
- ✅ 학습 모드: 카드 한 장씩 보여주고 평가 버튼
- ✅ 간격 반복 알고리즘:
next_review_date컬럼으로 복습 일자 관리 - ✅ 오늘 학습할 카드 필터링 (
next_review_date <= 오늘) - ✅ 간단한 통계 (총 카드 수, 오늘 학습 수)
보너스 기능
- 🎨 카드 뒤집기 애니메이션 (CSS flip effect)
- 📊 덱별 정답률 차트 (간단한 막대 그래프)
- 🔊 TTS API로 단어 발음 듣기 (영어 단어 덱 전용)
- 📱 모바일 반응형 레이아웃
- 🌙 다크 모드 토글
기술 스택
- PHP 8.3+ (Vanilla, 프레임워크 없음)
- SQLite (PDO)
- HTML/CSS/JavaScript (바닐라)
- PHP 내장 서버 (
php -S localhost:8000)
보안 요구사항
- 사용자 입력 출력 시
htmlspecialchars()이스케이프 - PDO prepared statement로 SQL 인젝션 방지
- CSRF 토큰 (세션 기반)
학습 목표: 간격 반복 학습 알고리즘을 직접 구현하며 날짜 연산과 조건부 로직을 익힙니다. 또한 CRUD 패턴을 플래시카드 맥락에서 실습합니다.
제약 조건
- • PHP 8.3 이상 사용 (Laravel, Symfony 등 프레임워크 금지)
- • SQLite + PDO로 데이터 저장 (MySQL 설치 불필요)
- • 프론트엔드는 순수 HTML/CSS/JavaScript (React, Vue 금지)
- • PHP 내장 서버로 실행 가능해야 함 (`php -S localhost:8000`)
- • Composer 패키지 사용 금지 (순수 PHP만)
- • 간격 반복 알고리즘: next_review_date 컬럼으로 복습 스케줄 관리
- • CSRF 토큰 검증 (세션 기반)
- • 모든 사용자 입력은 htmlspecialchars()로 이스케이프
- • PDO prepared statement 필수
프롬프트 레시피
아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.
mkdir flashcard-spaced-repetition-trainer && cd flashcard-spaced-repetition-trainer
이 폴더에서 플래시카드 암기 트레이너 프로젝트를 시작합니다.
PHP 8.3 기반의 간격 반복 학습 시스템을 만들어주세요.
**요구사항:**
1. **프로젝트 구조**
```
flashcard-spaced-repetition-trainer/
├── index.php # 홈: 덱 목록 & 오늘 학습할 카드 수 표시
├── deck.php # 덱 상세: 카드 목록 & 추가 폼
├── study.php # 학습 모드: 카드 한 장씩 보여주고 평가
├── api.php # AJAX 엔드포인트 (카드 평가, 덱 삭제 등)
├── db.php # SQLite 연결 & 초기화
├── style.css # 스타일시트
└── app.js # 프론트엔드 인터랙션
```
2. **데이터베이스 스키마 (SQLite)**
`db.php`에서 자동으로 테이블 생성:
```sql
CREATE TABLE IF NOT EXISTS decks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS cards (
id INTEGER PRIMARY KEY AUTOINCREMENT,
deck_id INTEGER NOT NULL,
front TEXT NOT NULL,
back TEXT NOT NULL,
next_review_date DATE NOT NULL,
interval_days INTEGER DEFAULT 1,
correct_count INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (deck_id) REFERENCES decks(id) ON DELETE CASCADE
);
```
- `next_review_date`: 다음 복습 예정일 (YYYY-MM-DD 형식)
- `interval_days`: 현재 복습 간격 (1, 3, 7, 14, 30일 등)
- `correct_count`: 연속 정답 횟수
3. **index.php (홈페이지)**
- 모든 덱 목록 표시 (덱명, 총 카드 수, 오늘 학습할 카드 수)
- 새 덱 추가 폼 (POST 제출 시 덱 생성)
- 오늘 학습할 카드 수 계산: `SELECT COUNT(*) FROM cards WHERE next_review_date <= date('now')`
- 각 덱 클릭 시 `deck.php?id=덱ID`로 이동
4. **간격 반복 알고리즘 기초**
학습 모드에서 카드 평가 시:
- **"몰랐어요" 클릭**: `interval_days = 1`, `next_review_date = 오늘 + 1일`, `correct_count = 0`
- **"알았어요" 클릭**:
- `correct_count` 1 증가
- `interval_days`를 다음 규칙으로 업데이트:
- 1회 정답: 3일
- 2회 정답: 7일
- 3회 정답: 14일
- 4회 이상: 30일
- `next_review_date = 오늘 + interval_days`
5. **보안**
- 모든 출력에 `htmlspecialchars($text, ENT_QUOTES, 'UTF-8')` 적용
- PDO prepared statement 사용
- CSRF 토큰: 세션에 토큰 저장 후 폼에 hidden input으로 포함, 제출 시 검증
6. **스타일**
- 깔끔한 카드 UI (border, shadow, padding)
- 덱 목록은 그리드 레이아웃
- 반응형 (모바일에서도 사용 가능)
**첫 단계 결과물:**
- `index.php`: 덱 목록 & 새 덱 추가 폼
- `db.php`: SQLite 연결 & 테이블 자동 생성
- `style.css`: 기본 스타일 (카드 레이아웃, 버튼)
- PHP 내장 서버로 실행: `php -S localhost:8000`
- 브라우저에서 `http://localhost:8000` 접속 시 덱 목록 페이지 표시
덱을 추가하고, 덱명과 "오늘 학습할 카드: 0개" 메시지가 보이면 성공입니다.
기대 결과: index.php에서 덱 목록이 표시되고, 새 덱 추가 폼이 작동합니다. db.php가 SQLite 파일(flashcards.db)을 생성하고 테이블을 초기화합니다. 기본 스타일이 적용되어 깔끔한 UI가 보입니다.
이제 **덱 상세 페이지(`deck.php`)**를 만들어주세요. **요구사항:** 1. **URL 파라미터** - `deck.php?id=1` 형식으로 덱 ID를 받음 - 해당 덱의 모든 카드 목록 표시 2. **카드 목록** - 테이블 형식으로 표시: - 앞면 (front) - 뒷면 (back) - 다음 복습일 (next_review_date) - 복습 간격 (interval_days) - 연속 정답 (correct_count) - 삭제 버튼 3. **새 카드 추가 폼** - 앞면 입력 (textarea, placeholder: "질문 또는 단어") - 뒷면 입력 (textarea, placeholder: "답변 또는 뜻") - 추가 버튼 - POST 제출 시: - 카드 생성 (`next_review_date = 오늘`, `interval_days = 1`, `correct_count = 0`) - CSRF 토큰 검증 - 생성 후 같은 페이지로 리다이렉트 4. **학습 시작 버튼** - 오늘 학습할 카드가 있으면 "학습 시작" 버튼 표시 - 클릭 시 `study.php?deck_id=1`로 이동 - 학습할 카드가 없으면 "모든 카드를 학습했습니다!" 메시지 5. **카드 삭제** - 각 카드 옆에 "삭제" 버튼 - 클릭 시 확인 후 `api.php`로 AJAX DELETE 요청 - 성공 시 해당 행 제거 (DOM 조작) 6. **뒤로가기 링크** - 상단에 "← 덱 목록으로" 링크 (`index.php`) **결과물:** - `deck.php`: 덱 상세 페이지 (카드 목록 + 추가 폼) - `api.php`: 카드 삭제 엔드포인트 (POST로 card_id 받아서 DELETE) - `app.js`: 삭제 버튼 클릭 시 AJAX 요청 & DOM 업데이트 덱에 카드를 추가하고, 목록에 표시되며, 삭제가 작동하면 성공입니다.
기대 결과: deck.php에서 선택한 덱의 카드 목록이 테이블로 표시됩니다. 새 카드 추가 폼이 작동하여 카드가 생성되고, 삭제 버튼 클릭 시 AJAX로 카드가 제거됩니다. 학습 시작 버튼이 조건부로 표시됩니다.
마지막으로 **학습 모드(`study.php`)**를 구현해주세요.
**요구사항:**
1. **학습 대상 카드 선택**
- `study.php?deck_id=1` 형식으로 덱 ID를 받음
- 오늘 학습할 카드만 조회:
```sql
SELECT * FROM cards
WHERE deck_id = ? AND next_review_date <= date('now')
ORDER BY RANDOM()
LIMIT 1
```
- 카드가 없으면 "학습할 카드가 없습니다" 메시지 + 덱으로 돌아가기 링크
2. **카드 표시**
- 처음엔 앞면(front)만 보여줌
- "답 보기" 버튼 클릭 시 뒷면(back) 표시 (JavaScript toggle)
- 카드 뒤집기 애니메이션 (CSS transform rotateY)
3. **평가 버튼**
- "몰랐어요" 버튼 (빨간색)
- "알았어요" 버튼 (초록색)
- 클릭 시 `api.php`로 POST 요청:
- `card_id`, `result` (correct/wrong), `csrf_token`
- 서버에서 간격 반복 알고리즘 적용하여 카드 업데이트:
- **wrong**: `interval_days = 1`, `next_review_date = 오늘 + 1일`, `correct_count = 0`
- **correct**:
- `correct_count++`
- `interval_days` 계산:
- 1회: 3일
- 2회: 7일
- 3회: 14일
- 4회 이상: 30일
- `next_review_date = 오늘 + interval_days`
- 응답으로 다음 카드 정보 반환 (JSON)
4. **진행률 표시**
- 상단에 "남은 카드: X개" 표시
- 카드 평가 후 카운트 감소
- 모든 카드 완료 시 "오늘 학습 완료! 🎉" 메시지 + 덱으로 돌아가기 버튼
5. **키보드 단축키 (보너스)**
- 스페이스바: 답 보기 토글
- 왼쪽 화살표: 몰랐어요
- 오른쪽 화살표: 알았어요
**결과물:**
- `study.php`: 학습 모드 페이지
- `api.php`에 카드 평가 엔드포인트 추가 (`/api.php?action=evaluate`)
- `app.js`: 평가 버튼 클릭 시 AJAX 요청 & 다음 카드 로드
- `style.css`: 카드 뒤집기 애니메이션 (CSS transform)
**테스트 시나리오:**
1. 덱에 카드 3개 추가 (모두 `next_review_date = 오늘`)
2. 학습 시작 클릭
3. 첫 카드 앞면 보고 "답 보기" → 뒷면 확인
4. "알았어요" 클릭 → 다음 카드 로드, 남은 카드 2개로 감소
5. 두 번째 카드 "몰랐어요" 클릭 → 다음 카드 로드
6. 세 번째 카드 완료 → "오늘 학습 완료!" 메시지
7. 덱으로 돌아가서 "알았어요"한 카드의 `next_review_date`가 3일 후로 업데이트됐는지 확인
8. "몰랐어요"한 카드는 1일 후로 설정됐는지 확인
모든 기능이 작동하면 플래시카드 암기 트레이너 완성입니다! 🎓
기대 결과: study.php에서 오늘 학습할 카드가 한 장씩 표시되고, 답 보기 버튼으로 뒷면을 확인할 수 있습니다. 알았어요/몰랐어요 버튼 클릭 시 간격 반복 알고리즘이 적용되어 next_review_date와 interval_days가 업데이트됩니다. 모든 카드 완료 시 완료 메시지가 표시되고, 덱 목록으로 돌아가면 오늘 학습할 카드 수가 0이 됩니다.
제출된 작품 (0)
로그인 후 제출아직 제출된 작품이 없습니다. 첫 번째 도전자가 되어보세요!