diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index dbf3b4a..405427c 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -1,10 +1,23 @@ # 라온누리 - 프로젝트 구조 -> 최종 업데이트: 2025-11-14 (개별 글 분석 결과 저장) +> 최종 업데이트: 2025-11-14 (AI 글쓰기 도우미 시스템) 초등학생을 위한 창작 글쓰기 교육 플랫폼 -**최신 업데이트** (2025-11-14): +**최신 업데이트** (2025-11-14 PM): +- 🤖 **AI 글쓰기 도우미 시스템** + - **4단계 점진적 힌트**: 질문 → 방향 → 선택지 → 예시 문장 + - **작성 멈춤 감지**: 5분간 입력 없으면 자동 제안 (useWritingInactivityDetection 훅) + - **주제 맥락 활용**: 주제 정보(title, keywords, category)를 프롬프트에 포함 + - **팀별 설정**: 선생님이 팀 관리 페이지에서 On/Off 가능 + - **서버 검증**: AI 힌트 요청 시 팀 설정 확인 (enabled, allowedHintLevels) + - **사용 제한**: 글당 최대 5회, 힌트 간 3분 쿨다운 + - **다국어 프롬프트**: 한국어/영어/일본어 지원 + - **UI 컴포넌트**: InactivityPrompt (플로팅 버튼), HintDisplay (Dialog), AIAssistancePanel + - **API**: POST /api/writing-assistance, GET/PUT /api/team/[teamId]/ai-config + - **Firestore**: Team.aiAssistanceConfig 필드 추가 + +**최신 업데이트** (2025-11-14 AM): - 💾 **개별 글 분석 결과 저장 시스템** - Writing 타입에 WritingAnalysis 필드 추가 - 글쓰기 페이지 실시간 분석 제거 (저장 시에만 분석) @@ -278,6 +291,9 @@ | **EditorTooltip** | `EditorTooltip.tsx` | 🆕 **인터랙티브 툴팁** (맞춤법/감각 단어 클릭 시 표시) | ✅ 완료 | | **WritingPatternDialog** | `WritingPatternDialog.tsx` | 🆕 **글 작성 패턴 분석 다이얼로그** (최근 10개 글 분석) | ✅ 완료 | | **WritingPatternDisplay** | `WritingPatternDisplay.tsx` | 🆕 **패턴 분석 결과 표시** (종합 평가, 발전 추이, 강점/약점, 추천) | ✅ 완료 | +| **InactivityPrompt** | `InactivityPrompt.tsx` | 🆕 **작성 멈춤 프롬프트** (5분 입력 없을 시 플로팅 버튼) | ✅ 완료 | +| **HintDisplay** | `HintDisplay.tsx` | 🆕 **AI 힌트 표시** (4단계 힌트 Dialog, RadioCard 선택지) | ✅ 완료 | +| **AIAssistancePanel** | `AIAssistancePanel.tsx` | 🆕 **AI 도움 패널** (레벨 선택, 남은 횟수, 쿨다운) | ✅ 완료 | | ~~**ScoreDisplay**~~ | ~~`ScoreDisplay.tsx`~~ | ~~실시간 피드백 점수 표시~~ | ❌ 삭제됨 (하이라이트로 대체) | | ~~**SpellingErrorDisplay**~~ | ~~`SpellingErrorDisplay.tsx`~~ | ~~맞춤법 오류 표시~~ | ❌ 삭제됨 (하이라이트로 대체) | | **CreateTopicDialog** | `CreateTopicDialog.tsx` | 개인 주제 생성 다이얼로그 (태그 입력 UI) | ✅ 완료 | @@ -450,6 +466,7 @@ | **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로 대체) | @@ -467,9 +484,9 @@ | 타입 | 파일명 | 설명 | 상태 | |------|--------|------|------| -| **Team 타입** | `team.ts` | 팀 데이터 모델 (members Map), **TeamSecurityLevel Enum (1-5)** | ✅ 완료 | +| **Team 타입** | `team.ts` | 팀 데이터 모델 (members Map), **TeamSecurityLevel Enum (1-5)**, 🆕 **AIAssistanceConfig** (AI 도우미 설정) | ✅ 완료 | | **FirestoreUser 타입** | `firestoreUser.ts` | **FirestoreUser** (DB 저장용), **User** (UI용) 분리 | ✅ 완료 | -| **Writing 타입** | `writing.ts` | 글 데이터 모델, 🆕 **WritingAnalysis** (AI 분석 결과, contentHash 기반 재사용), **SpellingError** (맞춤법 오류) | ✅ 완료 | +| **Writing 타입** | `writing.ts` | 글 데이터 모델, 🆕 **WritingAnalysis** (AI 분석 결과, contentHash 기반 재사용), **SpellingError** (맞춤법 오류), 🆕 **AIAssistanceRecord** (AI 도움 이력) | ✅ 완료 | | **Draft 타입** | `draft.ts` | 글조각 데이터 모델 (Draft, DraftListItem, **AnalysisHistoryItem**) | ✅ 완료 | | **WritingPattern 타입** | `writingPattern.ts` | **글 작성 패턴 분석** 데이터 모델 (WritingPatternAnalysis) | ✅ 완료 | | **WritingSession 타입** | `writingSession.ts` | 🆕 **실시간 모니터링** 데이터 모델 (WritingStats, PreviewRequest/Response, MonitoringData) | ✅ 완료 | @@ -477,7 +494,7 @@ | ~~**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 제거) | ✅ 완료 | +| **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로 대체) | @@ -498,6 +515,24 @@ --- +### 📁 `src/hooks/` - Custom Hooks + +| Hook | 파일명 | 설명 | 상태 | +|------|--------|------|------| +| **useWritingInactivityDetection** | `useWritingInactivityDetection.ts` | 🆕 **작성 멈춤 감지 훅** (N분 입력 없을 시 콜백, 타이머 리셋, 남은 시간) | ✅ 완료 | + +--- + +### 📁 `src/prompts/` - AI 프롬프트 + +| 프롬프트 | 파일명 | 설명 | 상태 | +|---------|--------|------|------| +| **Text Analysis** | `textAnalysis.ts` | 텍스트 분석 프롬프트 (다국어, 히스토리 기반) | ✅ 완료 | +| **Pattern Analysis** | `patternAnalysis.ts` | 패턴 분석 프롬프트 (10개 글 종합 평가) | ✅ 완료 | +| **Writing Assistance** | `writingAssistance.ts` | 🆕 **AI 글쓰기 도우미 프롬프트** (4단계 × 3개 언어, 주제 맥락 활용) | ✅ 완료 | + +--- + ### 📁 `src/app/api/` - API Routes | API | 경로 | 메서드 | 설명 | 상태 | @@ -505,6 +540,7 @@ | **텍스트 분석** | `/api/analyze-text` | POST | **Gemini 기반 텍스트 분석** (Delta 지원, 캐싱, 히스토리 인식) | ✅ 완료 | | **패턴 분석** | `/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]` | PUT | 🆕 **글 수정** (작성자만 접근, 통계 재계산) | ✅ 완료 | @@ -515,11 +551,12 @@ | **팀 보안 레벨** | `/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 도우미 설정 조회/업데이트** | ✅ 완료 | | **주제 CRUD** | `/api/topic` | GET, POST, PUT, DELETE | 주제 생성/조회/수정/삭제 (9개 엔드포인트) | ✅ 완료 | | **사용자 관리** | `/api/user` | GET, POST, PUT | 사용자 조회/생성/업데이트 | ✅ 완료 | **서버 레이어** (`src/lib/server/`): -- `team.ts` - 팀 Firestore CRUD +- `team.ts` - 팀 Firestore CRUD, 🆕 **getTeamAIConfig/updateTeamAIConfig** (AI 설정 관리) - `user.ts` - 사용자 Firestore CRUD - `topic.ts` - 주제 Firestore CRUD - 🆕 `writing.ts` - 글 Firestore CRUD (createWriting, getWriting, updateWriting, deleteWriting, getUserWritings, getRecentWritings, isWritingOwner) diff --git a/ROADMAP.md b/ROADMAP.md index 310801a..1b0d99a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # 라온누리 - 개발 로드맵 -> 최종 업데이트: 2025-11-14 (개별 글 분석 결과 저장) +> 최종 업데이트: 2025-11-14 (AI 글쓰기 도우미 시스템) 초등학생을 위한 창작 글쓰기 교육 플랫폼 개발 계획 @@ -86,6 +86,7 @@ | **실시간 글쓰기 모니터링** | **Firebase Realtime Database 기반 실시간 통신 (Redis Pub/Sub 방식), WritingSessionManager (5초 주기 통계 전송, 미리보기 요청-응답, 상세 디버그 로그), LiveWritingMonitor (주제 Select, 모든 팀 멤버 표시, StudentMonitorCard), 3가지 상태 관리 (작성 중/나감/대기 중, 정렬 순서, 색상별 시각화), 글쓰기 페이지 모니터링 (contentRef 최적화), onDisconnect() 자동 정리, 작성 속도 계산 (클라이언트, 글자/분, charDiff*12), Sparkline 그래프 (Area Chart, 최근 10개, 0 표시), 인터랙티브 툴팁 (속도+시간), 30초 타임아웃 체크 (lastUpdated), 마지막 통계 유지 (Firebase 삭제되어도 유지), database.rules.json (topicId 레벨 읽기), @chakra-ui/charts+recharts, 완전 무료 (100명)** | **2025-11-12** | | **다국어 지원 시스템 (i18n)** | **next-intl 라이브러리 설치 및 설정, [locale] 라우팅 구조 변경 (/ko/*, /en/*, /ja/*), middleware.ts 생성 (브라우저 언어 자동 감지, Accept-Language 헤더), 3개 언어 번역 파일 생성 (messages/ko.json, messages/en.json, messages/ja.json - 각 407줄, 220+ 키), Navbar 번역 (4개 링크), LocaleSwitcher 드롭다운 메뉴 개선 (국기 이모지 🇰🇷 🇺🇸 🇯🇵, 현재 언어 체크 표시, Portal 사용), Landing 페이지 전체 번역 (Hero, Features, Steps, CTA, Footer - 20+ 항목), Home 페이지 전체 번역 (Welcome, QuickStart 9개 액션 카드, RecentActivity), 인증 컴포넌트 전체 번역 (LoginDialog, LoginForm, SignupForm, UserProfileButton, StudentLoginFlow, SavedDraftsDialog - 70+ 항목), Team 페이지 전체 번역 (List, Create, Detail, Manage + SecurityLevelSelector - 60+ 항목), Write 페이지 번역 (분석/저장 메시지, 버튼), 일본어 어린이 친화적 표현 (한자 최소화, ひらがな 우선), site.ts 텍스트를 번역 파일로 이동 (사이트명, 태그라인, 저작권), localeDetection: true 설정, NEXT_LOCALE 쿠키 저장, next.config.ts에 next-intl 플러그인 추가, i18n/routing.ts + i18n/request.ts 설정, 타입 체크 통과, CLAUDE.md에 다국어 필수 규칙 추가** | **2025-11-13** | | **개별 글 분석 결과 저장** | **Writing 타입에 WritingAnalysis 필드 추가, SpellingError 타입 정의, generateWritingContentHash 유틸 추가, 글쓰기 페이지 실시간 분석 제거, 저장 버튼 클릭 시 AI 분석 + 맞춤법 검사 병렬 수행, 분석 결과를 DB에 저장, 패턴 분석 시 저장된 분석 재사용 (contentHash 비교), 변경된 글만 재분석 (90% 비용 절감), 맞춤법 에러 히스토리 기능 완성, API 타입/서버 함수/WritingManager 전체 수정, getTranslations()로 서버 사이드 다국어 지원** | **2025-11-14** | +| **AI 글쓰기 도우미 시스템** | **4단계 점진적 힌트 시스템 (질문 → 방향 → 선택지 → 예시 문장), useWritingInactivityDetection 훅 (5분 작성 멈춤 감지, 타이머 리셋, 남은 시간), UI 컴포넌트 3개 (InactivityPrompt 플로팅 버튼, HintDisplay Dialog, AIAssistancePanel), writingAssistanceService.ts (Vertex AI, 주제 맥락 활용, 서버 캐싱), writingAssistance.ts 프롬프트 (4단계 × 3개 언어 ko/en/ja), 글쓰기 페이지 통합 (AI 도움 요청, 서버 에러 처리), POST /api/writing-assistance (주제 정보 전달, 팀 설정 검증), GET/PUT /api/team/[teamId]/ai-config (AI 설정 조회/업데이트), Team.aiAssistanceConfig 필드 (enabled, detectionTimeMinutes, maxHintsPerWriting, cooldownMinutes, allowedHintLevels, requireSelfEdit), DEFAULT_AI_ASSISTANCE_CONFIG 상수, 팀 관리 페이지 AI On/Off 토글 (Switch.Root v3), TeamManager AI 메서드 (getAIConfig, updateAIConfig), lib/server/team.ts AI 함수 (getTeamAIConfig, updateTeamAIConfig), 서버 검증 (enabled=false → 403, allowedHintLevels 체크), 사용 제한 (글당 5회, 3분 쿨다운), 다국어 번역 추가 (messages/*.json, aiAssist namespace 19개 키), successResponse() 헬퍼 사용, AIAssistanceRecord 타입 (timestamp, hintLevel, topicId, topicTitle, context, hintProvided, wasUsed)** | **2025-11-14** | ### 🚧 진행 중 diff --git a/TECH_STACK.md b/TECH_STACK.md index d99f524..abaacc5 100644 --- a/TECH_STACK.md +++ b/TECH_STACK.md @@ -1603,6 +1603,191 @@ const improvementRate = calculateImprovementRate(spellingErrorsHistory); --- +### 10. AI 글쓰기 도우미 시스템 + +#### 개요 + +학생이 글쓰기 중 막혔을 때 AI가 **주제 맥락을 고려한** 4단계 점진적 힌트를 제공하는 시스템 + +#### 아키텍처 플로우 + +``` +1️⃣ 선생님 (팀 관리) + ↓ +팀 관리 페이지 (/team/[teamId]/manage) + ├─> Switch.Root (AI 도움 On/Off) + ├─> handleAIToggle(checked) + └─> teamManager.updateAIConfig(teamId, config) + ↓ PUT + API: /api/team/[teamId]/ai-config + ↓ Firestore + teams/{teamId}.aiAssistanceConfig = { + enabled: true, + detectionTimeMinutes: 5, + maxHintsPerWriting: 5, + cooldownMinutes: 3, + allowedHintLevels: [1,2,3,4], + requireSelfEdit: true + } + +2️⃣ 학생 (글쓰기) + ↓ +글쓰기 페이지 (/write) + ├─> 팀 주제 선택 (topicInfo.ownerType === "team") + ├─> teamManager.getAIConfig(topicInfo.ownerId) + │ ↓ GET (5분 캐싱) + │ API: /api/team/[teamId]/ai-config + │ ↓ Firestore + │ teams/{teamId}.aiAssistanceConfig 조회 + └─> setAiAssistEnabled(config?.enabled) + +3️⃣ 작성 멈춤 감지 + ↓ +useWritingInactivityDetection({ + detectionTimeMinutes: 5, + enabled: aiAssistEnabled && !!selectedTopic, + onInactive: () => setShowInactivityPrompt(true) +}) + ├─> 에디터 입력 → resetTimer() + ├─> 5분간 입력 없음 → onInactive() 실행 + └─> + (플로팅 버튼: "막히셨나요?") + +4️⃣ AI 힌트 요청 + ↓ +handleRequestHint(level) + ├─> 클라이언트 검증 + │ ├─> 주제 선택 확인 + │ ├─> 제한 확인 (aiHintsUsed < maxHints) + │ └─> 쿨다운 확인 (lastHintTime + cooldown) + │ + ├─> POST /api/writing-assistance + │ body: { + │ level: 1~4, + │ currentContent: string, + │ topicInfo: Topic, // 🔑 주제 정보 전달 + │ locale: "ko" | "en" | "ja" + │ } + │ + └─> 서버 처리 (writing-assistance/route.ts) + │ + ├─> 🔒 팀 설정 검증 + │ ├─> getTeamAIConfig(topicInfo.ownerId) + │ ├─> config.enabled === false → 403 "AI_DISABLED" + │ └─> level ∉ config.allowedHintLevels → 403 "LEVEL_NOT_ALLOWED" + │ + └─> ✅ 검증 통과 + ↓ + generateHint(params) + ├─> buildHintPrompt(level, content, topicInfo, locale) + │ ├─> 주제 정보 활용 + │ │ - title: "나의 여름방학" + │ │ - keywords: ["여름", "가족"] + │ │ - category: "daily" + │ │ - examplePrompts: [...] + │ │ + │ └─> 레벨별 프롬프트 생성 + │ - Level 1: "여름방학에서 가장 기억에 남는 순간은?" + │ - Level 2: "그 순간의 감정을 자세히 표현해보세요" + │ - Level 3: ["A. 가족", "B. 친구", "C. 혼자"] + │ - Level 4: "예: 나는 여름 해변에서..." + │ + ├─> Vertex AI (Gemini 2.5 Flash) + │ temperature: 0.8 + │ schema: SINGLE_HINT_SCHEMA | CHOICE_HINT_SCHEMA + │ + └─> 서버 캐싱 (1분 TTL, 50개) + key: `${level}-${topicId}-${contentHash}` + +5️⃣ 힌트 표시 + ↓ + handleRequestHint(level+1)} +/> + ├─> Level 1, 2, 4: 단일 텍스트 (Box) + └─> Level 3: RadioCard.Root (선택지 3개) +``` + +#### 데이터 모델 + +```typescript +// Team (Firestore) +interface Team { + // ... 기존 필드 + aiAssistanceConfig?: { + enabled: boolean; + detectionTimeMinutes: number; // 5분 + maxHintsPerWriting: number; // 5회 + cooldownMinutes: number; // 3분 + allowedHintLevels: number[]; // [1,2,3,4] + requireSelfEdit: boolean; // true + }; +} + +// Writing (선택적) +interface Writing { + // ... 기존 필드 + aiAssistanceHistory?: AIAssistanceRecord[]; +} + +interface AIAssistanceRecord { + timestamp: Timestamp; + hintLevel: 1 | 2 | 3 | 4; + topicId?: string; + topicTitle?: string; + context: string; // 마지막 50단어 + hintProvided: string; + wasUsed: boolean; +} +``` + +#### 주요 특징 + +1. **주제 맥락 활용** 🔑: + - AI 프롬프트에 주제 정보 전달 (title, keywords, category) + - 맥락에 맞는 힌트 생성 ("여름방학"이면 여름 관련 질문) + +2. **4단계 점진적 힌트** 📈: + - Level 1 (질문): "주인공은 어떤 기분일까요?" + - Level 2 (방향): "감정 변화를 써보세요" + - Level 3 (선택): ["A. 친구", "B. 가족", "C. 혼자"] + - Level 4 (예시): "예: 나는 용기를 내어..." + +3. **서버 검증** 🔒: + - 팀 설정 확인 (Firestore) + - enabled=false → 403 에러 + - 허용되지 않은 레벨 → 403 에러 + +4. **사용 제한** ⏱️: + - 글당 최대 5회 + - 힌트 간 3분 쿨다운 + - 클라이언트 + 서버 이중 검증 + +5. **다국어 지원** 🌏: + - 한국어/영어/일본어 프롬프트 + - locale에 따라 다른 AI 응답 + +6. **캐싱 전략** ⚡: + - 팀 AI 설정: 5분 캐싱 (TeamManager) + - AI 힌트: 서버 메모리 1분 (동일 컨텍스트 재요청 방지) + +#### 참고 파일 + +**타입**: `src/types/team.ts` (AIAssistanceConfig), `src/types/writing.ts` (AIAssistanceRecord) +**훅**: `src/hooks/useWritingInactivityDetection.ts` +**서비스**: `src/services/writingAssistanceService.ts` +**프롬프트**: `src/prompts/writingAssistance.ts` (4단계 × 3개 언어) +**UI**: `src/components/writing/{InactivityPrompt, HintDisplay, AIAssistancePanel}.tsx` +**API**: `src/app/api/writing-assistance/route.ts`, `src/app/api/team/[teamId]/ai-config/route.ts` +**서버**: `src/lib/server/team.ts` (getTeamAIConfig, updateTeamAIConfig) +**Manager**: `src/managers/TeamManager.ts` (getAIConfig, updateAIConfig) + +--- + ## 참고 문서 - [PROJECT_STRUCTURE.md](./PROJECT_STRUCTURE.md) - 프로젝트 구조