diff --git a/frontend/src/routes/study/topics/[id]/review/+page.svelte b/frontend/src/routes/study/topics/[id]/review/+page.svelte index dd4ca16..5d609bc 100644 --- a/frontend/src/routes/study/topics/[id]/review/+page.svelte +++ b/frontend/src/routes/study/topics/[id]/review/+page.svelte @@ -28,6 +28,12 @@ // 진입 화면 옵션 (start 모드용) let mode = $state('start'); // 'start' | 'playing' + // Phase 2-A: 학습 단계 + 분량 (Phase 1-E bucket+stage 알고리즘 입력) + // null = 기본 (subject bucket 모드, 기존 PR-12-B 동작) + let optStage = $state(null); // null | 'intro' | 'learning' | 'pre_exam' + let optSize = $state(50); // 30 / 50 / 100 + let advancedOpen = $state(false); + // 기존 옵션 (advanced — stage 미선택 시만 사용) let optSubject = $state(''); let optWrongOnly = $state(false); let optTarget = $state(20); @@ -89,18 +95,27 @@ } }); - /** 'start' 모드에서 [시작] 클릭 → 신규 세션 생성 후 ?session=N 으로 이동. */ + /** 'start' 모드에서 [시작] 클릭 → 신규 세션 생성 후 ?session=N 으로 이동. + * optStage 가 설정되면 Phase 1-E bucket+stage 알고리즘으로 출제 (단일 풀이 진입점). + * 미설정이면 기존 subject bucket + spacing 경로 (advanced 옵션 호환). */ async function start() { loading = true; try { + const body = optStage + ? { + stage: optStage, + size: optSize, + abandon_existing: false, + } + : { + target_per_subject: optTarget, + subject: optSubject.trim() || null, + wrong_only: optWrongOnly, + abandon_existing: false, + }; const res = await api(`/study-topics/${topicId}/quiz-sessions`, { method: 'POST', - body: JSON.stringify({ - target_per_subject: optTarget, - subject: optSubject.trim() || null, - wrong_only: optWrongOnly, - abandon_existing: false, // start 화면에서는 in_progress 있으면 그쪽으로 이어감. - }), + body: JSON.stringify(body), }); goto(`/study/topics/${topicId}/review?session=${res.id}`, { replaceState: true }); // loadSession 은 navigate 후 onMount 가 다시 안 트리거되므로 직접 호출. @@ -171,38 +186,93 @@
- 기본은 과목별 {optTarget}문제씩 무작위 균등 추출. 한 과목이 부족하면 가용한 만큼만 출제됩니다. + 학습 단계와 분량을 선택하세요. 단계에 맞춰 안 푼 문제, 오답, 복습 예정, 빈출 유형이 자동으로 섞여 출제됩니다. 풀이 중 정답·해설은 표시하지 않으며, 다 풀면 결과 화면에서 카테고리별로 한 번에 확인합니다. 나갔다 와도 같은 위치에서 이어풀 수 있습니다.
-학습 단계를 선택하거나 고급 옵션으로 시작
+ {/if}