# 라온누리 - 프로젝트 구조 > 최종 업데이트: 2025-12-23 (이미지 4:3 비율 표준화) 초등학생을 위한 창작 글쓰기 교육 플랫폼 **최신 업데이트** (2025-12-23): - 🖼️ **이미지 4:3 비율 표준화** - **AI 이미지 생성**: 16:9 → 4:3 비율 변경 (일관된 이미지 크기) - **ImageCropper 컴포넌트**: react-cropper 기반 이미지 크롭 기능 (4:3 고정) - **필수 크롭 단계**: 이미지 업로드 시 자동으로 크롭 모달 표시 - **조작 기능**: 회전, 확대/축소, 리셋 버튼 제공 - **최소 크기**: 400x300 (품질 보장) - **최대 크기**: 1600x1200 (4:3 비율, 1920x1080에서 변경) - **Dialog 통합**: Chakra UI v3 Dialog로 구현 - **이벤트 버블링 해결**: ImageCropper를 드롭존 외부로 분리 - **다국어 지원**: ko/en/ja 크롭 관련 메시지 추가 (7개 키) - **후위 호환성**: 기존 16:9 이미지는 그대로 표시 **업데이트** (2025-12-19): - 🔀 **Curriculum Fork Model 구현** - **소유권 모델 전환**: 팀 기반 → 사용자 소유(ownerId) + 공개 범위(visibility) 기반 - **Fork 기능**: 공개/시스템 커리큘럼을 사용자 라이브러리로 복사 - **새로운 필드**: ownerId, visibility, forkedFrom, isSystem, forkCount - **CurriculumFormModal**: 커리큘럼 생성/수정 시 공개 범위 설정 지원 - **API 변경**: /api/curriculum, /api/lesson 쿼리 파라미터 및 응답 형식 변경 - **Navbar 메뉴**: 'Curriculum' 메뉴 추가 - **번역 변경**: 'Curriculum' → 'Learning Course' - **문서 추가**: docs/CURRICULUM_FORK_MODEL.md - **WritingOwnerActions**: 글 작성자 수정/이미지/인터랙션 메뉴 컴포넌트 - 📌 **글 상세 페이지 Sticky Header** - **WritingDetailHeader.tsx**: 스크롤 시 상단에 고정되는 헤더 컴포넌트 - **표시 정보**: 글 제목, 작성자 정보, 이미지 포함 여부 - **WritingOwnerActions 재활용**: 작성자 본인일 때 수정 메뉴 표시 - 🔧 **AI 이미지 생성 에러 처리 개선** - **에러 코드별 메시지**: plan_not_supported, limit_exceeded, ai_disabled 등 - **다국어 지원**: 한국어/영어/일본어 메시지 추가 - ⬆️ **의존성 업데이트** - **@ark-ui/react, @zag-js**: v1.29.1 → v1.31.1 **업데이트** (2025-12-19 이전): - 📚 **커리큘럼 UX 개편** - **미리보기 모달**: CurriculumPreviewModal (목록 클릭 시 페이지 이동 대신 모달 표시) - **상세 블록 정보**: 레슨별 콘텐츠 블록 상세 표시 (Accordion UI) - **4가지 블록 타입 표시**: theory(이론), quiz(퀴즈), mission(미션), writing_prompt(글쓰기) - **팀 선택 모달**: TeamSelectModal (커리큘럼 가져오기 시 대상 팀 선택) - **커리큘럼 복사 API**: POST /api/curriculum/[curriculumId]/copy (레슨 포함 전체 복사) - **내 커리큘럼 페이지**: /my-curriculums (MyCurriculumsDashboard) - **커리큘럼 수정 모달**: CurriculumEditModal (제목/설명 수정) - **권한 분리**: 시스템/타팀 커리큘럼은 가져오기만, 내 팀 커리큘럼만 편집 가능 - **스켈레톤 로딩**: 미리보기 로딩 시 레슨 구조 형태의 Skeleton UI - **다국어 지원**: preview.blockType namespace (theory/quiz/mission/writing_prompt, ko/en/ja) **업데이트** (2025-12-17): - 📚 **커리큘럼/레슨 학습 시스템** - **Sandbox 모델**: 시스템 제공 + 팀 자체 생성 커리큘럼 - **4가지 콘텐츠 타입**: theory (이론), quiz (퀴즈), mission (미션), writing_prompt (글쓰기) - **API 엔드포인트**: GET/POST/PUT/DELETE /api/curriculum, /api/lesson - **Manager 추가**: CurriculumManager, LessonManager (캐싱 지원) - **초기화 스크립트**: scripts/seed-curriculums.ts (3개 시스템 커리큘럼, 15개 레슨) - **컴포넌트**: CurriculumDashboard, CurriculumList, CurriculumCreateModal, CurriculumDetailView, LessonEditor - **페이지**: /curriculum (목록), /curriculum/[curriculumId] (상세) - **타입 정의**: Curriculum, Lesson, LessonContent, LessonContentType - **다국어 지원**: curriculum, lesson namespace (ko/en/ja, 70+ 키) **업데이트** (2025-12-16): - 🖼️ **이미지 생성 가능 여부 확인 API** - **POST /api/check-image-generation**: 글 ID 기반 이미지 생성 권한 확인 - **팀/개인 분기 처리**: 팀 글쓰기 → 팀 AI 설정 + 월간/일일 제한, 개인 글쓰기 → 개인 플랜 + 월간 제한 - **5가지 비활성화 사유**: PLAN_NOT_SUPPORTED, LIMIT_EXCEEDED, TEAM_AI_DISABLED, TEAM_LIMIT_EXCEEDED, DAILY_LIMIT_EXCEEDED - **WritingManager.checkImageGenerationAvailability()**: 클라이언트 메서드 추가 - **타입 추가**: CheckImageGenerationRequest, CheckImageGenerationResult, ImageGenerationDisableReason - **다국어 지원**: imageUpload.disabledReasons namespace (ko/en/ja) - 📋 **계획된 기능 문서화** - **plannedFeature/ 디렉토리 신규 생성**: 향후 개발 예정 기능들 정리 - **우선순위별 분류**: high-priority.md, medium-priority.md, low-priority.md - **구현 가이드**: implementation-guide.md - **주요 기능**: 부모님 대시보드, 선생님 첨삭 시스템, 글 포트폴리오, 협업 글쓰기 등 **업데이트** (2025-12-12): - 🔒 **팀 보안 설정 통합** - **TeamSecuritySettingsDialog 확장**: 공개설정(isPublic) + 보안레벨(securityLevel) 통합 - **공개 설정 스위치**: 보안 단계 선택 아래에 배치 (팀 공개, 글 공개 허용, 팀 설명, 커버 이미지) - **검색 가능/불가능 태그**: TeamInfoCard 보안 정보에 isPublic 기반 배지 추가 - **TeamPublicSettings 제거**: 팀 관리 페이지에서 분리된 공개 설정 섹션 제거 - **다국어 지원**: searchable/notSearchable 키 추가 (ko/en/ja) - 👑 **팀 소유자 이전 기능** - **POST /api/team/[teamId]/transfer-ownership**: 소유자 권한 이전 API - **TeamMemberEditor 컴포넌트**: 멤버 메뉴에 "소유자 이전" 옵션 추가 - **소유자 표시**: 멤버 목록에서 owner 역할 배지 표시 - **다국어 지원**: transferOwnership, transferDialogTitle, transferConfirm 등 (ko/en/ja) - 🛡️ **SecurityLevelSelector 개선** - **검색 가능 여부 표시**: 각 보안 레벨별 검색 가능 아이콘 (LuSearch/LuSearchX) - **searchable 속성 추가**: SecurityLevelOption 타입 확장 **업데이트** (2025-12-10): - 📉 **플랜 다운그레이드 선택 옵션** - **두 가지 선택지**: 즉시 다운그레이드 (크레딧 전환) / 다음 결제일 적용 (기존 scheduledPlan) - **DowngradeOptionDialog 컴포넌트**: 다운그레이드 방식 선택 UI - **GET /api/user/plan/estimate-refund**: 예상 환불 크레딧 조회 API - **downgradeMode 파라미터**: "immediate" | "scheduled" - **planUtils.ts**: 클라이언트/서버 공용 플랜 유틸리티 (isUpgrade, isDowngrade) - 🔄 **결제 주기 변경 기능** - **월간 ↔ 연간 변경**: 동일 플랜 내 결제 주기 변경 지원 - **isBillingCycleChange 플래그**: 결제 주기만 변경 시 감지 - **scheduledPlan.billingCycle**: 예약된 결제 주기 저장 - **다음 결제일 자동 적용**: 만료 시 새 결제 주기로 전환 - 👥 **팀 기반 AI 사용량 제한** - **teamMemberUsage**: 팀원별 AI 크레딧 사용량 추적 - **팀 소유자 플랜 연동**: 팀원 AI 제한은 소유자 플랜 기준 - **credits.ts**: checkAIFeatureAvailability(), deductAICredits() 함수 **업데이트** (2025-12-08 오후): - 💳 **AI 크레딧 환불 시스템** - **업그레이드 환불**: Prorated 계산 → AI 크레딧 지급 - **환율**: 100원 = 10 크레딧 - **AI 기능 비용**: 분석 20, 이미지 100, 도우미 10 크레딧 - **FirestoreUser.aiCredits**: 영구 사용, 월 제한 무시 - **credits.ts**: calculateProratedRefund(), isUpgrade(), PLAN_MONTHLY_PRICES - **planLimits.ts**: AI_FEATURE_COSTS, CREDIT_EXCHANGE_RATE, convertKRWToCredits() - 🛒 **구매 플로우 구현** - **PurchaseConfirmationDialog**: 플랜 정보, 가격 포맷팅, 월간/연간 배지 - **POST /api/user/purchase**: Mock 승인 + 환불 계산 + 크레딧 지급 + 플랜 업데이트 (원자적) - **UserManager.purchasePlan()**: creditsAdded 반환 - **pricing 페이지**: 로그인 체크, 플랜별 분기, 크레딧 안내 toast - **향후 Toss Payments 연동 준비**: 주석으로 연동 포인트 표시 - 📊 **구독 관리 UI** - **UserSettingsDialog 구독 탭**: 현재 플랜, 플랜 제한, 실시간 사용량, AI 크레딧 잔액 - **SettingBox 컴포넌트**: 투명 배경, 얇은 테두리, 블러 효과 - **SettingButton 컴포넌트**: 브랜드 테두리, 호버 그라데이션 - **업그레이드 버튼**: 새 창, locale 포함 URL - 🔗 **팀 API 통합** - **GET /api/team/[teamId]**: 보안 로직 통합 (공개 팀 + 멤버 체크) - **/public 엔드포인트 삭제**: 중복 제거 - **TeamCard AI 배지**: team.aiEnabled 표시 - 🌐 **다국어 지원**: 20+ 키 추가 (ko/en/ja) **최신 업데이트** (2025-12-08 오전): - 🤖 **팀 AI 2단계 계층 구조** - **마스터 스위치**: `team.aiEnabled` (팀 전체 AI 기능 활성화) - **하위 옵션**: `team.aiAssistanceConfig.enabled` (글쓰기 도우미) - **플랜 제한**: `maxAIEnabledTeams` (Free: 0개, Classroom: 1개, Academy: 5개, School: 무제한) - **TeamAISettings 컴포넌트**: 2단계 UI (마스터 OFF 시 도우미 숨김) - **3가지 상태 피드백**: 활성화 / 플랜 제한 / 비활성화 - **API 권한 체크**: PUT /api/team/[teamId] aiEnabled 변경 시 플랜 검증 - **다국어 지원**: team.manage.teamAI namespace (ko/en/ja 6개 키) - 🎴 **TeamCard 컴포넌트 통합** - **리디자인**: 내 팀 페이지 스타일 (bg.subtle, border, hover 효과) - **커버 이미지**: team.coverImage 140px 높이 표시 - **팀 설명**: team.description 2줄 lineClamp - **Props**: isOwner, onClick 추가 - **적용 범위**: `/team` (내 팀 목록), `/team/all` (공개 팀 목록) - **인라인 함수 제거**: renderTeamCard → TeamCard 컴포넌트로 전환 - 🔒 **공개 팀 코드 보안 강화** - **Team.code**: `string` → `string?` (optional) - **서버 API**: getPublicTeams() 전체 코드 제거, GET /api/team/[teamId]/public 멤버 아닌 경우 제거 - **TeamCard**: 코드 없으면 숨김 (조건부 렌더링) - **타입 안전성**: StudentLoginFlow, TeamInfoCard, firebaseAuth.ts 수정 **업데이트** (2025-12-04): - 🔀 **글쓰기 페이지 라우트 분리** - **기존**: `/write?mode=wrt`, `/write?mode=img`, `/write?id=xxx` (1,540줄 단일 파일) - **변경**: 4개 독립 라우트로 분리 - `/write` - 모드 선택 화면 (~140줄) - `/write/text` - 글 먼저 모드 (~800줄) - `/write/image` - 그림 먼저 모드 (~900줄) - `/write/edit/[id]` - 수정 모드 (~700줄) - **하위 호환성**: 기존 URL은 새 URL로 자동 리다이렉트 - **ModeSelectionCard 업데이트**: 라우트 URL 변경 - **WritingCard 업데이트**: 수정 링크 `/write/edit/${id}`로 변경 **업데이트** (2025-12-03): - ⚙️ **사용자 설정 다이얼로그** (`UserSettingsDialog.tsx`) - **프로필 정보 수정**: 이름, 프로필 사진 업로드 (드래그앤드롭, Canvas 리사이즈) - **환경 설정**: 테마 (라이트/다크), 주간 목표 (1~10개) - **Firebase Auth + Firestore 분리 업데이트**: displayName/photoURL → Auth, settings → Firestore - **UserProfileButton 통합**: 설정 메뉴 클릭 시 다이얼로그 열림 - **Tabs 레이아웃**: 프로필/설정 탭 - **다국어 지원**: components.settingsDialog namespace (ko/en/ja) - 📸 **프로필 사진 업로드** - **드래그앤드롭**: 파일 업로드 및 미리보기 - **파일 검증**: JPEG/PNG/WebP, 5MB 제한 - **Canvas 리사이즈**: 800x800, 90% 품질 - **Firebase Storage**: `profile_photos/{uid}/` 경로 업로드 - **토스트 알림**: 성공/실패 메시지 - **Storage 규칙**: profile_photos 경로 읽기/쓰기 권한 추가 - 🎨 **GlassCard glow 기능 개선** - **glow prop**: 선택적 글로우 효과 추가 - **다크 모드 대응**: 라이트/다크 모드별 색상 조정 **업데이트** (2025-12-02): - 📰 **피드 시스템 전체 구축** (`/write`) - **4개 피드 컴포넌트**: TodayTopicCard (오늘의 글감), WeeklyGoalCard (주간 목표), RecentActivityCard (최근 활동), InspirationCard (추천 영감) - **GlassCard 컴포넌트**: 글래스모피즘 UI (반투명 배경, 블러 효과) - **CompactCardsRow**: 주간 목표 + 최근 활동 가로 배치 - **FeedManager**: 피드 데이터 관리 및 캐싱 (2분 TTL) - **API Routes 4개**: `/api/feed/daily-prompt`, `/api/feed/inspirations`, `/api/feed/weekly-stats`, `/api/feed/team-activity` - **타입 시스템**: Inspiration, DailyPrompt, WeeklyStats, TeamActivity - 🎨 **AI 영감 생성 시스템** - **Cloud Function (Scheduled)**: generateDailyInspirations (매일 새벽 자동 생성) - **Cloud Function (HTTP)**: generateInspirationsManual (관리자 수동 생성) - **Vertex AI 통합**: Gemini 2.5 Flash 모델 (@google/genai) - **Unsplash API**: 이미지 검색, 다운로드, Storage 저장, 크레딧 정보 - **싱글톤 패턴**: Vertex AI 클라이언트 재사용 최적화 - **Rate Limit 대응**: API 호출 1초 간격 추가 - 🌟 **컴포넌트 개선** - **InspirationCard**: vertical/horizontal 레이아웃, 이미지 로딩 스켈레톤 - **InspirationSection**: grid/horizontal 레이아웃, maxItems prop - **ModeSelectionCard**: 드롭 쉐도우, 부드러운 전환 애니메이션 - **WeeklyGoalCard**: 스켈레톤 UI 개선 - 🔤 **Tlab신영복체 폰트 추가** - **폰트 파일**: public/fonts/Tlab신영복체.ttf - **적용 위치**: write 페이지 제목 텍스트 **업데이트** (2025-12-01): - ✍️ **글쓰기 모드 선택 기능** (`/write`) - **모드 선택 화면**: 글부터 쓰기 / 그림부터 올리기 선택 - **URL 파라미터**: `?mode=wrt` (글부터), `?mode=img` (그림부터) - **ImageDropzone 컴포넌트**: 드래그앤드롭 이미지 업로드, 미리보기 - **ImageFirstLayout 컴포넌트**: 이미지+에디터 2컬럼 레이아웃 - **pendingImageStore 유틸리티**: IndexedDB 기반 이미지 임시 저장 (새로고침 유지) - **캐릭터 이미지**: startWriting.png, uploadImage.png - **카드 디자인**: 그라데이션 배경, 상단 장식 바, 호버 애니메이션 - **다국어 지원**: modeSelection namespace (ko/en/ja) **업데이트** (2025-11-28): - 💰 **가격정책 페이지 추가** (`/pricing`) - **4개 플랜**: Free, Classroom, Academy, School - **월간/연간 토글**: 연간 결제 시 20% 할인 - **기능 비교 테이블**: 플랜별 기능 한눈에 비교 - **FAQ 섹션**: 자주 묻는 질문 4개 - **다국어 지원**: ko, en, ja 완벽 지원 - **PricingCard 컴포넌트**: 재사용 가능한 가격 카드 - **Navbar 링크 추가**: "요금제" 메뉴 **업데이트** (2025-11-27 PM-2): - 📊 **채점 시스템 전면 개편** - **0~1 품질 기반 점수**: 기존 "표현 1개당 1점" → 5단계 품질 평가 (0, 0.25, 0.5, 0.75, 1.0) - **가중 평균 0~100점**: 최종 점수 = Σ(영역 점수 × 가중치) × 100 - **계층적 설정**: 기본값 → 팀 설정 → 주제 설정 (우선순위 오버라이드) - **타입 시스템**: `ScoringConfig`, `ScoringWeights`, `ScoringRubric`, `AreaRubric` - **설정 병합 서비스**: `scoringConfigService.ts` (mergeScoringConfig 함수) - **AI 일관성**: temperature=0 설정으로 점수 결정론적 출력 - **TeamScoringSettings 컴포넌트**: 4개 영역 가중치 슬라이더 (합계 100% 검증) - **TeamRubricSettings 컴포넌트**: 5단계 채점 기준 직접 편집 (아코디언 UI) - **팀 관리 페이지 통합**: AI 설정 → 채점 가중치 → 채점 기준 순서 - **다국어 지원**: `team.manage.scoring.*`, `team.manage.rubric.*` (ko/en/ja) - **UI 컴포넌트 업데이트**: ScoreBadge (0~100), ImprovementHint (퍼센트 표시) **최신 업데이트** (2025-11-27 PM): - 🖼️ **팀 커버 이미지 시스템 추가** - **Team 타입 확장**: `coverImage?: string` 필드 추가 - **Firebase Storage 업로드**: 이미지 → Storage → 공개 URL - **ImageDropzone 컴포넌트**: 드래그앤드롭 지원, 미리보기 (범용 컴포넌트) - **API Route**: POST/DELETE `/api/team/[teamId]/cover-image` - **TeamManager 메서드**: `uploadCoverImage()`, `deleteCoverImage()` - **팀 생성**: 생성 시 이미지 선택 가능 (선택적) - **팀 관리**: 공개 설정에서 이미지 즉시 업로드/삭제 - **TeamCard 표시**: 커버 이미지가 있으면 카드 상단에 140px 높이로 표시 - **다국어 지원**: `team.coverImage.*` (ko, en, ja) - **이미지 제한**: JPEG/PNG/WebP/GIF, 최대 5MB, 16:9 권장 **최신 업데이트** (2025-11-27 AM): - 🌐 **글 공개 범위 시스템 추가** - **WritingVisibility enum**: PUBLIC (전체 공개), TEAM (팀 내 공개), PRIVATE (비공개) - **VisibilitySelector 컴포넌트**: 글 저장 시 공개 범위 선택 - **VisibilityBadge 컴포넌트**: 글 목록에서 공개 범위 표시 - 🏢 **팀 공개 설정 추가** - **Team 타입 확장**: `isPublic`, `allowPublicWritings`, `description` 필드 - **공개 설정 UI**: 팀 관리 페이지에서 공개/비공개 전환 - 📋 **공개 팀 목록 페이지** (`/team/all`) - **TeamCard 컴포넌트**: 글래스모피즘 스타일 팀 카드 - **페이지네이션**: 커서 기반 무한 스크롤 - **Navbar 메뉴 추가**: "공개 팀" 링크 - 🔀 **팀 상세 페이지 통합** (`/team/[teamId]`) - **멤버 뷰**: 멤버 목록, 관리/나가기 버튼 - **공개 뷰**: 팀 정보, 공개 글 목록, 참여 버튼 - **비공개 팀**: 접근 불가 메시지 **업데이트** (2025-11-22): - 🔄 **글 상세보기 페이지 Server Component 전환** - **SEO 최적화**: 서버에서 HTML 생성 (검색엔진 크롤링 가능) - **SNS 공유 미리보기**: 카카오톡/페이스북 링크 미리보기 지원 - **서버 데이터 로딩**: Firebase Admin SDK 사용 (`src/lib/server/writing.ts`) - **성능 개선**: 초기 로딩 빠름 (데이터 포함된 HTML 전송) - **권한 체크**: 서버에서 처리 (클라이언트 깜빡임 없음) - `getTranslations()` 서버 번역 함수 사용 - `params: Promise<{locale, writingId}>` 타입 사용 - 🔙 **BackButton 공통 컴포넌트 추가** (`src/components/layout/BackButton.tsx`) - **기본 동작**: `router.back()` (브라우저 히스토리 뒤로) - **옵션 1**: `href` prop으로 특정 경로 이동 - **옵션 2**: `label` prop으로 버튼 텍스트 커스터마이징 - **다국어 지원**: `t('interaction.back')` 기본 라벨 - **확장성**: ButtonProps 상속으로 모든 Button 속성 지원 - **재사용성**: 모든 페이지에서 일관된 뒤로가기 UX **업데이트** (2025-11-21): - 📦 **홈 페이지 모듈화** - **6개 컴포넌트 분리**: HeroSection, QuickActionCard, QuickActionsGrid, ViewAllWritingsCard, EmptyStateCard, RecentActivitySection - **코드 감소**: 580줄 → 223줄 (62% 감소) - **Semantic token 적극 활용**: `bg`, `fg`, `border` 등 우선 사용 - **재사용성 향상**: 각 컴포넌트 단일 책임 원칙 준수 - **UI 일관성**: 글래스모피즘, framer-motion 애니메이션, 브랜드 컬러 통일 - **JSX 주석 한글화**: 모든 주석을 한글로 통일 - 🎨 **수정 모드 UX 대폭 개선** - **Sticky 헤더바**: 오렌지/앰버 그라데이션 배경, 상단 고정 (z-index: 100) - **강조된 테두리**: 주제 선택 + 글쓰기 영역에 오렌지 테두리 (2px solid) - **섀도우 효과**: 글쓰기 영역에 오렌지 글로우 (라이트/다크 모드 대응) - **Writing ID 표시**: 어떤 글을 수정 중인지 명확하게 표시 - **색상 시스템**: Light(#FFB366, #FF9800, #E65100) / Dark(#8B6B47, #C4A572) - 기존 단순 배지 → 전체 UI 테마로 업그레이드 - 🔒 **수정 모드 주제 변경 차단** - TopicSelector에 `readonly` prop 추가 - 수정 모드에서는 Dialog 트리거 버튼 숨김, "현재 주제" 라벨만 표시 - 데이터 무결성 보장 (템플릿 덮어쓰기 방지) - AI 설정/실시간 모니터링 혼선 방지 - 다국어 지원: `readonlyNote`, `currentTopic` (ko, en, ja) - 🧹 **UI 정리** - "새 글쓰기" 버튼 제거 (불필요한 기능, 실수 방지) - 상단 버튼 영역 단순화 ("저장된 글조각" 버튼만 유지) - 미사용 i18n 키 정리 (`newWriting`, `discardConfirm`) **업데이트** (2025-11-20): - 🎨 **AI 이미지 생성 스타일 일관성 개선** - **Vertex AI Imagen 4.0 Fast**: 글 내용 기반 자동 이미지 생성 (모델 업그레이드) - **일관된 스타일 가이드**: 모든 이미지에 동일한 화풍 적용 - 화풍: 따뜻한 디지털 일러스트, 애니메이션/만화 스타일 - 색감: 부드럽고 따뜻한 톤, 자연스러운 채도 - 분위기: 친근하고 밝은, 초등학생 눈높이 - **강화된 Negative Prompt**: 과도한 사실주의, 어두운 분위기, 유치한 캐릭터 차단 - **한국 문화권 고려**: "Korean elementary student" 명시로 아시아권 얼굴 특징 반영 - **AI 프롬프트 최적화**: Gemini Flash가 원문 → 핵심 키워드 추출 (6-12개) → 스타일 키워드 자동 추가 - **폴백 안전성**: AI 최적화 실패 시에도 일관된 스타일 적용 **업데이트** (2025-11-17): - 🎨 **AI 이미지 생성 시스템 + 장면 분리 + 프롬프트 최적화** - **AI 장면 분리**: Gemini가 글에서 3~5개 주요 장면 자동 추출 - **4단계 플로우**: 장면 추출 → 장면 선택 → 프롬프트 최적화 → 이미지 생성 → 결과 표시 - **사용자 선택권**: 여러 장면 중 원하는 장면만 이미지로 생성 - **구조화된 프롬프트**: 피사체/행동/배경/디테일/분위기/스타일 구분하여 추출 - **재선택 가능**: 이미지 생성 후 "다른 장면 선택"으로 여러 이미지 생성 - **Firebase Storage 저장**: base64 이미지 → Storage 업로드 → 공개 URL 생성 - **Writing 문서 업데이트**: generatedImage 필드에 이미지 정보 저장 - **안전 필터링**: 부적절한 콘텐츠 자동 차단 - **다국어 지원**: 한국어/영어/일본어 프롬프트 및 UI - **타입**: Scene, SceneExtractionResponse - **서비스**: sceneExtractionService.ts (장면 추출), imagenService.ts (프롬프트 최적화) - **프롬프트**: sceneExtraction.ts (장면 분리), promptOptimization.ts (키워드 추출) - **UI**: SceneSelector (장면 선택), GenerateImageDialog (4단계 플로우) - **API**: POST /api/extract-scenes (장면 추출), POST /api/generate-image (프롬프트 최적화 + 이미지 생성) **업데이트** (2025-11-14 PM): - 🤖 **AI 글쓰기 도우미 시스템** - **4단계 점진적 힌트**: 질문 → 방향 → 선택지 → 예시 문장 - **작성 멈춤 감지**: 5분간 입력 없으면 자동 제안 (useWritingInactivityDetection 훅) - **주제 맥락 활용**: 주제 정보(title, keywords, category)를 프롬프트에 포함 - **팀별 설정**: 선생님이 팀 관리 페이지에서 On/Off 가능 - **서버 검증**: AI 힌트 요청 시 팀 설정 확인 (enabled, allowedHintLevels) - **사용 제한**: 글당 최대 5회, 힌트 간 3분 쿨다운 - **다국어 프롬프트**: 한국어/영어/일본어 지원 - **UI 컴포넌트**: InactivityPrompt (플로팅 버튼), HintDisplay (Dialog) - **API**: POST /api/writing-assistance, GET/PUT /api/team/[teamId]/ai-config - **Firestore**: Team.aiAssistanceConfig 필드 추가 **업데이트** (2025-11-14 AM): - 💾 **개별 글 분석 결과 저장 시스템** - Writing 타입에 WritingAnalysis 필드 추가 - 글쓰기 페이지 실시간 분석 제거 (저장 시에만 분석) - AI 분석 + 맞춤법 검사를 DB에 저장 - 패턴 분석 시 저장된 결과 재사용 (90% 비용 절감) - contentHash 기반 변경 감지 - 맞춤법 에러 히스토리 기능 완성 **업데이트** (2025-11-13): - 🌏 **다국어 지원 시스템 (i18n)** - next-intl 라이브러리 기반 - **3개 언어 지원**: 한국어(ko), 영어(en), 일본어(ja) - **[locale] 라우팅**: URL에 언어 코드 표시 (`/ko/home`, `/en/home`, `/ja/home`) - **브라우저 언어 자동 감지**: `Accept-Language` 헤더 기반 자동 리다이렉트 - **개선된 언어 전환**: LocaleSwitcher 드롭다운 메뉴 (국기 이모지 🇰🇷 🇺🇸 🇯🇵, 현재 언어 체크 표시) - **번역 파일**: `messages/ko.json`, `messages/en.json`, `messages/ja.json` (각 407줄, 220+ 키) - **완성된 페이지**: Navbar, Landing, Home, Team(전체), Write 페이지 번역 완료 - **완성된 컴포넌트**: LoginDialog, LoginForm, SignupForm, UserProfileButton, StudentLoginFlow, SavedDraftsDialog, SecurityLevelSelector 번역 완료 - **어린이 친화적**: 일본어는 한자 최소화, ひらがな 우선 사용 - **타입 안전**: useTranslations 훅으로 타입 체크 - **쿠키 저장**: 사용자가 선택한 언어 기억 (`NEXT_LOCALE`) - **site.ts 텍스트 이동**: 사이트 메타데이터도 번역 파일로 관리 **업데이트** (2025-11-12 PM): - 📡 **실시간 글쓰기 모니터링 시스템** - Firebase Realtime Database 기반 실시간 통신 (Redis Pub/Sub 방식) - **모든 팀 멤버 표시** (getUsersByTeam) - **3가지 상태 관리 및 자동 정렬**: - 🟢 작성 중 (isActive: true, lastUpdated < 30초) - 초록 배지, 핑크 테두리 - 🟠 나감 (isActive: false, 마지막 통계 유지) - 주황 배지, 주황 테두리 - ⚪ 대기 중 (한 번도 작성 안 함) - 회색 배지, 투명도 60% - 5초 주기 자동 업데이트 (글자 수, 단어 수, lastUpdated 타임스탬프) - **작성 속도 계산** (클라이언트 측, charDiff * 12 = 글자/분) - **Sparkline 그래프** (Area Chart, 최근 10개 데이터 포인트, 0 표시) - **인터랙티브 툴팁** (마우스 오버 시 속도 + 몇 초 전 데이터) - 미리보기 요청-응답 (관리자 클릭 → 학생 응답 → Dialog, 작성 중만) - **30초 타임아웃**: 업데이트 없으면 "나감" 처리 - **마지막 통계 유지**: Firebase 삭제되어도 클라이언트 상태 유지 - onDisconnect() 자동 정리 (페이지 이탈 시 세션 삭제) - LiveWritingMonitor 컴포넌트 (주제 Select, StudentMonitorCard) - WritingSessionManager (Realtime DB 작업, 상세 디버그 로그) - 완전 무료 (동시 접속 100명까지, 1GB/day) - Security Rules (본인 쓰기, 인증된 사용자 읽기) **업데이트** (2025-11-12 AM): - ✅ **Writing API 구현 완료** - POST /api/writing - 글 생성 (서버에서 wordCount/charCount 자동 계산, 🆕 **analysis 저장**) - GET /api/writing/[id] - 글 조회 (작성자만 접근) - PUT /api/writing/[id] - 글 수정 (작성자만 접근) - DELETE /api/writing/[id] - 글 삭제 (작성자만 접근) - POST /api/writing/user - 사용자 글 목록 - POST /api/writing/recent - 최근 글 (limit 파라미터) - 서버 레이어: `src/lib/server/writing.ts` (Firestore CRUD) - WritingManager: 기존 클라이언트 캐싱 유지 (1분~5분) - 📊 **글 작성 패턴 분석 - 3가지 분석 타입 지원** - **self**: 본인의 모든 published 글 분석 (기존) - **by-team**: 팀 소유자가 팀원의 팀 내 전체 글 분석 (신규) - **by-topic**: 팀 소유자가 특정 주제로 작성된 팀원 글 분석 (신규 - UI만) - 권한 체크: 팀 소유자만 팀원 분석 가능, 프라이버시 보호 - API 파라미터 확장: `analysisType`, `targetUserId`, `topicId`, `teamId` - 🎯 **WritingPatternDialog 개선** - Props 확장: 분석 타입별 파라미터 지원 - 제목 동적 변경: "OOO 학생의 'XXX' 주제 분석" 등 - 분석 정보 안내: "이 팀에서 작성된 N개 글 분석" 등 - 🏫 **팀 관리 페이지 UI 추가** - 멤버 카드 메뉴에 "팀 내 글 분석" 버튼 (by-team) - TopicMemberAnalysisSection 컴포넌트 (by-topic - 추후 구현) - 🔒 **보안**: 팀 외 글(자유 주제, 다른 팀)은 분석에서 제외 - ⚡ **Content Hash 기반 3단계 스마트 캐싱** - L1 캐시: localStorage (영구, LRU 10개) ~1ms - L2 캐시: Firestore `patternAnalyses` 컬렉션 (영구) ~100ms - L3 캐시: Server in-memory (5분, 50개) ~50ms - 해시 생성: `id:updatedAt` 조합 (SHA-256) - 변경 자동 감지: 글 추가/수정 시 해시 변경 → 재분석 - AI 비용 절감: 동일 글 세트는 전체 사용자 기준 1회만 분석 - 서버 레이어: `src/lib/server/patternAnalysis.ts` (Firestore CRUD) - 유틸리티: `contentHash.ts`, `patternCacheManager.ts` **2025-11-11 (PM) 업데이트**: - 📊 **글 작성 패턴 분석 시스템** - 최근 10개 글을 분석하여 작성 스타일, 강점/약점, 발전 추이 파악 - AI 기반 종합 평가 및 맞춤형 추천 사항 제공 - 자주 사용하는 표현, 맞춤법 경향 분석 - WritingPatternDialog + WritingPatternDisplay 컴포넌트 - `/api/analyze-pattern` API 엔드포인트 (5분 캐싱) - ✨ **실시간 하이라이트 시스템** (Tiptap Extensions) - SpellingHighlight: 맞춤법 오류를 빨간 물결 밑줄로 표시 - SensoryWordHighlight: 감각 단어를 색상별 하이라이트 (초록/파랑/보라) - 기존 ScoreDisplay/SpellingErrorDisplay 제거 (하이라이트로 대체) - 💬 **인터랙티브 툴팁 시스템** - EditorTooltip: 하이라이트된 단어 클릭 시 상세 정보 표시 - 맞춤법 오류: 원본 → 수정, 이유 설명 - 감각 단어: 단어 타입, 격려 메시지 - Portal + 외부 클릭/ESC 키로 닫기 - 🔔 **Toast 알림 추가** (write 페이지) - 텍스트 분석 시작/완료/실패 알림 (점수 표시) - 맞춤법 검사 시작/완료/실패 알림 (에러 개수 표시) - 로딩 상태 표시 (duration: Infinity) **2025-11-11 (AM) 업데이트**: - 🔄 **Google AI SDK 마이그레이션** - `@google-cloud/vertexai` → `@google/genai` (최신 SDK) - Response Schema 지원 (JSON 응답 강제) - Vertex AI 모드 지원 (`vertexai: true`) - 📊 **텍스트 분석 개편** - 평가 기준 재설계: 오감(4점) + 감정(2점) + 대화(2점) + 의성어(2점) - `descriptive` → `emotion` 필드 변경 - 프롬프트 최적화 (칭찬 강화, 제안 0~1개로 제한) - 📜 **분석 히스토리 시스템** - Draft에 `analysisHistory` 추가 (최대 5개) - AI가 수정 과정 인식하여 격려 - 이전 버전 비교 피드백 - ✍️ **맞춤법 검사 서비스** (독립적) - Gemini 기반 맞춤법 검사 - 텍스트 분석과 별도 debounce (5초) - 🤖 **실시간 피드백 시스템** (Vertex AI 기반) - Delta 전송 (토큰 40% 절감) - 서버 캐싱 (중복 제거) - 🌏 **Multi-Region Failover** (가용성 99.9%) - 3개 region 자동 전환 (도쿄, 싱가포르, 미국) - Region health tracking - RPM 3배 증가 (15 → 45) **2025-11-10 업데이트**: - ⚠️ 주제 변경 경고 Dialog (내용 초기화 알림, 임시 저장 안내) - 📝 다중 글조각 관리 시스템 (DraftManager, SavedDraftsDialog) - 💾 강화된 자동 저장 (2초 debounce, 저장 상태 표시) - 🎨 테마 슬롯 레시피 추가 (Dialog, Select 자동 배경색) - 📋 TopicSelector Dialog 리디자인 (glassmorphism, 탭 기반 그룹핑, 미리보기 7:3 레이아웃) - 🔐 5단계 보안 레벨 시스템 (팀별 보안 정책 선택) - 📦 User 타입 분리 (FirestoreUser / User) - 🏷️ 닉네임 저장 위치 변경 (team.members[uid].nickname) - 🗑️ memberUids optional (Object.keys(members) 사용) --- ## 페이지 구조 ### 🌏 다국어 라우팅 (2025-11-13) 모든 페이지는 `[locale]` 세그먼트를 통해 다국어를 지원합니다: - **한국어**: `/ko/*` (기본값) - **영어**: `/en/*` - **일본어**: `/ja/*` 🆕 - **자동 감지**: 브라우저 언어 설정에 따라 첫 방문 시 자동 리다이렉트 - **언어 전환**: Navbar 우측 🌐 버튼 → 드롭다운 메뉴 (🇰🇷 🇺🇸 🇯🇵) **URL 예시**: - 랜딩: `/ko`, `/en`, `/ja` - 홈: `/ko/home`, `/en/home`, `/ja/home` - 글쓰기: `/ko/write`, `/en/write`, `/ja/write` - 팀: `/ko/team`, `/en/team`, `/ja/team` ### ✅ 구현 완료 | 페이지 | 경로 | 설명 | 주요 기능 | 다국어 | |-------|------|------|---------|--------| | **랜딩 페이지** | `/[locale]` | 서비스 소개 및 홍보 (비로그인 전용) | Hero, Features, How It Works, CTA, Footer
로그인 시 `/home`으로 자동 리다이렉트
🆕 **전체 번역 완료** (사이트명, 태그라인, 모든 섹션) | ✅ 완료 | | **유저 홈** | `/[locale]/home` | 인증된 사용자 대시보드 | 환영 메시지, 빠른 시작 대시보드, **최근 활동 (최근 글 3개 표시)**
비로그인 시 `/`로 자동 리다이렉트
정식 계정은 "내 팀" 카드 추가 표시
🆕 **WritingCard Grid, "모두 보기" 버튼**
🆕 **전체 번역 완료** (웰컴 메시지, 모든 액션 카드) | ✅ 완료 | | **내 글 모음** | `/[locale]/writings` | 🆕 **전체 글 목록 페이지** | 🆕 **사용자의 모든 글 표시 (Grid)**
🆕 **정렬 Select (최신순/오래된순)**
🆕 **WritingCard 컴포넌트 사용**
🆕 **Empty state 처리**
🆕 **전체 번역 완료** (ko/en/ja) | ✅ 완료 | | **글 상세보기** | `/[locale]/writing/[writingId]` | 🆕 **Server Component 기반 상세 페이지** | 🆕 **SEO 최적화** (서버에서 HTML 생성)
🆕 **SNS 공유 미리보기** (카카오톡/페이스북)
🆕 **서버 데이터 로딩** (Firebase Admin SDK)
제목, 내용, 생성된 이미지 표시
주제 및 팀 정보 Badge
프롬프트 Collapsible
🆕 **CommentList** (Client Component)
🆕 **BackButton** 공통 컴포넌트 사용 | ✅ 완료 | | **글쓰기** | `/[locale]/write` | Tiptap 기반 순수 텍스트 에디터 + 주제 선택 | 주제 선택 (자유 주제/개인 주제/팀 주제)
🆕 **글 수정 기능 (URL params ?id=xxx)**
🆕 **수정 모드 배지 표시**
🆕 **주제 변경 경고** (작성 중 내용 초기화 알림, 임시 저장 안내)
제목 입력 (Editable), 순수 텍스트 에디터 (포맷팅 없음)
🆕 **다중 글조각 관리** (최대 10개), "저장된 글조각" 버튼
🆕 **강화된 자동 저장** (2초 debounce, 저장 상태 표시: 저장 중/저장됨)
🆕 **저장 플로우 개편** (저장 → 백그라운드 분석 → `/imageUpload` 리다이렉트)
🆕 **GenerateImageDialog 제거** (새 플로우로 대체)
템플릿 미리채우기 (제목/내용), Firestore 저장
비로그인도 접근 가능 (저장 시 로그인 유도) | ✅ 완료 | | **이미지 업로드/선택** | `/[locale]/imageUpload` | 🆕 **이미지 소스 선택 페이지 (글 저장 후 자동 이동)** | 🆕 **2가지 선택지**: AI 생성 (장면 추출 + 선택 + 생성) / 직접 업로드
🆕 **드래그앤드롭 파일 업로드** (미리보기, 5MB 제한, JPEG/PNG/WebP)
🆕 **Canvas API 클라이언트 사이드 리사이즈** (1920x1080 최대, 85% 품질)
🆕 **Firebase Storage 업로드** (WritingManager.uploadUserImage)
🆕 **이미 이미지 있으면 자동으로 `/interaction` 리다이렉트**
🆕 **다국어 지원** (imageUpload namespace, ko/en/ja) | ✅ 완료 | | **인터랙션 편집** | `/[locale]/interaction` | 🆕 **이미지 왜곡 편집 페이지 (이미지 생성/업로드 후 이동)** | 🆕 **7:3 그리드 레이아웃** (이미지 70%, 컨트롤러 30%)
🆕 **Sticky Header** (InteractionHeader, 스크롤 시 상단 고정)
🆕 **framer-motion 애니메이션** (모드 전환, 영역 선택 부드러운 전환)
🆕 **영역 목록 일반 모드 표시** (CustomAreaList, 모든 모드에서 접근 가능)
🆕 **에디터 버튼 우측 배치** (추가/삭제/숨기기, 가로 3개)
🆕 **컨트롤러 내부 스크롤** (커스텀 스크롤바, 높이 80dvh)
🆕 **반응형 이미지** (aspectRatio 유지, 찌그러짐 해결)
왜곡 영역 편집 (EditorCanvas, DistortionArea)
모션 프리셋 선택 (horizontal, vertical, rotate, pulse 등)
물리 설정 (stiffness, damping, mass)
에디터/인터랙션 모드 전환 (Switch)
저장 시 Writing.distortionAreas 업데이트 | ✅ 완료 | | **테스트** | `/[locale]/test` | 팀 코드 시스템 테스트 페이지 | 팀 코드 생성/검증 테스트
팀/학생 생성 테스트
학생 로그인 테스트
authStore 상태 확인 | 🔜 예정 | | **공개 팀 목록** | `/[locale]/team/all` | 🆕 **공개 팀 둘러보기** | 🆕 **공개된 팀 목록 표시** (isPublic=true)
🆕 **TeamCard 그리드** (글래스모피즘)
🆕 **페이지네이션** (커서 기반)
🆕 **Navbar "공개 팀" 메뉴** | ✅ 완료 | | **내 팀 목록** | `/[locale]/team` | 내가 만든/참여한 팀 목록 (정식 계정 전용) | 팀 카드 그리드, 팀 정보 (코드, 멤버 수, 보안 설정)
"새 팀 만들기" 버튼 | ✅ 완료 | | **팀 생성** | `/[locale]/team/create` | 새 팀 만들기 (정식 계정 전용) | 팀 이름 입력, 팀 코드 자동 생성
🆕 **5단계 보안 레벨 선택** (RadioCard, 애니메이션)
🆕 **명단 관리 (Level 2/4)**: TagsInput으로 Enter/쉼표 입력
생성 후 `/team/[teamId]`로 이동 | ✅ 완료 | | **팀 상세 (통합)** | `/[locale]/team/[teamId]` | 🆕 **멤버/공개 뷰 통합 페이지** | 🆕 **멤버인 경우**: 멤버 목록, 관리/나가기 버튼
🆕 **비멤버 + 공개 팀**: 팀 정보, 공개 글 목록, 참여 버튼
🆕 **비멤버 + 비공개 팀**: 접근 불가 메시지
팀 코드 로그인 후 기본 이동 페이지 | ✅ 완료 | | **팀 관리** | `/[locale]/team/[teamId]/manage` | 팀 관리 페이지 (소유자 전용) | 팀 정보 및 코드, 보안 설정 표시
🆕 **팀 공개 설정** (isPublic, allowPublicWritings, description)
**팀 주제 관리 (생성/삭제)**
🆕 **주제별 학생 분석** (TopicMemberAnalysisSection)
멤버 목록 및 관리
🆕 **멤버 메뉴 - 팀 내 글 분석** (by-team)
"멤버 페이지 보기" 버튼 | ✅ 완료 | ### 🚧 구현 예정 | 페이지 | 경로 | 설명 | 상태 | |-------|------|------|------| | **학습하기** | `/[locale]/learn` | 레슨/코스 학습 | ❌ 미구현 (Navbar 링크만 존재) | | **스티커** | `/[locale]/stickers` | 스티커 컬렉션 | ❌ 미구현 (Navbar 링크만 존재) | | **마이페이지** | Dialog (별도 페이지 없음) | 사용자 대시보드 다이얼로그 | 🔜 계획 중 (UserProfileButton에서 열림) | --- ## 컴포넌트 구조 ### 📁 `src/components/auth/` - 인증 관련 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **AuthInitializer** | `AuthInitializer.tsx` | Firebase 인증 상태 초기화 | ✅ 완료 | | **LoginDialog** | `LoginDialog.tsx` | 로그인/회원가입 다이얼로그 (auth/team/link 모드 지원) | ✅ 완료 | | **StudentLoginFlow** | `StudentLoginFlow.tsx` | 팀 코드 학생 로그인 플로우 (3단계) | ✅ 완료 | | **LoginForm** | `LoginForm.tsx` | 로그인 폼 컴포넌트 (mode: auth\|link) | ✅ 완료 | | **SignupForm** | `SignupForm.tsx` | 회원가입 폼 컴포넌트 (mode: auth\|link) | ✅ 완료 | | **SocialLoginButton** | `SocialLoginButton.tsx` | 소셜 로그인 버튼 | ✅ 완료 | | **UserProfileButton** | `UserProfileButton.tsx` | 사용자 프로필/메뉴 버튼 (설정 메뉴 통합) | ✅ 완료 | **주요 기능**: - ✅ 이메일/비밀번호 로그인 - ✅ 이메일/비밀번호 회원가입 - ✅ 이름, 이메일, 비밀번호, 비밀번호 확인 입력 - ✅ 실시간 비밀번호 강도 게이지 - ✅ HIBP API 연동 (유출된 비밀번호 차단) - ✅ 폼 검증 및 에러 애니메이션 - ✅ Google OAuth 로그인 - ✅ 익명 계정 연결 기능 - ✅ 기존 폼 재사용 (LoginForm/SignupForm mode prop) - ✅ 신규 계정 생성 (linkWithCredential) - ✅ 기존 계정 병합 (API 데이터 마이그레이션) - ✅ 3개 소셜 로그인 버튼 표시 (Naver/Kakao/Google) - ✅ 용어 통일 ("병합" → "연결", "익명" → "임시") - ✅ 팀 코드 기반 사용자 로그인 (Anonymous Auth - 단순화됨) - ✅ 한글 팀 코드 ("춤추는 파란 사자" 형식) - ✅ 사용자 이름 입력 (2단계) - ❌ PIN 인증 제거 (복잡도 감소) - ✅ UID 기반 통합 인증 (currentStudent 제거) - ✅ 팀별 닉네임 시스템 - ✅ 로그인/회원가입 페이드 전환 애니메이션 - ✅ Anonymous ↔ 정식 계정 연결 (UID 유지) - 🔜 네이버 로그인 (준비 중) - 🔜 카카오 로그인 (준비 중) --- ### 📁 `src/components/settings/` - 사용자 설정 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **UserSettingsDialog** | `UserSettingsDialog.tsx` | 🆕 **사용자 설정 다이얼로그 (프로필/내 구독/환경설정)** - 3개 탭, 현재 플랜 표시, 플랜 제한 정보, AI 크레딧 잔액, 실시간 사용량, 업그레이드 버튼 (새 창, locale 포함) | ✅ 완료 | | **SettingBox** | `SettingBox.tsx` | 🆕 **설정 박스 컴포넌트** - 투명 배경 (3% opacity), 얇은 테두리 (whiteAlpha.200), 블러 효과 (blur 10px), BoxProps 확장 | ✅ 완료 | | **SettingButton** | `SettingButton.tsx` | 🆕 **설정 버튼 컴포넌트** - 투명 배경 (5% opacity), 브랜드 테두리, 호버 그라데이션, ButtonProps 확장 | ✅ 완료 | **주요 기능** (2025-12-03): - ✅ 프로필 정보 수정 - ✅ 이름 (displayName) 변경 - ✅ 프로필 사진 업로드 (드래그앤드롭, 미리보기) - ✅ 파일 유효성 검사 (JPEG/PNG/WebP, 5MB 제한) - ✅ Canvas API 리사이즈 (800x800, 90% 품질) - ✅ Firebase Storage 업로드 (`profile_photos/{uid}/` 경로) - ✅ 업로드 중 로딩 상태 표시 - ✅ 성공/실패 토스트 알림 - ✅ 환경 설정 - ✅ 테마 선택 (라이트/다크) - ✅ 주간 목표 설정 (슬라이더, 1~10개) - ✅ Firebase Auth + Firestore 분리 업데이트 - ✅ displayName, photoURL → Firebase Auth 업데이트 - ✅ settings → Firestore 업데이트 - ✅ userManager.updateUser() 자동 분리 처리 - ✅ UserProfileButton에서 "설정" 메뉴 클릭 시 열림 - ✅ Tabs 레이아웃 (프로필/설정) - ✅ GlassCard 컴포넌트 활용 - ✅ 다국어 지원 (components.settingsDialog namespace, ko/en/ja) --- ### 📁 `src/components/landing/` - 랜딩 페이지 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **FeatureCard** | `FeatureCard.tsx` | 특징 카드 | ✅ 완료 | | **StepCard** | `StepCard.tsx` | 단계 카드 | ✅ 완료 | | **SectionHeader** | `SectionHeader.tsx` | 섹션 헤더 | ✅ 완료 | --- ### 📁 `src/components/navigation/` - 네비게이션 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **Navbar** | `Navbar.tsx` | 상단 네비게이션 바 (다국어 지원) | ✅ 완료 | | **LocaleSwitcher** | `LocaleSwitcher.tsx` | 🆕 **언어 선택 메뉴** (KO/EN/JA, 드롭다운, 국기 이모지, 체크 표시) | ✅ 완료 | **네비게이션 링크** (다국어 지원): - 홈 (`/[locale]` 또는 `/[locale]/home`) - 인증 상태에 따라 동적 변경 - 비로그인: `/[locale]` (랜딩 페이지) - 로그인: `/[locale]/home` (유저 대시보드) - 글쓰기 (`/[locale]/write`) - 미구현 - 학습하기 (`/[locale]/learn`) - 미구현 - 스티커 (`/[locale]/stickers`) - 미구현 **주요 기능** (2025-11-13): - ✅ 3개 언어 지원 (ko, en, ja) - ✅ next-intl 타입 안전 Link 사용 - ✅ useTranslations 훅으로 번역 텍스트 관리 - ✅ LocaleSwitcher 드롭다운 메뉴 (국기, 언어명, 체크 표시) - ✅ 어린이 친화적 표현 (일본어 ひらがな 우선) --- ### 📁 `src/components/layout/` - 레이아웃 공통 컴포넌트 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **BackButton** | `BackButton.tsx` | 🆕 **뒤로가기 버튼 공통 컴포넌트** (router.back() 또는 특정 경로, 커스텀 라벨 지원) | ✅ 완료 | **주요 기능**: - ✅ `router.back()` 기본 동작 - ✅ `href` prop으로 특정 경로 이동 가능 - ✅ `label` prop으로 버튼 텍스트 커스터마이징 - ✅ 다국어 지원 (기본 라벨: `t('interaction.back')`) - ✅ ButtonProps 확장으로 모든 Button 속성 지원 **사용 예시**: ```tsx // 기본 사용 (router.back()) // 특정 경로로 이동 // 커스텀 라벨 // 추가 스타일링 ``` --- ### 📁 `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` | 🔄 **주제 선택 Dialog** (glassmorphism, 탭 기반 그룹핑, 미리보기 패널, 7:3 레이아웃) | ✅ 완료 | | **EditorTooltip** | `EditorTooltip.tsx` | 🆕 **인터랙티브 툴팁** (맞춤법/감각 단어 클릭 시 표시) | ✅ 완료 | | **WritingPatternDialog** | `WritingPatternDialog.tsx` | 🆕 **글 작성 패턴 분석 다이얼로그** (최근 10개 글 분석) | ✅ 완료 | | **WritingPatternDisplay** | `WritingPatternDisplay.tsx` | 🆕 **패턴 분석 결과 표시** (종합 평가, 발전 추이, 강점/약점, 추천) | ✅ 완료 | | **InactivityPrompt** | `InactivityPrompt.tsx` | 🆕 **작성 멈춤 프롬프트** (5분 입력 없을 시 플로팅 버튼) | ✅ 완료 | | **HintDisplay** | `HintDisplay.tsx` | 🆕 **AI 힌트 표시** (4단계 힌트 Dialog, RadioCard 선택지) | ✅ 완료 | | **GenerateImageDialog** | `GenerateImageDialog.tsx` | 🆕 **AI 이미지 생성 Dialog** (4단계 플로우: 장면 추출 → 장면 선택 → 이미지 생성 → 결과 표시) | ✅ 완료 | | **SceneSelector** | `SceneSelector.tsx` | 🆕 **장면 선택 컴포넌트** (RadioCard 기반, 이모지 표시, 원문 미리보기) | ✅ 완료 | | **WritingCard** | `WritingCard.tsx` | 🆕 **글 카드 컴포넌트** (제목, 날짜, 미리보기, 주제/점수/이미지 배지, 메뉴, 삭제) | ✅ 완료 | | **PublicWritingCard** | `PublicWritingCard.tsx` | 🆕 **공개 글 카드** (제목, 공개 범위 배지, 미리보기, 날짜) | ✅ 완료 | | **VisibilitySelector** | `VisibilitySelector.tsx` | 🆕 **공개 범위 선택** (PUBLIC/TEAM/PRIVATE, RadioCard 기반) | ✅ 완료 | | **VisibilityBadge** | `VisibilityBadge.tsx` | 🆕 **공개 범위 배지** (아이콘 + 라벨, 색상별 구분) | ✅ 완료 | | **InteractiveImageViewer** | `InteractiveImageViewer.tsx` | 🆕 **인터랙티브 이미지 뷰어** (왜곡 효과, 애니메이션, 오디오 반응) | ✅ 완료 | | **ImageDropzone** | `ImageDropzone.tsx` | 🆕 **범용 이미지 드롭존** (드래그앤드롭 업로드, 미리보기, 4:3 크롭 통합, 호버 오버레이, 삭제 버튼, AspectRatio 지원, 커스텀 라벨 — 글쓰기/팀 커버 이미지 공용) | ✅ 완료 | | **ImageCropper** | `ImageCropper.tsx` | 🆕 **이미지 크롭 모달** (react-cropper 기반, 4:3 고정 비율, 회전/확대/축소, 최소 400x300) | ✅ 완료 | | **CameraCaptureDialog** | `CameraCaptureDialog.tsx` | 🆕 **카메라 촬영 다이얼로그** (GlassDialog 기반, getUserMedia 카메라 스트림, 4:3 프레임 가이드 오버레이, 전/후면 카메라 전환, 촬영 후 ImageCropper 연동, 권한/미지원 에러 처리, 다국어 지원) | ✅ 완료 | | **ImageFirstLayout** | `ImageFirstLayout.tsx` | 🆕 **이미지 우선 레이아웃** (이미지+에디터 2컬럼, 반응형) | ✅ 완료 | | **GenerateImageDialog** | `GenerateImageDialog.tsx` | 🆕 **AI 이미지 생성 Dialog** (4단계 플로우: 장면 추출 → 장면 선택 → 이미지 생성 → 결과 표시) | ✅ 완료 | | ~~**ScoreDisplay**~~ | ~~`ScoreDisplay.tsx`~~ | ~~실시간 피드백 점수 표시~~ | ❌ 삭제됨 (하이라이트로 대체) | | ~~**SpellingErrorDisplay**~~ | ~~`SpellingErrorDisplay.tsx`~~ | ~~맞춤법 오류 표시~~ | ❌ 삭제됨 (하이라이트로 대체) | | **CreateTopicDialog** | `CreateTopicDialog.tsx` | 🆕 **통합 주제 생성 다이얼로그** (개인/팀 공용, 태그 입력 UI, 템플릿 지원, TopicFormData 반환) | ✅ 완료 | | **SavedDraftsDialog** | `SavedDraftsDialog.tsx` | 저장된 글조각 목록 다이얼로그 (불러오기/삭제, **동기화 상태 배지** 🟢synced/🟡syncing/⚪local) | ✅ 완료 | **주요 기능**: - ✅ 순수 텍스트 입력 (포맷팅 없음) - ✅ 초등학생 친화적 단순 인터페이스 - ✅ 실시간 글자 수/단어 수 카운터 - ✅ 🆕 **실시간 하이라이트 시스템** (Tiptap Extensions) - ✅ SpellingHighlight: 맞춤법 오류를 빨간 물결 밑줄로 표시 - ✅ SensoryWordHighlight: 감각 단어를 색상별 하이라이트 (초록/파랑/보라) - ✅ 클릭 시 툴팁 표시 (맞춤법: 원본→수정+이유, 감각 단어: 단어 타입+격려) - ✅ 브라우저 기본 맞춤법 검사 비활성화 (spellcheck="false") - ✅ 🆕 **글 작성 패턴 분석** (AI 기반) - ✅ 최근 10개 글 종합 분석 (작성 스타일, 표현력, 발전 추이) - ✅ 강점/약점 파악, 자주 쓰는 표현 분석 - ✅ AI 종합 평가 및 맞춤형 추천 사항 3가지 - ✅ 5분 캐싱 (성능 최적화) - ✅ **실시간 피드백 시스템** (Gemini 2.5 Flash-Lite) - ✅ 텍스트 분석 (오감/감정/대화/의성어 평가) - ✅ 5초 debounce + Delta 전송 (토큰 40% 절감) - ✅ Toast 알림 (시작/완료/실패, 점수 표시) - ✅ Multi-region failover (가용성 99.9%) - ✅ **맞춤법 검사** (독립적, Gemini 기반) - ✅ 초등학생 눈높이 설명 - ✅ 5초 debounce (텍스트 분석과 별도) - ✅ Toast 알림 (에러 개수 표시) - ✅ **주제 변경 경고 Dialog** (작성 중 내용 초기화 알림 + 임시 저장 안내) - ✅ **다중 글조각 관리** (최대 10개, FIFO 방식) - ✅ **강화된 자동 저장** (2초 debounce, localStorage) - ✅ **저장 상태 표시** (저장 중 → 저장됨 → 시간 표시) - ✅ "새 글쓰기" 버튼 (현재 글 초기화) - ✅ "저장된 글조각" Dialog (목록, 미리보기, 불러오기/삭제) - ✅ **주제 선택 그룹핑** (자유/팀/개인 주제 구분, ItemGroup 사용) - ✅ **팀 주제에 팀 이름 표시** (어느 팀의 주제인지 명확히 표시) - ✅ 주제 선택 (자유 주제/팀 주제/개인 주제) - ✅ 주제 정보 표시 (설명, 키워드, 예시 질문) - ✅ 템플릿 미리채우기 (제목/내용) - ✅ 개인 주제 생성 (카테고리, 난이도, 키워드, 템플릿 설정) - ✅ 팀 주제 생성 (팀 소유자 전용, 팀 관리 페이지) - ✅ 태그 입력 필드 UI (제목 템플릿: 방향키 네비게이션, Backspace/Delete 삭제) --- ### 📁 `src/components/interaction/` - 🆕 상호작용 및 분석 결과 표시 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **InteractionHeader** | `InteractionHeader.tsx` | 🆕 **인터랙션 페이지 Sticky Header** (IntersectionObserver + Sentinel 패턴, glassmorphism, 반응형 제목/버튼) | ✅ 완료 | | **AnalysisNeededBanner** | `AnalysisNeededBanner.tsx` | 분석 필요 알림 배너 (AI 분석 요청 유도) | ✅ 완료 | | **AreaUnlockBadge** | `AreaUnlockBadge.tsx` | 영역 잠금 해제 배지 (점수 달성 시 표시) | ✅ 완료 | | **ImprovementHint** | `ImprovementHint.tsx` | 개선 힌트 표시 (점수가 낮을 때 조언 제공) | ✅ 완료 | | **ScoreBadge** | `ScoreBadge.tsx` | 점수 배지 (오감/감정/대화/의성어 점수 표시) | ✅ 완료 | | **EditorModeSwitch** | `EditorModeSwitch.tsx` | 기본/고급 모드 전환 스위치 | ✅ 완료 | | **SimpleMotionSelector** | `SimpleMotionSelector.tsx` | 간소화된 모션 선택기 (기본 모드용) | ✅ 완료 | | **SimpleEasingSelector** | `SimpleEasingSelector.tsx` | 간소화된 이징 선택기 | ✅ 완료 | | **SimpleSpeedSelector** | `SimpleSpeedSelector.tsx` | 간소화된 속도 선택기 | ✅ 완료 | | **SimpleStrengthSelector** | `SimpleStrengthSelector.tsx` | 간소화된 강도 선택기 | ✅ 완료 | | **PhysicsPresetSelector** | `PhysicsPresetSelector.tsx` | 물리 프리셋 선택기 | ✅ 완료 | | **CustomAreaList** | `CustomAreaList.tsx` | 🆕 **왜곡 영역 목록 (일반/고급 모드 공통 표시)** | ✅ 완료 | | **CustomParameterPanel** | `CustomParameterPanel.tsx` | 커스텀 파라미터 패널 (고급 모드 전용) | ✅ 완료 | --- ### 📁 `src/components/feed/` - 🆕 피드 시스템 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **TodayTopicCard** | `TodayTopicCard.tsx` | 🆕 **오늘의 글감 카드** (매일 새로운 주제 제안, AI 생성) | ✅ 완료 | | **WeeklyGoalCard** | `WeeklyGoalCard.tsx` | 🆕 **주간 목표 카드** (목표 글 수 설정, 진행률 표시) | ✅ 완료 | | **RecentActivityCard** | `RecentActivityCard.tsx` | 🆕 **최근 활동 카드** (팀 활동 요약, 최근 글 표시) | ✅ 완료 | | **InspirationCard** | `InspirationCard.tsx` | 🆕 **영감 카드** (AI 생성 영감, Unsplash 이미지, vertical/horizontal 레이아웃) | ✅ 완료 | | **InspirationSection** | `InspirationSection.tsx` | 🆕 **영감 섹션** (영감 목록, grid/horizontal 레이아웃, maxItems 지원) | ✅ 완료 | | **CompactCardsRow** | `CompactCardsRow.tsx` | 🆕 **컴팩트 카드 행** (주간 목표 + 최근 활동 가로 배치) | ✅ 완료 | | **GlassCard** | `GlassCard.tsx` | 🆕 **글래스 카드** (반투명 배경, 블러 효과, 시각적 통일성) | ✅ 완료 | | ~~**FeedCompactCard**~~ | ~~`FeedCompactCard.tsx`~~ | ~~피드 컴팩트 카드~~ | ❌ 삭제됨 (GlassCard로 대체) | **주요 기능**: - ✅ **4개 피드 타입** (오늘의 글감, 주간 목표, 최근 활동, 추천 영감) - ✅ **FeedManager** (데이터 관리, 2분 캐싱) - ✅ **API Routes 4개** - `/api/feed/daily-prompt` - 오늘의 글감 조회 - `/api/feed/inspirations` - 추천 영감 목록 - `/api/feed/weekly-stats` - 주간 통계 조회 - `/api/feed/team-activity` - 팀 활동 조회 - ✅ **AI 영감 생성** (Gemini 2.5 Flash) - Cloud Function: generateDailyInspirations (매일 새벽 자동 생성) - HTTP Function: generateInspirationsManual (관리자 수동 생성) - Unsplash API 이미지 검색 및 다운로드 - 크레딧 정보 저장 (작가 이름, 프로필 링크) - ✅ **글래스모피즘 UI** (반투명 배경, 블러 효과) - ✅ **로딩 스켈레톤** (모든 카드 지원) - ✅ **다국어 지원** (ko/en/ja) --- ### 📁 `src/components/write/` - 🆕 글쓰기 모드 선택 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **ModeSelectionCard** | `ModeSelectionCard.tsx` | 🆕 **모드 선택 카드** (글부터/그림부터, 그라데이션, 애니메이션) | ✅ 완료 | **주요 기능**: - ✅ **2가지 모드** (글부터 쓰기, 그림부터 올리기) - ✅ **그라데이션 배경** (모드별 색상) - ✅ **캐릭터 이미지** (startWriting.png, uploadImage.png) - ✅ **호버 애니메이션** (scale, shadow) - ✅ **드롭 쉐도우** 효과 - ✅ **다국어 지원** (modeSelection namespace) --- ### 📁 `src/extensions/` - Tiptap Extensions | Extension | 파일명 | 설명 | 상태 | |-----------|--------|------|------| | **SpellingHighlight** | `spelling-highlight.ts` | 🆕 **맞춤법 오류 하이라이트** (빨간 물결 밑줄, data attributes) | ✅ 완료 | | **SensoryWordHighlight** | `sensory-word-highlight.ts` | 🆕 **감각 단어 하이라이트** (색상별 표시: 초록/파랑/보라) | ✅ 완료 | **주요 기능**: - ✅ Tiptap ProseMirror Plugin 기반 - ✅ DecorationSet을 사용한 효율적인 하이라이트 - ✅ Meta를 통한 강제 업데이트 지원 - ✅ data attributes로 툴팁 정보 전달 - ✅ 실시간 텍스트 변경 추적 **하이라이트 종류**: - **SpellingHighlight**: 맞춤법 오류 (빨간 물결 밑줄) - `spelling-error` 클래스 - data-original, data-correction, data-reason 속성 - **SensoryWordHighlight**: 감각 단어 (색상별) - `sensory-word` (감각 동사, 초록색) - `emotion-word` (감각 형용사, 파란색) - `onomatopoeia-word` (의성어/의태어, 보라색) - data-word, data-type 속성 --- ### 📁 `src/components/team/` - 팀 관리 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **TeamCard** | `TeamCard.tsx` | 🆕 **팀 카드 컴포넌트** (내 팀/공개 팀 공용, 커버 이미지 140px, 팀 설명 2줄, 팀 코드 조건부 표시, isOwner/onClick props) | ✅ 완료 | | ~~TeamCoverImageUploader~~ | 삭제됨 | ImageDropzone로 통합 (범용 이미지 업로드 컴포넌트) | ✅ 완료 | | **TeamTopicManager** | `TeamTopicManager.tsx` | 팀 주제 목록 및 생성/삭제 UI | ✅ 완료 | | **TeamAISettings** | `TeamAISettings.tsx` | 🆕 **팀 AI 설정 컴포넌트** (2단계 계층: 팀 AI 마스터 스위치 + AI 글쓰기 도우미, 플랜 제한 체크, 3가지 상태 피드백, VStack 레이아웃) | ✅ 완료 | | **AIConfigDialog** | `AIConfigDialog.tsx` | 🆕 **AI 도우미 고급 설정 Dialog** (Slider, 커스텀 CheckboxCard) | ✅ 완료 | | **SecurityLevelSelector** | `SecurityLevelSelector.tsx` | 5단계 보안 레벨 선택 (RadioCard, framer-motion 애니메이션) | ✅ 완료 | | **TopicMemberAnalysisSection** | `TopicMemberAnalysisSection.tsx` | 🆕 **주제별 학생 글쓰기 분석** (Accordion, 주제별 학생 목록, 글 개수, by-topic 분석 연동) | ✅ 완료 | | **LiveWritingMonitor** | `LiveWritingMonitor.tsx` | 🆕 **실시간 글쓰기 모니터링** (Firebase Realtime DB, 5초 주기) | ✅ 완료 | **주요 기능**: - ✅ **AIConfigDialog** (2025-11-17): - **Slider 설정**: 멈춤 감지 시간 (1-60분), 최대 힌트 횟수 (1-20회), 쿨다운 (0-30분) - **커스텀 힌트 레벨 카드** (직접 onClick 처리, CheckboxCard 미사용): - 반투명 배경 레벨 번호 (opacity: 0.12, 80px 폰트) - 우상단 접힌 페이지 인디케이터 (CSS border trick 삼각형) - 체크 시 브랜드 컬러 삼각형 + 배경 변경 - 2x2 그리드 레이아웃 (SimpleGrid columns={2}) - **AI 제안 그대로 사용 금지** (Switch) - 다국어 지원 (한국어/영어/일본어) - 함수형 상태 업데이트로 클로저 문제 해결 - ✅ **LiveWritingMonitor** (2025-11-12): - 주제 선택 드롭다운 (Chakra UI Select) - **모든 팀 멤버 표시** (getUsersByTeam) - **3가지 상태 관리 및 정렬**: - 🟢 작성 중 (isActive: true, lastUpdated < 30초) - 🟠 나감 (isActive: false, 마지막 통계 유지) - ⚪ 대기 중 (한 번도 작성 안 함) - StudentMonitorCard 컴포넌트 (개별 학생 카드) - 실시간 통계: 글자 수, 단어 수, 마지막 업데이트 시간 ("N초 전") - **작성 속도 계산** (클라이언트 측, charDiff * 12 = 글자/분) - **Sparkline 그래프** (@chakra-ui/charts, Area Chart) - 최근 10개 데이터 포인트 (speedHistory) - 0도 표시 (작성 멈춤 시각화) - Teal 색상, 투명도 30% - **인터랙티브 툴팁** (Recharts Tooltip) - 속도 값 ("N자/분") - 시간 정보 ("N초 전") - 미리보기 버튼 (작성 중인 학생만) - **30초 타임아웃**: 업데이트 없으면 "나감" 처리 - **마지막 통계 유지**: 나간 학생도 통계 표시 - 실시간 구독/구독 해제 (useEffect cleanup) - 시각적 구분 (색상별 테두리, 아바타, 배지) - ✅ SecurityLevelSelector: RadioCard 기반, 선택 시 추가 UI 애니메이션으로 표시 - ✅ 그라데이션 배경 (RadioCard와 자연스럽게 연결) - ✅ react-icons/lu 사용 (이모티콘 제거) --- ### 📁 `src/components/home/` - 홈 페이지 | 컴포넌트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **HeroSection** | `HeroSection.tsx` | 환영 메시지 섹션 (그라데이션 강조 라인, 사용자 이름) | ✅ 완료 | | **QuickActionCard** | `QuickActionCard.tsx` | 개별 빠른 실행 액션 카드 (아이콘, 제목, 설명, 글래스모피즘, 미구현 오버레이) | ✅ 완료 | | **QuickActionsGrid** | `QuickActionsGrid.tsx` | 액션 카드 그리드 레이아웃 (12컬럼 그리드, framer-motion) | ✅ 완료 | | **ViewAllWritingsCard** | `ViewAllWritingsCard.tsx` | "모든 글 보기" 액션 카드 (화살표 아이콘, 클릭 가능) | ✅ 완료 | | **EmptyStateCard** | `EmptyStateCard.tsx` | 글이 없을 때 빈 상태 표시 (이모티콘, CTA 버튼, 패턴 배경) | ✅ 완료 | | **RecentActivitySection** | `RecentActivitySection.tsx` | 최근 활동 섹션 전체 (글 목록, 로딩, 빈 상태 처리) | ✅ 완료 | **주요 기능**: - ✅ **모듈화** (2025-11-21): - 홈 페이지 580줄 → 223줄 (62% 코드 감소) - 6개 재사용 가능한 컴포넌트로 분리 - 각 컴포넌트 단일 책임 원칙 준수 - ✅ **Semantic Token 적극 활용**: - `bg`, `fg`, `border` 등 semantic token 우선 사용 - Conditional style 객체 최소화 (특수한 경우만) - Landing 페이지 전용 토큰 활용 (`landing.feature.*.bg`, `landing.text`) - ✅ **UI 일관성**: - 글래스모피즘 효과 (backdrop-filter, 반투명 배경) - framer-motion 애니메이션 (fade-in, scale, stagger) - 브랜드 컬러 시스템 통일 - ✅ **다국어 지원**: 한국어/영어/일본어 번역 - ✅ **JSX 주석 한글화**: 모든 주석을 한글로 통일 --- ### 📁 예정된 컴포넌트 디렉토리 | 디렉토리 | 설명 | 컴포넌트 | |---------|------|--------------| | `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]** | ✅ 완료 | | **DraftManager** | `DraftManager.ts` | 글조각 관리 (**localStorage + Realtime DB 하이브리드**, 기기 간 동기화, 최대 10개, CRUD, syncStatus) | ✅ 완료 | | **WritingSessionManager** | `WritingSessionManager.ts` | 🆕 **실시간 글쓰기 세션 관리** (Firebase Realtime DB 작업) | ✅ 완료 | | **WritingManager** | `WritingManager.ts` | 글쓰기 관련 비즈니스 로직 (CRUD, 통계) | ✅ 완료 | | **TopicManager** | `TopicManager.ts` | 주제 관련 비즈니스 로직 (CRUD, 템플릿 처리) | ✅ 완료 | | **AIUsageManager** | `AIUsageManager.ts` | 🆕 **AI 사용량 관리** (플랜 정보, 사용량 조회, 기능 사용 가능 여부 체크, 1분 캐싱) | ✅ 완료 | | **OrganizationManager** | `OrganizationManager.ts` | 🆕 **조직 관리** (Organization CRUD, 멤버 조회, 2분 캐싱) | ✅ 완료 | | **FeedManager** | `FeedManager.ts` | 피드 관련 API 호출 (영감, 주간 목표, 팀 활동) | ✅ 완료 | | **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 레이어 분리** **WritingSessionManager 주요 메서드** (2025-11-12): - `startMonitoring(teamId, topicId, getStatsCallback)`: 5초 주기 통계 전송 시작 - `stopMonitoring()`: 통계 전송 중지 (페이지 이탈 시) - `subscribeToTopic(teamId, topicId, callback)`: 실시간 구독 (관리자용) - `requestPreview(targetUserId)`: 미리보기 요청 (Promise 반환) - `listenForPreviewRequests(onRequestCallback)`: 미리보기 요청 리스너 (학생용) **WritingManager 주요 메서드** (2025-11-28 추가): - 🆕 `uploadUserImage(writingId, file)`: 클라이언트 사이드 이미지 업로드 - Canvas API로 이미지 리사이즈 (1920x1080 최대, 85% 품질) - Firebase Storage 업로드 (`uploadImage` from `@/utils/imageStorage`) - Writing.generatedImage 필드 업데이트 - 파일 검증 (JPEG/PNG/WebP, 5MB 제한) - 🆕 `analyzeWritingBackground(writingId, locale)`: 백그라운드 분석 (fire-and-forget) - 서버에 분석 요청만 전송, 응답 무시 - `.catch(() => {})` 패턴으로 에러 무시 - 🔒 `resizeImage(file, maxWidth, maxHeight, quality)`: private 이미지 리사이즈 헬퍼 - Canvas API 사용, data URL 반환 --- ### 🆕 `functions/` - Firebase Cloud Functions (서버리스 백엔드) Firebase Cloud Functions로 구현된 백그라운드 작업 및 자동화 로직입니다. | Function | 파일 | 타입 | 스케줄/Trigger | 설명 | 상태 | |----------|------|------|----------------|------|------| | **cleanupExpiredReservations** | `cleanup.ts` | Scheduled | 매 시간 0분 | 만료된 팀 코드 예약 정리 (expiresAt < now) | ✅ 배포됨 | | **cleanupExpiredDrafts** | `triggers/drafts.ts` | Scheduled | 매일 새벽 3시 | 180일 이상 오래된 drafts 정리 (Realtime DB) | ✅ 배포됨 | | **onTeamDeleted** | `triggers/team.ts` | Firestore Trigger | teams/{teamId} 삭제 | 팀 주제, 모니터링 데이터 cascade 삭제 | ✅ 배포됨 | | **onWritingCreated** | `triggers/writing.ts` | Firestore Trigger | writings/{writingId} 생성 | 글 생성 감지 (추후 백그라운드 분석) | ✅ 배포됨 | **주요 특징**: - ✅ **서버리스**: 별도 서버 관리 불필요, 자동 스케일링 - ✅ **한글 로그**: 모든 logger 메시지 한글 작성 - ✅ **리전**: asia-northeast1 (도쿄, 한국과 가장 가까움) - ✅ **파일 분리**: index.ts에서는 export만, 로직은 별도 파일 - ✅ **에러 처리**: 일부 실패해도 전체 작업 계속 진행 **배포 명령어**: ```bash cd functions npm run build npm run deploy ``` **로그 확인**: ```bash firebase functions:log firebase functions:log --only cleanupExpiredReservations ``` --- ### 📁 `src/services/` - 데이터 레이어 (일부 deprecated) | 서비스 | 파일명 | 설명 | 상태 | |-------|--------|------|------| | **Firebase Auth** | `firebaseAuth.ts` | 인증 서비스 (로그인, 회원가입, 소셜, Anonymous, 계정 연결) | ✅ 완료 (단순화됨) | | **Firestore** | `firestore.ts` | Firestore CRUD 헬퍼 함수 (WritingManager에서 사용) | ✅ 완료 | | **Vertex AI** | `vertexAI.ts` | **Gemini API 범용 래퍼** (`@google/genai`, Multi-region failover, Response Schema, 🆕 **Imagen 이미지 생성**) | ✅ 완료 | | **Imagen Service** | `imagenService.ts` | 🆕 **AI 이미지 생성 서비스** (글 → 프롬프트 변환, 장면 기반 이미지 생성, 🆕 **AI 프롬프트 최적화**) | ✅ 완료 | | **Scene Extraction** | `sceneExtractionService.ts` | 🆕 **AI 장면 분리 서비스** (글 → 3~5개 주요 장면 추출, 장면별 프롬프트 생성) | ✅ 완료 | | **Text Analysis** | `textAnalysisService.ts` | **텍스트 분석 서비스** (평가 기준 개편, 히스토리 기반 분석) | ✅ 완료 | | **Pattern Analysis** | `patternAnalysisService.ts` | 🆕 **글 작성 패턴 분석 서비스** (10개 글 종합 분석, AI 평가) | ✅ 완료 | | **Spelling Check** | `spellingService.ts` | **맞춤법 검사 서비스** (Gemini 기반, 초등학생 눈높이) | ✅ 완료 | | **Writing Assistance** | `writingAssistanceService.ts` | 🆕 **AI 글쓰기 도우미 서비스** (4단계 힌트 생성, 주제 맥락 활용, 서버 캐싱) | ✅ 완료 | | **Region Health** | `regionHealthManager.ts` | **Region 과부하 상태 추적** (자동 복구, 1분 TTL) | ✅ 완료 | | ~~**Team Service**~~ | ~~`teamService.ts`~~ | ~~팀 CRUD, 팀 코드 생성~~ | ⚠️ Deprecated (TeamManager로 이동) | | ~~**Student Service**~~ | ~~`studentService.ts`~~ | ~~학생 CRUD, PIN 해시/검증~~ | ⚠️ 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/` - 타입 정의 | 타입 | 파일명 | 설명 | 상태 | |------|--------|------|------| | **Plan 타입** | `plan.ts` | 🆕 **플랜 시스템 타입** (PlanType/BillingCycle/PlanSource/AIFeatureType Enum, UserPlan, Organization, AIUsage, PlanLimits, EffectivePlan, AIFeatureCheckResult) | ✅ 완료 | | **Team 타입** | `team.ts` | 팀 데이터 모델 (members Map), **TeamSecurityLevel Enum (1-5)**, 🆕 **AIAssistanceConfig** (AI 도우미 설정) | ✅ 완료 | | **FirestoreUser 타입** | `firestoreUser.ts` | **FirestoreUser** (DB 저장용, 🆕 **plan/organizationId 필드 추가**), **User** (UI용) 분리 | ✅ 완료 | | **Writing 타입** | `writing.ts` | 글 데이터 모델, 🆕 **WritingAnalysis** (AI 분석 결과, contentHash 기반 재사용), **SpellingError** (맞춤법 오류), 🆕 **AIAssistanceRecord** (AI 도움 이력), 🆕 **GeneratedImage** (AI 생성 이미지) | ✅ 완료 | | **Scene 타입** | `scene.ts` | 🆕 **장면 데이터 모델** (Scene, SceneExtractionResponse) | ✅ 완료 | | **Draft 타입** | `draft.ts` | 글조각 데이터 모델 (Draft, DraftListItem, **AnalysisHistoryItem**, **syncStatus**: 'local'\|'synced'\|'syncing') | ✅ 완료 | | **WritingPattern 타입** | `writingPattern.ts` | **글 작성 패턴 분석** 데이터 모델 (WritingPatternAnalysis) | ✅ 완료 | | **WritingSession 타입** | `writingSession.ts` | 🆕 **실시간 모니터링** 데이터 모델 (WritingStats, PreviewRequest/Response, MonitoringData) | ✅ 완료 | | ~~**User 타입**~~ | ~~`user.ts`~~ | ~~사용자 데이터 모델~~ | ⚠️ Deprecated (firestoreUser.ts로 변경) | | ~~**Student 타입**~~ | ~~`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 제거), 🆕 **AI 설정 API 타입** (GetAIConfig, UpdateAIConfig, GetAIStats) | ✅ 완료 | | **User API 타입** | `api/user.ts` | 사용자 API Request/Response (닉네임 관리 포함) | ✅ 완료 | | **Writing API 타입** | `api/writing.ts` | 글 API Request/Response, 🆕 **CreateWritingRequest.analysis** (AI 분석 결과 포함) | ✅ 완료 | | ~~**Student API 타입**~~ | ~~`api/student.ts`~~ | ~~학생 API Request/Response~~ | ⚠️ Deprecated (api/user.ts로 대체) | | **Topic API 타입** | `api/topic.ts` | 주제 API Request/Response (9개 엔드포인트, 팀 주제 포함) | ✅ 완료 | **타입 테스트** (`src/types/__tests__/`): - 🆕 `plan.test.ts` - PlanType/BillingCycle/PlanSource/AIFeatureType Enum 검증, 타입 호환성 테스트 (70개 통과) --- ### 📁 `src/utils/` - 유틸리티 함수 | 유틸리티 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **Team Code Generator** | `teamCodeGenerator.ts` | 한글/영어/일본어 팀 코드 생성 (형용사 + 색깔 + 동물, locale 파라미터) | ✅ 완료 | | **🆕 i18n 유틸리티** | `i18n.ts` | 서비스 레이어용 번역 함수 (detectLocale, t), nested key 지원, 파라미터 치환 | ✅ 완료 | | **🆕 Validation** | `validation.ts` | 폼 검증 유틸리티 (이메일/비밀번호/이름/비밀번호 확인), 타입 안전, 다국어 에러 메시지 | ✅ 완료 | | **🆕 SSE Stream Processor** | `sseStreamProcessor.ts` | Server-Sent Events 스트리밍 처리 (계정 병합 진행률 표시) | ✅ 완료 | | **Password Security** | `passwordSecurity.ts` | HIBP API 연동 (유출된 비밀번호 차단) | ✅ 완료 | | **Password Strength** | `passwordStrength.ts` | 비밀번호 강도 계산 | ✅ 완료 | | **Content Hash** | `contentHash.ts` | 🆕 **SHA-256 해시 생성** (글 목록 → 해시, id+updatedAt 조합), 🆕 **generateWritingContentHash** (개별 글 content 해시), 서버/클라이언트 지원 | ✅ 완료 | | **Pattern Cache Manager** | `patternCacheManager.ts` | 🆕 **패턴 분석 localStorage 캐싱** (LRU 최대 10개, 캐시 통계) | ✅ 완료 | | **Image Storage** | `imageStorage.ts` | 🆕 **Firebase Storage 이미지 업로드** (base64 → Storage, 공개 URL 반환) | ✅ 완료 | | **Area Limit** | `areaLimit.ts` | 🆕 **이미지 왜곡 영역 제한** (점수 기반 해금 로직, 좌표 계산) | ✅ 완료 | | **Pending Image Store** | `pendingImageStore.ts` | 🆕 **이미지 임시 저장** (IndexedDB 기반, 새로고침해도 유지, CRUD 메서드) | ✅ 완료 | --- ### 📁 `src/hooks/` - Custom Hooks | Hook | 파일명 | 설명 | 상태 | |------|--------|------|------| | **useRequireAuth** | `useRequireAuth.ts` | **인증 필수 페이지 훅** (비인증 시 자동 리다이렉트, additionalLoading 지원) | ✅ 완료 | | **useTeamData** | `useTeamData.ts` | 🆕 **팀 데이터 로딩 훅** (팀 + 멤버 로딩, 권한 체크, refreshMembers) | ✅ 완료 | | **🆕 useShakeAnimation** | `useShakeAnimation.ts` | **에러 Shake 애니메이션 훅** (에러 발생 시 자동 shake, getShakeAnimateProps 헬퍼, 중복 제거) | ✅ 완료 | | **useWritingInactivityDetection** | `useWritingInactivityDetection.ts` | **작성 멈춤 감지 훅** (N분 입력 없을 시 콜백, 타이머 리셋, 남은 시간) | ✅ 완료 | --- ### 📁 `src/prompts/` - AI 프롬프트 | 프롬프트 | 파일명 | 설명 | 상태 | |---------|--------|------|------| | **Text Analysis** | `textAnalysis.ts` | 텍스트 분석 프롬프트 (다국어, 히스토리 기반) | ✅ 완료 | | **Pattern Analysis** | `patternAnalysis.ts` | 패턴 분석 프롬프트 (10개 글 종합 평가) | ✅ 완료 | | **Writing Assistance** | `writingAssistance.ts` | 🆕 **AI 글쓰기 도우미 프롬프트** (4단계 × 3개 언어, 주제 맥락 활용) | ✅ 완료 | | **Scene Extraction** | `sceneExtraction.ts` | 🆕 **AI 장면 추출 프롬프트** (3~5개 장면 분리, Response Schema, ko/en/ja) | ✅ 완료 | | **Prompt Optimization** | `promptOptimization.ts` | 🆕 **프롬프트 최적화 프롬프트** (원문 → 핵심 키워드 배열 추출, Imagen 최적화) | ✅ 완료 | --- ### 📁 `src/app/api/` - API Routes | API | 경로 | 메서드 | 설명 | 상태 | |-----|------|--------|------|------| | **텍스트 분석** | `/api/analyze-text` | POST | **Gemini 기반 텍스트 분석** (Delta 지원, 캐싱, 히스토리 인식, 🆕 **선택적 인증 + 플랜 검증**, 비로그인 IP 해싱) | ✅ 완료 | | **패턴 분석** | `/api/analyze-pattern` | POST | **글 작성 패턴 분석** (3가지 타입, contentHash 기반 3단계 캐싱, 변경 감지) | ✅ 완료 | | **맞춤법 검사** | `/api/spelling/check` | POST | **Gemini 기반 맞춤법 검사** (초등학생 눈높이) | ✅ 완료 | | **AI 글쓰기 도우미** | `/api/writing-assistance` | POST | 🆕 **AI 힌트 생성** (4단계, 주제 맥락, 팀 설정 검증) | ✅ 완료 | | **글 생성** | `/api/writing` | POST | 🆕 **글 생성** (wordCount/charCount 자동 계산, 🆕 **analysis 저장**) | ✅ 완료 | | **글 조회** | `/api/writing/[id]` | GET | 🆕 **글 조회** (작성자만 접근) | ✅ 완료 | | **글 분석** | `/api/writing/[id]/analyze` | POST | 🆕 **글 분석 실행** (서버 데이터 기반, 결과 저장) | ✅ 완료 | | **글 수정** | `/api/writing/[id]` | PUT | 🆕 **글 수정** (작성자만 접근, 통계 재계산) | ✅ 완료 | | **글 삭제** | `/api/writing/[id]` | DELETE | 🆕 **글 삭제** (작성자만 접근) | ✅ 완료 | | **사용자 글 목록** | `/api/writing/user` | POST | 🆕 **사용자 글 목록** (userId 선택적, 본인 글만) | ✅ 완료 | | **최근 글** | `/api/writing/recent` | POST | 🆕 **최근 글** (limit 파라미터, 기본 5개) | ✅ 완료 | | **팀 CRUD** | `/api/team` | GET, POST, PUT, DELETE | 팀 생성/조회/수정/삭제 | ✅ 완료 | | **팀 보안 레벨** | `/api/team/[teamId]/security-level` | POST | 보안 레벨 변경 | ✅ 완료 | | **명단 관리** | `/api/team/[teamId]/allowed-names` | POST, DELETE | 허용 이름 추가/제거 | ✅ 완료 | | **이메일 관리** | `/api/team/[teamId]/allowed-emails` | POST, DELETE | 허용 이메일 추가/제거 | ✅ 완료 | | **팀 AI 설정** | `/api/team/[teamId]/ai-config` | GET, PUT | 🆕 **AI 도우미 설정 조회/업데이트** | ✅ 완료 | | **AI 장면 추출** | `/api/extract-scenes` | POST | 🆕 **글에서 주요 장면 추출** (Gemini Flash, 3~5개 장면, 각 장면별 이미지 프롬프트 자동 생성) | ✅ 완료 | | **AI 이미지 생성** | `/api/generate-image` | POST | 🆕 **장면 기반 이미지 생성** (🆕 **AI 프롬프트 최적화**, Imagen 3.0, Firebase Storage 저장, Writing 업데이트, **플랜 검증**) | ✅ 완료 | | **AI 사용량 조회** | `/api/ai-usage` | GET | 🆕 **AI 사용량 및 플랜 정보 조회** (userId 기반, usage + plan + features 반환) | ✅ 완료 | | **조직 관리** | `/api/organization` | GET, POST, PUT, DELETE | 🆕 **Organization CRUD** (School Plan 보유, 멤버 조회, 플랜 정보) | ✅ 완료 | | **주제 CRUD** | `/api/topic` | GET, POST, PUT, DELETE | 주제 생성/조회/수정/삭제 (9개 엔드포인트) | ✅ 완료 | | **주제별 작성자** | `/api/topic/[topicId]/writers` | GET | 🆕 **주제로 글 쓴 학생 목록** (글 개수, Firebase Auth 결합, 글 개수 내림차순) | ✅ 완료 | | **계정 병합** | `/api/auth/merge-account` | POST | 🆕 **익명 계정 데이터 병합** (Firestore + Realtime DB 마이그레이션, Batch/Transaction, 통계 반환) | ✅ 완료 | | **사용자 관리** | `/api/user` | GET, POST, PUT | 사용자 조회/생성/업데이트 | ✅ 완료 | **서버 레이어** (`src/lib/server/`): - `team.ts` - 팀 Firestore CRUD, 🆕 **getTeamAIConfig/updateTeamAIConfig** (AI 설정 관리), 🆕 **generateUniqueTeamCode(locale)** (언어별 코드 생성) - `user.ts` - 사용자 Firestore CRUD - `topic.ts` - 주제 Firestore CRUD - 🆕 `writing.ts` - 글 Firestore CRUD (createWriting, getWriting, updateWriting, deleteWriting, getUserWritings, getRecentWritings, isWritingOwner, 🆕 **getTopicWriters**) - 🆕 `patternAnalysis.ts` - 패턴 분석 결과 Firestore 저장/조회 (contentHash 키, 영구 저장) - 🆕 `teamCodeReservation.ts` - **팀 코드 예약 시스템** (Realtime DB transaction, atomic 예약, 5분 TTL, race condition 방지) - 🆕 `planLimits.ts` - **플랜별 제한 상수** (PLAN_LIMITS, 헬퍼 함수들) - 🆕 `planResolver.ts` - **플랜 결정 로직** (getEffectivePlan, getGuestEffectivePlan, canUseAIFeature) - 🆕 `aiUsage.ts` - **AI 사용량 추적** (getAIUsage, incrementAIUsage, hashIpAddress, getUsageDocId) - 🆕 `organization.ts` - **Organization CRUD** (getOrganization, createOrganization, updateOrganization, deleteOrganization, isOrganizationPlanValid) **서버 레이어 테스트** (`src/lib/server/__tests__/`): - 🆕 `planLimits.test.ts` - 플랜별 제한 상수 검증, 헬퍼 함수 테스트 - 🆕 `aiUsage.test.ts` - IP 해싱, 문서 ID 생성, 년월 포맷 검증 (5개 todo) - 🆕 `planResolver.test.ts` - 플랜 결정 로직, AI 기능 사용 가능 여부 체크 (Firebase 모킹) --- ## 상태 관리 (Zustand) ### 📁 `src/store/` | 스토어 | 파일명 | 설명 | 상태 | |-------|--------|------|------| | **Auth Store** | `authStore.ts` | 인증 상태 및 로그인 다이얼로그 (단순화됨, 🆕 **Firestore 실시간 구독**, aiCredits/plan/settings 자동 업데이트) | ✅ 완료 | | **User Progress Store** | `userProgressStore.ts` | 사용자 진행 상황 (레벨, XP) | ❌ 미구현 | | **Notification Store** | `notificationStore.ts` | 알림 상태 | ❌ 미구현 | **Auth Store 아키텍처 (2025-11-07 단순화, 2025-12-09 리팩토링)**: - ✅ **user** - Firebase Auth + Firestore 결합 사용자 (익명 + 정식 계정, 🆕 **실시간 구독**) - ✅ **isAuthenticated** - 로그인 여부 (익명 포함) - ✅ **isLoading** - 🆕 **초기값 `true`로 변경 (2025-11-28)** - Auth 초기화 완료 전 리다이렉트 방지 - ✅ **user.isAnonymous** - 익명/정식 계정 구분 - ✅ **loginAsUser()** - 팀 코드 로그인 (PIN 제거) - ✅ **linkWithEmail()** - 이메일 계정 연결 (신규 계정 생성) - ✅ **linkWithGoogle()** - Google 계정 연결 (신규 계정 생성) - ✅ **mergeWithEmail()** - 기존 이메일 계정과 병합 (데이터 마이그레이션, 🆕 **performMerge 헬퍼**) - ✅ **mergeWithGoogle()** - 기존 Google 계정과 병합 (데이터 마이그레이션, 🆕 **performMerge 헬퍼**) - ✅ **🆕 initializeAuth()** - Firestore `onSnapshot` 실시간 구독 (aiCredits/plan/settings 자동 업데이트) - ❌ ~~currentStudent~~, ~~ownedStudents~~, ~~switchStudent()~~ 제거 (복잡도 감소) --- ## 설정 파일 ### 📁 `src/config/` | 파일 | 설명 | 상태 | |------|------|------| | `firebase.ts` | Firebase 초기화 및 설정 (Auth, Firestore, **Realtime DB**) | ✅ 완료 | | `site.ts` | 사이트 메타데이터 및 설정 | ✅ 완료 | **Firebase 서비스** (2025-11-17): - ✅ Firebase Authentication (Email/Password, Google OAuth, Anonymous) - ✅ Cloud Firestore (데이터베이스) - ✅ Firebase Realtime Database (실시간 모니터링) - ✅ Firebase Storage (이미지 저장) - ✅ Firebase Analytics (분석) **Firebase Config**: - Firebase 설정은 `src/config/firebase.ts`에 하드코딩되어 있습니다 - Public API Key는 Firebase 프로젝트 설정에서 제한 가능 - 환경변수 대신 코드에 직접 포함 (클라이언트 SDK 표준 방식) --- ## 디렉토리 구조 요약 ``` project_w/ ├── database.rules.json # 🆕 Firebase Realtime DB Security Rules │ ├── functions/ # 🆕 Firebase Cloud Functions (서버리스 백엔드) │ ├── src/ │ │ ├── index.ts # Entry point (export만) │ │ ├── cleanup.ts # cleanupExpiredReservations (매 시간) │ │ └── triggers/ │ │ ├── drafts.ts # cleanupExpiredDrafts (매일 새벽 3시) │ │ ├── team.ts # onTeamDeleted (Firestore Trigger) │ │ └── writing.ts # onWritingCreated (Firestore Trigger) │ ├── lib/ # 빌드 결과 (tsc) │ ├── package.json │ └── tsconfig.json │ ├── messages/ # 🆕 다국어 번역 파일 │ ├── ko.json # 한국어 번역 │ └── en.json # 영어 번역 │ ├── src/ ├── i18n/ # 🆕 다국어 설정 │ ├── routing.ts # 라우팅 설정 (locales, defaultLocale) │ └── request.ts # 번역 메시지 로더 │ ├── middleware.ts # 🆕 next-intl 미들웨어 (언어 감지, 리다이렉트) │ ├── app/ # Next.js App Router │ ├── layout.tsx # 루트 레이아웃 (메타데이터만) │ ├── [locale]/ # 🆕 다국어 라우팅 │ │ ├── layout.tsx # locale별 레이아웃 (Provider, Navbar, Auth) │ │ ├── page.tsx # ✅ 랜딩 페이지 (/[locale]) - 🆕 전체 번역 완료 │ │ ├── home/ │ │ │ └── page.tsx # ✅ 유저 홈 페이지 (/[locale]/home) - 🆕 전체 번역 완료 │ │ ├── write/ # ✅ 글쓰기 페이지 (라우트 분리) │ │ │ ├── page.tsx # 모드 선택 화면 (/[locale]/write) │ │ │ ├── text/ │ │ │ │ └── page.tsx # 글 먼저 모드 (/[locale]/write/text) │ │ │ ├── image/ │ │ │ │ └── page.tsx # 그림 먼저 모드 (/[locale]/write/image) │ │ │ └── edit/ │ │ │ └── [id]/ │ │ │ └── page.tsx # 수정 모드 (/[locale]/write/edit/[id]) │ │ ├── writing/ # ✅ 글 상세보기 │ │ │ └── [writingId]/ │ │ │ └── page.tsx # 🆕 글 상세 페이지 (Server Component, SEO 최적화) │ │ ├── writings/ │ │ │ └── page.tsx # ✅ 내 글 모음 페이지 (/[locale]/writings) │ │ ├── test/ │ │ │ └── page.tsx # ✅ 테스트 페이지 (/[locale]/test) │ │ └── team/ # ✅ 팀 관리 페이지들 │ │ ├── page.tsx # ✅ 팀 목록 (/[locale]/team) │ │ ├── create/ │ │ │ └── page.tsx # ✅ 팀 생성 (/[locale]/team/create) │ │ └── [teamId]/ │ │ ├── page.tsx # ✅ 팀 멤버 페이지 (/[locale]/team/[teamId]) │ │ └── manage/ │ │ └── page.tsx # ✅ 팀 관리 페이지 (/[locale]/team/[teamId]/manage) │ ├── globals.css │ └── favicon.ico │ ├── components/ # React 컴포넌트 │ ├── auth/ # ✅ 인증 (로그인, 프로필, 팀 코드) │ ├── landing/ # ✅ 랜딩 페이지 카드들 (다국어 지원) │ ├── navigation/ # ✅ 네비게이션 바 (다국어 지원) │ │ ├── Navbar.tsx # 다국어 링크 텍스트 │ │ └── LocaleSwitcher.tsx # 🆕 언어 전환 버튼 │ ├── layout/ # 🆕 레이아웃 공통 컴포넌트 │ │ └── BackButton.tsx # 🆕 뒤로가기 버튼 (router.back/href/label 지원) │ ├── seo/ # ✅ SEO 컴포넌트 │ ├── ui/ # ✅ Chakra UI 기본 │ ├── writing/ # ✅ 글쓰기 에디터 │ │ ├── WritingEditor.tsx # 순수 텍스트 에디터 (포맷팅 없음) │ │ ├── TopicSelector.tsx # 🔄 주제 선택 Dialog (glassmorphism, 탭 기반, 미리보기) │ │ └── CreateTopicDialog.tsx # ✅ 통합 주제 생성 (개인/팀 공용) │ ├── team/ # ✅ 팀 관련 │ │ ├── TeamTopicManager.tsx # ✅ 팀 주제 관리 │ │ ├── SecurityLevelSelector.tsx # 보안 레벨 선택 (RadioCard, 애니메이션) │ │ ├── TopicMemberAnalysisSection.tsx # 주제별 학생 분석 (UI만) │ │ └── LiveWritingMonitor.tsx # 🆕 실시간 글쓰기 모니터링 (Realtime DB) │ └── [미구현] │ ├── lesson/ # 학습 컴포넌트 │ ├── sticker/ # 스티커 컴포넌트 │ ├── level/ # 레벨 시스템 │ ├── profile/ # 프로필 컴포넌트 │ ├── notification/ # 알림 컴포넌트 │ └── admin/ # 관리자 컴포넌트 │ ├── config/ # ✅ 설정 │ ├── firebase.ts │ └── site.ts │ ├── managers/ # ✅ 비즈니스 로직 (Manager 패턴) │ ├── ManagerBase.ts # 기본 Manager 클래스 │ ├── WritingManager.ts # 글쓰기 관리 │ ├── WritingSessionManager.ts # 🆕 실시간 세션 관리 (Realtime DB) │ ├── TopicManager.ts # 주제 관리 │ ├── TeamManager.ts # 팀 관리 │ ├── UserManager.ts # 사용자 관리 │ ├── DraftManager.ts # 글조각 관리 (localStorage + Realtime DB 하이브리드) │ └── [미구현] │ ├── 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) │ ├── firestoreUser.ts # ✅ 사용자 타입 (FirestoreUser, User) │ ├── draft.ts # ✅ 글조각 타입 │ ├── writingPattern.ts # ✅ 패턴 분석 타입 │ ├── writingSession.ts # 🆕 실시간 모니터링 타입 (WritingStats, PreviewRequest/Response) │ ├── api/ # ✅ API Request/Response 타입 │ │ ├── topic.ts # ✅ 주제 API (팀/개인 주제) │ │ ├── team.ts # ✅ 팀 API │ │ ├── user.ts # ✅ 사용자 API │ │ └── writing.ts # ✅ 글쓰기 API │ └── [미구현] │ └── utils/ # 유틸리티 함수 ├── passwordStrength.ts # ✅ 비밀번호 강도 계산 ├── passwordSecurity.ts # ✅ HIBP API 연동 └── classCodeGenerator.ts # ✅ 팀 코드 생성/검증/정규화 ``` --- ## 다음 구현 단계 ### Phase 1: 핵심 기능 (현재) 1. ✅ 프로젝트 설정 및 인프라 2. ✅ 인증 시스템 (로그인) 3. ✅ 랜딩 페이지 4. ✅ 회원가입 기능 (페이드 전환 + HIBP 보안 검증) 5. ✅ 인증 기반 라우팅 (`/`와 `/home` 분리) 6. ✅ 글쓰기 페이지 (Tiptap 에디터, 저장 시 AI 분석, 분석 결과 DB 저장) 7. ✅ 주제 선택 및 관리 (자유/개인 주제, 템플릿) 8. ✅ **팀 코드 시스템** (완료) - ✅ 한글 팀 코드 생성 ("춤추는 파란 사자") - ✅ Anonymous Auth 학생 로그인 - ✅ 팀/학생 관리 서비스 (ownerId 기반) - ✅ PIN 인증 (SHA-256) - ✅ 정식 계정 연결 (linkWithCredential) - ✅ currentStudent 중심 authStore 재설계 - ✅ 학생 로그인 UI (3단계 플로우, 이름 입력, 완료 화면) - ✅ 팀 관리 UI (목록/생성/멤버 페이지/관리 페이지) - ✅ 용어 변경: "클래스" → "팀", "교사" → "소유자" 9. 🚧 **다음**: 내가 쓴 글 목록 ### Phase 2: 팀 코드 UI 완성 - 학생 로그인 UI (팀 코드 입력 → 이름 선택 → PIN) - 팀 관리 (팀 생성, 멤버 관리) - LoginDialog에 학생 탭 추가 ### Phase 3: 학습 시스템 - `/learn` 학습 페이지 - 레슨 콘텐츠 및 진행 상황 ### Phase 4: 게임화 - 레벨업 시스템 - `/stickers` 스티커 페이지 ### Phase 5: 사용자 경험 - ProfileDialog 마이페이지 (Dialog 형식) - 검색 및 알림 ### Phase 6: 고급 기능 - 부모님 모드 (계정 연결) - 관리자 패널 --- ## 관련 문서 - [TECH_STACK.md](./TECH_STACK.md) - 기술 스택 및 개발 환경 설정 - [DATA_MODELS.md](./DATA_MODELS.md) - 데이터베이스 스키마 및 타입 정의 - [ROADMAP.md](./ROADMAP.md) - 개발 우선순위 및 로드맵 - [CLAUDE.md](./CLAUDE.md) - Claude Code 작업 가이드 --- © 2024 BlueNovaLab. All rights reserved.