Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e4990ed
docs: add mongodb logical erd
SolfE Mar 30, 2026
0e0214a
Track k6 scripts and seed scaffolding
SolfE Mar 31, 2026
25395d4
Refine k6 README overview
SolfE Mar 31, 2026
c88fc48
Add book progress to k6 book seed
SolfE Mar 31, 2026
0759699
Refactor k6 scripts around load profiles
SolfE Mar 31, 2026
7fa2e2a
Simplify architecture mini-map docs
SolfE Apr 1, 2026
767ac3d
Rename context diagram terminology
SolfE Apr 1, 2026
934f3a5
Align domain docs with mini-map structure
SolfE Apr 2, 2026
7ad6bcc
test: add BookImportService coverage
SolfE Apr 6, 2026
1dab896
test: add BookReadingTimeService coverage
SolfE Apr 6, 2026
502aeb9
test: add ChunkService coverage
SolfE Apr 7, 2026
aae6e96
test: add importBook service coverage
SolfE Apr 7, 2026
bd93ed0
test: add book progress and repository coverage
SolfE Apr 7, 2026
0b39a29
test: cover book service edge cases
SolfE Apr 7, 2026
c6d531b
fix: correct k6 book response validation and ids
SolfE Apr 7, 2026
28d4723
chore: align monitoring stack and simplify k6 setup
SolfE Apr 7, 2026
d00422d
docs: add glossary and concise decision log to architecture docs
SolfE Apr 8, 2026
0ce9478
docs(book): define chapter-first progress ordering invariant
SolfE Apr 8, 2026
5f4ea73
fix(book-progress): initialize normalized progress from chapter-compl…
SolfE Apr 8, 2026
ed4a259
fix(book-progress): return zero-state on missing progress without write
SolfE Apr 8, 2026
9875b04
fix(book-progress): unify book status filtering with normalized progress
SolfE Apr 8, 2026
88efe7d
feat(book-progress): implement chapter-first maxReadChunkNumber tracking
SolfE Apr 11, 2026
8965c63
fix(book-progress): use normalized progress as single source in book …
SolfE Apr 21, 2026
5a6bbbc
refactor(book): remove legacy chapter progress fallback
SolfE Apr 22, 2026
2372325
refactor(book): batch-fetch progress for getBooks
SolfE Apr 24, 2026
a1b9ba6
feat(k6): add local-k6 profile to disable rate limiting
SolfE Apr 24, 2026
f98478d
fix(book): classify partial reads as in-progress and align seed chunk…
SolfE Apr 24, 2026
4e279b6
test(feed): skip external RSS integration tests in CI
SolfE Apr 24, 2026
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
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,4 @@ monitoring/prometheus-*.yml
monitoring/alertmanager.yml

