diff --git a/NEXT_TASKS.md b/NEXT_TASKS.md
new file mode 100644
index 0000000..e9df313
--- /dev/null
+++ b/NEXT_TASKS.md
@@ -0,0 +1,281 @@
+# 다음 작업 계획
+
+> 작성일: 2025-11-18
+> Phase 1 마무리 및 다음 단계 준비
+
+---
+
+## ✅ 현재 상태
+
+- **Phase 1 진행률**: 99% 완료
+- **타입 체크**: ✅ 통과 (에러 0개)
+- **최근 완료**:
+ - Level 1 중복 체크 로직 (UID 기반, Custom Token)
+ - 팀 나가기 기능
+ - 서비스 레이어 i18n 유틸리티
+ - firebaseAuth.ts 다국어 지원
+
+---
+
+## 🔴 최우선 작업 (오늘~내일)
+
+### 1. Firebase Security Rules 작성 및 배포 ⚡ (30분)
+
+**현재 문제**: Firestore에 보안 규칙이 없어 누구나 모든 데이터 접근 가능 💥
+
+**작업 내용**:
+```
+1. firestore.rules 파일 생성
+2. 컬렉션별 규칙 작성:
+ - users: 본인만 수정 가능
+ - teams: 소유자만 수정, 멤버는 읽기
+ - writings: 본인만 CRUD
+ - topics: 소유자만 수정
+ - patternAnalyses: 읽기 전용 (캐시용)
+3. Firebase Console에 배포
+4. 테스트 (권한 없는 접근 차단 확인)
+```
+
+**우선순위**: 🔴 높음 (보안 필수)
+
+---
+
+### 2. Level 1 실제 작동 테스트 🧪 (30분)
+
+**목적**: 구현한 UID 기반 중복 체크 로직 검증
+
+**테스트 시나리오**:
+
+#### 시나리오 A: 첫 로그인
+```
+1. npm run dev
+2. Level 1 팀 생성 (완전 개방)
+3. 로그아웃 (또는 시크릿 모드)
+4. 팀 코드 입력 → "철수" 입력
+5. 예상: 새 익명 계정 생성 ✅
+6. 확인: /team/{teamId} 페이지에서 멤버 확인
+```
+
+#### 시나리오 B: 재로그인 (핵심)
+```
+1. 로그아웃
+2. 동일 팀 코드 → "철수" 입력
+3. 예상: Custom Token으로 기존 계정 로그인 ✅
+4. 확인: 이전 글이 그대로 있는지 확인
+```
+
+#### 시나리오 C: 다른 브라우저 (중요)
+```
+1. 다른 브라우저 또는 시크릿 모드
+2. 동일 팀 코드 → "철수" 입력
+3. 예상: 동일 계정으로 로그인 ✅
+4. 확인: 크로스 디바이스 로그인 작동
+```
+
+#### 시나리오 D: 정식 계정 이름 중복 (보안)
+```
+1. Google 로그인 → 팀 가입 → 닉네임 "영희"
+2. 로그아웃
+3. 비로그인 상태에서 "영희" 입력
+4. 예상: "이미 사용 중인 이름입니다" 에러 ✅
+5. 확인: 정식 계정 탈취 방지
+```
+
+#### 시나리오 E: 로그인 상태에서 중복
+```
+1. "철수"로 로그인된 상태
+2. 팀 참여 시도 → "철수" 입력
+3. 예상: "이미 이 팀에 가입되어 있습니다" 에러 ✅
+```
+
+**우선순위**: 🔴 높음 (복잡한 로직, 검증 필수)
+
+**예상 버그**:
+- Custom Token API 경로 오류 가능성
+- 에러 메시지 번역 누락 가능성
+- Firebase Admin SDK 권한 문제
+
+---
+
+### 3. 코드 정리 및 최적화 🧹 (30분)
+
+**체크리스트**:
+```
+□ console.log 제거 또는 조건부 처리 (process.env.NODE_ENV === 'development')
+□ 사용하지 않는 import 제거
+□ TODO 코멘트 확인 및 처리
+□ 중복 코드 리팩토링
+□ 불필요한 any 타입 제거
+□ ESLint 경고 수정
+```
+
+**대상 파일**:
+- `src/services/firebaseAuth.ts` (많은 로그)
+- `src/components/auth/StudentLoginFlow.tsx`
+- `src/managers/WritingSessionManager.ts` (디버그 로그)
+
+**우선순위**: 🟡 중간
+
+---
+
+## 🟡 이번 주 완료 목표
+
+### 4. 에러 처리 개선 (1시간)
+
+**작업 내용**:
+
+#### A. 전역 에러 바운더리
+```tsx
+// src/app/[locale]/error.tsx 생성
+'use client';
+
+export default function Error({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
+ 오류가 발생했습니다
+ {error.message}
+
+
+
+ );
+}
+```
+
+#### B. 404 페이지 개선
+```tsx
+// src/app/[locale]/not-found.tsx 개선
+// 현재: 없음
+// 추가: 사용자 친화적 디자인, 홈으로 돌아가기
+```
+
+#### C. API 에러 통합 처리
+```typescript
+// src/utils/apiErrorHandler.ts 생성
+// 일관된 에러 토스트 표시
+```
+
+**우선순위**: 🟡 중간
+
+---
+
+### 5. 성능 최적화 체크 (30분)
+
+**체크 항목**:
+```
+□ React DevTools Profiler로 불필요한 리렌더링 확인
+□ 번들 크기 분석 (npm run build 후 확인)
+□ 이미지 최적화 (Next.js Image 사용)
+□ Lighthouse 점수 측정 (목표: 90+)
+□ 초기 로딩 속도 (목표: 2초 이내)
+```
+
+**예상 개선점**:
+- WritingEditor 메모이제이션
+- 큰 컴포넌트 lazy loading
+- 사용하지 않는 라이브러리 제거
+
+**우선순위**: 🟡 중간
+
+---
+
+### 6. Phase 1 문서 최종 검토 (30분)
+
+**체크리스트**:
+```
+□ CLAUDE.md - 최신 정보 반영 확인
+□ PROJECT_STRUCTURE.md - 모든 파일 반영
+□ ROADMAP.md - 완료 항목 이동
+□ API_SPEC.md - 모든 엔드포인트 문서화
+□ README.md - 설치/실행 가이드 확인
+□ DATA_MODELS.md - 스키마 최신화
+```
+
+**우선순위**: 🟢 낮음
+
+---
+
+## 🟢 다음 주 시작 작업
+
+### 옵션 A: Phase 2 - 학습 시스템 설계
+
+#### 7. 학습 페이지 설계 (2-3시간)
+```
+1. /learn 페이지 와이어프레임
+2. Lesson 데이터 모델 설계:
+ - id, title, content, category, difficulty
+ - prerequisites (선수 레슨)
+ - quizzes (연습 문제)
+ - completionCriteria
+3. UI 컴포넌트 설계:
+ - LessonCard (썸네일, 제목, 난이도)
+ - LessonContent (이론, 예시)
+ - QuizSection (문제 풀이)
+ - ProgressBar (진행률)
+```
+
+#### 8. 첫 레슨 콘텐츠 작성 (1-2시간)
+```
+예시: "문장 만들기 첫걸음"
+- 이론: 주어와 서술어
+- 예시: "나는 달린다", "고양이가 잔다"
+- 연습: 주어를 고르세요 (4지선다)
+- 평가: 문장 3개 만들기
+```
+
+---
+
+### 옵션 B: 베타 테스트 준비
+
+#### 9. 베타 테스터 모집 (1주일)
+```
+1. 초등학교 선생님 1-2명 섭외
+2. 테스트 계정 준비
+3. 사용 가이드 작성
+4. 피드백 수집 양식 준비 (Google Forms)
+```
+
+#### 10. 실제 수업 시나리오 테스트
+```
+시나리오: 초등 2학년 반 (25명)
+1. 선생님이 팀 생성 (Level 2, 명단 등록)
+2. 학생들 팀 코드로 로그인
+3. 팀 주제 "오늘의 날씨" 작성
+4. 선생님 실시간 모니터링
+5. 피드백 수집
+```
+
+---
+
+## 💡 제 최종 추천 순서
+
+### 오늘 (1.5시간):
+1. **Firebase Security Rules** (30분) ⚡ 최우선
+2. **Level 1 테스트** (30분) 🧪 검증 필수
+3. **코드 정리** (30분) 🧹 품질 확보
+
+### 내일 (선택):
+4. **에러 처리 개선** (1시간) - Phase 1 완성도
+5. **성능 최적화** (30분) - 사용자 경험
+
+### 다음 주 (선택 1개):
+- **옵션 A**: Phase 2 시작 (학습 시스템) - 기능 확장
+- **옵션 B**: 베타 테스트 준비 - 실사용 피드백
+
+---
+
+## 📋 작업 선택 가이드
+
+**빠른 출시를 원하면**: Firebase Rules → 테스트 → 베타 테스트
+**기능을 더 만들고 싶으면**: Firebase Rules → 테스트 → Phase 2 시작
+**코드 품질 우선이면**: 코드 정리 → 에러 처리 → 성능 최적화
+
+---
+
+어떤 작업부터 시작할까요?
\ No newline at end of file
diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md
index 7ab3490..109668d 100644
--- a/PROJECT_STRUCTURE.md
+++ b/PROJECT_STRUCTURE.md
@@ -325,7 +325,7 @@
| ~~**SpellingErrorDisplay**~~ | ~~`SpellingErrorDisplay.tsx`~~ | ~~맞춤법 오류 표시~~ | ❌ 삭제됨 (하이라이트로 대체) |
| **CreateTopicDialog** | `CreateTopicDialog.tsx` | 개인 주제 생성 다이얼로그 (태그 입력 UI) | ✅ 완료 |
| **CreateTeamTopicDialog** | `CreateTeamTopicDialog.tsx` | 팀 주제 생성 다이얼로그 (템플릿 지원) | ✅ 완료 |
-| **SavedDraftsDialog** | `SavedDraftsDialog.tsx` | 저장된 글조각 목록 다이얼로그 (불러오기/삭제) | ✅ 완료 |
+| **SavedDraftsDialog** | `SavedDraftsDialog.tsx` | 저장된 글조각 목록 다이얼로그 (불러오기/삭제, **동기화 상태 배지** 🟢synced/🟡syncing/⚪local) | ✅ 완료 |
**주요 기능**:
- ✅ 순수 텍스트 입력 (포맷팅 없음)
@@ -469,7 +469,7 @@
| **ManagerBase** | `ManagerBase.ts` | 공통 기능 (authenticatedFetch, API 호출, 캐싱) | ✅ 완료 |
| **TeamManager** | `TeamManager.ts` | 팀 관련 API 호출 (생성, 조회, 수정, 삭제, 멤버 관리) | ✅ 완료 |
| **UserManager** | `UserManager.ts` | 사용자 관련 API 호출 (생성, 조회, 수정, 닉네임 관리) **[NEW]** | ✅ 완료 |
-| **DraftManager** | `DraftManager.ts` | 글조각 관리 (localStorage 기반, 최대 10개, CRUD) | ✅ 완료 |
+| **DraftManager** | `DraftManager.ts` | 글조각 관리 (**localStorage + Realtime DB 하이브리드**, 기기 간 동기화, 최대 10개, CRUD, syncStatus) | ✅ 완료 |
| **WritingSessionManager** | `WritingSessionManager.ts` | 🆕 **실시간 글쓰기 세션 관리** (Firebase Realtime DB 작업) | ✅ 완료 |
| ~~**StudentManager**~~ | ~~`StudentManager.ts`~~ | ~~학생 관련 API 호출~~ | ⚠️ Deprecated (UserManager로 대체) |
| **WritingManager** | `WritingManager.ts` | 글쓰기 관련 비즈니스 로직 (CRUD, 통계) | ✅ 완료 |
@@ -494,6 +494,41 @@
- `requestPreview(targetUserId)`: 미리보기 요청 (Promise 반환)
- `listenForPreviewRequests(onRequestCallback)`: 미리보기 요청 리스너 (학생용)
+---
+
+### 🆕 `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)
| 서비스 | 파일명 | 설명 | 상태 |
@@ -528,7 +563,7 @@
| **FirestoreUser 타입** | `firestoreUser.ts` | **FirestoreUser** (DB 저장용), **User** (UI용) 분리 | ✅ 완료 |
| **Writing 타입** | `writing.ts` | 글 데이터 모델, 🆕 **WritingAnalysis** (AI 분석 결과, contentHash 기반 재사용), **SpellingError** (맞춤법 오류), 🆕 **AIAssistanceRecord** (AI 도움 이력), 🆕 **GeneratedImage** (AI 생성 이미지) | ✅ 완료 |
| **Scene 타입** | `scene.ts` | 🆕 **장면 데이터 모델** (Scene, SceneExtractionResponse) | ✅ 완료 |
-| **Draft 타입** | `draft.ts` | 글조각 데이터 모델 (Draft, DraftListItem, **AnalysisHistoryItem**) | ✅ 완료 |
+| **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로 변경) |
@@ -663,6 +698,18 @@
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 # 영어 번역
@@ -734,7 +781,7 @@ project_w/
│ ├── TopicManager.ts # 주제 관리
│ ├── TeamManager.ts # 팀 관리
│ ├── UserManager.ts # 사용자 관리
-│ ├── DraftManager.ts # 글조각 관리 (localStorage)
+│ ├── DraftManager.ts # 글조각 관리 (localStorage + Realtime DB 하이브리드)
│ └── [미구현]
│ ├── LevelManager.ts
│ └── StickerManager.ts
diff --git a/ROADMAP.md b/ROADMAP.md
index 83e674d..4a107f5 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -1,6 +1,6 @@
# 라온누리 - 개발 로드맵
-> 최종 업데이트: 2025-11-18 (팀 코드 다국어 생성 + Realtime DB 예약)
+> 최종 업데이트: 2025-11-19 (AI Delta 개선 + Draft 동기화 + Firebase Functions Phase 1)
초등학생을 위한 창작 글쓰기 교육 플랫폼 개발 계획
@@ -63,12 +63,12 @@
| **API Routes 구현** | **보안 레벨 변경, 명단 관리 API (RESTful 원칙), POST/DELETE 메서드 구분** | **2025-11-10** |
| **lib/server/team 확장** | **updateTeamSecurityLevel, add/removeAllowedName/Email, 자동 명단 생성** | **2025-11-10** |
| **react-icons 전환** | **이모티콘 → react-icons/lu로 전환 (LuGlobe, LuClipboardList 등)** | **2025-11-10** |
-| **다중 글조각 관리** | **DraftManager (localStorage, 최대 10개), SavedDraftsDialog, 2초 debounce 자동 저장, 저장 상태 표시** | **2025-11-10** |
+| **다중 글조각 관리** | **DraftManager (localStorage + Realtime DB 하이브리드, 기기 간 동기화, 최대 10개), SavedDraftsDialog (syncStatus 배지), 2초 debounce 자동 저장** | **2025-11-10 / 2025-11-19** |
| **테마 슬롯 레시피** | **Dialog, Select slot recipe 추가 (자동 배경색, border, shadow)** | **2025-11-10** |
| **TopicSelector 그룹핑** | **ItemGroup으로 자유/팀/개인 주제 구분, 팀 주제에 팀 이름 표시, Separator 추가** | **2025-11-10** |
| **TopicOption 확장** | **teamName 필드 추가, TopicManager에서 팀 정보 조회 (동적 import)** | **2025-11-10** |
| **주제 변경 경고 Dialog** | **작성 중 내용이 있을 때 주제 변경 시 경고 Dialog 표시, 임시 저장 안내** | **2025-11-10** |
-| **실시간 피드백 시스템** | **Vertex AI 기반 텍스트 분석, ScoreDisplay 컴포넌트, Delta 전송 (토큰 40% 절감), 서버 캐싱 (LRU)** | **2025-11-11** |
+| **실시간 피드백 시스템** | **Vertex AI 기반 텍스트 분석, ScoreDisplay 컴포넌트, Delta 전송 (diff-match-patch 기반, 5자 미만 누적, 80% 기준), 서버 캐싱 (LRU)** | **2025-11-11 / 2025-11-19** |
| **Multi-Region Failover** | **3개 region 자동 전환 (도쿄/싱가포르/미국), Region health tracking, Exponential backoff, RPM 3배 증가 (15→45)** | **2025-11-11** |
| **서비스 레이어 분리** | **vertexAI.ts (범용 래퍼), textAnalysisService.ts (분석 로직), regionHealthManager.ts (상태 관리)** | **2025-11-11** |
| **문서화 완료** | **TECHNICAL_IMPLEMENTATION.md, SERVICE_DIRECTION.md 전면 개편 (Vertex AI 기반)** | **2025-11-11** |
@@ -96,6 +96,10 @@
| **팀 나가기 기능** | **팀 상세 페이지에 "팀 나가기" 버튼 추가 (멤버만 표시), Dialog 확인창, teamManager.removeMember() 호출, POST /api/team/remove-member 권한 체크 수정 (본인 제거 허용, 소유자 제거 금지), 성공 시 팀 목록으로 리다이렉트, 번역 추가 (team.detail namespace, leaveTeam/leaveTeamConfirm 등 7개 키, ko/en/ja)** | **2025-11-18** |
| **Level 1 중복 체크 로직 (UID 기반)** | **loginAsUser() 함수 수정 (currentUid 파라미터 추가), Level 1 닉네임 중복 체크 (team.members 검색), 4가지 케이스 처리 (비로그인/로그인 × 중복 유무), Custom Token API 생성 (POST /api/team/get-custom-token, 익명 계정만 발급), 비로그인 상태 중복 시 기존 계정으로 자동 로그인, 로그인 상태 중복 시 에러 (UID 일치 체크), 정식 계정 탈취 방지 (providerData 체크), authStore.loginAsUser에서 currentUid 전달, StudentLoginFlow 에러 메시지 처리, 번역 추가 (errors.team namespace, alreadyJoinedTeam/nicknameInUse 등 6개 키, ko/en/ja)** | **2025-11-18** |
| **서비스 레이어 i18n 유틸리티** | **src/utils/i18n.ts 생성 (React 훅 없이 번역 사용), detectLocale() 함수 (URL path 우선 → navigator.language fallback), t() 함수 (nested key 지원, 파라미터 치환), messages/*.json import, firebaseAuth.ts 전체 에러 메시지 다국어 처리 (getErrorMessage, loginAsUser, linkEmailPassword, linkGoogleAccount), convertFirebaseUser 기본 이름 다국어, 번역 추가 (errors.auth namespace 11개 + errors.team namespace 6개, ko/en/ja)** | **2025-11-18** |
+| **AI Delta 전송 로직 개선** | **diff-match-patch 라이브러리 도입, 정확한 diff 계산 (앞/중간/뒤 수정 모두 감지), 5자 미만 변경 누적 (previousText 유지), 완화된 기준 (80% 미만, 200자 미만), 9개 테스트 케이스 통과 (뒷부분 추가, 중간 수정, 앞부분 추가, 삭제, 대량 변경, 누적 변경), skipped 응답 처리 (클라이언트에서 prev 유지), analyze-text API 수정** | **2025-11-19** |
+| **Draft 클라우드 동기화** | **localStorage + Realtime DB 하이브리드 저장, syncStatus 필드 추가 ('local'\|'synced'\|'syncing'), DraftManager 확장 (syncToCloud, loadDraftsFromCloud, mergeDrafts, deleteDraftFromCloud), SavedDraftsDialog 배지 표시 (🟢동기화됨/🟡동기화 중/⚪기기만), write/page.tsx mergeDrafts 호출 (로그인 시), database.rules.json drafts 규칙 추가 (본인만 읽기/쓰기), 기기 간 동기화 (학교 ↔ 집), updatedAt 비교로 최신 버전 선택** | **2025-11-19** |
+| **팀 코드 예약 반환 로직** | **generate-code API 수정 (previousCode 파라미터 추가), 새 코드 받기 시 이전 예약 자동 해제, team/create page 중복 호출 방지 (isGeneratingCode 체크), 팀 생성 실패 시에도 예약 해제 (catch 블록), GenerateTeamCodeRequest 타입 확장, TeamManager.generateUniqueTeamCode previousCode 파라미터** | **2025-11-19** |
+| **Firebase Cloud Functions Phase 1** | **functions/ 프로젝트 초기화 (Node.js 22, v2 API), 파일 분리 구조 (index.ts export만, 로직 별도 파일), cleanupExpiredReservations (매 시간, 팀 코드 예약 정리), cleanupExpiredDrafts (매일 새벽 3시, 180일 이상 drafts 정리), onTeamDeleted (Firestore Trigger, cascade 삭제), onWritingCreated (Firestore Trigger, 추후 자동 분석), 한글 로그, asia-northeast1 리전, firebase.json predeploy 수정 (lint 제거), 4개 함수 배포 완료** | **2025-11-19** |
### 🚧 진행 중
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..d3afdc8
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,260 @@
+# Security Policy
+
+라온누리 프로젝트의 보안 정책 및 구현 내역을 문서화합니다.
+
+---
+
+## 🔒 보안 조치 요약
+
+| 보안 영역 | 조치 | 상태 | 적용일 |
+|----------|------|------|--------|
+| **XSS 방지** | HTML Sanitization | ✅ 적용 완료 | 2025-11-19 |
+| **인증** | Firebase Auth | ✅ 적용 완료 | 2025-10-xx |
+| **API 인증** | JWT Token (ID Token) | ✅ 적용 완료 | 2025-10-xx |
+| **SQL Injection** | Firestore (NoSQL) | ✅ 원천 방지 | - |
+| **CSRF** | SameSite Cookies | 🚧 검토 필요 | - |
+| **Rate Limiting** | API 요청 제한 | ⏳ 예정 | - |
+
+---
+
+## 1. XSS (Cross-Site Scripting) 방지
+
+### 문제점
+- 사용자가 작성한 글 (`writings` 컬렉션)의 `content` 필드는 **HTML 문자열**로 저장됩니다.
+- Tiptap 에디터는 안전한 HTML을 생성하지만, 악의적인 사용자가 **API를 직접 호출**하여 악성 스크립트를 주입할 수 있습니다.
+
+**공격 시나리오**:
+```typescript
+// 악의적인 API 호출
+POST /api/writing
+{
+ "title": "정상 제목",
+ "content": "
정상 내용
"
+}
+```
+
+### 해결책: HTML Sanitization
+
+**백엔드 자동 세탁** (`src/lib/server/writing.ts`):
+```typescript
+import { sanitizeHtml } from "@/utils/sanitizeHtml";
+
+// 글 생성 시 자동 세탁 (Line 46-47)
+const sanitizedTitle = sanitizeHtml(data.title);
+const sanitizedContent = sanitizeHtml(data.content);
+
+// 글 수정 시 자동 세탁 (Line 199-203)
+if (data.title) {
+ updateData.title = sanitizeHtml(data.title);
+}
+if (data.content) {
+ updateData.content = sanitizeHtml(data.content);
+}
+```
+
+**세탁 규칙** (`src/utils/sanitizeHtml.ts`):
+- ✅ **허용된 태그**: ``, ``, ``, ``, `