docs: Sync documentation from private repository

This commit is contained in:
Documentation Bot 2025-11-26 01:25:48 +00:00
parent 9d59776c86
commit e8d5da3866
7 changed files with 163 additions and 32 deletions

View File

@ -553,7 +553,35 @@ patternAnalyses/{contentHash}
--- ---
### 8. POST `/team/remove-student` - 팀에서 학생 제거 ### 8. POST `/team/add-member` - 팀에 멤버 추가
실제 URL: `POST /api/team/add-member`
**인증**: 필수
**Request**:
```typescript
{
teamId: string;
uid: string;
nickname?: string; // 🆕 닉네임 (선택적)
}
```
**Response**:
```typescript
{
success: true,
data: {
success: true;
}
}
```
**캐시 무효화**: 해당 팀
---
### 9. POST `/team/remove-student` - 팀에서 학생 제거
실제 URL: `POST /api/team/remove-student` 실제 URL: `POST /api/team/remove-student`
**인증**: 필수 **인증**: 필수
@ -582,7 +610,7 @@ patternAnalyses/{contentHash}
--- ---
### 9. POST `/team/generate-code` - 고유 팀 코드 생성 ### 10. POST `/team/generate-code` - 고유 팀 코드 생성
실제 URL: `POST /api/team/generate-code` 실제 URL: `POST /api/team/generate-code`
**인증**: 선택적 **인증**: 선택적
@ -606,7 +634,7 @@ patternAnalyses/{contentHash}
--- ---
### 10. POST `/team/check-code` - 팀 코드 존재 여부 ### 11. POST `/team/check-code` - 팀 코드 존재 여부
실제 URL: `POST /api/team/check-code` 실제 URL: `POST /api/team/check-code`
**인증**: 선택적 **인증**: 선택적
@ -630,7 +658,7 @@ patternAnalyses/{contentHash}
--- ---
### 🆕 11. POST `/team/get-custom-token` - Custom Token 생성 (Level 1 재로그인) ### 🆕 12. POST `/team/get-custom-token` - Custom Token 생성 (Level 1 재로그인)
실제 URL: `POST /api/team/get-custom-token` 실제 URL: `POST /api/team/get-custom-token`
**설명**: Level 1 (OPEN) 팀에서 같은 닉네임으로 재로그인 시 사용. 익명 계정만 허용. **설명**: Level 1 (OPEN) 팀에서 같은 닉네임으로 재로그인 시 사용. 익명 계정만 허용.
@ -674,7 +702,7 @@ patternAnalyses/{contentHash}
--- ---
### 🆕 12. POST `/team/remove-member` - 팀 멤버 제거/나가기 ### 🆕 13. POST `/team/remove-member` - 팀 멤버 제거/나가기
실제 URL: `POST /api/team/remove-member` 실제 URL: `POST /api/team/remove-member`
**설명**: 팀에서 멤버를 제거합니다. 소유자는 다른 멤버를 강퇴할 수 있고, 일반 멤버는 본인을 제거(팀 나가기)할 수 있습니다. **설명**: 팀에서 멤버를 제거합니다. 소유자는 다른 멤버를 강퇴할 수 있고, 일반 멤버는 본인을 제거(팀 나가기)할 수 있습니다.
@ -714,7 +742,7 @@ await teamManager.removeMember(teamId, currentUser.uid);
--- ---
### 🆕 13. POST `/team/:teamId/security-level` - 보안 레벨 변경 ### 🆕 14. POST `/team/:teamId/security-level` - 보안 레벨 변경
실제 URL: `POST /api/team/:teamId/security-level` 실제 URL: `POST /api/team/:teamId/security-level`
**인증**: 필수 (팀 소유자만) **인증**: 필수 (팀 소유자만)
@ -747,7 +775,7 @@ await teamManager.removeMember(teamId, currentUser.uid);
--- ---
### 🆕 12. POST/DELETE `/team/:teamId/allowed-names` - 허용 이름 관리 (Level 2) ### 🆕 15. POST/DELETE `/team/:teamId/allowed-names` - 허용 이름 관리 (Level 2)
실제 URL: 실제 URL:
- `POST /api/team/:teamId/allowed-names` - 이름 추가 - `POST /api/team/:teamId/allowed-names` - 이름 추가
- `DELETE /api/team/:teamId/allowed-names` - 이름 제거 - `DELETE /api/team/:teamId/allowed-names` - 이름 제거
@ -784,7 +812,7 @@ await teamManager.removeMember(teamId, currentUser.uid);
--- ---
### 🆕 13. POST/DELETE `/team/:teamId/allowed-emails` - 허용 이메일 관리 (Level 4) ### 🆕 16. POST/DELETE `/team/:teamId/allowed-emails` - 허용 이메일 관리 (Level 4)
실제 URL: 실제 URL:
- `POST /api/team/:teamId/allowed-emails` - 이메일 추가 - `POST /api/team/:teamId/allowed-emails` - 이메일 추가
- `DELETE /api/team/:teamId/allowed-emails` - 이메일 제거 - `DELETE /api/team/:teamId/allowed-emails` - 이메일 제거
@ -988,6 +1016,8 @@ await teamManager.removeMember(teamId, currentUser.uid);
topicId?: string | null; topicId?: string | null;
wordCount?: number; wordCount?: number;
charCount?: number; charCount?: number;
distortionAreas?: DistortionAreaData[]; // 🆕 왜곡 영역 설정
analysis?: WritingAnalysis; // 🆕 AI 분석 결과 (영역 제한용)
} }
} }
``` ```
@ -1036,6 +1066,38 @@ await teamManager.removeMember(teamId, currentUser.uid);
--- ---
### 7. POST `/writing/:id/analyze` - 글 분석 실행
실제 URL: `POST /api/writing/:id/analyze`
**인증**: 필수 (작성자 본인만 가능)
**설명**: 저장된 글을 서버에서 불러와 AI 분석을 실행하고 결과를 저장합니다.
**Request**:
```typescript
{
locale?: "ko" | "en" | "ja"; // 기본값: "ko"
}
```
**Response**:
```typescript
{
success: true,
data: {
analysis: WritingAnalysis;
cached: boolean; // true면 기존 분석 결과 반환 (재사용)
}
}
```
**특징**:
- **Content Hash 기반 재사용**: 글 내용이 변경되지 않았으면 기존 분석 결과 반환 (비용 절감)
- **최소 길이**: 30자 이상이어야 분석 가능
- **저장**: 분석 결과는 자동으로 `writings/{id}.analysis`에 저장됨
---
## Topic API ## Topic API
### 1. POST `/topic/available` - 사용 가능한 주제 목록 ### 1. POST `/topic/available` - 사용 가능한 주제 목록

