2025-11-10 10:04:29 +09:00

6.8 KiB

라온누리 (Raonnuri)

초등학생을 위한 창의적 글쓰기 교육 플랫폼

최종 업데이트: 2025-11-07

프로젝트 소개

라온누리는 초등학생들이 재미있게 글쓰기를 배울 수 있는 한국어 교육 플랫폼입니다.

주요 특징

  • 팀 코드 시스템: 초등 저학년도 쉽게 로그인 ("춤추는 파란 사자")
  • 개인 맞춤 주제: 자유 주제, 그룹 주제, 개인 주제 지원
  • 글쓰기 에디터: 초등학생 친화적인 순수 텍스트 에디터
  • 🔜 레벨업 시스템: 경험치와 스티커 보상 (예정)
  • 🔜 학습 커리큘럼: 체계적인 레슨 시스템 (예정)

기술 스택

  • Framework: Next.js 16 (App Router) with React 19
  • 언어: TypeScript
  • UI Library: Chakra UI v3
  • 인증: Firebase Authentication
    • Email/Password, Google OAuth (정식 계정)
    • Anonymous Auth (학생 팀 코드 로그인)
  • 데이터베이스: Firestore
  • 상태 관리: Zustand
  • 비즈니스 로직: Manager 패턴 (API 호출 + 클라이언트 캐싱)
  • 스타일링: Chakra UI + Emotion
  • 애니메이션: Framer Motion
  • 🔜 캐싱: Redis (예정)

시작하기

필수 요구사항

  • Node.js 18.17 이상
  • npm, yarn, pnpm, 또는 bun

설치

npm install

개발 서버 실행

npm run dev

개발 서버는 http://localhost:3001에서 실행됩니다.

참고: 이 프로젝트는 React Compiler를 사용하므로 webpack 모드로 실행됩니다 (Turbopack 아님).

기타 명령어

npm run build      # 프로덕션 빌드
npm start          # 프로덕션 서버 실행 (포트 3001)
npm run lint       # ESLint 실행

프로젝트 구조

src/
├── app/                    # Next.js App Router
│   ├── layout.tsx         # 루트 레이아웃
│   ├── page.tsx           # 랜딩 페이지
│   ├── home/              # 유저 대시보드
│   ├── write/             # 글쓰기 페이지
│   └── team/              # 팀 관련 페이지 (목록, 생성, 상세, 관리)
├── components/
│   ├── auth/              # 인증 (로그인, 회원가입, 학생 로그인)
│   ├── writing/           # 글쓰기 에디터, 주제 선택
│   ├── navigation/        # 네비게이션 바
│   └── ui/                # Chakra UI 기본 컴포넌트
├── managers/              # ✅ 비즈니스 로직 (API + 캐싱)
│   ├── ManagerBase.ts    # 공통 기능 (authenticatedFetch, caching)
│   ├── TeamManager.ts    # 팀 관련 API 호출
│   ├── StudentManager.ts # 학생 관련 API 호출
│   ├── WritingManager.ts # 글쓰기 API 호출
│   └── TopicManager.ts   # 주제 API 호출
├── types/                 # TypeScript 타입
│   ├── team.ts, student.ts, writing.ts, topic.ts
│   └── api/              # API Request/Response 타입
├── config/                # Firebase 설정
├── services/              # Firebase Auth, Firestore
├── store/                 # Zustand (인증 상태)
└── theme/                 # Chakra UI 커스텀 테마

주요 기능

인증 시스템

정식 계정 (학부모/고학년):

  • 이메일/비밀번호 로그인 및 회원가입
  • Google OAuth 소셜 로그인
  • 비밀번호 강도 체크 + HIBP API 유출 확인

학생 로그인 (초등 저학년):

  • 팀 코드 기반 로그인 ("춤추는 파란 사자")
  • Anonymous Auth 사용
  • 이름만 입력 또는 이름 + PIN
  • 정식 계정 연결 가능 (선택적)

팀 관리 시스템

  • 팀 생성 (누구나 가능)
  • 한글 팀 코드 자동 생성 (10만 가지 조합)
  • 보안 모드 3종: simple, normal, open
  • 팀원 관리 (이름 수정, 강퇴)
  • 멤버 페이지 (팀 정보 및 멤버 목록)

글쓰기 기능

  • Tiptap 순수 텍스트 에디터 (포맷팅 없음)
  • 주제 선택 (자유/그룹/개인)
  • 개인 주제 생성 (템플릿 지원)
  • 실시간 글자수/단어수 카운터
  • LocalStorage 자동 저장

UI/UX

  • 다크 모드 지원
  • 반응형 디자인 (모바일 우선)
  • Chakra UI v3 커스텀 테마
  • Framer Motion 애니메이션
  • 초등학생 친화적 디자인

아키텍처

  • Manager 패턴 (비즈니스 로직 레이어)
  • API 추상화 (HTTP 호출)
  • 클라이언트 사이드 캐싱 (TTL 기반)
  • 타입 안전성 (완전한 타입 정의)
  • 35개 API 엔드포인트 준비 완료

개발자 가이드

상세한 개발 가이드는 다음 문서를 참고하세요:

Manager 패턴 사용

서비스 직접 사용 금지:

// Bad - deprecated
import { getTeamsByOwner } from "@/services/teamService";

Manager 사용:

// Good
import { teamManager, studentManager } from "@/managers";

// 팀 목록 (1분 캐싱)
const teams = await teamManager.getMyTeams();

// 학생 목록 (30초 캐싱)
const students = await studentManager.getStudentsByTeam(teamId);

// 팀 생성 (캐시 자동 무효화)
const teamId = await teamManager.createTeam({
  name: "우리반",
  code: "춤추는파란사자",
  securityMode: "simple",
  requirePin: false,
  allowAnonymousJoin: true
});

보호된 페이지 만들기

"use client";
import { useAuthStore } from "@/store/authStore";
import { useRouter } from "next/navigation";
import { useEffect } from "react";

export default function ProtectedPage() {
  const { isAuthenticated, isLoading } = useAuthStore();
  const router = useRouter();

  useEffect(() => {
    if (!isLoading && !isAuthenticated) {
      router.push("/");
    }
  }, [isAuthenticated, isLoading, router]);

  if (isLoading) return <div>로딩 ...</div>;
  if (!isAuthenticated) return null;

  return <div>보호된 콘텐츠</div>;
}

환경 변수

Firebase 설정을 위해 .env.local 파일을 생성하세요:

# Firebase 설정 (필수)
NEXT_PUBLIC_FIREBASE_API_KEY=your_api_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_auth_domain
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_storage_bucket
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id

# 사이트 URL (프로덕션)
NEXT_PUBLIC_URL=https://raonnuri.com

# API Base URL (선택적, 기본값: /api)
NEXT_PUBLIC_API_URL=/api

라이선스

MIT License

기여하기

기여는 언제나 환영합니다! Pull Request를 보내주세요.


라온누리 - 즐거운 글쓰기, 밝은 배움터