docs: Sync documentation from private repository
This commit is contained in:
parent
02ef481baa
commit
ca707a6d6f
327
API_SPEC.md
327
API_SPEC.md
@ -861,333 +861,6 @@ await teamManager.removeMember(teamId, currentUser.uid);
|
||||
|
||||
---
|
||||
|
||||
### 2. GET `/student/:id` - 학생 조회
|
||||
실제 URL: `GET /api/student/:id`
|
||||
|
||||
**인증**: 선택적
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
student: Student;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**캐싱**: 클라이언트에서 5분간 캐싱
|
||||
|
||||
---
|
||||
|
||||
### 3. POST `/student/by-uid` - Firebase UID로 학생 조회
|
||||
실제 URL: `POST /api/student/by-uid`
|
||||
|
||||
**인증**: 필수 (Anonymous Auth)
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
firebaseUid: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
student: Student | null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**용도**: 로그인 시 기존 학생 확인
|
||||
|
||||
**캐싱**: 클라이언트에서 5분간 캐싱
|
||||
|
||||
---
|
||||
|
||||
### 4. POST `/student/by-team` - 팀별 학생 목록
|
||||
실제 URL: `POST /api/student/by-team`
|
||||
|
||||
**인증**: 선택적
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
teamId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
students: Student[];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**캐싱**: 클라이언트에서 30초간 캐싱 (자주 변경)
|
||||
|
||||
---
|
||||
|
||||
### 5. POST `/student/find-by-name` - 이름으로 학생 찾기
|
||||
실제 URL: `POST /api/student/find-by-name`
|
||||
|
||||
**인증**: 선택적
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
teamId: string;
|
||||
name: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
student: Student | null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**용도**: 학생 로그인 시 기존 학생 확인
|
||||
|
||||
---
|
||||
|
||||
### 6. PUT `/student/:id` - 학생 정보 수정
|
||||
실제 URL: `PUT /api/student/:id`
|
||||
|
||||
**인증**: 필수
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
data: {
|
||||
name?: string;
|
||||
pinHash?: string;
|
||||
linkedUserId?: string;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
student: Student;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**캐시 무효화**: 해당 학생, 팀별 학생 목록
|
||||
|
||||
---
|
||||
|
||||
### 7. POST `/student/kick` - 팀에서 학생 강퇴
|
||||
실제 URL: `POST /api/student/kick`
|
||||
|
||||
**인증**: 필수
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
teamId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
success: true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**권한**: 팀 소유자만 강퇴 가능
|
||||
|
||||
**부수 효과**:
|
||||
- `student.teamIds`에서 팀 제거
|
||||
- `team.studentIds`에서 학생 제거
|
||||
|
||||
**캐시 무효화**: 해당 학생, 팀, 팀별 학생 목록
|
||||
|
||||
---
|
||||
|
||||
### 8. POST `/student/update-pin` - PIN 변경
|
||||
실제 URL: `POST /api/student/update-pin`
|
||||
|
||||
**인증**: 필수
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
newPin: string; // 평문 (4자리 숫자)
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
success: true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**검증**: 서버에서 PIN 형식 검증 (4자리 숫자)
|
||||
|
||||
**보안**: PIN은 SHA-256 해시로 저장
|
||||
|
||||
**캐시 무효화**: 해당 학생
|
||||
|
||||
---
|
||||
|
||||
### 9. POST `/student/validate-pin` - PIN 검증
|
||||
실제 URL: `POST /api/student/validate-pin`
|
||||
|
||||
**인증**: 선택적
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
pin: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
valid: boolean;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**용도**: 학생 로그인 시 PIN 확인
|
||||
|
||||
---
|
||||
|
||||
### 10. POST `/student/link` - 정식 계정 연결
|
||||
실제 URL: `POST /api/student/link`
|
||||
|
||||
**인증**: 필수 (정식 계정)
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
// userId는 Authorization 헤더에서 추출
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
success: true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**권한**: 현재 로그인한 사용자와 연결
|
||||
|
||||
**검증**:
|
||||
- 학생이 이미 다른 계정과 연결되어 있으면 에러
|
||||
|
||||
**캐시 무효화**: 해당 학생, 내 학생 목록
|
||||
|
||||
---
|
||||
|
||||
### 11. POST `/student/unlink` - 정식 계정 연결 해제
|
||||
실제 URL: `POST /api/student/unlink`
|
||||
|
||||
**인증**: 필수
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
success: true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**캐시 무효화**: 해당 학생, 내 학생 목록
|
||||
|
||||
---
|
||||
|
||||
### 12. GET `/student/my-students` - 내 학생 목록
|
||||
실제 URL: `GET /api/student/my-students`
|
||||
|
||||
**인증**: 필수 (정식 계정)
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
students: Student[];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**권한**: 로그인한 사용자가 소유한 학생만 조회 (`linkedUserId` 기준)
|
||||
|
||||
**캐싱**: 클라이언트에서 1분간 캐싱
|
||||
|
||||
---
|
||||
|
||||
### 13. POST `/student/update-last-login` - 마지막 로그인 시간 업데이트
|
||||
실제 URL: `POST /api/student/update-last-login`
|
||||
|
||||
**인증**: 선택적
|
||||
|
||||
**Request**:
|
||||
```typescript
|
||||
{
|
||||
studentId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```typescript
|
||||
{
|
||||
success: true,
|
||||
data: {
|
||||
success: true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**참고**: 실패해도 클라이언트는 에러를 무시 (크리티컬하지 않음)
|
||||
|
||||
---
|
||||
|
||||
## Writing API
|
||||
|
||||
### 1. POST `/writing` - 글 생성
|
||||
|
||||
@ -1,10 +1,27 @@
|
||||
# 라온누리 - 프로젝트 구조
|
||||
|
||||
> 최종 업데이트: 2025-11-21 (홈 페이지 모듈화)
|
||||
> 최종 업데이트: 2025-11-22 (Server Component 전환 + 공통 컴포넌트)
|
||||
|
||||
초등학생을 위한 창작 글쓰기 교육 플랫폼
|
||||
|
||||
**최신 업데이트** (2025-11-21):
|
||||
**최신 업데이트** (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% 감소)
|
||||
@ -233,6 +250,7 @@
|
||||
| **랜딩 페이지** | `/[locale]` | 서비스 소개 및 홍보 (비로그인 전용) | Hero, Features, How It Works, CTA, Footer<br>로그인 시 `/home`으로 자동 리다이렉트<br>🆕 **전체 번역 완료** (사이트명, 태그라인, 모든 섹션) | ✅ 완료 |
|
||||
| **유저 홈** | `/[locale]/home` | 인증된 사용자 대시보드 | 환영 메시지, 빠른 시작 대시보드, **최근 활동 (최근 글 3개 표시)**<br>비로그인 시 `/`로 자동 리다이렉트<br>정식 계정은 "내 팀" 카드 추가 표시<br>🆕 **WritingCard Grid, "모두 보기" 버튼**<br>🆕 **전체 번역 완료** (웰컴 메시지, 모든 액션 카드) | ✅ 완료 |
|
||||
| **내 글 모음** | `/[locale]/writings` | 🆕 **전체 글 목록 페이지** | 🆕 **사용자의 모든 글 표시 (Grid)**<br>🆕 **정렬 Select (최신순/오래된순)**<br>🆕 **WritingCard 컴포넌트 사용**<br>🆕 **Empty state 처리**<br>🆕 **전체 번역 완료** (ko/en/ja) | ✅ 완료 |
|
||||
| **글 상세보기** | `/[locale]/writing/[writingId]` | 🆕 **Server Component 기반 상세 페이지** | 🆕 **SEO 최적화** (서버에서 HTML 생성)<br>🆕 **SNS 공유 미리보기** (카카오톡/페이스북)<br>🆕 **서버 데이터 로딩** (Firebase Admin SDK)<br>제목, 내용, 생성된 이미지 표시<br>주제 및 팀 정보 Badge<br>프롬프트 Collapsible<br>🆕 **CommentList** (Client Component)<br>🆕 **BackButton** 공통 컴포넌트 사용 | ✅ 완료 |
|
||||
| **글쓰기** | `/[locale]/write` | Tiptap 기반 순수 텍스트 에디터 + 주제 선택 | 주제 선택 (자유 주제/개인 주제/팀 주제)<br>🆕 **글 수정 기능 (URL params ?id=xxx)**<br>🆕 **수정 모드 배지 표시**<br>🆕 **주제 변경 경고** (작성 중 내용 초기화 알림, 임시 저장 안내)<br>제목 입력 (Editable), 순수 텍스트 에디터 (포맷팅 없음)<br>🆕 **다중 글조각 관리** (최대 10개), "새 글쓰기" / "저장된 글조각" 버튼<br>🆕 **강화된 자동 저장** (2초 debounce, 저장 상태 표시: 저장 중/저장됨)<br>🆕 **저장 시 AI 분석** (실시간 분석 제거, 저장 버튼 클릭 시 분석 수행)<br>🆕 **분석 결과 DB 저장** (WritingAnalysis + spellingErrors + contentHash)<br>템플릿 미리채우기 (제목/내용), Firestore 저장<br>비로그인도 접근 가능 (저장 시 로그인 유도) | ✅ 완료 |
|
||||
| **테스트** | `/[locale]/test` | 팀 코드 시스템 테스트 페이지 | 팀 코드 생성/검증 테스트<br>팀/학생 생성 테스트<br>학생 로그인 테스트<br>authStore 상태 확인 | 🔜 예정 |
|
||||
| **팀 목록** | `/[locale]/team` | 내가 만든 팀 목록 (정식 계정 전용) | 팀 카드 그리드, 팀 정보 (코드, 멤버 수, 보안 설정)<br>"새 팀 만들기" 버튼 | 🔜 예정 |
|
||||
@ -319,6 +337,36 @@
|
||||
|
||||
---
|
||||
|
||||
### 📁 `src/components/layout/` - 레이아웃 공통 컴포넌트
|
||||
|
||||
| 컴포넌트 | 파일명 | 설명 | 상태 |
|
||||
|---------|--------|------|------|
|
||||
| **BackButton** | `BackButton.tsx` | 🆕 **뒤로가기 버튼 공통 컴포넌트** (router.back() 또는 특정 경로, 커스텀 라벨 지원) | ✅ 완료 |
|
||||
|
||||
**주요 기능**:
|
||||
- ✅ `router.back()` 기본 동작
|
||||
- ✅ `href` prop으로 특정 경로 이동 가능
|
||||
- ✅ `label` prop으로 버튼 텍스트 커스터마이징
|
||||
- ✅ 다국어 지원 (기본 라벨: `t('interaction.back')`)
|
||||
- ✅ ButtonProps 확장으로 모든 Button 속성 지원
|
||||
|
||||
**사용 예시**:
|
||||
```tsx
|
||||
// 기본 사용 (router.back())
|
||||
<BackButton />
|
||||
|
||||
// 특정 경로로 이동
|
||||
<BackButton href="/home" />
|
||||
|
||||
// 커스텀 라벨
|
||||
<BackButton label="목록으로" />
|
||||
|
||||
// 추가 스타일링
|
||||
<BackButton colorPalette="brand" size="lg" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 📁 `src/components/ui/` - UI 기본 컴포넌트
|
||||
|
||||
| 컴포넌트 | 파일명 | 설명 | 상태 |
|
||||
@ -531,7 +579,6 @@
|
||||
| **UserManager** | `UserManager.ts` | 사용자 관련 API 호출 (생성, 조회, 수정, 닉네임 관리) **[NEW]** | ✅ 완료 |
|
||||
| **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, 통계) | ✅ 완료 |
|
||||
| **TopicManager** | `TopicManager.ts` | 주제 관련 비즈니스 로직 (CRUD, 템플릿 처리) | ✅ 완료 |
|
||||
| **index.ts** | `index.ts` | 모든 매니저 export | ✅ 완료 |
|
||||
@ -790,6 +837,11 @@ project_w/
|
||||
│ │ │ └── page.tsx # ✅ 유저 홈 페이지 (/[locale]/home) - 🆕 전체 번역 완료
|
||||
│ │ ├── write/
|
||||
│ │ │ └── page.tsx # ✅ 글쓰기 페이지 (/[locale]/write) - 🆕 실시간 모니터링
|
||||
│ │ ├── writing/ # ✅ 글 상세보기
|
||||
│ │ │ └── [writingId]/
|
||||
│ │ │ └── page.tsx # 🆕 글 상세 페이지 (Server Component, SEO 최적화)
|
||||
│ │ ├── writings/
|
||||
│ │ │ └── page.tsx # ✅ 내 글 모음 페이지 (/[locale]/writings)
|
||||
│ │ ├── test/
|
||||
│ │ │ └── page.tsx # ✅ 테스트 페이지 (/[locale]/test)
|
||||
│ │ └── team/ # ✅ 팀 관리 페이지들
|
||||
@ -809,6 +861,8 @@ project_w/
|
||||
│ ├── navigation/ # ✅ 네비게이션 바 (다국어 지원)
|
||||
│ │ ├── Navbar.tsx # 다국어 링크 텍스트
|
||||
│ │ └── LocaleSwitcher.tsx # 🆕 언어 전환 버튼
|
||||
│ ├── layout/ # 🆕 레이아웃 공통 컴포넌트
|
||||
│ │ └── BackButton.tsx # 🆕 뒤로가기 버튼 (router.back/href/label 지원)
|
||||
│ ├── seo/ # ✅ SEO 컴포넌트
|
||||
│ ├── ui/ # ✅ Chakra UI 기본
|
||||
│ ├── writing/ # ✅ 글쓰기 에디터
|
||||
|
||||
@ -79,11 +79,10 @@ src/
|
||||
├── managers/ # ✅ 비즈니스 로직 (API + 캐싱)
|
||||
│ ├── ManagerBase.ts # 공통 기능 (authenticatedFetch, caching)
|
||||
│ ├── TeamManager.ts # 팀 관련 API 호출
|
||||
│ ├── StudentManager.ts # 학생 관련 API 호출
|
||||
│ ├── WritingManager.ts # 글쓰기 API 호출
|
||||
│ └── TopicManager.ts # 주제 API 호출
|
||||
├── types/ # TypeScript 타입
|
||||
│ ├── team.ts, student.ts, writing.ts, topic.ts
|
||||
│ ├── team.ts, writing.ts, topic.ts
|
||||
│ └── api/ # API Request/Response 타입
|
||||
├── config/ # Firebase 설정
|
||||
├── services/ # Firebase Auth, Firestore
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 라온누리 - 개발 로드맵
|
||||
|
||||
> 최종 업데이트: 2025-11-21 (홈 페이지 모듈화)
|
||||
> 최종 업데이트: 2025-11-22 (Server Component 전환)
|
||||
|
||||
초등학생을 위한 창작 글쓰기 교육 플랫폼 개발 계획
|
||||
|
||||
@ -106,6 +106,10 @@
|
||||
| **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** |
|
||||
| **주제 생성 Dialog 통합** | **CreateTeamTopicDialog 삭제 (674줄), CreateTopicDialog로 통합 (개인/팀 공용), TopicFormData export (데이터 반환 방식), onSubmit 콜백 패턴 (부모가 topicManager 호출), team.manage.teamTopics.dialog 번역 키 제거 (30개), topicSelector.createSuccess 추가, 652줄 코드 감소, 관심사 분리 (Dialog는 UI만, 비즈니스 로직은 부모)** | **2025-11-21** |
|
||||
| **홈 페이지 모듈화** | **HeroSection/QuickActionCard/QuickActionsGrid/ViewAllWritingsCard/EmptyStateCard/RecentActivitySection 컴포넌트 분리 (src/components/home/), 580줄 → 223줄 (62% 감소), Semantic token 적극 활용 (bg/fg/border), Conditional style 객체 최소화, 재사용성 및 유지보수성 향상, JSX 주석 한글화** | **2025-11-21** |
|
||||
| **글 상세보기 Server Component 전환** | **src/app/[locale]/writing/[writingId]/page.tsx를 Server Component로 전환, SEO 최적화 (서버에서 HTML 생성), SNS 공유 미리보기 (카카오톡/페이스북 링크), Firebase Admin SDK 사용 (src/lib/server/writing.ts, getTopic, getTeam), getTranslations() 서버 번역 함수, params: Promise<{locale, writingId}> 타입, 초기 로딩 성능 개선 (데이터 포함된 HTML 전송), 서버 권한 체크 (클라이언트 깜빡임 없음)** | **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** |
|
||||
| **인터랙티브 이미지 비율 유지** | **InteractiveImage 컴포넌트 개선 (responsive-image-canvas 라이브러리), useEffect로 이미지 원본 크기 측정 (new Image, crossOrigin, onload), Box에 aspectRatio 속성 적용 (width/height 비율), Canvas 찌그러짐 방지, 로딩 상태 UI 추가, 캐시 무효화 (cacheBustedSrc ?t=Date.now())** | **2025-11-23** |
|
||||
|
||||
### 🚧 진행 중
|
||||
|
||||
|
||||
@ -243,7 +243,6 @@ NEXT_PUBLIC_API_URL=/api
|
||||
securityMode: 'simple' | 'normal' | 'open';
|
||||
requirePin: boolean;
|
||||
allowAnonymousJoin: boolean;
|
||||
studentIds: string[]; // students 컬렉션 참조
|
||||
createdAt: Timestamp;
|
||||
updatedAt: Timestamp;
|
||||
isActive: boolean;
|
||||
@ -828,7 +827,6 @@ writings/{writingId}
|
||||
|
||||
**참고 파일**:
|
||||
- `src/managers/TeamManager.ts` - 팀 관련 API 호출 + 캐싱
|
||||
- `src/managers/StudentManager.ts` - 학생 관련 API 호출 + 캐싱
|
||||
- `src/managers/ManagerBase.ts` - API 호출 및 캐싱 공통 로직
|
||||
- `src/services/firebaseAuth.ts:125-316` - 학생 로그인 로직
|
||||
- `src/store/authStore.ts` - currentStudent 중심 상태 관리
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user