Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions docs/01. 기획서.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## 1. 프로젝트 개요

### 1.1 프로젝트 배경
- 학생들은 강의 후 이해했다고 느끼지만, 실제로는 표면적 이해에 머무르는 경우가 많음
- 심화 질문을 통한 학습이 효과적이나, 학생이 직접 질문을 만들기는 어려움
- 강의 녹음은 쉽게 할 수 있지만, 이를 학습에 활용할 수 있는 도구가 부족함

### 1.2 서비스 목표
웹에서 강의를 녹음하고, 사용자가 분석을 요청하면 AI가 강의 내용을 분석하여 **심화 질문을 자동 생성**한다.

- **녹음의 학습 자산화**: 녹음을 텍스트 변환·요약·질문으로 전환하여 실질적 학습 자료로 활용
- **AI 심화 질문 제공**: 강의 내용 기반의 다양한 유형의 질문을 자동 생성
- **자기 주도 복습 유도**: 심화 질문을 통해 학생이 스스로 깊이 사고하도록 유도

### 1.3 타깃 사용자
- **대학생**: 전공 강의 복습, 시험 대비
- **온라인 강의 수강생**: 자기 주도 학습, 이해도 점검
- **자격증/시험 준비생**: 핵심 개념 정리, 취약 부분 파악

---

## 2. 요구사항 정의

#### FR-01. 강의 녹음
사용자가 웹 브라우저에서 강의를 실시간 녹음할 수 있다.
- 녹음 시작/일시정지/종료 제어
- 녹음 중 경과 시간 표시
- 녹음 메타데이터 저장 및 목록 관리
- 녹음 삭제 (단, 분석 진행 중인 녹음은 삭제 불가)
- 녹음 제목 편집
- 날짜/키워드별 필터링 및 검색

#### FR-02. 강의 분석
사용자가 분석을 요청하면 AI가 강의 내용을 분석하여 결과를 제공한다.
- 변환 텍스트: 한국어 음성을 텍스트로 변환하여 별도 열람 가능
- 요약본: 핵심 개념(용어+정의), 주제별 섹션 구조화, 핵심 키워드 추출
- 심화 질문: 응용·추론·비판적 사고를 요구하는 질문 5개 생성
- 질문 재생성 요청 가능 (기존 질문을 새 질문으로 대체)
- 진행 상태 표시
- 완료 또는 실패 시 브라우저 알림

#### FR-03. 사용자 인증
소셜 로그인 기반의 간편 인증으로 개인 데이터를 보호한다.
- 소셜 로그인 (카카오)
- 첫 로그인 시 자동 회원가입
- 개인 학습 데이터 계정 연동
- 로그아웃 및 계정 탈퇴
- 분석 진행 중인 경우 탈퇴 불가
144 changes: 144 additions & 0 deletions docs/02. 시스템 설계.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
## 1. 시스템 아키텍처

### 1.1 전체 시스템 구조도

![시스템 구조도](images/시스템%20구조도.png)

| 컴포넌트 | 역할 | 비고 |
|---------|------|------|
| 웹 클라이언트 | 녹음, UI, 사용자 인터랙션 | React + Vite |
| 로드 밸런서 | 트래픽 분산, Rolling 배포 지원 | NCP Load Balancer |
| 서버 (x2) | 비즈니스 로직, API 제공, 인증 처리 | Spring Boot |
| DB | 사용자, 녹음 메타데이터, 분석 결과, 질문 저장 | MySQL |
| 클라우드 스토리지 | 음성 파일 임시 저장 (STT 처리용) | NCP Object Storage |
| STT API | 음성 → 텍스트 변환 | Whisper API |
| LLM API | 텍스트 요약, 심화 질문 생성 | OpenAI API (GPT-4o mini) |
| 카카오 인증 서버 | 소셜 로그인 OAuth 2.0 처리 | Kakao Developers |

### 1.2 배포 전략

**Rolling 배포**를 적용한다. 평상시 서버 2대가 모두 트래픽을 처리하며, 배포 시 1대씩 순차 업데이트한다.

1. 로드 밸런서에서 서버 1을 제외
2. 서버 1에 신버전 배포 및 정상 동작 확인
3. 서버 1을 로드 밸런서에 복귀
4. 서버 2에 동일 과정 반복

### 1.3 인증 구조

**JWT + HttpOnly Cookie** 방식을 사용한다. 서버 2대 운영 시 세션 스토어 없이 stateless로 동작한다.

| 토큰 | 저장 위치 | 만료 | 용도 |
|------|----------|------|------|
| Access Token | HttpOnly Cookie | 짧은 만료 (30분) | API 요청 인증 |
| Refresh Token | HttpOnly Cookie + DB | 긴 만료 (14일) | Access Token 재발급, DB 저장으로 서버 측 무효화 가능 |

- **HttpOnly**: JavaScript에서 토큰 접근 불가 → XSS 방어
- **SameSite=Lax**: 외부 사이트에서의 쿠키 전송 제한 → CSRF 완화
- **Secure**: HTTPS에서만 쿠키 전송

---

## 2. 분석 파이프라인

### 2.1 파이프라인 흐름

![분석 파이프라인](images/분석%20파이프라인.png)

분석은 3단계로 순차 실행되며, 각 단계의 결과가 다음 단계의 입력이 된다.

| 단계 | 상태값 | 처리 내용 | 입력 | 출력 |
|------|-------|----------|------|------|
| 1 | STT | Whisper API로 음성→텍스트 변환 | 클라우드 임시 음성 파일 | 변환 텍스트 (DB 저장) |
| 2 | SUMMARIZING | LLM으로 텍스트 요약 | 변환 텍스트 | 요약본 JSON (DB 저장) |
| 3 | QUESTIONING | LLM으로 심화 질문 생성 | 요약본 | 질문 5개 (DB 저장) |