### K6 data ###
k6/data/**
k6/reports/**
k6/scripts/**
31 changes: 13 additions & 18 deletions docs/architecture/README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
# Architecture Documents

이 디렉터리는 프로젝트의 구조와 핵심 흐름을 정리하는 문서 모음이다.
이 디렉터리는 리팩터링이나 성능 개선 전에 빠르게 구조를 파악하기 위한 미니맵 문서 모음이다.

## 포함 대상
## 문서 원칙

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

## 작성 기준

- 클래스 전체 나열보다 도메인과 흐름을 우선 정리한다.
- Mermaid 다이어그램은 핵심 구조와 흐름만 표현한다.
- 문서는 실제 리팩터링과 성능 개선 판단에 도움이 되는 수준으로 유지한다.
- 구현 상세보다 “어디가 핵심이고 어디가 위험한지”가 먼저 보이게 적는다.
- 목적은 현재 구조를 빠르게 이해하는 것이다.
- 문서는 책임, 외부 의존성, 핵심 기능 흐름만 남긴다.
- 도메인별로 `핵심 용어 사전(용어/정의)`을 유지해 의미 흔들림을 줄인다.
- 도메인 의미에 영향을 주는 선택은 `간결 의사결정 기록`에 누적한다.
- 핵심 기능은 중요도와 이해 난이도를 기준으로 2~3개만 고른다.
- 도메인 내부 구현 상세나 세부 설계 판단은 `MISSIONS.md` 또는 `docs/decisions`에서 다룬다.

## 템플릿

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

## 현재 문서

- [프로젝트 전체 구조 개요](overview.md)
- [Streak 도메인 구조](streak.md)
- [Word 도메인 구조](word.md)
- [Book 도메인 구조](content-book.md)
- [시스템 컨텍스트 다이어그램](overview.md)
- [Streak 도메인 미니맵](streak.md)
- [Word 도메인 미니맵](word.md)
- [Book 도메인 미니맵](content-book.md)
- [MongoDB 논리 ERD (dbdiagram.io용 DBML)](mongodb-logical-erd.dbml)
125 changes: 78 additions & 47 deletions docs/architecture/content-book.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
# Book 도메인 구조
# Book 도메인 미니맵

## 목적
## 현재 시스템의 책임
- 책, 챕터, 청크로 구성된 콘텐츠를 관리한다.
- 사용자에게 책 콘텐츠를 제공하고, 읽기 진행도를 계산·저장한다.
- 관리자가 새로운 책과 콘텐츠를 등록할 수 있도록 한다.

이 문서는 책 콘텐츠 도메인이 조회, 진행도, import, 이미지 처리를 어떻게 함께 다루는지 설명한다.
## 도메인 구조
- 책은 여러 개의 챕터로 구성된다.
- 챕터는 여러 개의 청크로 구성된다.
- 청크는 텍스트, 이미지 등의 타입을 가질 수 있다.

## 범위
## 핵심 용어 사전

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

## 핵심 구성 요소

- `BooksController`, `BooksProgressController`
- `BookService`
- `ChapterService`
- `ProgressService`
- `BookRepository`, `ChapterRepository`, `ChunkRepository`, `BookProgressRepository`
| 용어 | 정의 |
| --- | --- |
| Book | 여러 챕터를 포함하는 최상위 학습 콘텐츠 |
| Chapter | Book 내부의 순차 학습 단위 |
| Chunk | Chapter 내부의 세부 학습 단위(텍스트/이미지 등) |
| BookProgress | 사용자별 책 학습 상태를 저장하는 엔티티 |
| normalizedProgress | 완료된 챕터 수를 기준으로 계산한 책 진행률(%) |
| maxReadChunkNumber | 챕터/청크 조합 위치를 전역 순서값으로 환산한 최대 도달 지표 |

## 구조 요약
## 핵심 불변식

Book 도메인은 사용자에게 보이는 조회 API와 운영성 있는 import 파이프라인이 함께 들어 있는 구조다.
책 기본 정보와 챕터/청크는 MongoDB에 저장되고, import 시에는 AI 결과 파일 다운로드, 이미지 이동, 썸네일 생성이 같이 수행된다.
사용자 진행도는 책 단위가 아니라 챕터와 청크를 기반으로 계산되며, 읽기 완료는 스트릭 갱신으로 이어진다.
1. 책 진행률(`normalizedProgress`)은 챕터 완료 기반으로 계산한다.
2. 상태 분류(`NOT_STARTED`, `IN_PROGRESS`, `COMPLETED`)는 `normalizedProgress`와 `isCompleted`만으로 판정한다.
3. `maxReadChunkNumber`는 챕터 우선 정렬 기준으로 계산한다. 비교 순서는 `(chapterNumber, chunkNumber)`이며, chapter가 더 크면 항상 더 큰 진행 위치로 본다.
4. `GET /progress`는 학습 상태를 변경하지 않는다. (progress 문서 생성/수정 금지, 검증 중)
5. GET API의 부작용은 분석 목적(`viewCount`, 읽기 세션 시작)으로만 허용한다.
6. 진행도 모델은 V3 단일 경로를 목표로 하며, fallback은 검증 완료 후 제거한다.

## Mermaid 다이어그램
## 외부 시스템 의존성

### 구조 관계
- MongoDB: 책, 챕터, 청크, 진행도 저장
- S3 / R2: 표지 이미지와 import 산출물 저장
- StreakService: 읽기 완료 이후 스트릭 반영

```mermaid
flowchart TD
Expand Down Expand Up @@ -58,7 +65,37 @@ flowchart TD
ProgressService --> Streak
```

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

- 책 목록 조회
- 진행도 업데이트
- 책 import 및 이미지 처리

## 핵심 기능 흐름

### 책 목록 조회

```mermaid
sequenceDiagram
participant Client
participant BooksController
participant BookService
participant BookRepository
participant BookProgressRepository
participant Mongo

Client->>BooksController: GET /api/v1/books
BooksController->>BookService: getBooks(...)
BookService->>BookRepository: find books
BookService->>BookProgressRepository: load user progress
BookRepository->>Mongo: query books
BookProgressRepository->>Mongo: query bookProgress
Mongo-->>BookService: books + progress
BookService-->>BooksController: BookResponse list
BooksController-->>Client: response
```

### 진행도 업데이트와 스트릭 연결

```mermaid
sequenceDiagram
Expand All @@ -81,35 +118,29 @@ sequenceDiagram
ProgressService-->>Client: ProgressResponse
```

## 주요 흐름 설명

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

## 핵심 데이터
## 핵심 기능 선정 기준

- `Book`
- 책 메타데이터, 표지 이미지, 난이도, 챕터 수
- `Chapter`
- 챕터 번호, 설명, 읽기 시간
- `Chunk`
- 난이도별 세부 텍스트 조각
- `BookProgress`
- 사용자별 현재 청크, 챕터별 진행도, 완료 여부
1. 책 목록 조회는 사용자 트래픽과 성능 이슈가 가장 자주 모이는 진입점이다.
2. 진행도 업데이트는 `book`, `chapter`, `chunk`, `streak`를 함께 이해해야 한다.
3. import는 운영 기능이지만 파일 저장과 후처리가 함께 묶여 있어 읽기 진입점으로 가치가 있다.

## 이 도메인의 특징
## 간결 의사결정 기록

- 조회 응답이 단순 조회가 아니라 사용자 진행도와 이미지 URL 조합을 포함한다.
- import와 조회가 가까운 서비스에 있어 운영 기능과 사용자 API가 한 도메인 아래 모여 있다.
- 챕터 완료 판단은 청크 수 기준으로 계산되고, 책 완료 여부는 챕터 진행도 배열을 기반으로 계산된다.
| 날짜 | 결정 | 이유 | 영향 범위 | 상태 |
| --- | --- | --- | --- | --- |
| 2026-04-08 | Book 도메인은 책/챕터/청크 3계층 구조를 문서 표준으로 유지 | 기능 확장 시 공통 읽기 모델을 보존하기 위함 | BookService, ChapterService, ProgressService | 유지 |
| 2026-04-08 | 진행도 갱신과 스트릭 연동 흐름을 핵심 시나리오로 고정 | 교차 도메인 영향이 가장 큰 지점이기 때문 | ProgressService, StreakService | 유지 |
| 2026-04-08 | `normalizedProgress`를 챕터 완료 기반으로 통일 | 청크만으로는 책 진행 의미를 안정적으로 표현하기 어려움 | ProgressService, BookService | 유지 |
| 2026-04-08 | 상태 판정은 `normalizedProgress` + `isCompleted`로 단일화 | 상태 분류 기준 다중화로 인한 의미 흔들림 방지 | BookRepositoryImpl, BookService, ProgressService | 유지 |
| 2026-04-08 | `maxReadChunkNumber`를 정식 필드로 유지하고 챕터 우선 `(chapterNumber, chunkNumber)` 순서로 계산 | 챕터 경계를 보존한 진행 위치 비교를 위해서 | BookProgress, ProgressService, DTO | 유지 |
| 2026-04-08 | `GET /progress`에서 progress 미존재 시 0% 조회 정책 검증 | 조회 API의 상태 변경 부작용 제거 필요 | BooksProgressController, ProgressService | 검증 중 |
| 2026-04-08 | GET API는 분석성 부작용만 허용 | 사용자 학습 상태와 운영 지표를 분리하기 위함 | ChapterService, ReadingSessionService | 유지 |
| 2026-04-08 | V3 단일화 전환 가능성 사전 검증 후 fallback 제거 | 데이터 호환성 리스크를 통제하기 위함 | ProgressService, ChapterService, ChapterRepositoryImpl | 검증 중 |

## 개선 포인트
## 검증 필요 항목

- `BookService`는 import, 이미지 처리, 조회 응답 조립이 함께 있어 책임 분리가 가능하다.
- `ProgressService`는 검증, 진행도 계산, 읽기 완료 처리, 스트릭 연계를 한 번에 수행한다.
- `ChapterService`는 조회 응답 조립과 view count 증가, backward compatibility 로직이 같이 들어 있다.
- `GET /progress`에서 progress 문서가 없는 경우에도 DB 변경 없이 0% 응답 가능한지 확인
- V3 단일화 시 기존 데이터/조회 경로에서 fallback 제거해도 회귀가 없는지 확인

## 참고 코드

Expand Down
Loading
Loading