Knowledge Base

북곽원

활성

과학고 학생들이 직접 문제를 만들고 실전 모의고사를 생성하는 협력 플랫폼 — 학원 없이도, 학교에서 해결한다

bukgwakwon.vercel.app
Next.jsReactTypeScriptSupabaseTailwind CSSshadcn/uiZustandjsPDFFramer Motion

Overview

What

북곽원은 경기북과학고등학교 학생들을 위한 모의고사 생성 플랫폼이다. 학생 커뮤니티가 직접 문제를 축적하고 공유하며, 실제 학교 시험지 양식 그대로의 모의고사를 자동 생성할 수 있다.

Why

과학고에 처음 입학한 학생들은 모든 문제가 서술형인 시험을 처음 마주한다. 이 불안감을 해소하려면 실전 연습이 필요한데, 학원에 다니지 않는 학생들에게는 그 기회가 부족하다.

북곽원은 세 가지 문제를 동시에 풀려고 했다. 학원 없이도 시험 대비가 가능해야 한다. 시험 자료가 흩어져 있으면 안 된다. 그리고 학생이 문제를 만드는 과정 자체가 학습이 되어야 한다.

학생이 문제를 출제하고, 다른 학생이 해설을 달고, 스타로 기여를 인정받는 구조를 만들어서 "학생이 학생을 가르치는" 선순환을 설계했다.

How

핵심 흐름은 출제 → 생성 → 풀이 → 피드백이다.

학생이 과목별 문제 세트를 업로드하면 관리자 승인을 거쳐 공개된다. 다른 학생은 학년, 학기, 시험 유형, 난이도 비율을 선택하여 문제를 조합하고, jsPDF로 학교 시험지 양식 그대로의 PDF를 생성한다. PDF를 출력해서 풀고, 사이트에서 채점하면 오답노트가 자동으로 만들어진다.

커뮤니티 해설 시스템으로 공식 풀이가 없는 문제에도 학생들이 직접 풀이를 공유할 수 있고, 게이미피케이션으로 문제 세트 승인 시 10스타, 해설 제출 시 3스타를 부여하여 기여를 독려한다. 스타 누적으로 "북곽원 스타 강사" 랭킹이 매겨진다.

Impact

학원에 의존하지 않고도 실전과 동일한 형식의 시험 연습이 가능해졌다. 학생이 문제를 만드는 과정에서 해당 개념을 더 깊이 이해하게 되고, 해설을 작성하면서 설명 능력도 기른다. 실제로 운영 중이며 학생들이 활발하게 문제를 축적하고 있다.

Architecture

Tech Stack

  • Frontend: Next.js 15, React 19, TypeScript
  • Styling: Tailwind CSS 4 + shadcn/ui
  • State: Zustand (인증, 모의고사 생성, 업로드 3개 스토어)
  • Backend/DB: Supabase (PostgreSQL + Auth + Storage + RLS)
  • PDF: jsPDF (시험지 양식 기반 동적 생성)
  • Animation: Framer Motion
  • Deploy: Vercel

Architecture

인증은 Supabase Auth로 이메일 기반 회원가입/로그인을 처리하고, 가입 시 트리거로 프로필이 자동 생성된다.

문제 업로드는 Zustand 스토어가 멀티파일 업로드의 복잡한 상태를 관리한다. 최대 3개 동시 업로드로 속도를 최적화하고, 문제 이미지와 풀이 이미지를 순차적으로 Supabase Storage에 저장한다.

모의고사 생성 엔진은 사용자가 선택한 조건(학년, 학기, 시험 유형, 과목, 난이도 비율)에 맞는 문제를 조합하고, jsPDF로 학교 시험지 템플릿에 이미지를 정밀 배치하여 A4 PDF를 생성한다.

11개 테이블에 모두 RLS 정책이 적용되어 있다.

Decisions

Decision 1: jsPDF로 학교 시험지 양식 재현

