본문으로 건너뛰기
버전: 개발 버전 (최신)

회차 누적 결과 조회 API

회차 누적 결과 조회 API는 사용자가 특정 회차까지 완료된 모든 설문 결과를 누적으로 조회합니다. 예를 들어, 3차를 요청하면 1, 2, 3차의 완료된 설문 결과를 모두 반환합니다.

주의사항
  • 사용자가 참여하지 않은 설문: 사용자가 완료하지 않은 설문의 경우 해당 설문 정보는 undefined로 제공됩니다.
  • 존재하지 않는 회차: 요청한 회차가 시스템에 정의되지 않은 경우 HTTP 404 에러가 발생합니다.
  • 데이터 일관성: 회차 정의 조회 실패 시 더 이상 부분적 데이터를 제공하지 않고 명확한 에러를 반환합니다.

회차 누적 결과 조회

특정 회차까지의 누적 설문 결과를 조회합니다.

  • HTTP Method: GET
  • Path: /questionnaires/rounds/cumulative-results
  • 인증: Access Token 필요 (Authorization: Bearer {accessToken})

Headers

HeaderTypeDescriptionRequired
AuthorizationstringBearer 토큰 형식의 JWT 액세스 토큰이 필요합니다.Yes
Accept-Languagestring조회 언어 (허용 형식: de-DE, en-US, ko-KR)Yes

Query Parameters

ParameterTypeDescriptionRequiredExample
roundNumberinteger조회할 회차 번호 (1 이상의 정수, 미제공시 모든 회차 결과 반환)No3

Responses

HTTP Status Code설명Error Code(s)
200 OK누적 결과 조회 성공-
400 Bad Request잘못된 요청 (유효하지 않은 회차 번호)-
401 Unauthorized인증 실패2051
404 Not Found리소스 없음 (사용자 상태, 번들, 회차)7008, 9010, 9031
422 Unprocessable Entity잘못된 회차 번호9056
500 Internal Server Error서버 내부 오류9000, 9500
200 OK - 누적 결과 조회 성공

성공적으로 누적 결과를 조회하면 지정된 회차까지의 모든 설문 결과가 반환됩니다.

{
"userId": "user_abc_123",
"requestedRoundNumber": 3,
"allRounds": [
{
"id": "round_123",
"roundNumber": 1,
"questionnaires": [
{
"type": "ISI",
"orderIndex": 0
},
{
"type": "DBAS16",
"orderIndex": 1
},
{
"type": "WIS",
"orderIndex": 2
}
],
"questionnaireResponses": [
{
"id": "q_isi123",
"type": "ISI",
"title": "불면증 심각도 지수",
"score": {
"calculationType": "SUM",
"range": {
"min": {
"value": 0
},
"max": {
"value": 28
}
},
"userScore": 18,
"level": {
"id": "sl_isi3",
"range": {
"min": {
"value": 15
},
"max": {
"value": 21
}
},
"label": "중간 정도의 불면증",
"chartLabel": "수면 불량",
"description": "중등도의 불면 증상이 나타날 수 있습니다.",
"feedback": "중등도의 불면 증상이 나타날 수 있습니다. 의료 전문가의 도움이 필요한 상황입니다."
}
},
"completedAt": 1711929600000,
"completedDayIndex": 12
}
]
},
{
"id": "round_456",
"roundNumber": 2,
"questionnaires": [
{
"type": "ISI",
"orderIndex": 0
},
{
"type": "DBAS16",
"orderIndex": 1
},
{
"type": "WIS",
"orderIndex": 2
}
],
"questionnaireResponses": [
{
"id": "q_isi456",
"type": "ISI",
"title": "불면증 심각도 지수",
"score": {
"calculationType": "SUM",
"range": {
"min": {
"value": 0
},
"max": {
"value": 28
}
},
"userScore": 16,
"level": {
"id": "sl_isi3",
"range": {
"min": {
"value": 15
},
"max": {
"value": 21
}
},
"label": "중간 정도의 불면증",
"chartLabel": "수면 불량",
"description": "중등도의 불면 증상이 나타날 수 있습니다.",
"feedback": "중등도의 불면 증상이 나타날 수 있습니다. 의료 전문가의 도움이 필요한 상황입니다."
}
},
"completedAt": 1712534400000,
"completedDayIndex": 19
}
]
},
{
"id": "round_789",
"roundNumber": 3,
"questionnaires": [
{
"type": "ISI",
"orderIndex": 0
},
{
"type": "DBAS16",
"orderIndex": 1
},
{
"type": "WIS",
"orderIndex": 2
}
],
"questionnaireResponses": [
{
"id": "q_isi789",
"type": "ISI",
"title": "불면증 심각도 지수",
"score": {
"calculationType": "SUM",
"range": {
"min": {
"value": 0
},
"max": {
"value": 28
}
},
"userScore": 12,
"level": {
"id": "sl_isi2",
"range": {
"min": {
"value": 8
},
"max": {
"value": 14
}
},
"label": "약간의 불면증",
"chartLabel": "수면 양호",
"description": "경미한 불면 증상이 나타날 수 있습니다.",
"feedback": "수면 상태가 개선되고 있습니다. 현재 수준을 유지하세요."
}
},
"completedAt": 1713139200000,
"completedDayIndex": 26
}
]
}
]
}
필드타입설명예시필수 (Yes/No)
userIdstring사용자 ID"user_abc_123"Yes
requestedRoundNumberinteger요청한 회차 번호3Yes
allRoundsRoundSummaryDto[]1회차부터 요청한 회차까지의 모든 회차 정보-Yes
allRounds[].idstring회차 ID"round_123"Yes
allRounds[].roundNumberinteger회차 번호1Yes
allRounds[].questionnairesRoundQuestionnaireSectionDto[]회차 내 설문 타입과 순서 정보-Yes
allRounds[].questionnaires[].typestring설문 타입 (enum: QuestionnaireType)"ISI"Yes
allRounds[].questionnaires[].orderIndexinteger설문 순서 인덱스 (0부터 시작)0Yes
allRounds[].questionnaireResponsesQuestionnaireResponseInRoundDto[]해당 회차의 설문 응답 목록-Yes

