20 KiB
20 KiB
라온누리 - 프로젝트 구조
최종 업데이트: 2025-11-10 (5단계 보안 레벨 시스템, User 타입 최소화)
초등학생을 위한 창작 글쓰기 교육 플랫폼
주요 업데이트 (2025-11-10):
- 🔐 5단계 보안 레벨 시스템 (팀별 보안 정책 선택)
- 📦 User 타입 분리 (FirestoreUser / User)
- 🏷️ 닉네임 저장 위치 변경 (team.members[uid].nickname)
- 🗑️ memberUids optional (Object.keys(members) 사용)
페이지 구조
✅ 구현 완료
| 페이지 | 경로 | 설명 | 주요 기능 |
|---|---|---|---|
| 랜딩 페이지 | / |
서비스 소개 및 홍보 (비로그인 전용) | Hero, Features, How It Works, CTA, Footer 로그인 시 /home으로 자동 리다이렉트 |
| 유저 홈 | /home |
인증된 사용자 대시보드 | 환영 메시지, 빠른 시작 대시보드, 최근 활동 비로그인 시 /로 자동 리다이렉트정식 계정은 "내 팀" 카드 추가 표시 |
| 글쓰기 | /write |
Tiptap 기반 순수 텍스트 에디터 + 주제 선택 | 주제 선택 (자유 주제/개인 주제) 제목 입력 (Editable), 순수 텍스트 에디터 (포맷팅 없음) 실시간 글자수/단어수, 자동 저장 (LocalStorage 3초마다) 템플릿 미리채우기 (제목/내용), Firestore 저장 비로그인도 접근 가능 (저장 시 로그인 유도) |
| 테스트 | /test |
팀 코드 시스템 테스트 페이지 | 팀 코드 생성/검증 테스트 팀/학생 생성 테스트 학생 로그인 테스트 authStore 상태 확인 |
| 팀 목록 | /team |
내가 만든 팀 목록 (정식 계정 전용) | 팀 카드 그리드, 팀 정보 (코드, 멤버 수, 보안 설정) "새 팀 만들기" 버튼 |
| 팀 생성 | /team/create |
새 팀 만들기 (정식 계정 전용) | 팀 이름 입력, 팀 코드 자동 생성 보안 모드 선택 (simple/normal/open) 상세 설정 (PIN, 자유 가입) 생성 후 /team/[teamId]/manage로 이동 |
| 팀 멤버 페이지 | /team/[teamId] |
팀 멤버용 페이지 (멤버/소유자 모두 접근) | 팀 정보, 팀 코드 복사, 멤버 목록 소유자는 "팀 관리" 버튼 표시 팀 코드 로그인 후 기본 이동 페이지 |
| 팀 관리 | /team/[teamId]/manage |
팀 관리 페이지 (소유자 전용) | 팀 정보 및 코드, 보안 설정 표시 팀 주제 관리 (생성/삭제) 멤버 목록 및 관리 "멤버 페이지 보기" 버튼 |
🚧 구현 예정
| 페이지 | 경로 | 설명 | 상태 |
|---|---|---|---|
| 학습하기 | /learn |
레슨/코스 학습 | ❌ 미구현 (Navbar 링크만 존재) |
| 스티커 | /stickers |
스티커 컬렉션 | ❌ 미구현 (Navbar 링크만 존재) |
| 마이페이지 | Dialog (별도 페이지 없음) | 사용자 대시보드 다이얼로그 | 🔜 계획 중 (UserProfileButton에서 열림) |
컴포넌트 구조
📁 src/components/auth/ - 인증 관련
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| AuthInitializer | AuthInitializer.tsx |
Firebase 인증 상태 초기화 | ✅ 완료 |
| LoginDialog | LoginDialog.tsx |
로그인/회원가입 다이얼로그 (일반/팀 코드 모드 전환) | ✅ 완료 |
| StudentLoginFlow | StudentLoginFlow.tsx |
팀 코드 학생 로그인 플로우 (3단계) | ✅ 완료 |
| LoginForm | LoginForm.tsx |
로그인 폼 컴포넌트 | ✅ 완료 |
| SignupForm | SignupForm.tsx |
회원가입 폼 컴포넌트 | ✅ 완료 |
| SocialLoginButton | SocialLoginButton.tsx |
소셜 로그인 버튼 | ✅ 완료 |
| UserProfileButton | UserProfileButton.tsx |
사용자 프로필/메뉴 버튼 | ✅ 완료 |
주요 기능:
- ✅ 이메일/비밀번호 로그인
- ✅ 이메일/비밀번호 회원가입
- ✅ 이름, 이메일, 비밀번호, 비밀번호 확인 입력
- ✅ 실시간 비밀번호 강도 게이지
- ✅ HIBP API 연동 (유출된 비밀번호 차단)
- ✅ 폼 검증 및 에러 애니메이션
- ✅ Google OAuth 로그인
- ✅ 팀 코드 기반 사용자 로그인 (Anonymous Auth - 단순화됨)
- ✅ 한글 팀 코드 ("춤추는 파란 사자" 형식)
- ✅ 사용자 이름 입력 (2단계)
- ❌ PIN 인증 제거 (복잡도 감소)
- ✅ UID 기반 통합 인증 (currentStudent 제거)
- ✅ 팀별 닉네임 시스템
- ✅ 로그인/회원가입 페이드 전환 애니메이션
- ✅ Anonymous ↔ 정식 계정 연결 (UID 유지)
- 🔜 네이버 로그인 (준비 중)
- 🔜 카카오 로그인 (준비 중)
📁 src/components/landing/ - 랜딩 페이지
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| FeatureCard | FeatureCard.tsx |
특징 카드 | ✅ 완료 |
| StepCard | StepCard.tsx |
단계 카드 | ✅ 완료 |
| SectionHeader | SectionHeader.tsx |
섹션 헤더 | ✅ 완료 |
📁 src/components/navigation/ - 네비게이션
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| Navbar | Navbar.tsx |
상단 네비게이션 바 | ✅ 완료 |
네비게이션 링크:
- 홈 (
/또는/home) - 인증 상태에 따라 동적 변경- 비로그인:
/(랜딩 페이지) - 로그인:
/home(유저 대시보드)
- 비로그인:
- 글쓰기 (
/write) - 미구현 - 학습하기 (
/learn) - 미구현 - 스티커 (
/stickers) - 미구현
📁 src/components/ui/ - UI 기본 컴포넌트
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| Provider | provider.tsx |
Chakra UI Provider | ✅ 완료 |
| ColorMode | color-mode.tsx |
다크모드 토글 | ✅ 완료 |
| Toaster | toaster.tsx |
토스트 알림 | ✅ 완료 |
| Tooltip | tooltip.tsx |
툴팁 | ✅ 완료 |
📁 src/components/seo/ - SEO
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| StructuredData | StructuredData.tsx |
JSON-LD 구조화 데이터 | ✅ 완료 |
📁 src/components/writing/ - 글쓰기 에디터
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| WritingEditor | WritingEditor.tsx |
Tiptap 기반 순수 텍스트 에디터 | ✅ 완료 |
| TopicSelector | TopicSelector.tsx |
주제 선택 드롭다운, 팀/개인 주제 배지 표시 | ✅ 완료 |
| CreateTopicDialog | CreateTopicDialog.tsx |
개인 주제 생성 다이얼로그 (태그 입력 UI) | ✅ 완료 |
| CreateTeamTopicDialog | CreateTeamTopicDialog.tsx |
팀 주제 생성 다이얼로그 (템플릿 지원) | ✅ 완료 |
주요 기능:
- ✅ 순수 텍스트 입력 (포맷팅 없음)
- ✅ 초등학생 친화적 단순 인터페이스
- ✅ 실시간 글자 수/단어 수 카운터
- ✅ 자동 저장 (LocalStorage)
- ✅ 주제 선택 (자유 주제/팀 주제/개인 주제)
- ✅ 주제 정보 표시 (설명, 키워드, 예시 질문)
- ✅ 팀/개인 주제 배지 표시 (teal/pink)
- ✅ 템플릿 미리채우기 (제목/내용)
- ✅ 개인 주제 생성 (카테고리, 난이도, 키워드, 템플릿 설정)
- ✅ 팀 주제 생성 (팀 소유자 전용, 팀 관리 페이지)
- ✅ 태그 입력 필드 UI (제목 템플릿: 방향키 네비게이션, Backspace/Delete 삭제)
📁 src/components/team/ - 팀 관리
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| TeamTopicManager | TeamTopicManager.tsx |
팀 주제 목록 및 생성/삭제 UI | ✅ 완료 |
📁 예정된 컴포넌트 디렉토리
| 디렉토리 | 설명 | 컴포넌트 |
|---|---|---|
lesson/ |
학습 관련 | LessonCard, LessonContent, QuizSection, ProgressBar, LevelBadge |
sticker/ |
스티커 관련 | StickerGrid, StickerCard, StickerDetail, StickerStats, LockedSticker |
level/ |
레벨 시스템 | LevelBadge, LevelUpModal, ExperienceBar |
profile/ |
프로필 Dialog | ProfileDialog (탭: 내정보, 내글, 통계, 설정), ProfileCard, StatsWidget, WritingHistory |
notification/ |
알림 시스템 | NotificationBell, NotificationList, NotificationItem |
admin/ |
관리자 | TopicManager, UserManager, ContentEditor |
Notes:
profile/디렉토리는 Dialog 기반으로 구현됩니다. UserProfileButton 클릭 시 ProfileDialog가 열립니다.
비즈니스 로직 레이어
📁 src/managers/ - Manager 패턴 (API 호출 + 클라이언트 캐싱)
| Manager | 파일명 | 설명 | 상태 |
|---|---|---|---|
| ManagerBase | ManagerBase.ts |
공통 기능 (authenticatedFetch, API 호출, 캐싱) | ✅ 완료 |
| TeamManager | TeamManager.ts |
팀 관련 API 호출 (생성, 조회, 수정, 삭제, 멤버 관리) | ✅ 완료 |
| UserManager | UserManager.ts |
사용자 관련 API 호출 (생성, 조회, 수정, 닉네임 관리) [NEW] | ✅ 완료 |
StudentManager.ts |
⚠️ Deprecated (UserManager로 대체) | ||
| WritingManager | WritingManager.ts |
글쓰기 관련 비즈니스 로직 (CRUD, 통계) | ✅ 완료 |
| TopicManager | TopicManager.ts |
주제 관련 비즈니스 로직 (CRUD, 템플릿 처리) | ✅ 완료 |
| index.ts | index.ts |
모든 매니저 export | ✅ 완료 |
| LevelManager | LevelManager.ts |
레벨/경험치 관리 | ❌ 미구현 |
| StickerManager | StickerManager.ts |
스티커 획득/관리 | ❌ 미구현 |
주요 기능:
- ✅ 싱글톤 패턴으로 전역 인스턴스 관리
- ✅ HTTP API 호출: Next.js API Routes로 서버 로직 분리
- ✅ 클라이언트 사이드 캐싱: in-memory 캐싱 (TTL 기반)
- ✅ 자동 캐시 무효화: 변경 작업 시 관련 캐시 삭제
- ✅ 인증 자동 처리: ID Token 자동 헤더 추가
- ✅ 타입 안전성: Request/Response 타입 완전 정의
- ✅ 비즈니스 로직과 UI 레이어 분리
📁 src/services/ - 데이터 레이어 (일부 deprecated)
| 서비스 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| Firebase Auth | firebaseAuth.ts |
인증 서비스 (로그인, 회원가입, 소셜, Anonymous, 계정 연결) | ✅ 완료 (단순화됨) |
| Firestore | firestore.ts |
Firestore CRUD 헬퍼 함수 (WritingManager에서 사용) | ✅ 완료 |
teamService.ts |
⚠️ Deprecated (TeamManager로 이동) | ||
studentService.ts |
⚠️ Deprecated (UserManager로 대체) | ||
| Level System | levelSystem.ts |
레벨/경험치 계산 로직 | ❌ 미구현 |
| Sticker System | stickerSystem.ts |
스티커 획득 조건 엔진 | ❌ 미구현 |
마이그레이션 완료:
- ✅ teamService.ts → TeamManager (API 호출 방식)
- ✅ studentService.ts → UserManager (UID 기반 단순화)
- ✅ students 컬렉션 → users 컬렉션 (UID 기반)
- ✅ Firestore 직접 접근 → HTTP API 호출로 전환
- ✅ PIN 기능 제거, 팀별 닉네임 시스템 추가
📁 src/types/ - 타입 정의
| 타입 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| Team 타입 | team.ts |
팀 데이터 모델 (memberUids, members Map), TeamSecurityMode Enum (simple/open) | ✅ 완료 |
| User 타입 | user.ts |
사용자 데이터 모델 (nicknames Map) [NEW] | ✅ 완료 |
student.ts |
⚠️ Deprecated (user.ts로 대체) | ||
| Topic 타입 | topic.ts |
주제 데이터 모델, TopicCategory/Difficulty/OwnerType Enum, 팀 주제 유틸 함수 | ✅ 완료 |
| API 공통 타입 | api.ts |
ApiResponse, ApiError, HttpMethod Enum | ✅ 완료 |
| Team API 타입 | api/team.ts |
팀 API Request/Response (add/removeMember 추가, requirePin 제거) | ✅ 완료 |
| User API 타입 | api/user.ts |
사용자 API Request/Response (닉네임 관리 포함) [NEW] | ✅ 완료 |
api/student.ts |
⚠️ Deprecated (api/user.ts로 대체) | ||
| Topic API 타입 | api/topic.ts |
주제 API Request/Response (9개 엔드포인트, 팀 주제 포함) | ✅ 완료 |
상태 관리 (Zustand)
📁 src/store/
| 스토어 | 파일명 | 설명 | 상태 |
|---|---|---|---|
| Auth Store | authStore.ts |
인증 상태 및 로그인 다이얼로그 (단순화됨) | ✅ 완료 |
| User Progress Store | userProgressStore.ts |
사용자 진행 상황 (레벨, XP) | ❌ 미구현 |
| Notification Store | notificationStore.ts |
알림 상태 | ❌ 미구현 |
Auth Store 아키텍처 (2025-11-07 단순화):
- ✅ user - Firebase Auth 기반 통합 사용자 (익명 + 정식 계정)
- ✅ isAuthenticated - 로그인 여부 (익명 포함)
- ✅ user.isAnonymous - 익명/정식 계정 구분
- ✅ loginAsUser() - 팀 코드 로그인 (PIN 제거)
- ✅ linkWithEmail() - 이메일 계정 연결
- ✅ linkWithGoogle() - Google 계정 연결
- ❌
currentStudent,ownedStudents,switchStudent()제거 (복잡도 감소)
설정 파일
📁 src/config/
| 파일 | 설명 | 상태 |
|---|---|---|
firebase.ts |
Firebase 초기화 및 설정 | ✅ 완료 |
site.ts |
사이트 메타데이터 및 설정 | ✅ 완료 |
디렉토리 구조 요약
src/
├── app/ # Next.js App Router
│ ├── layout.tsx # 루트 레이아웃
│ ├── page.tsx # 랜딩 페이지 (/) - 로그인 시 /home 리다이렉트
│ ├── home/
│ │ └── page.tsx # ✅ 유저 홈 페이지 (/home)
│ ├── write/
│ │ └── page.tsx # ✅ 글쓰기 페이지 (/write)
│ ├── test/
│ │ └── page.tsx # ✅ 테스트 페이지 (/test) - 팀 코드 시스템 테스트
│ ├── globals.css
│ ├── favicon.ico
│ ├── team/ # ✅ 팀 관리 페이지들
│ │ ├── page.tsx # ✅ 팀 목록 (/team)
│ │ ├── create/
│ │ │ └── page.tsx # ✅ 팀 생성 (/team/create)
│ │ └── [teamId]/
│ │ ├── page.tsx # ✅ 팀 멤버 페이지 (/team/[teamId])
│ │ └── manage/
│ │ └── page.tsx # ✅ 팀 관리 페이지 (/team/[teamId]/manage)
│ └── [미구현 페이지들]
│ ├── learn/ # 학습 페이지
│ ├── stickers/ # 스티커 페이지
│ └── admin/ # 관리자
│
├── components/ # React 컴포넌트
│ ├── auth/ # ✅ 인증 (로그인, 프로필, 팀 코드)
│ ├── landing/ # ✅ 랜딩 페이지 카드들
│ ├── navigation/ # ✅ 네비게이션 바
│ ├── seo/ # ✅ SEO 컴포넌트
│ ├── ui/ # ✅ Chakra UI 기본
│ ├── writing/ # ✅ 글쓰기 에디터
│ │ ├── WritingEditor.tsx # 순수 텍스트 에디터 (포맷팅 없음)
│ │ ├── TopicSelector.tsx # ✅ 주제 선택 컴포넌트 (팀/개인 배지)
│ │ ├── CreateTopicDialog.tsx # ✅ 개인 주제 생성
│ │ └── CreateTeamTopicDialog.tsx # ✅ 팀 주제 생성
│ ├── team/ # ✅ 팀 관련
│ │ └── TeamTopicManager.tsx # ✅ 팀 주제 관리
│ └── [미구현]
│ ├── lesson/ # 학습 컴포넌트
│ ├── sticker/ # 스티커 컴포넌트
│ ├── level/ # 레벨 시스템
│ ├── profile/ # 프로필 컴포넌트
│ ├── notification/ # 알림 컴포넌트
│ └── admin/ # 관리자 컴포넌트
│
├── config/ # ✅ 설정
│ ├── firebase.ts
│ └── site.ts
│
├── managers/ # ✅ 비즈니스 로직 (Manager 패턴)
│ ├── ManagerBase.ts # 기본 Manager 클래스
│ ├── WritingManager.ts # 글쓰기 관리
│ ├── TopicManager.ts # ✅ 주제 관리
│ └── [미구현]
│ ├── LevelManager.ts
│ └── StickerManager.ts
│
├── data/ # ✅ 정적 데이터
│ └── classCodeWords.ts # ✅ 한글 팀 코드 단어 (형용사, 색상, 동물)
│
├── services/ # 데이터 레이어 (Firestore/API 호출)
│ ├── firebaseAuth.ts # ✅ 인증 (이메일, Google, Anonymous)
│ ├── classroomService.ts # ✅ 클래스룸 CRUD
│ ├── studentService.ts # ✅ 학생 CRUD, PIN 관리
│ ├── firestore.ts # ✅ Firestore CRUD
│ └── [미구현]
│ ├── levelSystem.ts
│ └── stickerSystem.ts
│
├── store/ # Zustand 상태 관리
│ ├── authStore.ts # ✅ 인증 상태 (currentStudent 중심)
│ └── [미구현]
│ ├── userProgressStore.ts
│ └── notificationStore.ts
│
├── theme/ # ✅ Chakra UI 테마
│ └── system.ts
│
├── types/ # TypeScript 타입
│ ├── topic.ts # ✅ 주제 관련 타입 (Enum + 유틸 함수)
│ ├── team.ts # ✅ 팀 관련 타입 (Enum)
│ ├── student.ts # ✅ 학생 타입
│ ├── api/ # ✅ API Request/Response 타입
│ │ ├── topic.ts # ✅ 주제 API (팀/개인 주제)
│ │ ├── team.ts # ✅ 팀 API
│ │ └── student.ts # ✅ 학생 API
│ └── [미구현]
│
└── utils/ # 유틸리티 함수
├── passwordStrength.ts # ✅ 비밀번호 강도 계산
├── passwordSecurity.ts # ✅ HIBP API 연동
└── classCodeGenerator.ts # ✅ 팀 코드 생성/검증/정규화
다음 구현 단계
Phase 1: 핵심 기능 (현재)
- ✅ 프로젝트 설정 및 인프라
- ✅ 인증 시스템 (로그인)
- ✅ 랜딩 페이지
- ✅ 회원가입 기능 (페이드 전환 + HIBP 보안 검증)
- ✅ 인증 기반 라우팅 (
/와/home분리) - ✅ 글쓰기 페이지 (Tiptap 에디터, LocalStorage 자동 저장, Firestore 저장)
- ✅ 주제 선택 및 관리 (자유/개인 주제, 템플릿)
- ✅ 팀 코드 시스템 (완료)
- ✅ 한글 팀 코드 생성 ("춤추는 파란 사자")
- ✅ Anonymous Auth 학생 로그인
- ✅ 팀/학생 관리 서비스 (ownerId 기반)
- ✅ PIN 인증 (SHA-256)
- ✅ 정식 계정 연결 (linkWithCredential)
- ✅ currentStudent 중심 authStore 재설계
- ✅ 학생 로그인 UI (3단계 플로우, 이름 입력, 완료 화면)
- ✅ 팀 관리 UI (목록/생성/멤버 페이지/관리 페이지)
- ✅ 용어 변경: "클래스" → "팀", "교사" → "소유자"
- 🚧 다음: 내가 쓴 글 목록
Phase 2: 팀 코드 UI 완성
- 학생 로그인 UI (팀 코드 입력 → 이름 선택 → PIN)
- 팀 관리 (팀 생성, 멤버 관리)
- LoginDialog에 학생 탭 추가
Phase 3: 학습 시스템
/learn학습 페이지- 레슨 콘텐츠 및 진행 상황
Phase 4: 게임화
- 레벨업 시스템
/stickers스티커 페이지
Phase 5: 사용자 경험
- ProfileDialog 마이페이지 (Dialog 형식)
- 검색 및 알림
Phase 6: 고급 기능
- 부모님 모드 (계정 연결)
- 관리자 패널
관련 문서
- TECH_STACK.md - 기술 스택 및 개발 환경 설정
- DATA_MODELS.md - 데이터베이스 스키마 및 타입 정의
- ROADMAP.md - 개발 우선순위 및 로드맵
- CLAUDE.md - Claude Code 작업 가이드
© 2024 BlueNovaLab. All rights reserved.