Skip to content
Merged
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
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Ling Level Spring API

## 프로젝트 소개

Ling Level API는 학습 콘텐츠, 단어 학습, 스트릭, 추천, 알림 기능을 포함하는 Spring Boot 기반 백엔드 서버입니다.

이 프로젝트는 단순 기능 구현용 저장소가 아니라, 구조 개선, 성능 최적화, 안정성 강화, 의사결정 기록을 함께 관리하는 운영형 API 프로젝트를 목표로 합니다.

## 문서

- [프로젝트 문서 허브](docs/README.md)
- [아키텍처 문서 모음](docs/architecture/)
- [의사결정 기록 모음](docs/decisions/)

## 사전 요구사항

- JDK 17
Expand Down Expand Up @@ -40,4 +52,4 @@ docker-compose -f monitoring/docker-compose.monitoring-prod.yml up -d
# 접속 정보
# Prometheus: http://localhost:9090
# Grafana: http://localhost:3000 (admin/admin123 또는 환경변수)
```
```
22 changes: 22 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Project Documentation

이 디렉터리는 프로젝트 구조와 주요 의사결정을 정리하는 문서 허브이자, 기술 블로그에 가까운 기록을 모으는 공간이다.

## 문서 구성

- [아키텍처 문서 모음](architecture/)
- [의사결정 기록 모음](decisions/)
- [템플릿 모음](templates/)

## 언제 무엇을 쓰는가

- 현재 구조, 도메인 관계, 대표 흐름을 정리할 때: [architecture](architecture/)
- 구조, 성능, 안정성, 테스트 전략에 영향을 주는 큰 결정을 남길 때: [decisions](decisions/)
- 새 문서를 시작할 때: [templates](templates/)

## 기본 원칙

- 문서는 길게 쓰기보다 빠르게 읽히는 수준으로 유지한다.
- 자잘한 구현 선택보다 구조와 판단이 드러나는 내용만 기록한다.
- 같은 설명을 여러 문서에 반복하지 않고, 허브에서는 링크 중심으로 정리한다.
- 단순 변경 내역보다 문제 인식, 선택 이유, 결과와 남은 이슈가 드러나도록 정리한다.
28 changes: 28 additions & 0 deletions docs/architecture/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Architecture Documents

이 디렉터리는 프로젝트의 구조와 핵심 흐름을 정리하는 문서 모음이다.

## 포함 대상

- 시스템 개요
- 도메인 관계
- 대표 요청 흐름
- 상태 전이
- 외부 시스템 연결 구조

## 작성 기준

- 클래스 전체 나열보다 도메인과 흐름을 우선 정리한다.
- Mermaid 다이어그램은 핵심 구조와 흐름만 표현한다.
- 문서는 실제 리팩터링과 성능 개선 판단에 도움이 되는 수준으로 유지한다.

## 템플릿

- [아키텍처 템플릿](../templates/architecture-template.md)

## 현재 문서

- [프로젝트 전체 구조 개요](overview.md)
- [Streak 도메인 구조](streak.md)
- [Word 도메인 구조](word.md)
- [Book 도메인 구조](content-book.md)
120 changes: 120 additions & 0 deletions docs/architecture/content-book.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Book 도메인 구조

## 목적

이 문서는 책 콘텐츠 도메인이 조회, 진행도, import, 이미지 처리를 어떻게 함께 다루는지 설명한다.

## 범위

- `BookService`
- `ChapterService`
- `ProgressService`
- 책 import 및 이미지 처리

## 핵심 구성 요소

- `BooksController`, `BooksProgressController`
- `BookService`
- `ChapterService`
- `ProgressService`
- `BookRepository`, `ChapterRepository`, `ChunkRepository`, `BookProgressRepository`

## 구조 요약

Book 도메인은 사용자에게 보이는 조회 API와 운영성 있는 import 파이프라인이 함께 들어 있는 구조다.
책 기본 정보와 챕터/청크는 MongoDB에 저장되고, import 시에는 AI 결과 파일 다운로드, 이미지 이동, 썸네일 생성이 같이 수행된다.
사용자 진행도는 책 단위가 아니라 챕터와 청크를 기반으로 계산되며, 읽기 완료는 스트릭 갱신으로 이어진다.

## Mermaid 다이어그램

### 구조 관계