**상태 전이**: `PENDING` → `STT` → `SUMMARIZING` → `QUESTIONING` → `COMPLETED` (또는 `FAILED`)

### 2.2 비동기 처리

- 분석 요청(POST)은 즉시 202 응답을 반환하고, 서버에서 비동기로 파이프라인을 실행한다
- 클라이언트는 폴링(GET /analysis/status)으로 진행 상태를 확인한다
- 완료 또는 실패 시 Web Notifications API로 브라우저 알림을 표시한다

### 2.3 질문 재생성

질문 재생성은 분석 파이프라인과 별도로, 기존 요약본을 기반으로 **질문 생성(3단계)만 재실행**한다.
- 기존 질문 5개를 새로운 질문 5개로 대체
- 분석이 COMPLETED 상태인 경우에만 요청 가능
- 요약본은 DB에 저장되어 있으므로 추가 입력 없이 처리

### 2.4 재시도 전략

| 실패 단계 | 재시도 방법 | 시간 제한 |
|----------|-----------|----------|
| STT | 클라우드 임시 파일로 재시도 | 24시간 (임시 파일 만료 후 재시도 불가, 분석 새로 요청) |
| 요약 | DB에 저장된 변환 텍스트로 재시도 | 없음 |
| 질문 생성 | DB에 저장된 요약본으로 재시도 | 없음 |

### 2.5 에러 처리

- **빈 텍스트**: STT 결과가 빈 텍스트인 경우 분석 실패로 처리
- **API 오류**: 외부 API(Whisper, OpenAI) 호출 실패 시 해당 단계에서 FAILED 처리

### 2.6 파일 업로드 흐름

클라이언트가 Object Storage에 직접 업로드하기 위해 Presigned URL 방식을 사용한다.

1. 클라이언트가 서버에 업로드 URL 발급 요청
2. 서버가 NCP Object Storage의 Presigned URL 생성 후 응답
3. 클라이언트가 Presigned URL로 Object Storage에 음성 파일 직접 업로드
4. 업로드 완료 후 클라이언트가 서버에 분석 요청

---

## 3. 데이터 관리

### 3.1 데이터 흐름

![데이터 흐름도](images/데이터%20흐름도.png)

| 데이터 | 생성 시점 | 저장 위치 | 삭제 시점 |
|--------|----------|----------|----------|
| 녹음 메타데이터 | 녹음 완료 | DB | 사용자 삭제 또는 계정 탈퇴 |
| 음성 파일 (임시) | 분석 요청 | 클라우드 스토리지 `/tmp/{recording_id}.m4a` | STT 성공 시 즉시 삭제, 실패 시 24시간 후 자동 삭제 |
| 변환 텍스트 | STT 완료 | DB | 사용자 삭제 또는 계정 탈퇴 |
| 요약본 | LLM 요약 완료 | DB | 사용자 삭제 또는 계정 탈퇴 |
| 심화 질문 (5개) | LLM 질문 생성 완료 | DB | 사용자 삭제 또는 계정 탈퇴 |
| 사용자 정보 | 최초 소셜 로그인 | DB | 계정 탈퇴 |
| 인증 토큰 (JWT) | 로그인 | HttpOnly Cookie | 로그아웃 또는 만료 |

### 3.2 데이터 보관 정책

- **분석 결과 (변환 텍스트, 요약본, 질문)**: 사용자가 녹음을 삭제하거나 계정을 탈퇴할 때까지 유지
- **임시 음성 파일**: STT 성공 시 즉시 삭제. STT 실패 시 24시간 보관 후 자동 삭제
- **계정 탈퇴 시**: 사용자 데이터 및 관련 녹음/분석/질문 데이터 일괄 삭제

---

## 4. 시스템 제약사항

| 항목 | 제약 | 비고 |
|------|------|------|
| 녹음 최대 길이 | 2시간 | 초과 시 자동 종료 및 안내 |
| 녹음 최대 파일 크기 | 200MB | 초과 시 자동 종료 및 안내 |
| 동시 분석 | 사용자당 1건 | 초과 시 요청 거부 |
| 브라우저 탭 전환 | 녹음 유지 | MediaRecorder API + 백그라운드 동작 |
| 지원 오디오 포맷 | M4A (AAC) | MediaRecorder 출력을 M4A로 변환하여 사용 |

---

## 5. 기술 스택

| 구분 | 기술 | 선정 이유 |
|------|------|----------|
| **프론트엔드** | React + Vite | CSR 기반 SPA, 정적 파일 배포로 운영 단순화, 빠른 빌드 |
| **백엔드** | Spring Boot (Java) | 안정적인 REST API 구축, 풍부한 생태계 및 레퍼런스 |
| **DB** | MySQL | 정형 데이터 관리에 적합, 운영 안정성 확보 |
| **인프라** | NCP (Naver Cloud Platform) | Load Balancer, Object Storage, 서버 호스팅, 국내 리전 |
| **STT** | OpenAI Whisper API | 한국어 인식 정확도 우수, API 기반으로 별도 인프라 불필요 |
| **LLM** | OpenAI API (GPT-4o mini) | 요약 및 질문 생성에 충분한 성능, 비용 효율적 |
| **인증** | 카카오 로그인 (OAuth 2.0) + JWT | HttpOnly Cookie 기반, stateless로 서버 확장에 유리 |
| **상태 관리** | Zustand | 경량 상태 관리, 간결한 코드 구조 |
| **API 통신** | Axios | 인터셉터 기반 토큰 관리 용이 |
| **알림** | Web Notifications API | 브라우저 기본 알림 지원, 별도 인프라 불필요 |
Loading
Loading