설문 응답 객체 (QuestionnaireResponseInRoundDto) 필드:

필드타입설명예시필수 (Yes/No)
idstring설문 ID"q_isi123"Yes
typestring설문 타입"ISI"Yes
titlestring설문 제목"불면증 심각도 지수"Yes
scoreQuestionnaireScoreSectionDto점수 관련 정보 (점수가 없으면 undefined)-No
score.calculationTypestring점수 계산 유형 (SUM, AVERAGE, WEIGHTED)"SUM"Yes (score가 있을 때)
score.rangeRangeDto설문지 전체 점수 범위-No
score.range.minRangeValueDto설문지 최소 점수{"value": 0.0}Yes (range가 있을 때)
score.range.maxRangeValueDto설문지 최대 점수{"value": 28.0}Yes (range가 있을 때)
score.userScorefloat사용자 점수18.0No
score.levelScoreLevelDto점수 구간 정보 (구간이 없으면 undefined)-No
score.level.idstring점수 구간 ID"sl_isi3"Yes (level이 있을 때)
score.level.rangeRangeDto점수 구간 범위-Yes (level이 있을 때)
score.level.range.minRangeValueDto구간 최소 점수{"value": 15.0}Yes (level range가 있을 때)
score.level.range.maxRangeValueDto구간 최대 점수{"value": 21.0}Yes (level range가 있을 때)
score.level.labelstring점수 구간 라벨"중간 정도의 불면증"No
score.level.chartLabelstring차트용 라벨"수면 불량"No
score.level.descriptionstring점수 구간 설명"중등도의 불면 증상..."No
score.level.feedbackstring피드백 메시지"의료 전문가의 도움..."No
completedAtinteger완료 시간 (Unix timestamp in milliseconds, Kotlin: Long, Swift: Int64, 완료하지 않았으면 undefined)1711929600000No
completedDayIndexinteger완료 일자 인덱스 (사이클 시작일로부터, 완료하지 않았으면 undefined)12No
400 Bad Request - 잘못된 요청
{
"statusCode": 400,
"message": "roundNumber must be greater than or equal to 1",
"error": "Bad Request"
}

이 오류는 roundNumber 쿼리 파라미터가 1보다 작거나 정수가 아닐 때 발생합니다.

401 Unauthorized - 인증 실패
{
"code": 2051,
"message": "INVALID_TOKEN",
"detail": "토큰이 유효하지 않습니다"
}
404 Not Found - 리소스 없음

예시: 사용자 활성 상태를 찾을 수 없음 (7008)

{
"code": 7008,
"message": "USER_STATE_NOT_FOUND",
"detail": "사용자의 활성 주기를 찾을 수 없습니다"
}

예시: 설문 번들을 찾을 수 없음 (9010)

{
"code": 9010,
"message": "QUESTIONNAIRE_BUNDLE_NOT_FOUND",
"detail": "설문지 번들을 찾을 수 없습니다"
}

예시: 회차를 찾을 수 없음 (9031)

{
"code": 9031,
"message": "QUESTIONNAIRE_ROUND_NOT_FOUND",
"detail": "설문지 회차를 찾을 수 없습니다"
}
422 Unprocessable Entity - 잘못된 회차 번호
{
"code": 9056,
"message": "INVALID_ROUND_NUMBER",
"detail": "유효하지 않은 회차 번호입니다"
}

이 오류는 요청한 회차 번호가 사용자의 설문 번들에 정의되지 않은 경우 발생합니다.

500 Internal Server Error - 서버 내부 오류

일반적인 서버 오류 (9000)

{
"code": 9000,
"message": "SERVER_ERROR",
"detail": "서버 내부 오류"
}

데이터베이스 접근 오류 (9500)

{
"code": 9500,
"message": "REPOSITORY_ERROR",
"detail": "데이터베이스 접근 중 오류가 발생했습니다"
}

이 오류들은 처리 중 예기치 않은 서버 내부 문제나 데이터베이스 접근 문제가 발생했을 때 반환됩니다.

