(English description) | (한국어 버전)
NOTE + AI를 의미하는 NOTAI는 대학생을 주 타깃으로 하여
효율적이고 효과적인 강의 학습 및 시험 대비를 도와주는
안드로이드 태블릿에 최적화된 애플리케이션입니다.
1️. 동기화된 강의 자료 3-TYPE
- 한눈에 보이는
- 강의 녹음 → PDF 파일 — 사용자 필기
2️. AI 학습 보조 자료 3-STEP
-
음성 필기
- 강의 녹음 파일을 STT (Speech to Text) 변환
-
AI 요약
- 강의 자료 3가지를 통합한 요약본 제공
-
AI 예상 문제
- 강의 자료 3가지를 통합한 예상 문제 생성
3️. 해결하려는 문제점 및 기대효과
| 문제점 BIG 3 | ➡️ | 기대효과 |
|---|---|---|
| 1. 필기하느라 수업을 놓친 흑우가 있다?! 🐂 | ➡️ | 1. 필기는 AI에게 맡겨요! 강의 집중 UP 📈 |
| 2. 너무 긴 강의내용... 다 못 보게 되는데... 😅 | ➡️ | 2. AI 요약으로 핵심만! 학습 효율 UP 🔝 |
| 3. 이거 시험에는 어떻게 나올지 도저히 모르겠어!! 💢 | ➡️ | 3. AI가 만들어주는 문제로 더 완벽한 시험대비 💯 |
Backend
hynseoj |
rladbrua0207 |
mingjuu |
Shsin9797 |
yunjunghun0116 |
|---|---|---|---|---|
| Backend | Backend | Backend | Backend | Backend |
Frontend (Android)
aengzu |
Kjamm |
|---|---|
| Android | Android |
| 구분 | 링크 | |
|---|---|---|
| 앱 다운로드(원스토어) 링크 | ➡️ | 앱 다운로드 링크 |
| 소개 자료 | ➡️ | 소개 자료 링크 |
| ERD 설계서 | ➡️ | ERD 설계서 링크 |
| Figma 기획 파일 | ➡️ | Figma 기획 파일 링크 |
클린아키텍처 & MVVM & 멀티모듈
- 클린 아키텍처를 통해 비즈니스 로직, 데이터 처리, ui 명확히 분리
- 멀티모듈 구조를 통해 공통 기능을 별도의 모듈로 분리하여 각 부분의 독립성을 높임
- MVVM을 통해 테스트와 유지보수가 용이해짐
- 전체 모듈을 빌드할 필요가 없어 빌드시간을 줄이는데 용이해짐
📦 notai
├───📂app
│ └───📂src
│ └───📂main
│ ├───📂java/com/iguana/notai
│ │ └───📄NotaiApplication.kt
│ └───📂res
│ ├───📂layout
│ └───📂values
│
├───📂build-logic (여러 모듈에서 공통적으로 사용되는 빌드 설정(플러그인 적용, 의존성 관리, 컴파일 옵션 등)을 중앙에서 관리)
│
├───📂core
│ ├───📂data
│ │ ├───📂di (의존성 주입과 관련된 모듈)
│ │ ├───📂local (db 관련 모듈)
│ │ │ ├───📂dao
│ │ │ ├───📂db
│ │ │ ├───📂entity
│ │ │ └───📂files
│ │ ├───📂mapper (데이터 모델 분리 관련 모듈)
│ │ ├───📂remote
│ │ │ |───📂api (API 서비스 인터페이스 정의)
│ │ │ └───📂model (DTO 정의)
│ │ ├───📂repository (domain/repository에서 원격 API, 로컬 db에 대해 제공한 추상화 계층을 구체화)
│ │ └───📂utils (포매팅이나 확장 함수 관련)
│ │
│ ├───📂domain
│ │ ├───📂model (비즈니스 로직에 사용되는 데이터 모델)
│ │ ├───📂repository
│ │ ├───📂usecase (도메인 로직을 처리하는 유스케이스)
│ │ └───📂utils
│ │
│ ├───📂designsystem (앱 전반의 색상, 테마, 폰트 설정)
│ │
│ └───📂ui
│ ├───📄BaseActivity.kt (사이드탭을 포함하는 공통 액티비티)
│ ├───📄SideTabLayoutFragment.kt (사이드탭은 공통적으로 사용되므로 따로 정의하여 재사용)
│ └───📄StatusBarManager.kt
│
└───📂feature (각 기능들을 모듈로 분리)
├───📂ai
├───📂community
├───📂dashBoard
├───📂documents
├───📂favorites
├───📂login
├───📂notetaking
├───📂settings
└───📂userInfo
CQRS 패턴 & Command 패턴
- 데이터 변경과 조회 작업을 분리하여 최적화된 작업 수행 가능
- 추후 데이터 저장소를 분리하여 효율을 높일 수 있음
- presentation 계층과 application 계층의 요청을 분리하여 독립성 보장
- 비즈니스 로직의 확장 및 변경이 유연
📦notai
└── 📁src
├── 📁main
│ ├── 📁java
│ │ └── 📁notai
│ │ ├── 📄BackendApplication.java
│ │ ├── 📁annotation
│ │ ├── 📁auth `사용자 로그인 관련 resolver 와 JWT 컴포넌트`
│ │ ├── 📁client `외부로의 API 요청 처리`
│ │ │ ├── 📄HttpInterfaceUtil.java
│ │ │ ├── 📁ai `AI 서버 API`
│ │ │ ├── 📁oauth `사용자 로그인 관련 OAuth API`
│ │ │ └── 📁slack `백엔드 서버 Slak Webhook`
│ │ ├── 📁comment
│ │ ├── 📁common
│ │ │ ├── 📁config `Swagger, QueryDSL 등의 애플리케이션 설정`
│ │ │ ├── 📁converter `JSON 직렬화/역직렬화 처리`
│ │ │ ├── 📁domain `RootEntity 등 공통 도메인 관련 폴더`
│ │ │ ├── 📁exception `전역 예외 처리`
│ │ │ │ ├── 📄ApplicationException.java
│ │ │ │ ├── 📄ErrorMessages.java
│ │ │ │ ├── 📄ExceptionControllerAdvice.java
│ │ │ │ ├── 📄ExceptionResponse.java
│ │ │ │ └── 📁type
│ │ │ └── 📁utils
│ │ ├── 📁document
│ │ │ ├── 📁application `비즈니스 로직 계층`
│ │ │ │ ├── 📄DocumentQueryService.java `C,U,D 전용 서비스 (CQRS 패턴)`
│ │ │ │ ├── 📄DocumentService.java `Read 전용 서비스 (CQRS 패턴)`
│ │ │ │ └── 📁result `application 계층의 응답 DTO`
│ │ │ │ ├── 📄DocumentFindResult.java
│ │ │ │ ├── 📄DocumentSaveResult.java
│ │ │ │ └── 📄DocumentUpdateResult.java
│ │ │ ├── 📁domain `도메인 모델 계층`
│ │ │ │ ├── 📄Document.java
│ │ │ │ └── 📄DocumentRepository.java `JPA 레포지토리 인터페이스`
│ │ │ ├── 📁presentation `프레젠테이션 계층`
│ │ │ │ ├── 📄DocumentController.java `API 엔드포인트`
│ │ │ │ ├── 📁request `API 요청 DTO`
│ │ │ │ │ ├── 📄DocumentSaveRequest.java
│ │ │ │ │ └── 📄DocumentUpdateRequest.java
│ │ │ │ └── 📁response `API 응답 DTO`
│ │ │ │ ├── 📄DocumentFindResponse.java
│ │ │ │ ├── 📄DocumentSaveResponse.java
│ │ │ │ └── 📄DocumentUpdateResponse.java
│ │ │ └── 📁query `조회 전용 쿼리 레포지토리 (CQRS 패턴)`
│ │ │ ├── 📄DocumentQueryRepository.java
│ │ │ └── 📄DocumentQueryRepositoryImpl.java
│ │ ├── 📁folder
│ │ ├── 📁llm
│ │ ├── 📁member
│ │ ├── 📁ocr
│ │ ├── 📁pageRecording
│ │ ├── 📁pdf
│ │ ├── 📁post
│ │ ├── 📁problem
│ │ ├── 📁recording
│ │ ├── 📁stt
│ │ ├── 📁sttTask
│ │ └── 📁summary
│ └── 📁resources
│ ├── 📄application-local.yml
│ └── 📄application.yml
└── 📁test
└── 📁java
└── 📁notai
├── 📄BackendApplicationTests.java
├── 📁annotation
├── 📁client
├── 📁folder
├── 📁llm
├── 📁ocr
├── 📁pageRecording
├── 📁recording
└── 📁stt
회원 API
| 기능 | URL | Method | Status | 설명 |
|---|---|---|---|---|
| 카카오 로그인 | /api/members/oauth/login/{oauthProvider} |
POST | 완료 | |
| 토큰 리프레쉬 | /api/members/token/refresh |
POST | 완료 | |
| 본인 프로필 조회 | /api/members/me |
GET | 완료 |
Document API
| 기능 | URL | Method | Status | 설명 |
|---|---|---|---|---|
| 폴더에 Document 업로드 | /api/folders/{folderId}/document |
POST | 완료 | |
| 폴더의 목록 조회 | /api/folders/{folderId} |
GET | 완료 | |
| 여러 Document 조회 | /api/folders/{folderId}/documents |
GET | 완료 | |
| Document 상세 조회 | /api/folders/{folderId}/documents/{documentId} |
GET | 완료 | |
| Document 수정 | /api/folders/{folderId}/documents/{documentId} |
PUT | 완료 | |
| Document 삭제 | /api/folders/{folderId}/documents/{documentId} |
DELETE | 완료 | |
| 폴더 생성 | /api/folders |
POST | 완료 | |
| 폴더 조회 | /api/folders?parentFolderId={parentFolderId} |
GET | 완료 | |
| 폴더 삭제 | /api/folders/{folderId} |
DELETE | 완료 | |
| 속해있는 폴더 변경(위치변경) | /api/folders/{folderId}/move |
POST | 완료 |
Annotation API
| 기능 | URL | Method | Status | 설명 |
|---|---|---|---|---|
| 주석 추가 | /api/documents/{documentId}/annotations |
POST | 완료 | |
| 주석 목록 조회 | /api/documents/{documentId}/annotations |
GET | 완료 | |
| 주석 수정 | /api/documents/{documentId}/annotations/{annotationId} |
PUT | 완료 | |
| 주석 삭제 | /api/documents/{documentId}/annotations/{annotationId} |
DELETE | 완료 |
Record API
| 기능 | URL | Method | Status | 설명 |
|---|---|---|---|---|
| 페이지 넘김 이벤트 | /api/documents/{documentId}/recordings/page-turns |
POST | 완료 | |
| 녹음 파일 업로드 | /api/documents/{documentId}/recordings |
POST | 완료 | |
| STT 결과 업로드 X (서버에서 처리) | /api/documents/{documentId}/recordings/{recordingId}/stt-results |
POST | 완료 |
Summarize API
| 기능 | URL | Method | Status | 설명 |
|---|---|---|---|---|
| STT결과 | /api/ai/ |
POST | 완료 | |
| 요약 정리 및 문제생성 (client → server) | /api/ai/llm |
POST | 완료 | |
| OCR (server → AI server) | /api/ai/ocr |
POST | 시작 전 | |
| 요약 정리 및 문제생성 결과 전달 (AI server → server) | /api/ai/llm/callback |
POST | 완료 | 요약정리 페이지별로 완성될 때마다 AI서버에서 웹서버로 내용을 전달하는 API |
| 요약 정리 및 문제생성 상태 확인 (client → server) | /api/ai/llm/status/{documentId} |
GET | 완료 | |
| 페이지별 요약 정리 및 문제생성 상태 확인 (client → server) | /api/ai/llm/status/{documentId}/{pageNumber} |
GET | 완료 | |
| 생성된 요약 정리 결과 조회 (client → server) | /api/ai/llm/results/{documentId} |
GET | 완료 | |
| 페이지별 생성된 요약 정리 및 문제 조회 (client → server) | /api/ai/llm/results/{documentId}/{pageNumber} |
GET | 완료 | |
| task 상태 확인 | /api/ai/tasks/{taskId} |
GET | 완료 | 우선은 존재하지 않는 task로 요청하더라도 PENDING입니다 |
- Kotlin: 안드로이드 클라이언트 개발
- Spring Boot: 백엔드 애플리케이션 개발
- MySQL: 데이터베이스 관리
- NGINX: 리버스 프록시 및 로드 밸런싱
- Docker: 컨테이너화 및 마이크로서비스 관리
- Flask: AI 서버용 경량 웹 프레임워크
- PyTorch: 딥러닝 프레임워크
- Tesseract OCR: PDF 텍스트 추출
- OpenAI Whisper: 음성 인식 및 STT
- GitHub Actions: CI/CD 자동화
- Kotlin 안드로이드 앱
- Docker 컨테이너 환경
- NGINX → Spring Boot 서버
- 주요 기능
- REST API 제공
- MySQL DB 관리
- 사용자 관리: Kakao OAuth 기반 인증
- PDF/음성 파일 관리
- 실시간 필기 처리
- 폴더/문서 구조화
- 녹음/STT 관리:
- 페이지 전환 이벤트 기반 녹음 구간 태깅
- 페이지별 STT 결과 매핑
- OCR 처리: Tesseract 기반 비동기 OCR
- STT 처리:
- Whisper 모델 활용
- 워커당 30% GPU VRAM 제한으로 3개 병렬 처리
- 음성 전처리 (노이즈 제거, 정규화)
- LLM 처리:
- OpenAI API 통합
- 강의 요약 및 시험문제 생성
- 작업 관리:
- Celery + Redis 기반 비동기 큐
- GitHub Actions 자동화
주안점을 두고 개발한 기능
- 멀티모듈구조 : 협업 역량을 최대화 하기 위해 멀티 모듈 구조를 선택했으며, 기능을 연결되게 개발해야 본인 코드에 대한 이해도가 높아진다 생각해 노트 필기 화면을 들어가기 전/후로 나누어 개발을 진행함
- 클린아키텍처+mvvm
- STT(Speech To Text) 조회 기능 : 안드로이드 시장에는 제대로된 노트앱 + 녹음 변환 기능을 제공해주는 곳이 없어 집중적으로 개발함.
- 페이지 이동 이벤트 : 페이지 단위로 ocr과 녹음 싱크를 합쳐 제대로 된 요약을 제공해주기 위해 개발
- AI 서버와 연결 : 결국 대부분의 핵심 기능들은 AI를 통해 진행되기 때문에 서버와 안정적으로 연결되도록 개발
주안점을 두고 개발한 기능
- STT 결과 매칭 알고리즘 사용자가 PDF 페이지를 넘길 때마다 기록되는 타임스탬프와 STT 결과의 단어별 타임스탬프를 비교하여 해당 페이지에서 발화된 내용을 자동으로 분류합니다.
- AI 기반 학습 자료 생성 각 페이지마다 문서 OCR 텍스트, 강의 음성의 STT 결과, 사용자 필기 데이터를 통합적으로 분석합니다. 이 데이터를 AI 모델에 전달하여 페이지별 맥락을 고려한 요약본과 예상 시험 문제를 생성합니다. 세 가지 데이터를 통합 분석함으로써 실제 학습 컨텍스트를 반영한 학습 자료를 제공합니다.
강의 녹음 및 필기
- 사용자가 PDF 문서 업로드
- 페이지 전환시마다 타임스탬프 기록
- 녹음 파일 생성 및 업로드
- AI 서버에서 음성-텍스트 변환
- STT 결과의 단어별 타임스탬프와 페이지 전환 타임스탬프 매칭
- 페이지별 음성 텍스트 데이터 분류
AI 기반 요약본 및 시험 문제 생성
- OCR로 PDF 텍스트 추출
- STT로 변환된 강의 음성
- 사용자 필기 데이터 수집
- 위 3가지 데이터 통합 처리
- OpenAI API 기반 요약본 생성 및 예상 시험 문제 생성
💡 Note: AI 관련 구현의 상세 코드는 AI 서버 레포지토리에서 확인할 수 있습니다.
NOTAI (short for NOTE + AI) is an Android tablet-optimized application primarily targeting university students, designed to support efficient and effective lecture learning and exam preparation.
1. Three Types of Synchronized Lecture Materials
- At a glance
- Lecture recording → PDF file → User notes
Tired of scattered lecture materials? With content organized in sync with the lecture flow, studying becomes much more convenient!
2. Three-Step AI Learning Assistance
-
Voice notes
- Converts lecture recordings into STT (Speech-to-Text)
-
AI Summary
- Provides a unified summary integrating all three lecture resources
-
AI Practice Questions
- Generates expected exam questions from the integrated lecture data
3. Problems We Aim to Solve & Expected Outcomes
| Problems (BIG 3) | ➡️ | Expected Effects |
|---|---|---|
| 1. Missing content while taking notes 🐂 | ➡️ | 1. Let AI handle the notes! Focus on lectures UP 📈 |
| 2. Long lecture content that’s hard to review 😅 | ➡️ | 2. AI summary highlights only the essentials! Study efficiency UP 🔝 |
| 3. No idea what might show up on the exam 💢 | ➡️ | 3. AI-generated practice questions for better exam prep 💯 |
Clean Architecture & MVVM & Multi-Module
- Separate business logic, data processing, and UI clearly through Clean Architecture
- Improve modular independence by separating common features into individual modules with a multi-module structure
- Make testing and maintenance easier with MVVM
- Reduce build time since there is no need to build all modules at once
📦 notai
├───📂app
│ └───📂src
│ └───📂main
│ ├───📂java/com/iguana/notai
│ │ └───📄NotaiApplication.kt
│ └───📂res
│ ├───📂layout
│ └───📂values
│
├───📂build-logic (Centralized management for build settings commonly used across multiple modules, such as plugin application, dependency management, and compile options)
│
├───📂core
│ ├───📂data
│ │ ├───📂di (Modules related to dependency injection)
│ │ ├───📂local (Modules related to database)
│ │ │ ├───📂dao
│ │ │ ├───📂db
│ │ │ ├───📂entity
│ │ │ └───📂files
│ │ ├───📂mapper (Modules related to separating data models)
│ │ ├───📂remote
│ │ │ |───📂api (Defines API service interfaces)
│ │ │ └───📂model (Defines DTOs)
│ │ ├───📂repository (Implements abstractions provided in domain/repository for remote API and local DB)
│ │ └───📂utils (Formatting or extension function utilities)
│ │
│ ├───📂domain
│ │ ├───📂model (Data models used in business logic)
│ │ ├───📂repository
│ │ ├───📂usecase (Use cases handling domain logic)
│ │ └───📂utils
│ │
│ ├───📂designsystem (App-wide settings for colors, themes, and fonts)
│ │
│ └───📂ui
│ ├───📄BaseActivity.kt (Common activity including the side tab)
│ ├───📄SideTabLayoutFragment.kt (Side tab is commonly used, so it is separately defined for reusability)
│ └───📄StatusBarManager.kt
│
└───📂feature (Each feature separated into individual modules)
├───📂ai
├───📂community
├───📂dashBoard
├───📂documents
├───📂favorites
├───📂login
├───📂notetaking
├───📂settings
└───📂userInfo
CQRS Pattern & Command Pattern
- Separate data modification and query operations for optimized performance
- Improve efficiency by allowing future separation of data storage
- Guarantee independence by separating requests between the presentation layer and the application layer
- Enable flexible expansion and modification of business logic
📦notai
└── 📁src
├── 📁main
│ ├── 📁java
│ │ └── 📁notai
│ │ ├── 📄BackendApplication.java
│ │ ├── 📁annotation
│ │ ├── 📁auth `Resolver and JWT components for user login`
│ │ ├── 📁client `Handles external API requests`
│ │ │ ├── 📄HttpInterfaceUtil.java
│ │ │ ├── 📁ai `AI server API`
│ │ │ ├── 📁oauth `OAuth API for user login`
│ │ │ └── 📁slack `Backend server Slack Webhook`
│ │ ├── 📁comment
│ │ ├── 📁common
│ │ │ ├── 📁config `Application settings such as Swagger, QueryDSL`
│ │ │ ├── 📁converter `JSON serialization/deserialization`
│ │ │ ├── 📁domain `Common domain folder including RootEntity`
│ │ │ ├── 📁exception `Global exception handling`
│ │ │ │ ├── 📄ApplicationException.java
│ │ │ │ ├── 📄ErrorMessages.java
│ │ │ │ ├── 📄ExceptionControllerAdvice.java
│ │ │ │ ├── 📄ExceptionResponse.java
│ │ │ │ └── 📁type
│ │ │ └── 📁utils
│ │ ├── 📁document
│ │ │ ├── 📁application `Business logic layer`
│ │ │ │ ├── 📄DocumentQueryService.java `Service for C,U,D operations (CQRS pattern)`
│ │ │ │ ├── 📄DocumentService.java `Read-only service (CQRS pattern)`
│ │ │ │ └── 📁result `Response DTOs in the application layer`
│ │ │ │ ├── 📄DocumentFindResult.java
│ │ │ │ ├── 📄DocumentSaveResult.java
│ │ │ │ └── 📄DocumentUpdateResult.java
│ │ │ ├── 📁domain `Domain model layer`
│ │ │ │ ├── 📄Document.java
│ │ │ │ └── 📄DocumentRepository.java `JPA repository interface`
│ │ │ ├── 📁presentation `Presentation layer`
│ │ │ │ ├── 📄DocumentController.java `API endpoint`
│ │ │ │ ├── 📁request `API request DTO`
│ │ │ │ │ ├── 📄DocumentSaveRequest.java
│ │ │ │ │ └── 📄DocumentUpdateRequest.java
│ │ │ │ └── 📁response `API response DTO`
│ │ │ │ ├── 📄DocumentFindResponse.java
│ │ │ │ ├── 📄DocumentSaveResponse.java
│ │ │ │ └── 📄DocumentUpdateResponse.java
│ │ │ └── 📁query `Query repository for read-only operations (CQRS pattern)`
│ │ │ ├── 📄DocumentQueryRepository.java
│ │ │ └── 📄DocumentQueryRepositoryImpl.java
│ │ ├── 📁folder
│ │ ├── 📁llm
│ │ ├── 📁member
│ │ ├── 📁ocr
│ │ ├── 📁pageRecording
│ │ ├── 📁pdf
│ │ ├── 📁post
│ │ ├── 📁problem
│ │ ├── 📁recording
│ │ ├── 📁stt
│ │ ├── 📁sttTask
│ │ └── 📁summary
│ └── 📁resources
│ ├── 📄application-local.yml
│ └── 📄application.yml
└── 📁test
└── 📁java
└── 📁notai
├── 📄BackendApplicationTests.java
├── 📁annotation
├── 📁client
├── 📁folder
├── 📁llm
├── 📁ocr
├── 📁pageRecording
├── 📁recording
└── 📁stt
Member API
| Feature | URL | Method | Status | Description |
|---|---|---|---|---|
| Kakao Login | /api/members/oauth/login/{oauthProvider} |
POST | Done | |
| Token Refresh | /api/members/token/refresh |
POST | Done | |
| Get My Profile | /api/members/me |
GET | Done |
Document API
| Feature | URL | Method | Status | Description |
|---|---|---|---|---|
| Upload Document to Folder | /api/folders/{folderId}/document |
POST | Done | |
| Get Folder Details | /api/folders/{folderId} |
GET | Done | |
| Get Multiple Documents | /api/folders/{folderId}/documents |
GET | Done | |
| Get Document Details | /api/folders/{folderId}/documents/{documentId} |
GET | Done | |
| Update Document | /api/folders/{folderId}/documents/{documentId} |
PUT | Done | |
| Delete Document | /api/folders/{folderId}/documents/{documentId} |
DELETE | Done | |
| Create Folder | /api/folders |
POST | Done | |
| Get Folders | /api/folders?parentFolderId={parentFolderId} |
GET | Done | |
| Delete Folder | /api/folders/{folderId} |
DELETE | Done | |
| Move Folder (Change Path) | /api/folders/{folderId}/move |
POST | Done |
Annotation API
| Feature | URL | Method | Status | Description |
|---|---|---|---|---|
| Add Annotation | /api/documents/{documentId}/annotations |
POST | Done | |
| Get Annotations | /api/documents/{documentId}/annotations |
GET | Done | |
| Update Annotation | /api/documents/{documentId}/annotations/{annotationId} |
PUT | Done | |
| Delete Annotation | /api/documents/{documentId}/annotations/{annotationId} |
DELETE | Done |
Record API
| Feature | URL | Method | Status | Description |
|---|---|---|---|---|
| Page-Turn Event | /api/documents/{documentId}/recordings/page-turns |
POST | Done | |
| Upload Recording | /api/documents/{documentId}/recordings |
POST | Done | |
| Upload STT Result (Processed on server) | /api/documents/{documentId}/recordings/{recordingId}/stt-results |
POST | Done |
Summarize API
| Feature | URL | Method | Status | Description |
|---|---|---|---|---|
| STT Result | /api/ai/ |
POST | Done | |
| Summarization & Question Generation (client → server) | /api/ai/llm |
POST | Done | |
| OCR (server → AI server) | /api/ai/ocr |
POST | Not started | |
| Summarization & Question Result Delivery (AI server → server) | /api/ai/llm/callback |
POST | Done | The AI server sends results to the web server as soon as each page’s summarization is completed |
| Check Summarization/Question Status (client → server) | /api/ai/llm/status/{documentId} |
GET | Done | |
| Check Summarization/Question Status by Page (client → server) | /api/ai/llm/status/{documentId}/{pageNumber} |
GET | Done | |
| Get Summarization Results (client → server) | /api/ai/llm/results/{documentId} |
GET | Done | |
| Get Summarization & Questions by Page (client → server) | /api/ai/llm/results/{documentId}/{pageNumber} |
GET | Done | |
| Check Task Status | /api/ai/tasks/{taskId} |
GET | Done | Even if a non-existent task is requested, the response will be PENDING for now |
- Kotlin: Android client development
- Spring Boot: Backend application development
- MySQL: Database management
- NGINX: Reverse proxy & load balancing
- Docker: Containerization & microservice management
- Flask: Lightweight web framework for AI server
- PyTorch: Deep learning framework
- Tesseract OCR: PDF text extraction
- OpenAI Whisper: Speech recognition & STT
- GitHub Actions: CI/CD automation
- Kotlin Android app
- Docker containerized environment
- NGINX → Spring Boot server
- Main Functions
- Provide REST API
- Manage MySQL DB
- User management: Kakao OAuth authentication
- PDF/audio file management
- Real-time note-taking
- Folder/document structuring
- Recording/STT management:
- Page-turn event–based recording segmentation
- Mapping STT results to each page
- OCR processing: asynchronous Tesseract-based OCR
- STT Processing:
- Uses Whisper model
- Limited to 30% GPU VRAM per worker, supports 3 parallel workers
- Audio preprocessing (noise reduction, normalization)
- LLM Processing:
- Integrated with OpenAI API
- Generates lecture summaries and exam questions
- Task Management:
- Celery + Redis for asynchronous queue
- Automated with GitHub Actions
Key Features Developed
- Multi-Module Architecture: Chosen to maximize collaboration efficiency. We believed that connecting features across modules would deepen our understanding of the code. Therefore, we split development into before/after entering the note-taking screen.
- Clean Architecture + MVVM
- STT (Speech-To-Text) Retrieval: Since the Android market lacks a proper note-taking app that integrates voice-to-text conversion, we focused heavily on developing this feature.
- Page-Turn Event Handling: Developed to combine OCR and audio sync at the page level, enabling accurate summarization.
- AI Server Integration: As most core features rely on AI, stable communication with the server was emphasized.
Key Features Developed
-
STT Result Matching Algorithm
When the user flips through PDF pages, timestamps are recorded. These timestamps are compared with word-level timestamps from STT results to automatically classify spoken content by page. -
AI-Based Study Material Generation
For each page, the system integrates document OCR text, STT results from lecture audio, and user notes. This combined dataset is sent to the AI model to generate context-aware summaries and predicted exam questions. By analyzing these three sources together, the study materials better reflect the actual learning context.
Lecture Recording and Note-Taking
- User uploads a PDF document
- Timestamps are recorded each time a page is turned
- Recording file is created and uploaded
- AI server converts audio to text
- Word-level STT timestamps are matched with page-turn timestamps
- Audio text is classified by page
AI-Based Summaries and Exam Questions
- Extract text from PDF via OCR
- Convert lecture audio to text using STT
- Collect user notes
- Integrate the three datasets for processing
- Generate summaries and predicted exam questions via OpenAI API
💡 Note: Detailed implementations related to AI can be found in the AI Server Repository.