```mermaid
flowchart TD
Client[Client]
Admin[Admin Import]
BooksController[BooksController]
ProgressController[BooksProgressController]
BookService[BookService]
ChapterService[ChapterService]
ProgressService[ProgressService]
Mongo[(MongoDB)]
S3[(S3 / R2)]
Streak[StreakService]

Client --> BooksController
Client --> ProgressController
Admin --> BooksController

BooksController --> BookService
BooksController --> ChapterService
ProgressController --> ProgressService

BookService --> Mongo
ChapterService --> Mongo
ProgressService --> Mongo

BookService --> S3
ProgressService --> Streak
```

### 대표 흐름: 진행도 업데이트와 스트릭 연결

```mermaid
sequenceDiagram
participant Client
participant ProgressService
participant ChunkRepo
participant ChapterRepo
participant BookProgressRepo
participant StreakService
participant Mongo

Client->>ProgressService: updateProgress(bookId, chunkId)
ProgressService->>ChunkRepo: load chunk
ProgressService->>ChapterRepo: resolve chapter
ProgressService->>BookProgressRepo: load or create progress
ProgressService->>Mongo: update chapter progress / normalized progress
alt last chunk in chapter
ProgressService->>StreakService: updateStreak(...)
end
ProgressService-->>Client: ProgressResponse
```

## 주요 흐름 설명

1. `BookService`는 책 조회와 import를 함께 담당한다.
2. 조회 시에는 사용자 진행도를 합쳐 `BookResponse`를 만들고, import 시에는 AI 결과 파일 다운로드와 이미지 후처리까지 수행한다.
3. `ChapterService`는 챕터 목록 조회와 탐색을 맡고, 챕터별 청크 수와 사용자 진행도를 조합해 응답을 만든다.
4. `ProgressService`는 청크 단위 요청을 챕터 단위 진행도와 책 완료 상태로 변환하고, 마지막 청크를 읽은 경우 `StreakService`를 호출한다.

## 핵심 데이터

- `Book`
- 책 메타데이터, 표지 이미지, 난이도, 챕터 수
- `Chapter`
- 챕터 번호, 설명, 읽기 시간
- `Chunk`
- 난이도별 세부 텍스트 조각
- `BookProgress`
- 사용자별 현재 청크, 챕터별 진행도, 완료 여부

## 이 도메인의 특징

- 조회 응답이 단순 조회가 아니라 사용자 진행도와 이미지 URL 조합을 포함한다.
- import와 조회가 가까운 서비스에 있어 운영 기능과 사용자 API가 한 도메인 아래 모여 있다.
- 챕터 완료 판단은 청크 수 기준으로 계산되고, 책 완료 여부는 챕터 진행도 배열을 기반으로 계산된다.

## 개선 포인트

- `BookService`는 import, 이미지 처리, 조회 응답 조립이 함께 있어 책임 분리가 가능하다.
- `ProgressService`는 검증, 진행도 계산, 읽기 완료 처리, 스트릭 연계를 한 번에 수행한다.
- `ChapterService`는 조회 응답 조립과 view count 증가, backward compatibility 로직이 같이 들어 있다.

## 참고 코드

- `src/main/java/com/linglevel/api/content/book/service/BookService.java`
- `src/main/java/com/linglevel/api/content/book/service/ChapterService.java`
- `src/main/java/com/linglevel/api/content/book/service/ProgressService.java`
- `src/main/java/com/linglevel/api/content/book/entity/Book.java`
- `src/main/java/com/linglevel/api/content/book/entity/BookProgress.java`
134 changes: 134 additions & 0 deletions docs/architecture/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# 프로젝트 전체 구조 개요

## 목적

이 문서는 `llv-api`의 상위 구조를 한 장으로 설명하기 위한 문서다.
세부 구현보다 어떤 도메인이 핵심이고, 어떤 저장소와 외부 시스템이 붙어 있는지 빠르게 파악하는 데 초점을 둔다.

## 범위

- 주요 사용자 요청 경로
- 핵심 도메인 묶음
- 공통 인프라와 외부 시스템
- 우선 문서화 대상 도메인

## 핵심 구성 요소

- API 진입점: `controller`
- 핵심 도메인: `streak`, `word`, `content/book`
- 보조 도메인: `content/recommendation`, `fcm`, `crawling`
- 공통 인프라: MongoDB, Redis, S3/R2, Spring AI, FCM

## 구조 요약

