diff --git a/API_SPEC.md b/API_SPEC.md
index 2b3c954..b14598e 100644
--- a/API_SPEC.md
+++ b/API_SPEC.md
@@ -2,7 +2,26 @@
라온누리 서버 API 명세서
-## ⚠️ 최신 변경사항 (2025-11-11)
+## ⚠️ 최신 변경사항 (2025-11-12)
+
+### ✅ Writing API 구현 완료
+- **POST /api/writing**: 글 생성 (서버에서 wordCount/charCount 자동 계산)
+- **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)
+
+### ⚡ Content Hash 기반 스마트 캐싱
+- **POST /api/analyze-pattern**: contentHash 파라미터 추가
+- **L1 캐시**: localStorage (영구, LRU 10개)
+- **L2 캐시**: Server in-memory (5분, 50개)
+- **해시 생성**: `id:updatedAt` 조합 (SHA-256)
+- **자동 변경 감지**: 글 추가/수정 → 해시 변경 → 재분석
+- **성능 개선**: 캐시 히트 시 1ms vs AI 분석 5~10초
+
+## ⚠️ 변경사항 (2025-11-11)
### 🤖 실시간 피드백 시스템
- **POST /api/analyze-text**: Vertex AI 기반 텍스트 분석 API
@@ -153,6 +172,168 @@ const result = await analyzeText("오늘 날씨가 좋다.");
---
+## Pattern Analysis API
+
+### POST /api/analyze-pattern
+
+**설명**: 글 작성 패턴 분석 (사용자의 여러 글을 종합 분석)
+
+**인증**: 필수
+
+**Request Body**:
+```typescript
+{
+ analysisType?: "self" | "by-topic" | "by-team"; // 분석 타입 (기본: self)
+ targetUserId?: string; // 분석 대상 유저 (팀원 분석 시)
+ topicId?: string; // 주제 ID (by-topic 시 필수)
+ teamId?: string; // 팀 ID (by-team 시 필수)
+ limit?: number; // 분석할 글의 최대 개수 (기본: 10개)
+ contentHash?: string; // 🆕 클라이언트가 계산한 해시 (캐시 조회용, 선택)
+}
+```
+
+**Response**:
+```typescript
+{
+ success: true,
+ pattern: {
+ userId: string;
+ analyzedAt: Date;
+ totalWritingsAnalyzed: number;
+
+ // 분석 컨텍스트
+ analysisType?: "self" | "by-topic" | "by-team";
+ targetUserName?: string;
+ topicId?: string;
+ topicName?: string;
+ teamId?: string;
+ teamName?: string;
+
+ // 작성 스타일
+ writingStyle: {
+ averageWordCount: number;
+ averageCharCount: number;
+ preferredLength: "짧음" | "보통" | "긴편";
+ sentenceStructure: "단문 위주" | "복문 위주" | "혼합형";
+ };
+
+ // 표현력 분석
+ expressionAnalysis: {
+ averageScore: number; // 0~10
+ strongPoints: string[];
+ weakPoints: string[];
+ breakdown: {
+ sensory: number; // 오감 표현 (0~4)
+ emotion: number; // 감정 표현 (0~2)
+ dialogue: number; // 대화 표현 (0~2)
+ onomatopoeia: number; // 의성어/의태어 (0~2)
+ };
+ frequentExpressions: {
+ sensory: string[];
+ emotion: string[];
+ onomatopoeia: string[];
+ };
+ };
+
+ // 맞춤법 경향
+ spellingTendency: {
+ commonErrors: Array<{
+ error: string;
+ correction: string;
+ frequency: number;
+ }>;
+ improvementRate: number; // 0~100
+ };
+
+ // 발전 추이
+ progressTrend: {
+ isImproving: boolean;
+ scoreChange: number;
+ improvementAreas: string[];
+ needsAttention: string[];
+ };
+
+ // AI 종합 평가
+ summary: {
+ overallAssessment: string;
+ encouragement: string;
+ recommendations: string[];
+ };
+ },
+ contentHash: string; // 🆕 서버가 계산한 해시 (클라이언트 캐싱용)
+}
+```
+
+**에러**:
+```typescript
+// 404 - 분석할 글 없음
+{
+ success: false,
+ error: "분석할 글이 없습니다. 글을 작성한 후 다시 시도해주세요."
+}
+
+// 403 - 권한 없음 (by-topic, by-team)
+{
+ success: false,
+ error: "팀 소유자만 팀원의 글을 분석할 수 있습니다"
+}
+```
+
+**분석 타입**:
+
+1. **self (본인 분석)**:
+ - 모든 published 글 분석
+ - 권한: 본인만
+
+2. **by-topic (주제별 분석)**:
+ - 특정 팀 주제로 작성된 글만 분석
+ - 권한: 팀 소유자만
+ - 주제가 팀 주제(`ownerType="team"`)여야 함
+
+3. **by-team (팀 전체 분석)**:
+ - 팀의 모든 주제로 작성된 글 분석
+ - 권한: 팀 소유자만
+ - 팀 외 글(자유 주제, 다른 팀)은 제외
+
+**🆕 Content Hash 기반 캐싱** (2025-11-12):
+
+**캐싱 전략**:
+- **L1 (Client)**: localStorage에 contentHash를 키로 저장 (영구, LRU 10개)
+- **L2 (Server)**: In-memory에 contentHash를 키로 저장 (5분 TTL, 최대 50개)
+- **변경 감지**: 글 추가/수정 시 `updatedAt` 변경 → 해시 변경 → 자동 재분석
+
+**Hash 생성 규칙**:
+```typescript
+// 입력: analysisType | limit | topicId | teamId | id:updatedAt,id:updatedAt,...
+// 예시: "self|10|||abc:2024-01-01T00:00:00.000Z,def:2024-01-02T00:00:00.000Z"
+// SHA-256 → "abc123def456..."
+```
+
+**성능**:
+- 캐시 히트 (동일 글 세트): ~1ms (localStorage)
+- 캐시 히트 (서버): ~50ms (in-memory)
+- 캐시 미스: 5~10초 (AI 분석)
+
+**사용 흐름**:
+```typescript
+// 클라이언트 (self 분석)
+1. 글 목록 조회
+2. contentHash 계산
+3. localStorage 확인 → 히트 시 즉시 반환
+4. 서버 요청 (contentHash 포함)
+5. 서버 응답 → localStorage에 저장
+
+// 서버
+1. contentHash 받음 → 캐시 확인 → 히트 시 즉시 반환
+2. 캐시 미스 → 글 조회
+3. 서버 contentHash 계산 → 캐시 확인
+4. AI 분석 수행
+5. contentHash 키로 캐시 저장
+6. contentHash 포함하여 응답
+```
+
+---
+
## Team API
### 1. POST `/team` - 팀 생성
@@ -942,7 +1123,9 @@ const result = await analyzeText("오늘 날씨가 좋다.");
### 2. GET `/writing/:id` - 글 조회
실제 URL: `GET /api/writing/:id`
-**인증**: 선택적
+**인증**: 필수
+
+**권한**: 작성자만 조회 가능 (`writing.userId === currentUserId`)
**Response**:
```typescript
@@ -954,6 +1137,10 @@ const result = await analyzeText("오늘 날씨가 좋다.");
}
```
+**에러**:
+- `404 Not Found`: 글이 존재하지 않음
+- `403 Forbidden`: 작성자가 아님
+
**캐싱**: 클라이언트에서 5분간 캐싱
---
diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md
index 31fd2da..1168dcf 100644
--- a/PROJECT_STRUCTURE.md
+++ b/PROJECT_STRUCTURE.md
@@ -1,10 +1,63 @@
# 라온누리 - 프로젝트 구조
-> 최종 업데이트: 2025-11-11 (Google AI SDK 마이그레이션, 분석 히스토리, 맞춤법 검사)
+> 최종 업데이트: 2025-11-12 (Writing API, 패턴 분석 확장, Content Hash 캐싱)
초등학생을 위한 창작 글쓰기 교육 플랫폼
-**주요 업데이트** (2025-11-11):
+**최신 업데이트** (2025-11-12):
+- ✅ **Writing API 구현 완료**
+ - POST /api/writing - 글 생성 (서버에서 wordCount/charCount 자동 계산)
+ - 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 기반 스마트 캐싱**
+ - L1 캐시: localStorage (영구, LRU 10개)
+ - L2 캐시: Server in-memory (5분, 50개)
+ - 해시 생성: `id:updatedAt` 조합 (SHA-256)
+ - 변경 자동 감지: 글 추가/수정 시 해시 변경 → 재분석
+ - 성능: 캐시 히트 시 1ms (localStorage) vs 5~10초 (AI 분석)
+ - 유틸리티: `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 응답 강제)
@@ -19,10 +72,8 @@
- 이전 버전 비교 피드백
- ✍️ **맞춤법 검사 서비스** (독립적)
- Gemini 기반 맞춤법 검사
- - SpellingErrorDisplay 컴포넌트
- 텍스트 분석과 별도 debounce (5초)
- 🤖 **실시간 피드백 시스템** (Vertex AI 기반)
- - ScoreDisplay 컴포넌트 (점수, 찾은 단어, 수정 제안)
- Delta 전송 (토큰 40% 절감)
- 서버 캐싱 (중복 제거)
- 🌏 **Multi-Region Failover** (가용성 99.9%)
@@ -56,7 +107,7 @@
| **팀 목록** | `/team` | 내가 만든 팀 목록 (정식 계정 전용) | 팀 카드 그리드, 팀 정보 (코드, 멤버 수, 보안 설정)
"새 팀 만들기" 버튼 |
| **팀 생성** | `/team/create` | 새 팀 만들기 (정식 계정 전용) | 팀 이름 입력, 팀 코드 자동 생성
🆕 **5단계 보안 레벨 선택** (RadioCard, 애니메이션)
🆕 **명단 관리 (Level 2/4)**: TagsInput으로 Enter/쉼표 입력
생성 후 `/team/[teamId]`로 이동 |
| **팀 멤버 페이지** | `/team/[teamId]` | 팀 멤버용 페이지 (멤버/소유자 모두 접근) | 팀 정보, 팀 코드 복사, 멤버 목록
소유자는 "팀 관리" 버튼 표시
팀 코드 로그인 후 기본 이동 페이지 |
-| **팀 관리** | `/team/[teamId]/manage` | 팀 관리 페이지 (소유자 전용) | 팀 정보 및 코드, 보안 설정 표시
**팀 주제 관리 (생성/삭제)**
멤버 목록 및 관리
"멤버 페이지 보기" 버튼 |
+| **팀 관리** | `/team/[teamId]/manage` | 팀 관리 페이지 (소유자 전용) | 팀 정보 및 코드, 보안 설정 표시
**팀 주제 관리 (생성/삭제)**
🆕 **주제별 학생 분석** (TopicMemberAnalysisSection)
멤버 목록 및 관리
🆕 **멤버 메뉴 - 팀 내 글 분석** (by-team)
"멤버 페이지 보기" 버튼 |
### 🚧 구현 예정
@@ -152,37 +203,48 @@
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---------|--------|------|------|
-| **WritingEditor** | `WritingEditor.tsx` | Tiptap 기반 순수 텍스트 에디터 | ✅ 완료 |
-| **TopicSelector** | `TopicSelector.tsx` | 🆕 주제 선택 드롭다운 (그룹핑, 팀 이름 표시) | ✅ 완료 |
-| **ScoreDisplay** | `ScoreDisplay.tsx` | 🆕 **실시간 피드백 점수 표시** (Gemini 기반) | ✅ 완료 |
-| **SpellingErrorDisplay** | `SpellingErrorDisplay.tsx` | 🆕 **맞춤법 오류 표시** (Gemini 기반, 별도 독립) | ✅ 완료 |
+| **WritingEditor** | `WritingEditor.tsx` | Tiptap 기반 순수 텍스트 에디터 (하이라이트 통합) | ✅ 완료 |
+| **TopicSelector** | `TopicSelector.tsx` | 주제 선택 드롭다운 (그룹핑, 팀 이름 표시) | ✅ 완료 |
+| **EditorTooltip** | `EditorTooltip.tsx` | 🆕 **인터랙티브 툴팁** (맞춤법/감각 단어 클릭 시 표시) | ✅ 완료 |
+| **WritingPatternDialog** | `WritingPatternDialog.tsx` | 🆕 **글 작성 패턴 분석 다이얼로그** (최근 10개 글 분석) | ✅ 완료 |
+| **WritingPatternDisplay** | `WritingPatternDisplay.tsx` | 🆕 **패턴 분석 결과 표시** (종합 평가, 발전 추이, 강점/약점, 추천) | ✅ 완료 |
+| ~~**ScoreDisplay**~~ | ~~`ScoreDisplay.tsx`~~ | ~~실시간 피드백 점수 표시~~ | ❌ 삭제됨 (하이라이트로 대체) |
+| ~~**SpellingErrorDisplay**~~ | ~~`SpellingErrorDisplay.tsx`~~ | ~~맞춤법 오류 표시~~ | ❌ 삭제됨 (하이라이트로 대체) |
| **CreateTopicDialog** | `CreateTopicDialog.tsx` | 개인 주제 생성 다이얼로그 (태그 입력 UI) | ✅ 완료 |
| **CreateTeamTopicDialog** | `CreateTeamTopicDialog.tsx` | 팀 주제 생성 다이얼로그 (템플릿 지원) | ✅ 완료 |
-| **SavedDraftsDialog** | `SavedDraftsDialog.tsx` | 🆕 저장된 글조각 목록 다이얼로그 (불러오기/삭제) | ✅ 완료 |
+| **SavedDraftsDialog** | `SavedDraftsDialog.tsx` | 저장된 글조각 목록 다이얼로그 (불러오기/삭제) | ✅ 완료 |
**주요 기능**:
- ✅ 순수 텍스트 입력 (포맷팅 없음)
- ✅ 초등학생 친화적 단순 인터페이스
- ✅ 실시간 글자 수/단어 수 카운터
-- ✅ 🆕 **실시간 피드백 시스템** (Gemini 2.5 Flash-Lite)
- - ✅ 점수 표시 (0~10점, 개편된 평가 기준)
- - ✅ 찾은 표현 목록 (오감, 감정, 의성어/의태어)
- - ✅ 분석 히스토리 추적 (이전 버전 비교, 발전 과정 격려)
- - ✅ 스마트 제안 (칭찬 강화, 제안 0~1개)
+- ✅ 🆕 **실시간 하이라이트 시스템** (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 기반)
+- ✅ **맞춤법 검사** (독립적, Gemini 기반)
- ✅ 초등학생 눈높이 설명
- ✅ 5초 debounce (텍스트 분석과 별도)
- - ✅ 오류 목록 표시 (원본 → 수정, 이유)
-- ✅ 🆕 **주제 변경 경고 Dialog** (작성 중 내용 초기화 알림 + 임시 저장 안내)
-- ✅ 🆕 **다중 글조각 관리** (최대 10개, FIFO 방식)
-- ✅ 🆕 **강화된 자동 저장** (2초 debounce, localStorage)
-- ✅ 🆕 **저장 상태 표시** (저장 중 → 저장됨 → 시간 표시)
-- ✅ 🆕 "새 글쓰기" 버튼 (현재 글 초기화)
-- ✅ 🆕 "저장된 글조각" Dialog (목록, 미리보기, 불러오기/삭제)
-- ✅ 🆕 **주제 선택 그룹핑** (자유/팀/개인 주제 구분, ItemGroup 사용)
-- ✅ 🆕 **팀 주제에 팀 이름 표시** (어느 팀의 주제인지 명확히 표시)
+ - ✅ Toast 알림 (에러 개수 표시)
+- ✅ **주제 변경 경고 Dialog** (작성 중 내용 초기화 알림 + 임시 저장 안내)
+- ✅ **다중 글조각 관리** (최대 10개, FIFO 방식)
+- ✅ **강화된 자동 저장** (2초 debounce, localStorage)
+- ✅ **저장 상태 표시** (저장 중 → 저장됨 → 시간 표시)
+- ✅ "새 글쓰기" 버튼 (현재 글 초기화)
+- ✅ "저장된 글조각" Dialog (목록, 미리보기, 불러오기/삭제)
+- ✅ **주제 선택 그룹핑** (자유/팀/개인 주제 구분, ItemGroup 사용)
+- ✅ **팀 주제에 팀 이름 표시** (어느 팀의 주제인지 명확히 표시)
- ✅ 주제 선택 (자유 주제/팀 주제/개인 주제)
- ✅ 주제 정보 표시 (설명, 키워드, 예시 질문)
- ✅ 템플릿 미리채우기 (제목/내용)
@@ -192,13 +254,40 @@
---
+### 📁 `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/` - 팀 관리
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---------|--------|------|------|
| **TeamTopicManager** | `TeamTopicManager.tsx` | 팀 주제 목록 및 생성/삭제 UI | ✅ 완료 |
-| **SecurityLevelSelector** | `SecurityLevelSelector.tsx` | 🆕 5단계 보안 레벨 선택 (RadioCard, framer-motion 애니메이션) | ✅ 완료 |
-| **AllowListManager** | `AllowListManager.tsx` | 🆕 명단 관리 (이름/이메일 추가/제거, TagsInput) | ✅ 완료 |
+| **SecurityLevelSelector** | `SecurityLevelSelector.tsx` | 5단계 보안 레벨 선택 (RadioCard, framer-motion 애니메이션) | ✅ 완료 |
+| **AllowListManager** | `AllowListManager.tsx` | 명단 관리 (이름/이메일 추가/제거, TagsInput) | ✅ 완료 |
+| **TopicMemberAnalysisSection** | `TopicMemberAnalysisSection.tsx` | 🆕 주제별 학생 글쓰기 분석 (Accordion, by-topic 분석) | 🚧 UI만 (API 추후 구현) |
**주요 기능** (2025-11-10):
- ✅ SecurityLevelSelector: RadioCard 기반, 선택 시 추가 UI 애니메이션으로 표시
@@ -256,10 +345,11 @@
|-------|--------|------|------|
| **Firebase Auth** | `firebaseAuth.ts` | 인증 서비스 (로그인, 회원가입, 소셜, Anonymous, 계정 연결) | ✅ 완료 (단순화됨) |
| **Firestore** | `firestore.ts` | Firestore CRUD 헬퍼 함수 (WritingManager에서 사용) | ✅ 완료 |
-| **Vertex AI** | `vertexAI.ts` | 🆕 **Gemini API 범용 래퍼** (`@google/genai`, Multi-region failover, Response Schema) | ✅ 완료 |
-| **Text Analysis** | `textAnalysisService.ts` | 🆕 **텍스트 분석 서비스** (평가 기준 개편, 히스토리 기반 분석) | ✅ 완료 |
-| **Spelling Check** | `spellingService.ts` | 🆕 **맞춤법 검사 서비스** (Gemini 기반, 초등학생 눈높이) | ✅ 완료 |
-| **Region Health** | `regionHealthManager.ts` | 🆕 **Region 과부하 상태 추적** (자동 복구, 1분 TTL) | ✅ 완료 |
+| **Vertex AI** | `vertexAI.ts` | **Gemini API 범용 래퍼** (`@google/genai`, Multi-region failover, Response Schema) | ✅ 완료 |
+| **Text Analysis** | `textAnalysisService.ts` | **텍스트 분석 서비스** (평가 기준 개편, 히스토리 기반 분석) | ✅ 완료 |
+| **Pattern Analysis** | `patternAnalysisService.ts` | 🆕 **글 작성 패턴 분석 서비스** (10개 글 종합 분석, AI 평가) | ✅ 완료 |
+| **Spelling Check** | `spellingService.ts` | **맞춤법 검사 서비스** (Gemini 기반, 초등학생 눈높이) | ✅ 완료 |
+| **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` | 레벨/경험치 계산 로직 | ❌ 미구현 |
@@ -276,15 +366,16 @@
| 타입 | 파일명 | 설명 | 상태 |
|------|--------|------|------|
-| **Team 타입** | `team.ts` | 🆕 팀 데이터 모델 (members Map), **TeamSecurityLevel Enum (1-5)** | ✅ 완료 |
-| **FirestoreUser 타입** | `firestoreUser.ts` | 🆕 **FirestoreUser** (DB 저장용), **User** (UI용) 분리 | ✅ 완료 |
-| **Draft 타입** | `draft.ts` | 🆕 글조각 데이터 모델 (Draft, DraftListItem, **AnalysisHistoryItem**) | ✅ 완료 |
+| **Team 타입** | `team.ts` | 팀 데이터 모델 (members Map), **TeamSecurityLevel Enum (1-5)** | ✅ 완료 |
+| **FirestoreUser 타입** | `firestoreUser.ts` | **FirestoreUser** (DB 저장용), **User** (UI용) 분리 | ✅ 완료 |
+| **Draft 타입** | `draft.ts` | 글조각 데이터 모델 (Draft, DraftListItem, **AnalysisHistoryItem**) | ✅ 완료 |
+| **WritingPattern 타입** | `writingPattern.ts` | 🆕 **글 작성 패턴 분석** 데이터 모델 (WritingPatternAnalysis) | ✅ 완료 |
| ~~**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 제거) | ✅ 완료 |
-| **User API 타입** | `api/user.ts` | 사용자 API Request/Response (닉네임 관리 포함) **[NEW]** | ✅ 완료 |
+| **User API 타입** | `api/user.ts` | 사용자 API Request/Response (닉네임 관리 포함) | ✅ 완료 |
| ~~**Student API 타입**~~ | ~~`api/student.ts`~~ | ~~학생 API Request/Response~~ | ⚠️ Deprecated (api/user.ts로 대체) |
| **Topic API 타입** | `api/topic.ts` | 주제 API Request/Response (9개 엔드포인트, 팀 주제 포함) | ✅ 완료 |
@@ -294,10 +385,12 @@
| 유틸리티 | 파일명 | 설명 | 상태 |
|---------|--------|------|------|
-| **Korean Word List** | `koreanWordList.ts` | 🆕 **한글 감각 동사/형용사 목록** (점수 가중치, 영역 변환 함수) | ✅ 완료 |
+| **Korean Word List** | `koreanWordList.ts` | 한글 감각 동사/형용사 목록 (점수 가중치, 영역 변환 함수) | ✅ 완료 |
| **Team Code Generator** | `teamCodeGenerator.ts` | 한글 팀 코드 생성 (형용사 + 색깔 + 동물) | ✅ 완료 |
| **Password Security** | `passwordSecurity.ts` | HIBP API 연동 (유출된 비밀번호 차단) | ✅ 완료 |
| **Password Strength** | `passwordStrength.ts` | 비밀번호 강도 계산 | ✅ 완료 |
+| **Content Hash** | `contentHash.ts` | 🆕 **SHA-256 해시 생성** (글 목록 → 해시, id+updatedAt 조합, 서버/클라이언트 지원) | ✅ 완료 |
+| **Pattern Cache Manager** | `patternCacheManager.ts` | 🆕 **패턴 분석 localStorage 캐싱** (LRU 최대 10개, 캐시 통계) | ✅ 완료 |
---
@@ -305,8 +398,15 @@
| API | 경로 | 메서드 | 설명 | 상태 |
|-----|------|--------|------|------|
-| **텍스트 분석** | `/api/analyze-text` | POST | 🆕 **Gemini 기반 텍스트 분석** (Delta 지원, 캐싱, 히스토리 인식) | ✅ 완료 |
-| **맞춤법 검사** | `/api/spelling/check` | POST | 🆕 **Gemini 기반 맞춤법 검사** (초등학생 눈높이) | ✅ 완료 |
+| **텍스트 분석** | `/api/analyze-text` | POST | **Gemini 기반 텍스트 분석** (Delta 지원, 캐싱, 히스토리 인식) | ✅ 완료 |
+| **패턴 분석** | `/api/analyze-pattern` | POST | **글 작성 패턴 분석** (3가지 타입, contentHash 기반 2단계 캐싱, 변경 감지) | ✅ 완료 |
+| **맞춤법 검사** | `/api/spelling/check` | POST | **Gemini 기반 맞춤법 검사** (초등학생 눈높이) | ✅ 완료 |
+| **글 생성** | `/api/writing` | POST | 🆕 **글 생성** (wordCount/charCount 자동 계산) | ✅ 완료 |
+| **글 조회** | `/api/writing/[id]` | GET | 🆕 **글 조회** (작성자만 접근) | ✅ 완료 |
+| **글 수정** | `/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 | 허용 이름 추가/제거 | ✅ 완료 |
@@ -314,6 +414,12 @@
| **주제 CRUD** | `/api/topic` | GET, POST, PUT, DELETE | 주제 생성/조회/수정/삭제 (9개 엔드포인트) | ✅ 완료 |
| **사용자 관리** | `/api/user` | GET, POST, PUT | 사용자 조회/생성/업데이트 | ✅ 완료 |
+**서버 레이어** (`src/lib/server/`):
+- `team.ts` - 팀 Firestore CRUD
+- `user.ts` - 사용자 Firestore CRUD
+- `topic.ts` - 주제 Firestore CRUD
+- 🆕 `writing.ts` - 글 Firestore CRUD (createWriting, getWriting, updateWriting, deleteWriting, getUserWritings, getRecentWritings, isWritingOwner)
+
---
## 상태 관리 (Zustand)
diff --git a/ROADMAP.md b/ROADMAP.md
index 9db44d7..f95b75f 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -1,6 +1,6 @@
# 라온누리 - 개발 로드맵
-> 최종 업데이트: 2025-11-11 (실시간 피드백 시스템, Multi-Region Failover)
+> 최종 업데이트: 2025-11-12 (Writing API, 패턴 분석 확장, Content Hash 캐싱)
초등학생을 위한 창작 글쓰기 교육 플랫폼 개발 계획
@@ -8,7 +8,7 @@
## 현재 개발 단계
-**Phase 1: 핵심 기능** (진행 중 - 98% 완료)
+**Phase 1: 핵심 기능** (진행 중 - 99% 완료)
---
@@ -75,7 +75,14 @@
| **Google AI SDK 마이그레이션** | **`@google-cloud/vertexai` → `@google/genai` (v1.29.0), Response Schema 지원, Gemini 2.0+ 기능** | **2025-11-11** |
| **텍스트 분석 평가 기준 개편** | **오감(4점) + 감정(2점) + 대화(2점) + 의성어(2점), `descriptive` → `emotion`, 프롬프트 최적화 (칭찬 강화, 제안 0~1개)** | **2025-11-11** |
| **분석 히스토리 시스템** | **Draft.analysisHistory 추가 (최대 5개), AI가 수정 과정 인식, 이전 버전 비교 피드백** | **2025-11-11** |
-| **맞춤법 검사 서비스** | **spellingService.ts (Gemini 기반), SpellingErrorDisplay 컴포넌트, 독립적 debounce (5초)** | **2025-11-11** |
+| **맞춤법 검사 서비스** | **spellingService.ts (Gemini 기반), 독립적 debounce (5초)** | **2025-11-11** |
+| **글 작성 패턴 분석 시스템** | **patternAnalysisService.ts, WritingPatternDialog/Display, 최근 10개 글 종합 분석, AI 평가 및 맞춤형 추천, 5분 캐싱** | **2025-11-11** |
+| **실시간 하이라이트 시스템** | **SpellingHighlight/SensoryWordHighlight Extensions, 맞춤법(빨간 물결)/감각 단어(색상별) 하이라이트, ScoreDisplay/SpellingErrorDisplay 제거** | **2025-11-11** |
+| **인터랙티브 툴팁** | **EditorTooltip, 하이라이트 클릭 시 상세 정보 표시 (맞춤법: 원본→수정+이유, 감각 단어: 타입+격려), Portal + ESC/외부 클릭** | **2025-11-11** |
+| **Toast 알림 추가** | **텍스트 분석/맞춤법 검사 시작/완료/실패 알림, 점수/에러 개수 표시, 로딩 상태 (duration: Infinity)** | **2025-11-11** |
+| **Writing API 구현** | **POST /api/writing (글 생성), GET/PUT/DELETE /api/writing/[id] (조회/수정/삭제), POST /api/writing/user (목록), POST /api/writing/recent (최근 글), src/lib/server/writing.ts (Firestore CRUD), 권한 체크 (작성자만), 텍스트 통계 자동 계산** | **2025-11-12** |
+| **패턴 분석 - 팀 소유자 기능** | **3가지 분석 타입 (self/by-team/by-topic), API 권한 체크, 팀 주제 필터링, WritingPatternDialog Props 확장, TopicMemberAnalysisSection (UI만), 팀 관리 페이지에 멤버 분석 메뉴** | **2025-11-12** |
+| **Content Hash 기반 스마트 캐싱** | **글 목록 해시 생성 (id+updatedAt), L1: localStorage (영구, LRU 10개), L2: Server in-memory (5분, 50개), 변경 자동 감지, 재분석 최소화, contentHash.ts + patternCacheManager.ts** | **2025-11-12** |
### 🚧 진행 중
@@ -86,12 +93,11 @@
| 항목 | 설명 | 우선순위 | 예상 일정 |
|-----|------|---------|---------|
-| **Next.js API Routes 구현** | **Team/User API 엔드포인트 구현, ID Token 검증, 권한 체크** | 🔴 **긴급** | **2025-11-08** |
-| **서버 사이드 Redis 캐싱** | **API Routes에 Redis 캐싱, Rate Limiting 추가** | 🟡 중간 | 2025-11-09 |
-| 내가 쓴 글 목록 | `/home`에 최근 글 표시, 글 목록 페이지 | 🔴 높음 | 2025-11-10 |
-| 글 수정 기능 | 기존 글 불러와서 수정 | 🔴 높음 | 2025-11-11 |
-| ~~firestore.ts userId→studentId 변경~~ | ~~글쓰기 기능과 팀 코드 시스템 통합~~ | ~~🟡 중간~~ | ✅ **완료 (2025-11-07)** |
-| 이미지 업로드 | Firebase Storage 연동 | 🟡 중간 | 2025-11-13 |
+| **서버 사이드 Redis 캐싱** | **API Routes에 Redis 캐싱, Rate Limiting 추가** | 🟡 중간 | 2025-11-13 |
+| 내가 쓴 글 목록 | `/home`에 최근 글 표시, 글 목록 페이지 | 🔴 높음 | 2025-11-13 |
+| 글 수정 기능 | 기존 글 불러와서 수정 | 🔴 높음 | 2025-11-13 |
+| 이미지 업로드 | Firebase Storage 연동 | 🟡 중간 | 2025-11-14 |
+| 주제별 학생 분석 API | GET /api/topic/[topicId]/writers (주제로 글 쓴 학생 목록) | 🟡 중간 | 2025-11-14 |
**Phase 1 완료 목표**: 2025년 11월 15일
diff --git a/SERVICE_DIRECTION.md b/SERVICE_DIRECTION.md
index 7bc818b..90c93fc 100644
--- a/SERVICE_DIRECTION.md
+++ b/SERVICE_DIRECTION.md
@@ -417,8 +417,6 @@ Tier 3: 고급 AI (Claude Sonnet, $0.03/회, 95% 정확도)
#### ✅ 결정 사항
- **3-Tier 하이브리드 시스템** 채택
- Phase 1: 로컬 규칙만 구현 (MVP)
-- 상세 내용: [**기술 구현 문서**](./TECHNICAL_IMPLEMENTATION.md) 참고
-
---
### 5차 논의: 한글 패턴 매칭 문제 (2025-11-11)
@@ -449,7 +447,6 @@ Tier 3: 고급 AI (Claude Sonnet, $0.03/회, 95% 정확도)
- Tier 1: 간단한 정규식 10개 (즉시 응답)
- Tier 2: Mecab 서버 (5초 후 정밀 분석)
- Phase 1부터 Mecab 구현 시작
-- 상세 내용: [**기술 구현 문서**](./TECHNICAL_IMPLEMENTATION.md#2-한글-패턴-매칭-문제-해결) 참고
---
@@ -491,8 +488,7 @@ Tier 3: Gemini 2.5 Flash (90% 정확도, $0.0001/회)
- **AI 모델: Gemini 2.5 Flash** 채택
- **한글 분석: Mecab + 간단한 정규식** (하이브리드)
- **비용**: 연간 $1.20 (99.9% 절감)
-- 상세 내용: [기술 문서](./TECHNICAL_IMPLEMENTATION.md) 참고
-
+-
---
### 7차 논의: Mecab 배포 문제 및 Vertex AI 단일 시스템 재설계 (2025-11-11)
@@ -667,7 +663,6 @@ if (cached && Date.now() - cached.timestamp < 60000) {
- 추가 인프라 불필요
#### 📝 기술 문서 업데이트
-- [TECHNICAL_IMPLEMENTATION.md](./TECHNICAL_IMPLEMENTATION.md) 전면 개편
- Mecab 관련 내용 제거
- Vertex AI + Delta + Caching 중심으로 재작성
@@ -824,8 +819,6 @@ Region 3개 = 45 RPM (3배)
- 가용성: 95% → **99.9%**
- 추가 비용: **없음**
-**상세 내용**: [기술 문서 - Multi-Region](./TECHNICAL_IMPLEMENTATION.md#2-multi-region-failover-시스템)
-
---
## 🔄 다음 논의 주제
@@ -844,7 +837,7 @@ Region 3개 = 45 RPM (3배)
- 실제 서비스 구조 공개 - 움직이는 그림 메커니즘 (2차)
- **2025-11-11**:
- 초기 기획안 평가 - 후처리 방식의 문제점 분석 (3차)
- - 실시간 피드백 기술 구현 (4차) → [기술 문서](./TECHNICAL_IMPLEMENTATION.md)
+ - 실시간 피드백 기술 구현 (4차)
- 한글 패턴 매칭 문제 해결 (5차)
- AI 모델 선택 - Gemini 채택 (6차)
- **Mecab 배포 문제 발견 및 Vertex AI 단일 시스템 재설계 (7차)** ⭐
diff --git a/TECH_STACK.md b/TECH_STACK.md
index 35a46ab..027e907 100644
--- a/TECH_STACK.md
+++ b/TECH_STACK.md
@@ -1,6 +1,6 @@
# 라온누리 - 기술 스택 및 개발 환경
-> 최종 업데이트: 2025-11-11 (Google AI SDK 마이그레이션, 분석 히스토리, 맞춤법 검사)
+> 최종 업데이트: 2025-11-11 (글 작성 패턴 분석, 실시간 하이라이트, 인터랙티브 툴팁)
---
@@ -35,8 +35,9 @@
| **Redis** | - | Cache 데이터 베이스 (예정) |
**AI 서비스**:
-- **Gemini 2.5 Flash-Lite**: 텍스트 분석 (오감/감정/대화/의성어 평가)
+- **Gemini 2.5 Flash-Lite**: 텍스트 분석 (오감/감정/대화/의성어 평가, Delta 전송)
- **Gemini 2.5 Flash-Lite**: 맞춤법 검사 (초등학생 눈높이)
+- **Gemini 2.5 Flash-Lite**: 글 작성 패턴 분석 (최근 10개 글 종합 분석, AI 평가 및 맞춤형 추천)
- **Vertex AI 모드**: Multi-region failover 지원 (`vertexai: true`)
- **Response Schema**: JSON 응답 강제 (`Type.OBJECT`, `Type.ARRAY` 등)
@@ -849,10 +850,10 @@ interface Draft {
**API & 컴포넌트**:
- `src/app/api/analyze-text/route.ts` - 텍스트 분석 API
-- `src/app/api/spelling/check/route.ts` - 🆕 맞춤법 검사 API
-- `src/components/writing/ScoreDisplay.tsx` - 점수 표시 UI
-- `src/components/writing/SpellingErrorDisplay.tsx` - 🆕 맞춤법 오류 표시
-- `src/app/write/page.tsx` - Delta 추적 + 통합 + 맞춤법 검사
+- `src/app/api/spelling/check/route.ts` - 맞춤법 검사 API
+- ~~`src/components/writing/ScoreDisplay.tsx`~~ - ❌ 삭제됨 (하이라이트로 대체)
+- ~~`src/components/writing/SpellingErrorDisplay.tsx`~~ - ❌ 삭제됨 (하이라이트로 대체)
+- `src/app/write/page.tsx` - Delta 추적 + 통합 + Toast 알림
**타입 정의**:
- `src/types/draft.ts` - Draft, AnalysisHistoryItem
@@ -866,6 +867,142 @@ interface Draft {
---
+### 8. 글 작성 패턴 분석 시스템
+
+#### 핵심 개념
+
+**목적**: 사용자의 여러 글을 분석하여 작성 패턴, 강점, 약점을 파악하고 맞춤형 피드백 제공
+
+**분석 항목**:
+1. **작성 스타일**: 평균 글자/단어 수, 선호하는 글 길이, 문장 구조 (단문/복문/혼합)
+2. **표현력 분석**: 평균 점수, 강점/약점, 카테고리별 점수, 자주 쓰는 표현
+3. **맞춤법 경향**: 자주 하는 실수, 개선율
+4. **발전 추이**: 최근 5개 vs 이전 5개 비교, 개선 영역, 주의 필요 영역
+5. **AI 종합 평가**: 전반적 평가, 격려 메시지, 맞춤형 추천 3가지
+
+**서비스 레이어**:
+- `patternAnalysisService.ts` - 10개 글 종합 분석, Gemini 기반 AI 평가, Response Schema 사용
+
+**API**:
+- `POST /api/analyze-pattern` - 최근 10개 글 분석 (5분 캐싱)
+ - 인증 필요 (ID Token)
+ - Firestore에서 글 조회 → 각 글 AI 분석 (병렬) → 패턴 분석 → 캐싱
+
+**컴포넌트**:
+- `WritingPatternDialog` - 패턴 분석 다이얼로그 (로딩/에러/성공 상태)
+- `WritingPatternDisplay` - 분석 결과 표시 (종합 평가, 발전 추이, 작성 스타일, 표현력, 강점/약점, 자주 쓰는 표현, 추천)
+
+**타입**:
+- `src/types/writingPattern.ts` - WritingPatternAnalysis, AnalyzePatternRequest/Response
+
+**참고 파일**:
+- `src/services/patternAnalysisService.ts` - 패턴 분석 로직
+- `src/app/api/analyze-pattern/route.ts` - 패턴 분석 API
+- `src/components/writing/WritingPatternDialog.tsx` - 다이얼로그
+- `src/components/writing/WritingPatternDisplay.tsx` - 표시 컴포넌트
+- `src/app/home/page.tsx` - "작성 패턴 분석" 카드 추가
+
+---
+
+### 9. 실시간 하이라이트 시스템 (Tiptap Extensions)
+
+#### 핵심 개념
+
+**목적**: 에디터에서 맞춤법 오류와 감각 단어를 실시간으로 시각적으로 표시
+
+**하이라이트 종류**:
+1. **맞춤법 오류**: 빨간 물결 밑줄 (`spelling-error` 클래스)
+2. **감각 동사**: 초록색 하이라이트 (`sensory-word` 클래스)
+3. **감각 형용사**: 파란색 하이라이트 (`emotion-word` 클래스)
+4. **의성어/의태어**: 보라색 하이라이트 (`onomatopoeia-word` 클래스)
+
+**Tiptap Extensions**:
+- `SpellingHighlight` - 맞춤법 오류 하이라이트
+ - data-original, data-correction, data-reason 속성
+ - Meta를 통한 강제 업데이트
+- `SensoryWordHighlight` - 감각 단어 하이라이트
+ - data-word, data-type 속성
+ - 색상별 구분 (초록/파랑/보라)
+
+**DecorationSet 기반**:
+- ProseMirror Decoration을 사용한 효율적인 하이라이트
+- 문서 변경 시 자동 업데이트
+- 하이라이트 위치를 정확하게 추적
+
+**WritingEditor 통합**:
+- `spellingErrors`, `foundWords` props 추가
+- Extension 옵션 실시간 업데이트
+- 브라우저 기본 맞춤법 검사 비활성화 (`spellcheck="false"`)
+
+**참고 파일**:
+- `src/extensions/spelling-highlight.ts` - 맞춤법 하이라이트 Extension
+- `src/extensions/sensory-word-highlight.ts` - 감각 단어 하이라이트 Extension
+- `src/components/writing/WritingEditor.tsx` - Extensions 통합
+
+---
+
+### 10. 인터랙티브 툴팁 시스템
+
+#### 핵심 개념
+
+**목적**: 하이라이트된 단어를 클릭하면 상세 정보를 툴팁으로 표시
+
+**툴팁 종류**:
+1. **맞춤법 오류 툴팁**:
+ - 원본 → 수정 (취소선 → 굵은 글씨)
+ - 이유 설명 (초등학생 눈높이)
+ - 빨간색 테두리
+2. **감각 단어 툴팁**:
+ - 단어 표시
+ - 단어 타입 (감각 동사/형용사/의성어)
+ - 격려 메시지 ("이렇게 구체적으로 표현하면 글이 더 생생해져요!")
+ - 색상별 테두리 (초록/파랑/보라)
+
+**기술 구현**:
+- Portal 사용 (z-index 문제 해결)
+- 클릭한 요소의 data attributes 읽기
+- 외부 클릭/ESC 키로 닫기
+- Fade-in 애니메이션
+
+**WritingEditor 통합**:
+- DOM 클릭 이벤트 리스너 등록
+- 하이라이트 클래스 확인 (spelling-error, sensory-word 등)
+- 툴팁 위치 계산 (getBoundingClientRect)
+- 여러 개 툴팁 동시 표시 가능 (배열 관리)
+
+**참고 파일**:
+- `src/components/writing/EditorTooltip.tsx` - 툴팁 컴포넌트
+- `src/components/writing/WritingEditor.tsx` - 클릭 이벤트 처리
+
+---
+
+### 11. Toast 알림 시스템
+
+#### 핵심 개념
+
+**목적**: 텍스트 분석 및 맞춤법 검사 진행 상태를 사용자에게 알림
+
+**알림 종류**:
+1. **텍스트 분석**:
+ - 시작: "글을 분석하고 있어요..." (loading, duration: Infinity)
+ - 완료: "분석 완료! 점수: X.X점" (success, 3초)
+ - 실패: "분석 실패, 다시 시도해주세요." (error, 3초)
+2. **맞춤법 검사**:
+ - 시작: "맞춤법을 검사하고 있어요..." (loading, duration: Infinity)
+ - 완료: "맞춤법 검사 완료! X개의 오류 발견" 또는 "맞춤법 오류 없음!" (success, 3초)
+ - 실패: "맞춤법 검사 실패" (error, 3초)
+
+**기술 구현**:
+- Chakra UI Toaster 사용
+- Toast ID 관리 (ref로 저장, dismiss 호출)
+- 로딩 상태 toast는 수동으로 dismiss
+- 성공/실패 시 기존 loading toast 제거 후 새 toast 표시
+
+**참고 파일**:
+- `src/app/write/page.tsx` - Toast 알림 통합
+
+---
+
## 참고 문서
- [PROJECT_STRUCTURE.md](./PROJECT_STRUCTURE.md) - 프로젝트 구조