View File

@ -321,6 +321,37 @@ interface WritingAnalysis {
contentHash: string; // 분석 시점의 content 해시 (SHA-256) contentHash: string; // 분석 시점의 content 해시 (SHA-256)
} }
// AI 생성 이미지 정보
interface GeneratedImage {
url: string; // Firebase Storage에 저장된 이미지 URL
prompt: string; // 생성에 사용된 프롬프트
generatedAt: Timestamp; // 생성 시각
modelName: string; // "imagen-4.0-generate-001"
bytesBase64?: string; // (선택) base64 인코딩 원본
}
// 이미지 왜곡 영역 정보 (responsive-image-canvas)
interface DistortionAreaData {
id: string;
basePoints: Array<{x: number; y: number}>;
movement: {
preset?: 'none' | 'horizontal' | 'vertical' | 'rotate-cw' | 'rotate-ccw' | 'pulse' | 'diagonal-1' | 'diagonal-2';
vectorA: {x: number; y: number};
vectorB: {x: number; y: number};
duration: number;
easing: string;
strength?: number;
};
distortionStrength: number;
physics?: {
stiffness: number;
damping: number;
mass: number;
influenceRadius: number;
maxStrength: number;
};
}
interface Writing { interface Writing {
id: string; // 문서 ID id: string; // 문서 ID
userId: string; // 작성자 UID userId: string; // 작성자 UID
@ -334,10 +365,20 @@ interface Writing {
// 상태 // 상태
status: 'draft' | 'published'; // 임시저장/발행 status: 'draft' | 'published'; // 임시저장/발행
commentCount: number; // 🆕 댓글 총 개수 (기본값: 0)
// 🆕 AI 분석 결과 (저장 시 자동 생성) // 🆕 AI 분석 결과 (저장 시 자동 생성)
analysis?: WritingAnalysis; // AI 분석 결과 (선택적) analysis?: WritingAnalysis; // AI 분석 결과 (선택적)
// 🆕 AI 도움 이력
aiAssistanceHistory?: AIAssistanceRecord[];
// 🆕 AI 생성 이미지
generatedImage?: GeneratedImage;
// 🆕 이미지 왜곡 영역 설정
distortionAreas?: DistortionAreaData[];
// 타임스탬프 // 타임스탬프
createdAt: Timestamp; // 최초 작성일 createdAt: Timestamp; // 최초 작성일
updatedAt: Timestamp; // 최종 수정일 updatedAt: Timestamp; // 최종 수정일

View File

@ -1,19 +1,22 @@
# 다음 작업 계획 # 다음 작업 계획
> 작성일: 2025-11-18 > 작성일: 2025-11-25
> Phase 1 마무리 및 다음 단계 준비 > Phase 1 마무리 및 기능 고도화
--- ---
## ✅ 현재 상태 ## ✅ 최근 완료된 작업
- **Phase 1 진행률**: 99% 완료 - **글 분석 및 상호작용 기능** (2025-11-25)
- **타입 체크**: ✅ 통과 (에러 0개) - `/api/writing/[id]/analyze` API 추가
- **최근 완료**: - 글 분석 결과에 따른 상호작용 컴포넌트 추가 (`components/interaction/*`)
- Level 1 중복 체크 로직 (UID 기반, Custom Token) - 점수 기반 영역 해금 로직 (`utils/areaLimit.ts`)
- 팀 나가기 기능 - **이미지 왜곡 영역 기능** (2025-11-25)
- 서비스 레이어 i18n 유틸리티 - `DistortionAreaData` 모델 추가
- firebaseAuth.ts 다국어 지원 - `InteractiveImageViewer` 컴포넌트 추가
- 글 수정 시 왜곡 영역 저장 지원
- **팀 멤버 닉네임 추가** (2025-11-25)
- `POST /api/team/add-member`에 닉네임 파라미터 추가
--- ---
@ -21,6 +24,7 @@
### 1. Firebase Security Rules 작성 및 배포 ⚡ (30분) ### 1. Firebase Security Rules 작성 및 배포 ⚡ (30분)
**현재 문제**: Firestore에 보안 규칙이 없어 누구나 모든 데이터 접근 가능 💥 **현재 문제**: Firestore에 보안 규칙이 없어 누구나 모든 데이터 접근 가능 💥
**작업 내용**: **작업 내용**:

View File

@ -85,7 +85,7 @@
- **서버 검증**: AI 힌트 요청 시 팀 설정 확인 (enabled, allowedHintLevels) - **서버 검증**: AI 힌트 요청 시 팀 설정 확인 (enabled, allowedHintLevels)
- **사용 제한**: 글당 최대 5회, 힌트 간 3분 쿨다운 - **사용 제한**: 글당 최대 5회, 힌트 간 3분 쿨다운
- **다국어 프롬프트**: 한국어/영어/일본어 지원 - **다국어 프롬프트**: 한국어/영어/일본어 지원
- **UI 컴포넌트**: InactivityPrompt (플로팅 버튼), HintDisplay (Dialog), AIAssistancePanel - **UI 컴포넌트**: InactivityPrompt (플로팅 버튼), HintDisplay (Dialog)
- **API**: POST /api/writing-assistance, GET/PUT /api/team/[teamId]/ai-config - **API**: POST /api/writing-assistance, GET/PUT /api/team/[teamId]/ai-config
- **Firestore**: Team.aiAssistanceConfig 필드 추가 - **Firestore**: Team.aiAssistanceConfig 필드 추가
@ -397,10 +397,11 @@
| **WritingPatternDisplay** | `WritingPatternDisplay.tsx` | 🆕 **패턴 분석 결과 표시** (종합 평가, 발전 추이, 강점/약점, 추천) | ✅ 완료 | | **WritingPatternDisplay** | `WritingPatternDisplay.tsx` | 🆕 **패턴 분석 결과 표시** (종합 평가, 발전 추이, 강점/약점, 추천) | ✅ 완료 |
| **InactivityPrompt** | `InactivityPrompt.tsx` | 🆕 **작성 멈춤 프롬프트** (5분 입력 없을 시 플로팅 버튼) | ✅ 완료 | | **InactivityPrompt** | `InactivityPrompt.tsx` | 🆕 **작성 멈춤 프롬프트** (5분 입력 없을 시 플로팅 버튼) | ✅ 완료 |
| **HintDisplay** | `HintDisplay.tsx` | 🆕 **AI 힌트 표시** (4단계 힌트 Dialog, RadioCard 선택지) | ✅ 완료 | | **HintDisplay** | `HintDisplay.tsx` | 🆕 **AI 힌트 표시** (4단계 힌트 Dialog, RadioCard 선택지) | ✅ 완료 |
| **AIAssistancePanel** | `AIAssistancePanel.tsx` | 🆕 **AI 도움 패널** (레벨 선택, 남은 횟수, 쿨다운) | ✅ 완료 |
| **GenerateImageDialog** | `GenerateImageDialog.tsx` | 🆕 **AI 이미지 생성 Dialog** (4단계 플로우: 장면 추출 → 장면 선택 → 이미지 생성 → 결과 표시) | ✅ 완료 | | **GenerateImageDialog** | `GenerateImageDialog.tsx` | 🆕 **AI 이미지 생성 Dialog** (4단계 플로우: 장면 추출 → 장면 선택 → 이미지 생성 → 결과 표시) | ✅ 완료 |
| **SceneSelector** | `SceneSelector.tsx` | 🆕 **장면 선택 컴포넌트** (RadioCard 기반, 이모지 표시, 원문 미리보기) | ✅ 완료 | | **SceneSelector** | `SceneSelector.tsx` | 🆕 **장면 선택 컴포넌트** (RadioCard 기반, 이모지 표시, 원문 미리보기) | ✅ 완료 |
| **WritingCard** | `WritingCard.tsx` | 🆕 **글 카드 컴포넌트** (제목, 날짜, 미리보기, 주제/점수/이미지 배지, 메뉴, 삭제) | ✅ 완료 | | **WritingCard** | `WritingCard.tsx` | 🆕 **글 카드 컴포넌트** (제목, 날짜, 미리보기, 주제/점수/이미지 배지, 메뉴, 삭제) | ✅ 완료 |
| **InteractiveImageViewer** | `InteractiveImageViewer.tsx` | 🆕 **인터랙티브 이미지 뷰어** (왜곡 효과, 애니메이션, 오디오 반응) | ✅ 완료 |
| **GenerateImageDialog** | `GenerateImageDialog.tsx` | 🆕 **AI 이미지 생성 Dialog** (4단계 플로우: 장면 추출 → 장면 선택 → 이미지 생성 → 결과 표시) | ✅ 완료 |
| ~~**ScoreDisplay**~~ | ~~`ScoreDisplay.tsx`~~ | ~~실시간 피드백 점수 표시~~ | ❌ 삭제됨 (하이라이트로 대체) | | ~~**ScoreDisplay**~~ | ~~`ScoreDisplay.tsx`~~ | ~~실시간 피드백 점수 표시~~ | ❌ 삭제됨 (하이라이트로 대체) |
| ~~**SpellingErrorDisplay**~~ | ~~`SpellingErrorDisplay.tsx`~~ | ~~맞춤법 오류 표시~~ | ❌ 삭제됨 (하이라이트로 대체) | | ~~**SpellingErrorDisplay**~~ | ~~`SpellingErrorDisplay.tsx`~~ | ~~맞춤법 오류 표시~~ | ❌ 삭제됨 (하이라이트로 대체) |
| **CreateTopicDialog** | `CreateTopicDialog.tsx` | 🆕 **통합 주제 생성 다이얼로그** (개인/팀 공용, 태그 입력 UI, 템플릿 지원, TopicFormData 반환) | ✅ 완료 | | **CreateTopicDialog** | `CreateTopicDialog.tsx` | 🆕 **통합 주제 생성 다이얼로그** (개인/팀 공용, 태그 입력 UI, 템플릿 지원, TopicFormData 반환) | ✅ 완료 |
@ -446,6 +447,17 @@
--- ---
### 📁 `src/components/interaction/` - 🆕 상호작용 및 분석 결과 표시
| 컴포넌트 | 파일명 | 설명 | 상태 |
|---------|--------|------|------|
| **AnalysisNeededBanner** | `AnalysisNeededBanner.tsx` | 분석 필요 알림 배너 (AI 분석 요청 유도) | ✅ 완료 |
| **AreaUnlockBadge** | `AreaUnlockBadge.tsx` | 영역 잠금 해제 배지 (점수 달성 시 표시) | ✅ 완료 |
| **ImprovementHint** | `ImprovementHint.tsx` | 개선 힌트 표시 (점수가 낮을 때 조언 제공) | ✅ 완료 |
| **ScoreBadge** | `ScoreBadge.tsx` | 점수 배지 (오감/감정/대화/의성어 점수 표시) | ✅ 완료 |
---
### 📁 `src/extensions/` - Tiptap Extensions ### 📁 `src/extensions/` - Tiptap Extensions
| Extension | 파일명 | 설명 | 상태 | | Extension | 파일명 | 설명 | 상태 |
@ -479,7 +491,6 @@
| **TeamTopicManager** | `TeamTopicManager.tsx` | 팀 주제 목록 및 생성/삭제 UI | ✅ 완료 | | **TeamTopicManager** | `TeamTopicManager.tsx` | 팀 주제 목록 및 생성/삭제 UI | ✅ 완료 |
| **AIConfigDialog** | `AIConfigDialog.tsx` | 🆕 **AI 도우미 고급 설정 Dialog** (Slider, 커스텀 CheckboxCard) | ✅ 완료 | | **AIConfigDialog** | `AIConfigDialog.tsx` | 🆕 **AI 도우미 고급 설정 Dialog** (Slider, 커스텀 CheckboxCard) | ✅ 완료 |
| **SecurityLevelSelector** | `SecurityLevelSelector.tsx` | 5단계 보안 레벨 선택 (RadioCard, framer-motion 애니메이션) | ✅ 완료 | | **SecurityLevelSelector** | `SecurityLevelSelector.tsx` | 5단계 보안 레벨 선택 (RadioCard, framer-motion 애니메이션) | ✅ 완료 |
| **AllowListManager** | `AllowListManager.tsx` | 명단 관리 (이름/이메일 추가/제거, TagsInput) | ✅ 완료 |
| **TopicMemberAnalysisSection** | `TopicMemberAnalysisSection.tsx` | 🆕 **주제별 학생 글쓰기 분석** (Accordion, 주제별 학생 목록, 글 개수, by-topic 분석 연동) | ✅ 완료 | | **TopicMemberAnalysisSection** | `TopicMemberAnalysisSection.tsx` | 🆕 **주제별 학생 글쓰기 분석** (Accordion, 주제별 학생 목록, 글 개수, by-topic 분석 연동) | ✅ 완료 |
| **LiveWritingMonitor** | `LiveWritingMonitor.tsx` | 🆕 **실시간 글쓰기 모니터링** (Firebase Realtime DB, 5초 주기) | ✅ 완료 | | **LiveWritingMonitor** | `LiveWritingMonitor.tsx` | 🆕 **실시간 글쓰기 모니터링** (Firebase Realtime DB, 5초 주기) | ✅ 완료 |
@ -517,7 +528,6 @@
- 실시간 구독/구독 해제 (useEffect cleanup) - 실시간 구독/구독 해제 (useEffect cleanup)
- 시각적 구분 (색상별 테두리, 아바타, 배지) - 시각적 구분 (색상별 테두리, 아바타, 배지)
- ✅ SecurityLevelSelector: RadioCard 기반, 선택 시 추가 UI 애니메이션으로 표시 - ✅ SecurityLevelSelector: RadioCard 기반, 선택 시 추가 UI 애니메이션으로 표시
- ✅ AllowListManager: Level 2/4용 명단 관리, Enter/쉼표로 구분 입력
- ✅ 그라데이션 배경 (RadioCard와 자연스럽게 연결) - ✅ 그라데이션 배경 (RadioCard와 자연스럽게 연결)
- ✅ react-icons/lu 사용 (이모티콘 제거) - ✅ react-icons/lu 사용 (이모티콘 제거)
@ -689,7 +699,6 @@ firebase functions:log --only cleanupExpiredReservations
| 유틸리티 | 파일명 | 설명 | 상태 | | 유틸리티 | 파일명 | 설명 | 상태 |
|---------|--------|------|------| |---------|--------|------|------|
| **Korean Word List** | `koreanWordList.ts` | 한글 감각 동사/형용사 목록 (점수 가중치, 영역 변환 함수) | ✅ 완료 |
| **Team Code Generator** | `teamCodeGenerator.ts` | 한글/영어/일본어 팀 코드 생성 (형용사 + 색깔 + 동물, locale 파라미터) | ✅ 완료 | | **Team Code Generator** | `teamCodeGenerator.ts` | 한글/영어/일본어 팀 코드 생성 (형용사 + 색깔 + 동물, locale 파라미터) | ✅ 완료 |
| **🆕 i18n 유틸리티** | `i18n.ts` | 서비스 레이어용 번역 함수 (detectLocale, t), nested key 지원, 파라미터 치환 | ✅ 완료 | | **🆕 i18n 유틸리티** | `i18n.ts` | 서비스 레이어용 번역 함수 (detectLocale, t), nested key 지원, 파라미터 치환 | ✅ 완료 |
| **Password Security** | `passwordSecurity.ts` | HIBP API 연동 (유출된 비밀번호 차단) | ✅ 완료 | | **Password Security** | `passwordSecurity.ts` | HIBP API 연동 (유출된 비밀번호 차단) | ✅ 완료 |
@ -697,6 +706,7 @@ firebase functions:log --only cleanupExpiredReservations
| **Content Hash** | `contentHash.ts` | 🆕 **SHA-256 해시 생성** (글 목록 → 해시, id+updatedAt 조합), 🆕 **generateWritingContentHash** (개별 글 content 해시), 서버/클라이언트 지원 | ✅ 완료 | | **Content Hash** | `contentHash.ts` | 🆕 **SHA-256 해시 생성** (글 목록 → 해시, id+updatedAt 조합), 🆕 **generateWritingContentHash** (개별 글 content 해시), 서버/클라이언트 지원 | ✅ 완료 |
| **Pattern Cache Manager** | `patternCacheManager.ts` | 🆕 **패턴 분석 localStorage 캐싱** (LRU 최대 10개, 캐시 통계) | ✅ 완료 | | **Pattern Cache Manager** | `patternCacheManager.ts` | 🆕 **패턴 분석 localStorage 캐싱** (LRU 최대 10개, 캐시 통계) | ✅ 완료 |
| **Image Storage** | `imageStorage.ts` | 🆕 **Firebase Storage 이미지 업로드** (base64 → Storage, 공개 URL 반환) | ✅ 완료 | | **Image Storage** | `imageStorage.ts` | 🆕 **Firebase Storage 이미지 업로드** (base64 → Storage, 공개 URL 반환) | ✅ 완료 |
| **Area Limit** | `areaLimit.ts` | 🆕 **이미지 왜곡 영역 제한** (점수 기반 해금 로직, 좌표 계산) | ✅ 완료 |
--- ---
@ -704,7 +714,9 @@ firebase functions:log --only cleanupExpiredReservations
| Hook | 파일명 | 설명 | 상태 | | Hook | 파일명 | 설명 | 상태 |
|------|--------|------|------| |------|--------|------|------|
| **useWritingInactivityDetection** | `useWritingInactivityDetection.ts` | 🆕 **작성 멈춤 감지 훅** (N분 입력 없을 시 콜백, 타이머 리셋, 남은 시간) | ✅ 완료 | | **useRequireAuth** | `useRequireAuth.ts` | **인증 필수 페이지 훅** (비인증 시 자동 리다이렉트, additionalLoading 지원) | ✅ 완료 |
| **useTeamData** | `useTeamData.ts` | 🆕 **팀 데이터 로딩 훅** (팀 + 멤버 로딩, 권한 체크, refreshMembers) | ✅ 완료 |
| **useWritingInactivityDetection** | `useWritingInactivityDetection.ts` | **작성 멈춤 감지 훅** (N분 입력 없을 시 콜백, 타이머 리셋, 남은 시간) | ✅ 완료 |
--- ---
@ -730,6 +742,7 @@ firebase functions:log --only cleanupExpiredReservations
| **AI 글쓰기 도우미** | `/api/writing-assistance` | POST | 🆕 **AI 힌트 생성** (4단계, 주제 맥락, 팀 설정 검증) | ✅ 완료 | | **AI 글쓰기 도우미** | `/api/writing-assistance` | POST | 🆕 **AI 힌트 생성** (4단계, 주제 맥락, 팀 설정 검증) | ✅ 완료 |
| **글 생성** | `/api/writing` | POST | 🆕 **글 생성** (wordCount/charCount 자동 계산, 🆕 **analysis 저장**) | ✅ 완료 | | **글 생성** | `/api/writing` | POST | 🆕 **글 생성** (wordCount/charCount 자동 계산, 🆕 **analysis 저장**) | ✅ 완료 |
| **글 조회** | `/api/writing/[id]` | GET | 🆕 **글 조회** (작성자만 접근) | ✅ 완료 | | **글 조회** | `/api/writing/[id]` | GET | 🆕 **글 조회** (작성자만 접근) | ✅ 완료 |
| **글 분석** | `/api/writing/[id]/analyze` | POST | 🆕 **글 분석 실행** (서버 데이터 기반, 결과 저장) | ✅ 완료 |
| **글 수정** | `/api/writing/[id]` | PUT | 🆕 **글 수정** (작성자만 접근, 통계 재계산) | ✅ 완료 | | **글 수정** | `/api/writing/[id]` | PUT | 🆕 **글 수정** (작성자만 접근, 통계 재계산) | ✅ 완료 |
| **글 삭제** | `/api/writing/[id]` | DELETE | 🆕 **글 삭제** (작성자만 접근) | ✅ 완료 | | **글 삭제** | `/api/writing/[id]` | DELETE | 🆕 **글 삭제** (작성자만 접근) | ✅ 완료 |
| **사용자 글 목록** | `/api/writing/user` | POST | 🆕 **사용자 글 목록** (userId 선택적, 본인 글만) | ✅ 완료 | | **사용자 글 목록** | `/api/writing/user` | POST | 🆕 **사용자 글 목록** (userId 선택적, 본인 글만) | ✅ 완료 |
@ -872,7 +885,6 @@ project_w/
│ ├── team/ # ✅ 팀 관련 │ ├── team/ # ✅ 팀 관련
│ │ ├── TeamTopicManager.tsx # ✅ 팀 주제 관리 │ │ ├── TeamTopicManager.tsx # ✅ 팀 주제 관리
│ │ ├── SecurityLevelSelector.tsx # 보안 레벨 선택 (RadioCard, 애니메이션) │ │ ├── SecurityLevelSelector.tsx # 보안 레벨 선택 (RadioCard, 애니메이션)
│ │ ├── AllowListManager.tsx # 명단 관리 (TagsInput)
│ │ ├── TopicMemberAnalysisSection.tsx # 주제별 학생 분석 (UI만) │ │ ├── TopicMemberAnalysisSection.tsx # 주제별 학생 분석 (UI만)
│ │ └── LiveWritingMonitor.tsx # 🆕 실시간 글쓰기 모니터링 (Realtime DB) │ │ └── LiveWritingMonitor.tsx # 🆕 실시간 글쓰기 모니터링 (Realtime DB)
│ └── [미구현] │ └── [미구현]

View File

@ -59,7 +59,6 @@
| **authStore DB 연동** | **combineUserData로 Firebase Auth + Firestore 자동 결합, userManager.getUser() 활용** | **2025-11-10** | | **authStore DB 연동** | **combineUserData로 Firebase Auth + Firestore 자동 결합, userManager.getUser() 활용** | **2025-11-10** |
| **memberUids 제거** | **Team.memberUids 필드 제거, Object.keys(members) 사용, 데이터 중복 제거** | **2025-11-10** | | **memberUids 제거** | **Team.memberUids 필드 제거, Object.keys(members) 사용, 데이터 중복 제거** | **2025-11-10** |
| **SecurityLevelSelector** | **RadioCard 기반 보안 레벨 선택 UI, framer-motion 애니메이션, 그라데이션 배경** | **2025-11-10** | | **SecurityLevelSelector** | **RadioCard 기반 보안 레벨 선택 UI, framer-motion 애니메이션, 그라데이션 배경** | **2025-11-10** |
| **AllowListManager** | **명단 관리 컴포넌트 (TagsInput), Enter/쉼표 구분 입력 지원** | **2025-11-10** |
| **API Routes 구현** | **보안 레벨 변경, 명단 관리 API (RESTful 원칙), POST/DELETE 메서드 구분** | **2025-11-10** | | **API Routes 구현** | **보안 레벨 변경, 명단 관리 API (RESTful 원칙), POST/DELETE 메서드 구분** | **2025-11-10** |
| **lib/server/team 확장** | **updateTeamSecurityLevel, add/removeAllowedName/Email, 자동 명단 생성** | **2025-11-10** | | **lib/server/team 확장** | **updateTeamSecurityLevel, add/removeAllowedName/Email, 자동 명단 생성** | **2025-11-10** |
| **react-icons 전환** | **이모티콘 → react-icons/lu로 전환 (LuGlobe, LuClipboardList 등)** | **2025-11-10** | | **react-icons 전환** | **이모티콘 → react-icons/lu로 전환 (LuGlobe, LuClipboardList 등)** | **2025-11-10** |
@ -86,7 +85,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** | | **실시간 글쓰기 모니터링** | **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** | | **다국어 지원 시스템 (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** | | **개별 글 분석 결과 저장** | **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** | | **AI 글쓰기 도우미 시스템** | **4단계 점진적 힌트 시스템 (질문 → 방향 → 선택지 → 예시 문장), useWritingInactivityDetection 훅 (5분 작성 멈춤 감지, 타이머 리셋, 남은 시간), UI 컴포넌트 2개 (InactivityPrompt 플로팅 버튼, HintDisplay Dialog), 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** |
| **AI 설정 고급 UI 완성** | **AIConfigDialog 컴포넌트 (팀 관리 페이지), Slider 3개 (멈춤 감지/최대 힌트/쿨다운), 커스텀 힌트 레벨 카드 (반투명 배경 번호, 우상단 접힌 페이지 삼각형 인디케이터, CSS border trick, 직접 onClick 처리), SimpleGrid 2x2 레이아웃, 브랜드 컬러 상태 변화, Switch (AI 제안 그대로 사용 금지), 함수형 상태 업데이트 (클로저 해결), 다국어 지원 (ko/en/ja, team.manage.aiConfig namespace 28개 키)** | **2025-11-17** | | **AI 설정 고급 UI 완성** | **AIConfigDialog 컴포넌트 (팀 관리 페이지), Slider 3개 (멈춤 감지/최대 힌트/쿨다운), 커스텀 힌트 레벨 카드 (반투명 배경 번호, 우상단 접힌 페이지 삼각형 인디케이터, CSS border trick, 직접 onClick 처리), SimpleGrid 2x2 레이아웃, 브랜드 컬러 상태 변화, Switch (AI 제안 그대로 사용 금지), 함수형 상태 업데이트 (클로저 해결), 다국어 지원 (ko/en/ja, team.manage.aiConfig namespace 28개 키)** | **2025-11-17** |
| **AI 이미지 생성 + 장면 분리 + 프롬프트 최적화** | **Vertex AI Imagen 3.0 통합, AI 장면 분리 기능 (Gemini Flash), AI 프롬프트 최적화 (Gemini Flash-Lite, 원문 → 핵심 키워드 배열 추출 → 쉼표 연결, Fallback 안전성), 4단계 플로우 (장면 추출 → 장면 선택 → 프롬프트 최적화 → 이미지 생성 → 결과 표시), Scene/SceneExtractionResponse 타입 추가, sceneExtractionService.ts (글 → 3~5개 장면 자동 추출, 장면별 프롬프트 생성), sceneExtraction.ts 프롬프트 (ko/en/ja, Response Schema), promptOptimization.ts 프롬프트 (키워드 추출, ko/en/ja), POST /api/extract-scenes (장면 추출 API), SceneSelector 컴포넌트 (RadioCard, 이모지, 원문 미리보기 80자, ItemHiddenInput 추가), GeneratedImage 타입 (url, prompt, generatedAt, modelName), imagenService.ts (글 → 어린이 친화적 프롬프트 자동 변환, optimizePromptForImage 함수, 안전 필터링), vertexAI.ts 확장 (generateImage 함수, multi-region failover 재사용), imageStorage.ts (Firebase Storage 업로드, base64 → 공개 URL 변환, toDataURL 헬퍼), POST /api/generate-image (권한 체크, AI 프롬프트 최적화, Imagen API 호출, Storage 저장, Writing.generatedImage 필드 업데이트), GenerateImageDialog 개선 (4단계 플로우, 장면 선택 UI, "다른 장면 선택" 버튼), 글쓰기 페이지 통합 ("구체화하기" 버튼, 저장 완료 후 표시, 홈 이동 제거), Firebase Storage 초기화 (fbStorage), 다국어 번역 (write.generateImage + write.extractScenes namespace, ko/en/ja 22개 키), 타입 체크 통과** | **2025-11-17** | | **AI 이미지 생성 + 장면 분리 + 프롬프트 최적화** | **Vertex AI Imagen 3.0 통합, AI 장면 분리 기능 (Gemini Flash), AI 프롬프트 최적화 (Gemini Flash-Lite, 원문 → 핵심 키워드 배열 추출 → 쉼표 연결, Fallback 안전성), 4단계 플로우 (장면 추출 → 장면 선택 → 프롬프트 최적화 → 이미지 생성 → 결과 표시), Scene/SceneExtractionResponse 타입 추가, sceneExtractionService.ts (글 → 3~5개 장면 자동 추출, 장면별 프롬프트 생성), sceneExtraction.ts 프롬프트 (ko/en/ja, Response Schema), promptOptimization.ts 프롬프트 (키워드 추출, ko/en/ja), POST /api/extract-scenes (장면 추출 API), SceneSelector 컴포넌트 (RadioCard, 이모지, 원문 미리보기 80자, ItemHiddenInput 추가), GeneratedImage 타입 (url, prompt, generatedAt, modelName), imagenService.ts (글 → 어린이 친화적 프롬프트 자동 변환, optimizePromptForImage 함수, 안전 필터링), vertexAI.ts 확장 (generateImage 함수, multi-region failover 재사용), imageStorage.ts (Firebase Storage 업로드, base64 → 공개 URL 변환, toDataURL 헬퍼), POST /api/generate-image (권한 체크, AI 프롬프트 최적화, Imagen API 호출, Storage 저장, Writing.generatedImage 필드 업데이트), GenerateImageDialog 개선 (4단계 플로우, 장면 선택 UI, "다른 장면 선택" 버튼), 글쓰기 페이지 통합 ("구체화하기" 버튼, 저장 완료 후 표시, 홈 이동 제거), Firebase Storage 초기화 (fbStorage), 다국어 번역 (write.generateImage + write.extractScenes namespace, ko/en/ja 22개 키), 타입 체크 통과** | **2025-11-17** |
| **AI 이미지 생성 스타일 일관성 개선** | **Imagen 4.0 Fast로 업그레이드, 일관된 스타일 가이드 적용 (모든 이미지 동일 화풍), 애니메이션/만화 스타일로 전환 (세미 리얼리즘 제거), 한국 문화권 고려 ("Korean elementary student" 명시), 강화된 Negative Prompt (과도한 사실주의, 어두운 분위기 차단), 키워드 개수 증가 (6-12개), promptOptimization.ts 프롬프트 개선 (스타일 가이드 추가, 예시 업데이트), imagenService.ts 폴백 로직 개선 (일관된 스타일 유지), vertexAI.ts Negative Prompt 강화 (excessive realism, photorealistic, dark atmosphere 추가)** | **2025-11-20** | | **AI 이미지 생성 스타일 일관성 개선** | **Imagen 4.0 Fast로 업그레이드, 일관된 스타일 가이드 적용 (모든 이미지 동일 화풍), 애니메이션/만화 스타일로 전환 (세미 리얼리즘 제거), 한국 문화권 고려 ("Korean elementary student" 명시), 강화된 Negative Prompt (과도한 사실주의, 어두운 분위기 차단), 키워드 개수 증가 (6-12개), promptOptimization.ts 프롬프트 개선 (스타일 가이드 추가, 예시 업데이트), imagenService.ts 폴백 로직 개선 (일관된 스타일 유지), vertexAI.ts Negative Prompt 강화 (excessive realism, photorealistic, dark atmosphere 추가)** | **2025-11-20** |
@ -110,6 +109,12 @@
| **BackButton 공통 컴포넌트** | **src/components/layout/BackButton.tsx 생성, router.back() 기본 동작, href prop으로 특정 경로 이동, label prop으로 텍스트 커스터마이징, ButtonProps 확장으로 모든 Button 속성 지원, 다국어 지원 (t('interaction.back')), 재사용성 극대화 (모든 페이지에서 일관된 뒤로가기 UX)** | **2025-11-22** | | **BackButton 공통 컴포넌트** | **src/components/layout/BackButton.tsx 생성, router.back() 기본 동작, href prop으로 특정 경로 이동, label prop으로 텍스트 커스터마이징, ButtonProps 확장으로 모든 Button 속성 지원, 다국어 지원 (t('interaction.back')), 재사용성 극대화 (모든 페이지에서 일관된 뒤로가기 UX)** | **2025-11-22** |
| **Firebase Storage CORS 설정** | **firebase-storage-cors.json 생성 (origin: *, method: GET/HEAD, maxAge: 3600), gsutil cors set 명령어로 적용, Canvas 이미지 조작 허용, 캐시 문제 (CDN 1시간 캐시로 즉시 반영 안 됨, ?t=timestamp 쿼리 파라미터로 해결), TextureLoader.setCrossOrigin("anonymous") 확인** | **2025-11-23** | | **Firebase Storage CORS 설정** | **firebase-storage-cors.json 생성 (origin: *, method: GET/HEAD, maxAge: 3600), gsutil cors set 명령어로 적용, Canvas 이미지 조작 허용, 캐시 문제 (CDN 1시간 캐시로 즉시 반영 안 됨, ?t=timestamp 쿼리 파라미터로 해결), TextureLoader.setCrossOrigin("anonymous") 확인** | **2025-11-23** |
| **인터랙티브 이미지 비율 유지** | **InteractiveImage 컴포넌트 개선 (responsive-image-canvas 라이브러리), useEffect로 이미지 원본 크기 측정 (new Image, crossOrigin, onload), Box에 aspectRatio 속성 적용 (width/height 비율), Canvas 찌그러짐 방지, 로딩 상태 UI 추가, 캐시 무효화 (cacheBustedSrc ?t=Date.now())** | **2025-11-23** | | **인터랙티브 이미지 비율 유지** | **InteractiveImage 컴포넌트 개선 (responsive-image-canvas 라이브러리), useEffect로 이미지 원본 크기 측정 (new Image, crossOrigin, onload), Box에 aspectRatio 속성 적용 (width/height 비율), Canvas 찌그러짐 방지, 로딩 상태 UI 추가, 캐시 무효화 (cacheBustedSrc ?t=Date.now())** | **2025-11-23** |
| **글 분석 및 상호작용 기능** | **POST /api/writing/[id]/analyze 추가 (서버 데이터 기반 분석), 상호작용 컴포넌트 (AnalysisNeededBanner, AreaUnlockBadge, ImprovementHint, ScoreBadge), 점수 기반 영역 해금 로직 (areaLimit.ts), WritingAnalysis 타입 확장** | **2025-11-25** |
| **이미지 왜곡 영역 기능** | **DistortionAreaData 데이터 모델 추가, InteractiveImageViewer 컴포넌트 (왜곡 효과, 애니메이션), 글 수정 시 왜곡 영역 저장/불러오기 지원** | **2025-11-25** |
| **팀 멤버 닉네임 추가** | **POST /api/team/add-member API에 nickname 파라미터 추가, 팀원 추가 시 닉네임 설정 지원** | **2025-11-25** |
| **글 상세 페이지 댓글 기능 연결** | **CommentList 컴포넌트를 writing/[writingId]/page.tsx에 연결, 댓글 보기/작성/답글/삭제 기능 활성화** | **2025-11-26** |
| **미사용 코드 정리** | **koreanWordList.ts 삭제 (AI 분석으로 대체), InteractiveImage.tsx 삭제 (InteractiveImageViewer로 대체), AllowListManager.tsx 삭제 (미통합), 관련 문서 업데이트** | **2025-11-26** |
| **팀 페이지 리팩토링** | **useTeamData 훅 생성 (팀 + 멤버 로딩, 권한 체크, refreshMembers), 팀 페이지 중복 코드 제거 (~200줄 절감), 각 하위 컴포넌트 자체 로딩 스켈레톤 활용** | **2025-11-26** |
### 🚧 진행 중 ### 🚧 진행 중

View File

@ -647,7 +647,6 @@ if (cached && Date.now() - cached.timestamp < 60000) {
- `src/app/api/analyze-text/route.ts` - Vertex AI API - `src/app/api/analyze-text/route.ts` - Vertex AI API
- `src/components/writing/ScoreDisplay.tsx` - 실시간 점수 표시 - `src/components/writing/ScoreDisplay.tsx` - 실시간 점수 표시
- `src/app/write/page.tsx` - Delta 추적 + 통합 - `src/app/write/page.tsx` - Delta 추적 + 통합
- `src/utils/koreanWordList.ts` - 참고 단어 목록 (프롬프트용)
**비용**: **비용**:
- **$0.009/글** (Delta + Cache 기준) - **$0.009/글** (Delta + Cache 기준)

View File

@ -439,6 +439,17 @@ const nickname = teamManager.getMemberNickname(team, uid, user?.name);
4. 보호된 페이지 패턴 4. 보호된 페이지 패턴
└─> useAuthStore()로 currentStudent 확인 └─> useAuthStore()로 currentStudent 확인
└─> 미인증 시 redirect(/) 또는 openLoginDialog() └─> 미인증 시 redirect(/) 또는 openLoginDialog()
5. 인증/데이터 로딩 훅
├─> useRequireAuth(additionalLoading?)
│ ├─> 인증 필수 페이지에서 사용
│ ├─> 미인증 시 자동 리다이렉트
│ └─> additionalLoading: 데이터 로딩 중 리다이렉트 방지
└─> useTeamData({teamId, requiredAccess, t})
├─> 팀 페이지 공통 데이터 로딩 (team + members)
├─> requiredAccess: "member" | "owner" 권한 체크
└─> 반환: team, members, isLoadingTeam, isLoadingMembers, isOwner, refreshMembers
``` ```
### 3. 글쓰기 및 저장 로직 (Manager 패턴 적용) ### 3. 글쓰기 및 저장 로직 (Manager 패턴 적용)
@ -1038,9 +1049,6 @@ interface Draft {
**타입 정의**: **타입 정의**:
- `src/types/draft.ts` - Draft, AnalysisHistoryItem - `src/types/draft.ts` - Draft, AnalysisHistoryItem
**유틸리티**:
- `src/utils/koreanWordList.ts` - 감각 동사/형용사 목록
**문서**: **문서**:
- `TECHNICAL_IMPLEMENTATION.md` - 상세 기술 구현 가이드 - `TECHNICAL_IMPLEMENTATION.md` - 상세 기술 구현 가이드
- `SERVICE_DIRECTION.md` - 서비스 방향성 논의 (8차) - `SERVICE_DIRECTION.md` - 서비스 방향성 논의 (8차)
@ -1983,7 +1991,7 @@ interface AIAssistanceRecord {
**훅**: `src/hooks/useWritingInactivityDetection.ts` **훅**: `src/hooks/useWritingInactivityDetection.ts`
**서비스**: `src/services/writingAssistanceService.ts` **서비스**: `src/services/writingAssistanceService.ts`
**프롬프트**: `src/prompts/writingAssistance.ts` (4단계 × 3개 언어) **프롬프트**: `src/prompts/writingAssistance.ts` (4단계 × 3개 언어)
**UI**: `src/components/writing/{InactivityPrompt, HintDisplay, AIAssistancePanel}.tsx` **UI**: `src/components/writing/{InactivityPrompt, HintDisplay}.tsx`
**API**: `src/app/api/writing-assistance/route.ts`, `src/app/api/team/[teamId]/ai-config/route.ts` **API**: `src/app/api/writing-assistance/route.ts`, `src/app/api/team/[teamId]/ai-config/route.ts`
**서버**: `src/lib/server/team.ts` (getTeamAIConfig, updateTeamAIConfig) **서버**: `src/lib/server/team.ts` (getTeamAIConfig, updateTeamAIConfig)
**Manager**: `src/managers/TeamManager.ts` (getAIConfig, updateAIConfig) **Manager**: `src/managers/TeamManager.ts` (getAIConfig, updateAIConfig)