일일 콘텐츠 조회 API
일일 콘텐츠 조회 API는 사용자의 학습 진도와 치료 일차에 따라 하루에 하나의 콘텐츠(레슨 또는 퀴즈)를 제공하는 API입니다. 사용자의 현재 상태를 기반으로 적절한 콘텐츠를 결정하여 반환합니다.
주요 특징
- 통합 콘텐츠 제공: 레슨과 퀴즈를 하나의 API로 통합 제공
- 진도 기반 추천: 사용자의 학습 진도에 따른 맞춤형 콘텐츠 제공
- 캐싱 최적화: Redis 캐시를 통한 고성능 응답 (15분 TTL)
- 번들 버전 관리: 클라이언트와 서버 간 콘텐츠 버전 일관성 보장
- 치료 일차 기반: 90일 치료 프로그램에 따른 콘텐츠 스케줄링
주의사항
- 언어 헤더 필수: Accept-Language 헤더가 필요합니다 (de-DE, ko-KR, en-US)
- 사용자 인증: 유효한 Access Token이 필요합니다
- 일일 제한: 하루에 하나의 콘텐츠만 제공됩니다
- 순차 진행: 레슨은 순차적으로 진행되며, 퀴즈는 모든 일반 레슨 완료 후 제공됩니다
일일 콘텐츠 조회
사용자의 현재 치료 일차와 학습 진도에 따라 적절한 콘텐츠를 조회합니다.
- HTTP Method:
GET - Path:
/v1/learning/daily/content - 인증: Access Token 필요 (Authorization: Bearer
{accessToken})
Headers
| Header | Type | Description | Required |
|---|---|---|---|
Authorization | string | Bearer 토큰 형식의 JWT 액세스 토큰이 필요합니다. | Yes |
Accept-Language | string | 언어 코드 (de-DE, ko-KR, en-US) | Yes |
콘텐츠 결정 로직
1. 치료 기간별 콘텐츠 제공 규칙
- 1-45일차: 일반 레슨 제공 (순차 진행)
- 46-89일차: 퀴즈 제공 (모든 일반 레슨 완료 시) 또는 미완료 레슨 제공
- 90일차: 최종 레슨 제공 (진도와 관계없이)
2. 레슨 추천 로직
- 진도가 빠른 사용자:
- 1-45일차: 현재 일차 번호에 해당하는 레슨 추천
- 46-89일차: 미완료 레슨이 있으면 해당 레슨 추천, 모든 레슨 완료 시 퀴즈 제공
- 진도가 느린 사용자: 다음 미완료 레슨 추천
3. 퀴즈 제공 로직
- 빠른/정상 진도: 학습 시작일로부터 (일반 레슨 수 + 1)일차부터
- 느린 진도: 모든 일반 레슨 완료 다음날부터
Responses
| HTTP Status Code | 설명 | Error Code(s) |
|---|---|---|
200 OK | 일일 콘텐츠 조회 성공 | - |
400 Bad Request | 잘못된 요청 (언어 헤더 누락) | 8001 |
401 Unauthorized | 인증 실패 | 2051 |
404 Not Found | 리소스 없음 | 7008, 11001, 11010 |
500 Internal Server Error | 서버 내부 오류 | 11000, 11500 |
200 OK - 레슨 제공 응답
현재 일차에 해당하는 레슨을 제공하는 경우의 응답입니다.
{
"bundleId": "bundle_learning_2024_v1",
"currentDayIndex": 7,
"contentType": "LESSON",
"lessonLabel": 7,
"quizId": undefined,
"completed": false
}
GetDailyContentResponseDto 필드 설명
| 필드 | 타입 | 설명 | 예시 | 필수 (Yes/No) |
|---|---|---|---|---|
bundleId | string | 번들 ID - 현재 활성화된 학습 콘텐츠 번들의 고유 식별자 | "bundle_learning_2024_v1" | Yes |
currentDayIndex | integer | 현재 일차 (학습 시작일 기준) - 사용자의 치료 시작일로부터 계산된 현재 일차 (1일차부터 시작) | 7 | Yes |
contentType | DailyContentType | 콘텐츠 타입 - 제공되는 콘텐츠의 유형 (LESSON: 레슨, QUIZ: 퀴즈, NONE: 제공할 콘텐츠 없음) | "LESSON" | Yes |
lessonLabel | integer | undefined | 레슨 라벨 - 치료 프로그램의 권장 수강 일차 (번들 내 모든 레슨에서 고유값, 불변값). contentType이 LESSON인 경우에만 제공됨. 최종 레슨(46번)까지 순차적으로 제공됨 | 7 | No |
quizId | string | undefined | 퀴즈 ID - 제공되는 퀴즈의 고유 식별자. contentType이 QUIZ인 경우에만 제공됨. 모든 일반 레슨 완료 후 순차적으로 제공됨 | undefined | No |
completed | boolean | undefined | 콘텐츠 완료 상태 - 사용자가 해당 콘텐츠를 완료했는지 여부 (true: 완료됨, false: 미완료됨) | false | No |
200 OK - 퀴즈 제공 응답
모든 일반 레슨 완료 후 퀴즈를 제공하는 경우의 응답입니다.
{
"bundleId": "bundle_learning_2024_v1",
"currentDayIndex": 50,
"contentType": "QUIZ",
"quizId": "quiz_001",
"completed": false
}
200 OK - 치료 마지막 날 응답
치료 기간 마지막 날(90일차)에 최종 레슨을 제공하는 경우의 응답입니다.
{
"bundleId": "bundle_learning_2024_v1",
"currentDayIndex": 90,
"contentType": "LESSON",
"lessonLabel": 46,
"completed": false
}
200 OK - 콘텐츠 없음 응답
제공할 콘텐츠가 없는 경우의 응답입니다.
{
"bundleId": "bundle_learning_2024_v1",
"currentDayIndex": 48,
"contentType": "NONE"
}
400 Bad Request - 언어 헤더 누락
{
"code": 8001,
"message": "INVALID_LANGUAGE",
"detail": "Accept-Language 헤더가 필요합니다"
}
Accept-Language 헤더가 누락되었거나 지원하지 않는 언어 코드인 경우 반환됩니다.
401 Unauthorized - 인증 실패
{
"code": 2051,
"message": "INVALID_TOKEN",
"detail": "토큰이 유효하지 않습니다"
}
유효하지 않은 액세스 토큰이 제공되었거나 토큰이 만료된 경우 반환됩니다.
404 Not Found - 리소스 없음
사용자 상태 없음 (7008)
{
"code": 7008,
"message": "USER_STATE_NOT_FOUND",
"detail": "사용자의 활성 주기를 찾을 수 없습니다"
}
사용자의 활성 사이클 정보가 존재하지 않을 때 발생합니다.
학습 번들 없음 (11001)
{
"code": 11001,
"message": "LEARNING_BUNDLE_NOT_FOUND",
"detail": "활성 학습 번들이 존재하지 않습니다"
}
활성 학습 번들이 존재하지 않을 때 발생합니다.
레슨 없음 (11010)
{
"code": 11010,
"message": "LESSON_NOT_FOUND",
"detail": "존재하지 않는 레슨입니다"
}
요청된 레슨을 찾을 수 없을 때 발생합니다.
500 Internal Server Error - 서버 내부 오류
일반적인 서버 오류 (11000)
{
"code": 11000,
"message": "SERVER_ERROR",
"detail": "서버 내부 오류"
}
일일 콘텐츠 조회 중 예상치 못한 서버 내부 오류가 발생했을 때 반환됩니다.
데이터베이스 접근 오류 (11500)
{
"code": 11500,
"message": "REPOSITORY_ERROR",
"detail": "데이터 저장소 오류"
}
데이터베이스 접근 중 오류가 발생했을 때 반환됩니다.
콘텐츠 타입 (DailyContentType)
일일 콘텐츠 API에서 사용되는 콘텐츠 타입 열거형입니다.
자세한 내용은 DailyContentType 문서를 참조하세요.
| 값 | 설명 |
|---|---|
LESSON | 레슨 콘텐츠 - 일반 레슨(1-45번) 또는 최종 레슨(46번)을 제공합니다. lessonLabel 필드에 해당 레슨의 라벨이 포함됩니다. 사용자는 이 라벨을 통해 번들에서 실제 레슨 콘텐츠를 조회할 수 있습니다. |
QUIZ | 퀴즈 콘텐츠 - 모든 일반 레슨 완료 후 제공되는 복습 퀴즈입니다. quizId 필드에 해당 퀴즈의 ID가 포함됩니다. 사용자는 이 ID를 통해 번들에서 실제 퀴즈 콘텐츠를 조회할 수 있습니다. |
NONE | 제공할 콘텐츠 없음 - 치료 기간 초과, 시스템 오류, 또는 특정 조건 미충족 시 반환됩니다. 이 경우 lessonLabel과 quizId 모두 undefined입니다. |
주요 특징
콘텐츠 결정 알고리즘
일일 콘텐츠 API는 사용자의 치료 진행 상황과 완료한 레슨을 기반으로 다음과 같은 우선순위로 콘텐츠를 결정합니다:
- 치료 마지막 날 (90일차): 진도와 관계없이 최종 레슨(46번) 제공
- 일반 레슨 기간 (1-45일차): 사용자 진도에 따라 현재 일차 레슨 또는 다음 미완료 레슨 제공
- 퀴즈 기간 (46-89일차): 모든 일반 레슨 완료 시 퀴즈 제공, 미완료 시 남은 레슨 제공
진도 기반 레슨 추천
- 빠른 진도: 완료한 레슨 수 ≥ 현재 일차
- 1-45일차: 현재 일차에 해당하는 레슨 추천
- 46-89일차: 미완료 레슨이 있으면 해당 레슨 추천, 모든 레슨 완료 시 퀴즈 제공
- 느린 진도: 완료한 레슨 수 < 현재 일차 → 다음 미완료 레슨 추천
번들 기반 콘텐츠 관리
- API 응답의
bundleId를 통해 클라이언트는 해당 번들에서 실제 콘텐츠를 조회 lessonLabel을 사용하여 번들 내 특정 레슨 식별quizId를 사용하여 번들 내 특정 퀴즈 식별
다국어 지원
Accept-Language헤더를 통해 언어별 콘텐츠 제공- 지원 언어: 독일어(de-DE), 한국어(ko-KR), 영어(en-US)
사용 예시
1. 기본 레슨 조회
curl -X GET "https://api.example.com/v1/learning/daily/content" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept-Language: ko-KR"
2. 독일어 레슨 조회
curl -X GET "https://api.example.com/v1/learning/daily/content" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept-Language: de-DE"
3. 영어 레슨 조회
curl -X GET "https://api.example.com/v1/learning/daily/content" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept-Language: en-US"
성능 최적화
캐싱 전략
- Redis 캐시: 15분 TTL로 사용자별 일일 콘텐츠 캐싱
- 캐시 키 구조:
daily_content:{userId}:{userCycleId}:{currentDayIndex}:{bundleId} - 캐시 히트율: 95% 이상 (예상 성능 향상: 200ms → 1-5ms)
최적화 포인트
- 사용자 상태 조회: User 도메인과의 효율적인 연동
- 번들 정보 캐싱: 활성 번들 정보 메모리 캐싱
- 쿼리 최적화: 완료된 레슨 조회 쿼리 인덱스 활용
- 응답 압축: gzip 압축을 통한 네트워크 최적화
에러 코드 상세 정보
Learning 도메인 에러 코드 (11000-11099)
| 에러 코드 | 메시지 | 설명 | HTTP 상태 |
|---|---|---|---|
11000 | SERVER_ERROR | 서버 내부 오류 | 500 |
11001 | LEARNING_BUNDLE_NOT_FOUND | 활성 학습 번들이 존재하지 않습니다 | 404 |
11010 | LESSON_NOT_FOUND | 존재하지 않는 레슨입니다 | 404 |
11500 | REPOSITORY_ERROR | 데이터 저장소 오류 | 500 |
에러 발생 시나리오
1. 사용자 상태 관련 오류
- 7008 (USER_STATE_NOT_FOUND): 사용자의 활성 사이클이 존재하지 않을 때
- 해결 방법: 사용자 등록 및 치료 시작 프로세스 확인
2. 학습 번들 관련 오류
- 11001 (LEARNING_BUNDLE_NOT_FOUND): 활성 학습 번들이 설정되지 않았을 때
- 해결 방법: 시스템 관리자에게 번들 설정 요청
3. 레슨 관련 오류
- 11010 (LESSON_NOT_FOUND): 요청된 레슨이 번들에 존재하지 않을 때
- 발생 상황: 번들 업데이트 중 또는 데이터 불일치
- 해결 방법: 번들 데이터 재동기화 또는 시스템 관리자 문의
4. 시스템 오류
- 11000 (SERVER_ERROR): 예상치 못한 서버 내부 오류
- 11500 (REPOSITORY_ERROR): 데이터베이스 접근 오류
- 해결 방법: 잠시 후 재시도, 지속 시 시스템 관리자 문의
관련 API
- 레슨 완료 API - 레슨 완료 처리
- 사용자 레슨 상태 조회 API - 전체 레슨 상태 조회
- 최신 학습 번들 조회 API - 번들 정보 조회
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.53.18 | 2025-11-04 | pibi@weltcorp.com | 콘텐츠 완료 상태 추가: completed 필드 추가로 사용자의 콘텐츠 완료 여부 제공. 캐싱 로직 최적화: 완료된 콘텐츠는 캐시 재사용, 미완료 콘텐츠는 실시간 상태 조회. 성능 개선 및 클라이언트 UX 향상 |
| 2.0.0 | 2025-01-10 | elizabeth@weltcorp.com | API 응답 구조 단순화: undefined 필드 제거로 JSON 응답 최적화. lessonLabel/quizId 필드만 조건부 포함. 번들 버전 관리 로직 추가. 콘텐츠 결정 우선순위 명확화. DTO 필드 설명 상세화 및 문서 개선 |
| 1.0.0 | 2025-01-01 | elizabeth@weltcorp.com | 최초 문서 작성 |