Context: 학생들이 실전 감각을 익히려면 학교 시험지와 동일한 형식이어야 한다. 단순히 문제를 나열하는 것으로는 부족하다. Decision: jsPDF로 한국어 폰트를 등록하고, A4 2단 레이아웃에 학번/이름 입력란, 페이지 번호까지 포함한 학교 시험지 템플릿을 구현했다. Consequence: 출력하면 실제 시험과 구분이 안 될 정도의 모의고사가 나온다. 이미지 배치와 페이지 넘김 계산이 복잡했지만, "실전과 같은 연습"이라는 핵심 가치를 실현했다.

Decision 2: 게이미피케이션 스타 시스템

Context: 학생들이 자발적으로 문제를 만들고 해설을 달게 하려면 동기 부여가 필요하다. 강제로는 안 된다. Decision: 문제 세트 승인 시 10스타 + 문제 수량 보너스, 해설 제출 시 3스타. 스타 누적으로 "스타 강사" 랭킹. 동점 시 조회수로 타이브레이크. Consequence: 기여를 정량화하고 인정하는 구조가 만들어졌다. 익명 업로드 옵션도 추가해서 스타를 포기하더라도 자유롭게 기여할 수 있게 했다.

Decision 3: 익명 업로드 옵션

Context: 학생들 사이에서 "내가 문제를 만들었다"는 게 부담이 될 수 있다. 특히 틀린 문제를 올렸을 때 평판 걱정이 기여를 막을 수 있다. Decision: 업로드 시 익명 토글을 제공하고, 익명 세트는 스타 보상을 받지 않는 대신 출제자 정보가 공개되지 않는다. Consequence: 부담 없이 문제를 올릴 수 있는 안전망이 생겼다. 스타를 포기해서라도 기여하고 싶은 학생들의 참여를 이끌어냈다.

Lessons

배운 점

교육 플랫폼에서 게이미피케이션은 균형이 중요하다. 보상이 너무 크면 양에만 집중하게 되고, 너무 작으면 동기가 없다. 문제 세트 승인 10스타 + 해설 3스타라는 비율은 "만드는 것이 푸는 것보다 가치 있다"는 메시지를 구조에 심어놓은 것이다.

학교 시험지 양식을 PDF로 재현하는 건 예상보다 훨씬 복잡했다. 한국어 폰트 렌더링, 이미지 비율 유지, 2단 레이아웃의 페이지 넘김 계산 등 작은 디테일들이 "실전과 같은 느낌"을 좌우한다.

익명 옵션은 처음에는 고려하지 않았다. 학생들이 실제로 올리기 시작하면서 "이름이 나오는 게 부담된다"는 피드백이 왔고, 그제서야 추가했다. 사용자 피드백이 기능을 만든 좋은 사례다.

이 프로젝트의 독특한 점

교사가 만든 플랫폼이지만, 콘텐츠를 만드는 것은 전적으로 학생이다. 교사는 시스템을 설계하고, 학생이 문제를 출제하고, 해설을 달고, 서로를 평가한다. "학생이 학생을 가르치는" 구조를 기술로 뒷받침한 것이다.

Timeline

2026-03 — 프로젝트 시작

경기북과학고 학생들의 시험 대비 자료 부재 문제를 해결하기 위해 프로젝트를 시작했다. Next.js + Supabase 기반 아키텍처 확립.

2026-03 — 핵심 기능 구현

문제 세트 업로드, 모의고사 PDF 생성, 채점, 오답노트까지 핵심 파이프라인을 완성했다. jsPDF로 학교 시험지 양식을 재현하고, RLS로 데이터 격리를 구현했다.

2026-04 — 커뮤니티 기능 + 게이미피케이션

스타 시스템, 스타 강사 랭킹, 커뮤니티 해설, 익명 업로드를 추가했다. 학생 기여를 독려하는 보상 구조를 완성.

현재 — 실제 운영 중

학생들이 활발하게 문제를 축적하고 모의고사를 생성하고 있다.

관련 지식 노드