diff --git a/dev-step-01-review.md b/dev-step-01-review.md new file mode 100644 index 0000000..8ea1c89 --- /dev/null +++ b/dev-step-01-review.md @@ -0,0 +1,103 @@ +# dev-step-01 계획 검토 및 단계별 진행 제안 + +`dev-step-01.md`의 방향은 전반적으로 좋다. 특히 첫 이터레이션에서 DB, 인증, Redis, 유형 선택, 모드 선택을 제외하고 **괄호 앞 음수 분배 문제 풀이 기능만 먼저 만든다**는 판단은 `AGENTS.md`의 프로젝트 방향과 잘 맞는다. + +다만 첫 단계는 조금 더 작게 쪼개는 것이 좋다. 현재 계획의 “1단계: 프로젝트 초기화”는 적절하지만, 바로 Zustand, Framer Motion, react-katex까지 모두 설치하면 첫 확인 지점이 흐려질 수 있다. + +## 추천 첫 단계 + +1. Next.js 프로젝트 초기화 +2. Tailwind 기본 화면 정리 +3. `/`에서 “괄호 음수 분배 연습 시작” 버튼만 보이게 만들기 +4. `/play` 빈 페이지까지 라우팅 확인 +5. `pnpm dev`로 브라우저에서 화면 이동 확인 + +첫 단계의 완료 기준은 “앱이 실행되고 시작 화면에서 풀이 화면으로 이동된다” 정도가 적당하다. 아직 문제 생성, KaTeX, 상태 관리는 넣지 않는다. + +## 단계별 진행안 + +### 1차 이터레이션: 화면 뼈대 + +- `app/page.tsx` +- `app/(game)/play/page.tsx` +- 시작 버튼에서 `/play`로 이동 +- 아직 문제 생성 없음 +- 완료 기준: 브라우저에서 시작 화면에서 풀이 화면으로 이동 확인 + +### 2차 이터레이션: 문제 생성 엔진 + +- `lib/engine/parenthesis-sign.ts` +- `generateProblem` +- `gradeAnswer` +- Vitest 테스트 +- UI는 건드리지 않고 순수 알고리즘만 검증 +- 완료 기준: `pnpm test` 통과 + +### 3차 이터레이션: 수식 표시 + +- `components/math/KatexRenderer.tsx` +- KaTeX CSS import +- `/play`에 임시 문제 하나 표시 +- 완료 기준: 브라우저에서 `-2(3 - 6)` 같은 수식이 KaTeX로 표시됨 + +### 4차 이터레이션: 한 문제 풀기 + +- 답 입력 UI +- 제출 버튼 +- 채점 결과 표시 +- 아직 Zustand 없이 `useState`만 사용해도 충분함 +- 완료 기준: 한 문제를 풀고 정답/오답 피드백 확인 + +### 5차 이터레이션: 10문제 세션 + +- 이때 Zustand 도입 +- `initSession` +- `submitAnswer` +- `nextProblem` +- `score` +- 완료 기준: 10문제 풀이 후 점수 화면 표시 + +### 6차 이터레이션: UX 다듬기 + +- ProgressBar +- FeedbackBanner +- ScoreSummary +- Framer Motion은 이 단계에서 도입해도 충분함 + +## Claude 계획에서 조정하면 좋은 점 + +Claude의 계획에서 가장 조정하면 좋은 부분은 **Zustand와 Framer Motion을 너무 빨리 넣지 않는 것**이다. + +첫 기능의 핵심은 다음 세 가지다. + +1. 문제를 정확히 만든다. +2. 문제를 화면에 보여준다. +3. 사용자의 답을 채점한다. + +상태 관리와 애니메이션은 이 기본 동작이 확인된 뒤 붙이는 편이 단계별 바이브 코딩에 더 잘 맞는다. + +## 단계별 바이브 코딩 진행 방식 + +매 단계마다 아래 순서를 따른다. + +```text +1. 이번 단계 목표를 한 문장으로 정한다 +2. 수정할 파일을 2~4개 이하로 제한한다 +3. 완료 기준을 명확히 둔다 +4. 실행해서 직접 확인한다 +5. 다음 단계로 넘어가기 전에 짧게 회고한다 +``` + +## 다음 요청 예시 + +첫 개발 요청은 이렇게 주면 좋다. + +> 1차 이터레이션으로 Next.js 14 프로젝트를 초기화하고, 시작 화면과 `/play` 페이지 이동까지만 구현해줘. AGENTS.md 규칙을 따르고, 아직 문제 생성 엔진이나 DB/Auth/Redis는 만들지 마. + +그 다음 요청은 이렇게 이어갈 수 있다. + +> 2차 이터레이션으로 `lib/engine/`에 괄호 앞 음수 분배 문제 생성 엔진과 Vitest 단위 테스트를 추가해줘. UI는 건드리지 마. + +이런 식으로 “이번 단계에서 하지 않을 것”을 함께 말하면 범위가 잘 고정된다. + +현재 프로젝트는 아직 파일이 거의 없는 초기 상태이므로, 위 방식으로 진행하면 작은 단위로 확인하면서 안정적으로 기능을 쌓아갈 수 있다. diff --git a/dev-step-01.md b/dev-step-01.md new file mode 100644 index 0000000..a08b73d --- /dev/null +++ b/dev-step-01.md @@ -0,0 +1,153 @@ +Here is Claude's plan: +╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ +이터레이션 1: 괄호 음수 분배 문제 풀이 기능 + +Context + +완전 초기 상태(코드 없음)에서 바이브 코딩 방식으로 시작. DB·인증·Redis 없이 프론트엔드와 문제 생성 +엔진만으로 첫 기능을 동작 가능한 상태까지 만든다. + + --- +단계별 접근법 (바이브 코딩) + +각 단계가 독립적으로 실행·확인 가능한 단위로 나뉜다. 다음 단계로 넘어가기 전에 해당 단계가 정상 +동작하는지 함께 확인한다. + +┌──────┬──────────────────────────────┬────────────────────────────────────┐ +│ 단계 │ 내용 │ 완료 기준 │ +├──────┼──────────────────────────────┼────────────────────────────────────┤ +│ 1 │ 프로젝트 초기화 │ pnpm dev 실행 시 Next.js 기본 화면 │ +├──────┼──────────────────────────────┼────────────────────────────────────┤ +│ 2 │ 문제 생성 엔진 + 단위 테스트 │ pnpm test 통과 │ +├──────┼──────────────────────────────┼────────────────────────────────────┤ +│ 3 │ KaTeX 수식 렌더링 컴포넌트 │ 브라우저에서 수식 정상 표시 │ +├──────┼──────────────────────────────┼────────────────────────────────────┤ +│ 4 │ Zustand 게임 상태 │ store에서 문제 생성·채점 동작 │ +├──────┼──────────────────────────────┼────────────────────────────────────┤ +│ 5 │ 게임 UI 조립 │ 문제 풀이 전체 흐름 플레이 가능 │ +└──────┴──────────────────────────────┴────────────────────────────────────┘ + + --- +1단계: 프로젝트 초기화 + +pnpm create next-app@14 . --typescript --tailwind --eslint --app --no-src-dir --import-alias "@/*" +pnpm add zustand katex react-katex framer-motion clsx tailwind-merge +pnpm add -D @types/katex vitest @vitejs/plugin-react jsdom @testing-library/react + +app/layout.tsx에 추가: +import 'katex/dist/katex.min.css' + + --- +2단계: 문제 생성 엔진 + +lib/engine/types.ts + +interface ParenthesisSignProblem { +id: string +multiplier: number // 항상 음수 (-1 ~ -9) +a: number // 괄호 안 첫째 항 (1 ~ 9) +operator: '+' | '-' +b: number // 괄호 안 둘째 항 (1 ~ 9) +distributedA: number // multiplier * a +distributedB: number // multiplier * (op==='-' ? -b : b) +latexBefore: string // 문제 수식 +latexAfter: string // 정답 수식 +} +interface UserAnswer { a: number; b: number } +interface GradeResult { correct: boolean; correctAnswer: [number, number] } + +lib/engine/parenthesis-sign.ts + +핵심 로직: +- multiplier: -9 ~ -1 (음수 강제) +- a, b: 1 ~ 9, a ≠ b +- distributedB 계산: operator === '-' 이면 multiplier * (-b), 아니면 multiplier * b +- KaTeX 빌드: -2(3 - 6) → 정답: -6 + 12 + +함수 목록: +- generateProblem(): ParenthesisSignProblem +- generateSession(count: number): ParenthesisSignProblem[] (중복 방지) +- gradeAnswer(problem, answer): GradeResult + +테스트 파일: lib/engine/parenthesis-sign.test.ts + + --- +3단계: 수식 렌더링 컴포넌트 + +components/math/KatexRenderer.tsx ('use client') + +- props: latex: string, displayMode?: boolean +- react-katex의 InlineMath / BlockMath 래핑 + +components/math/ExpressionDisplay.tsx + +- props: problem, showAnswer?: boolean +- showAnswer=false: latexBefore 표시 +- showAnswer=true: latexBefore → latexAfter (Framer Motion fade-in) + + --- +4단계: Zustand Store + +store/gameStore.ts + +interface GameState { +session: { problems: ParenthesisSignProblem[]; currentIndex: number; results: (GradeResult|null)[] } +| null +initSession: (count?: number) => void // 기본 10문제 +submitAnswer: (answer: UserAnswer) => void +nextProblem: () => void +resetSession: () => void +// 셀렉터 +currentProblem: () => ParenthesisSignProblem | null +currentResult: () => GradeResult | null +isComplete: () => boolean +score: () => { correct: number; total: number } +} + + --- +5단계: 게임 UI 조립 + +게임 컴포넌트 + +- components/game/AnswerInput.tsx: 두 개의 숫자 입력 (distributedA, distributedB), Enter 제출 지원 +- components/game/FeedbackBanner.tsx: 정답(초록)/오답(빨강) + Framer Motion 슬라이드 인 +- components/game/ProgressBar.tsx: n/total 진행 표시 +- components/game/ScoreSummary.tsx: 최종 점수 + 다시 시작 버튼 + +페이지 + +- app/(game)/play/page.tsx: Server Component 래퍼 +- app/(game)/play/PlayClient.tsx ('use client'): 상태에 따라 분기 렌더링 + session===null → initSession() + !isComplete() → 문제 풀이 UI + isComplete() → ScoreSummary +- app/page.tsx: "연습 시작" → /play 이동 + + --- +화면 흐름 + +app/page.tsx (시작) +→ (game)/play/PlayClient.tsx +├─ ProgressBar +├─ ExpressionDisplay (문제 수식) +├─ AnswerInput (두 항 입력) +├─ FeedbackBanner (제출 후) +├─ "다음 문제" 버튼 +└─ [완료] ScoreSummary → "다시 시작" + + --- +검증 방법 + +1. pnpm test → 엔진 단위 테스트 전체 통과 +2. pnpm dev → 브라우저에서 수식 렌더링 확인 +3. 10문제 전체 풀이 → 점수 화면 확인 +4. 오답 입력 → 오답 피드백 및 정답 표시 확인 +5. "다시 시작" → 새 세션 생성 확인 + + --- +이번 이터레이션에서 제외 + +- DB(MariaDB), Redis, NextAuth (2차 이터레이션) +- 유형 선택 / 모드 선택 화면 (3차 이터레이션) +- 스피드 퀴즈 모드 (4차 이터레이션) +- 미지수(x, y, z) 포함 문제 (파라미터 확장 이터레이션) \ No newline at end of file