이 프로젝트는 하나의 Spring Boot 애플리케이션 안에 학습 콘텐츠, 단어 분석, 스트릭, 추천, 알림, 크롤링, 파일 처리 기능을 함께 두고 있다.
데이터 저장은 MongoDB를 중심으로 하고, Redis는 읽기 세션과 rate limit 같은 짧은 상태 관리에 사용한다.
외부 연동은 AI 모델, FCM, S3/R2, 크롤링 대상 사이트가 중심이며, 도메인 서비스가 이 인프라를 직접 조합하는 구조가 많다.

## Mermaid 다이어그램

```mermaid
flowchart TD
Client[Client App]
Admin[Admin]
Api[Spring Boot API]

Streak[Streak Domain]
Word[Word Domain]
Book[Book Domain]
Recommend[Recommendation / Notification]
Crawl[Crawling / Feed]

Mongo[(MongoDB)]
Redis[(Redis)]
S3[(S3 / R2)]
AI[AI Model]
FCM[Firebase Cloud Messaging]
External[External Content Sites]

Client --> Api
Admin --> Api

Api --> Streak
Api --> Word
Api --> Book
Api --> Recommend
Api --> Crawl

Streak --> Mongo
Streak --> Redis
Streak --> FCM

Word --> Mongo
Word --> AI

Book --> Mongo
Book --> S3
Book --> Streak

Recommend --> Mongo
Recommend --> FCM

Crawl --> Mongo
Crawl --> External
```

## 주요 흐름 설명

1. `book`, `word`, `streak` 요청은 각각 전용 서비스로 들어가지만, 실제 사용자 학습 흐름에서는 서로 연결된다.
2. `content/book`의 읽기 완료는 `streak` 갱신과 이어지고, 읽기 로그는 `content/recommendation`에서 선호도 집계에 사용된다.
3. `word`는 MongoDB 캐시와 AI 호출을 조합해 결과를 만들고, `streak`는 Redis 읽기 세션과 MongoDB 리포트를 함께 사용한다.
4. `crawling`과 `feed`는 외부 사이트 구조 변화에 영향을 많이 받는 별도 리스크 영역이다.

## 핵심 도메인

### `streak`

- 사용자 학습 연속성, 프리즈, 보상, 알림을 담당한다.
- Redis 기반 읽기 세션과 MongoDB 기반 누적 리포트를 함께 사용한다.
- 스케줄러와 알림이 얽혀 있어 구조적으로 가장 복잡한 영역 중 하나다.

### `word`

- 단어 조회, 원형/변형 매핑, AI 분석, 유효하지 않은 단어 차단을 담당한다.
- 캐시와 AI 호출, 응답 검증이 한 흐름에 들어가 있어 비용과 안정성 측면에서 중요하다.

### `content/book`

- 책 조회, 챕터/청크, 진행도, 이미지 처리, 가져오기(import)까지 맡는다.
- 조회 성능과 진행도 계산, 다른 도메인과의 연결 지점이 함께 모여 있다.

## 공통 인프라

### MongoDB

- 주요 도메인 엔티티와 로그, 추천 데이터를 저장한다.
- 도메인 서비스는 Mongo 문서 구조를 직접 전제로 동작하는 경우가 많다.

### Redis

- `streak` 읽기 세션과 `common/ratelimit` 같은 짧은 상태 관리에 사용된다.

### S3 / R2

- 책 이미지와 AI 생성 결과 파일 처리를 담당한다.
- `content/book`는 import 이후 이미지 이동과 썸네일 생성까지 이어진다.

### AI / FCM / External Sites

- AI는 `word` 분석의 핵심 의존성이다.
- FCM은 `streak`, `notification` 쪽에서 사용된다.
- 외부 사이트는 `crawling`, `feed` 영역의 가장 큰 불안정 요소다.

## 현재 문서화 우선순위

- [Streak 도메인 구조](streak.md)
- [Word 도메인 구조](word.md)
- [Book 도메인 구조](content-book.md)

## 개선 포인트

- `streak`는 상태 계산, 보상, 통계, 알림 관련 책임이 큰 서비스에 집중돼 있다.
- `word`는 캐시 정책과 AI 실패 처리, 응답 검증이 서비스 흐름 안에 함께 들어가 있다.
- `content/book`는 조회, import, 이미지 처리, 진행도 계산이 서로 가까이 있어 변경 영향 범위가 넓다.
- 외부 의존성이 큰 `crawling`, `feed`는 이후 안정성 문서에서 별도로 다루는 편이 맞다.
Loading
Loading