설명

  • 이 API는 apps/dta-wide-api/src/app/questionnaire/services/questionnaire-round.service.tsgetCumulativeRoundResults 메서드의 로직을 기반으로 합니다.
  • 주요 처리 단계 (서비스 로직 내):
    1. 사용자 상태 조회: 사용자의 활성 사이클 ID와 현재 진행 상태 조회 (getUserState)
    2. 누적 응답 조회: GetUserQuestionnaireResponsesUpToRoundQuery를 통해 지정된 회차까지의 모든 설문 응답 조회
    3. 데이터 변환: 조회된 결과를 CumulativeQuestionnaireResultsDto 형태로 변환
  • 조회 범위:
    • roundNumber가 제공된 경우: 1회차부터 해당 회차까지의 모든 완료된 설문 결과 반환
    • roundNumber가 제공되지 않은 경우: 모든 완료된 회차의 설문 결과 반환
  • 점수 정보: 각 설문 응답에는 사용자 점수, 점수 구간 정보, 피드백 등이 포함됩니다. 점수가 계산되지 않은 설문의 경우 score 필드가 undefined로 제공됩니다.
  • 시간 정보: 설문 완료 시점(completedAt)과 사용자 사이클 기준 완료 일자(completedDayIndex)를 제공합니다. 완료하지 않은 설문의 경우 두 필드 모두 undefined로 제공됩니다.
  • 누락된 회차: 사용자가 참여하지 않은 회차의 경우 해당 회차 정보가 allRounds 배열에서 제외됩니다.
  • Accept-Language 헤더를 통해 조회 언어를 지정할 수 있으며, 기본값은 'de-DE'입니다.

사용 예시

예시 1: 3회차까지의 누적 결과 조회

GET /questionnaires/rounds/cumulative-results?roundNumber=3
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept-Language: ko-KR

예시 2: 모든 회차의 누적 결과 조회

GET /questionnaires/rounds/cumulative-results
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept-Language: de-DE

DTO 상세 설명

CumulativeQuestionnaireResultsDto

회차 누적 결과 조회 API의 응답 DTO입니다.

필드타입설명필수 (Yes/No)
userIdstring사용자 IDYes
requestedRoundNumberinteger요청한 회차 번호Yes
allRoundsRoundSummaryDto[]1회차부터 요청한 회차까지의 모든 회차 정보Yes

RoundSummaryDto

회차별 설문 응답 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
idstring회차 IDYes
roundNumberinteger회차 번호Yes
questionnairesRoundQuestionnaireSectionDto[]회차 내 설문 타입과 순서 정보Yes
questionnaireResponsesQuestionnaireResponseInRoundDto[]해당 회차의 설문 응답 목록Yes

RoundQuestionnaireSectionDto

회차별 설문 타입과 순서 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
typestring설문 타입 (enum: QuestionnaireType)Yes
orderIndexinteger설문 순서 인덱스 (0부터 시작)Yes

QuestionnaireResponseInRoundDto

개별 설문 응답 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
idstring설문 IDYes
typestring설문 타입Yes
titlestring설문 제목Yes
scoreQuestionnaireScoreSectionDto점수 관련 정보 (점수가 없으면 undefined)No
completedAtinteger완료 시간 (Unix timestamp in milliseconds, Kotlin: Long, Swift: Int64, 완료하지 않았으면 undefined)No
completedDayIndexinteger완료 일자 인덱스 (사이클 시작일로부터, 완료하지 않았으면 undefined)No

QuestionnaireScoreSectionDto

설문 점수 관련 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
calculationTypestring점수 계산 유형 (SUM, AVERAGE, WEIGHTED)Yes
rangeRangeDto설문지 전체 점수 범위No
userScorefloat사용자 점수No
levelScoreLevelDto점수 구간 정보 (구간이 없으면 undefined)No

RangeDto

점수 범위 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
minRangeValueDto최소값Yes
maxRangeValueDto최대값Yes

RangeValueDto

범위 값 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
valuefloatYes
labelstring라벨No

ScoreLevelDto

점수 구간 정보를 담는 DTO입니다.

필드타입설명필수 (Yes/No)
idstring점수 구간 IDYes
rangeRangeDto범위Yes
labelstring라벨No
chartLabelstring차트 라벨No
descriptionstring점수 구간 설명No
feedbackstring피드백No

활용 사례

  • 진행 상황 추적: 사용자의 설문 진행 상황과 점수 변화 추이를 확인
  • 분석 대시보드: 회차별 점수 변화를 차트로 시각화
  • 개선 평가: 치료나 프로그램 효과를 평가하기 위한 누적 데이터 분석
  • 리포트 생성: 사용자별 누적 진행 리포트 작성
  • 회차 구성 파악: 각 회차별로 어떤 설문들이 포함되어 있는지 확인

변경 이력

버전날짜작성자변경 내용
0.1.02025-06-23elizabeth@weltcorp.com최초 문서 작성
0.2.02025-06-30elizabeth@weltcorp.comfallback 처리 제거, 숫자 타입 float/integer 구분
0.3.02025-07-03elizabeth@weltcorp.comquestionnaires 필드 추가, RoundQuestionnaireSectionDto DTO 추가