본문으로 건너뛰기

Sleep API 엔드포인트

목차

접근 권한 매트릭스

엔드포인트System AdminIAM AdminService AccountRegular User비고
POST /v1/sleep/logs/day-index당일 일차만 가능
PATCH /v1/sleep/logs/day-index/{dayIndex}당일 일차만 가능
GET /v1/sleep/logs/day-index/{dayIndex}
GET /v1/sleep/logs/day-index-range일차 범위 조회
POST /v1/sleep/logs/temporary임시 기록 저장
PUT /v1/sleep/logs/temporary/complete/day-index/{dayIndex}임시→완전 전환
GET /v1/sleep/goals/day-index/{dayIndex}
GET /v1/sleep/goals/day-index-range일차 범위 조회
GET /v1/sleep/goals/users/{userId}/latest특정 사용자 최근 목표 조회
GET /v1/sleep/goals/users/me/latest내 최근 목표 조회
PUT /v1/sleep/goals/target-wake-timerTIB 처방일에만 가능
GET /v1/sleep/rtib/day-index/{dayIndex}
GET /v1/sleep/rtib/eligibilityrTIB 계산 자격 확인
GET /v1/sleep/goal-adherence/day-index/{dayIndex}
GET /v1/sleep/goal-adherence/day-index-range일차 범위 조회
GET /v1/sleep/statistics/weekly주차별 통계
GET /v1/sleep/statistics/weekly/efficiency수면 효율 통계
GET /v1/sleep/statistics/weekly/quality수면의 질 통계
GET /v1/sleep/statistics/weekly/tst총 수면 시간 통계
GET /v1/sleep/statistics/weekly/medication수면제 복용 통계
GET /v1/sleep/statistics/weekly/solSOL 통계
GET /v1/sleep/statistics/weekly/nap-time낮잠 시간 통계
GET /v1/sleep/statistics/weekly/factors영향 요인 통계
GET /v1/sleep/statistics/weekly/goal-adherence목표 달성 통계
GET /v1/sleep/statistics/custom-range사용자 지정 범위
GET /v1/sleep/admin/data/{userId}관리자 데이터 접근
POST /v1/sleep/admin/users/{userId}/archive사용자 데이터 아카이빙
POST /v1/sleep/admin/users/{userId}/restore사용자 데이터 복원
DELETE /v1/sleep/admin/users/{userId}/data사용자 데이터 영구 삭제
POST /v1/sleep/admin/users/{userId}/anonymize사용자 데이터 익명화
GET /v1/sleep/users/me/data-export내 데이터 추출 요청
GET /v1/sleep/admin/users/{userId}/data-export특정 사용자 데이터 추출 요청

참고:

  • ✓: 접근 가능
  • ✘: 접근 불가
  • (범위 내): 할당된 조직/팀 범위 내에서만 접근 가능
  • (자신만): 자신의 데이터에만 접근 가능

수면 기록 API

📌 구현 순서: 수면 기록 관리는 Sleep 도메인의 핵심 기능이며 가장 먼저 구현되어야 합니다.

수면 기록 API는 사용자의 일일 수면 데이터를 생성, 조회, 수정하는 기능을 제공합니다. 수면 기록은 당일 일차에 한해 생성 및 수정이 가능하며, 일차가 변경된 이후에는 수정이 불가능합니다.

2.1 수면 기록 생성 API

  • HTTP 메서드: POST
  • 경로: /v1/sleep/logs/day-index
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"dayIndex": 5,
"dns": false,
"pill": false,
"negativeFactorIds": [1, 2, 3],
"positiveFactorIds": [4],
"napMinutes": 30,
"lot": 1748268000000,
"aet": 1748300400000,
"sleepQuality": 3,
"solMinutes": 15,
"wasoMinutes": 20,
"tstMinutes": 505
}

참고:

  • dns가 true인 경우(전혀 못 잤을 경우) 필수 항목은 negativeFactorIds, pill, napMinutes입니다.
  • dns가 false인 경우(잠을 잤을 경우) 필수 항목은 lot, aet, sleepQuality, solMinutes, wasoMinutes, positiveFactorIds, negativeFactorIds, pill, napMinutes입니다.
  • lot, aet는 ISO 8601 형식의 Date 객체로 제공해야 하며, 5분 단위여야 합니다.
  • lot(잠자리에 든 시각)는 18:00 이후 또는 새벽시간(0~6시)이어야 합니다.
  • tstMinutes는 선택적 필드이며, 제공할 경우 시스템이 계산한 값과 정확히 일치해야 합니다. (TST = TIB - SOL - WASO)
  • 당일 일차(현재 진행 중인 일차)에만 생성이 가능합니다.

응답 (Response)

  • 성공 응답 (201 Created)
{
"sleepLog": {
"id": "d2f6d3e7-bf74-45dd-aeef-102a3f9671d3",
"dayIndex": 5,
"date": "2025-05-27",
"dns": false,
"lot": 1748300400000,
"aet": 1748332800000,
"tstMinutes": 505,
"sleepEfficiency": 0.94,
"sleepQuality": 3,
"positiveFactorIds": [4],
"negativeFactorIds": [1, 2, 3],
"pill": false,
"napMinutes": 30,
"positiveCustomFactors": [],
"negativeCustomFactors": [],
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540,
"isTemporary": false,
"createdAt": 1748311037142,
"updatedAt": 1748311037142
},
"goalAdherence": {
"id": "adh_12345",
"dayIndex": 7,
"date": "2025-05-10",
"sleepGoalId": "sg_12345",
"bedTimeGoalMet": true,
"wakeTimeGoalMet": false,
"createdAt": 1715315400000,
"updatedAt": 1715315400000
}
}

참고:

  • tstMinutes(총 수면 시간)와 sleepEfficiency(수면 효율)는 시스템에서 자동 계산됩니다.
  • goalAdherence는 수면 목표가 존재하지 않으면 Null입니다.
  • 응답의 date는 사용자 시간대 기준 날짜 문자열(YYYY-MM-DD)입니다.
  • lot, aet는 ISO 8601 형식의 Date 객체로 응답됩니다.
  • createdAt, updatedAt은 Unix timestamp(밀리초) 형식입니다.
  • sleepQuality는 1(매우 나쁨)부터 5(매우 좋음)까지의 수면의 질 점수입니다.
  • 오류 응답 (400 Bad Request - DNS=false일 때 필수 필드 누락)
{
"code": 10001,
"message": "MISSING_REQUIRED_FIELDS",
"detail": "잠을 잤을 경우 필수 입력 항목이 누락되었습니다.",
"fields": ["sleepQuality", "lot", "aet"]
}
  • 오류 응답 (400 Bad Request - 날짜 유효성 검증 실패)
{
"code": 10009,
"message": "DATE_VALIDATION_FAILED",
"detail": "수면 기록은 당일 일차에 한해서만 생성/수정이 가능합니다."
}
  • 오류 응답 (400 Bad Request - 시간 유효성 검증 실패)
{
"code": 10008,
"message": "SLEEP_TIME_VALIDATION_FAILED",
"detail": "LOT는 18:00 이후여야 하고, 시간 값은 5분 단위여야 하며, AET는 LOT보다 이후여야 합니다."
}
  • 오류 응답 (400 Bad Request - TST 불일치)
{
"code": 10013,
"message": "INVALID_TST",
"detail": "계산된 총 수면 시간(TST)과 제공된 값이 일치하지 않습니다."
}
  • 오류 응답 (400 Bad Request - DNS=true일 때 수면 데이터 포함)
{
"code": 10014,
"message": "UNEXPECTED_SLEEP_DATA",
"detail": "DNS=true인 경우 수면 관련 데이터(lot, aet, solMinutes, wasoMinutes, tstMinutes)를 입력할 수 없습니다."
}
  • 오류 응답 (403 Forbidden - 치료 활동 일시 정지)
{
"code": 10010,
"message": "TREATMENT_SUSPENDED",
"detail": "치료 활동 일시 정지 상태에서는 수면 기록을 생성할 수 없습니다."
}
  • 오류 응답 (409 Conflict - 중복 기록)
{
"code": 10090,
"message": "SLEEP_LOG_ALREADY_EXISTS",
"detail": "해당 날짜에 이미 수면 기록이 존재합니다."
}

2.2 수면 기록 수정 API

  • HTTP 메서드: PATCH
  • 경로: /v1/sleep/logs/day-index/{dayIndex}
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"dns": false,
"lot": 1715299700000,
"sleepQuality": 3,
"negativeFactorIds": [2, 4],
"pill": true
}

참고: 수정 API는 부분 업데이트를 지원하므로 변경하려는 필드만 포함하면 됩니다. dns 상태를 변경할 경우, 해당 상태에 맞는 필수 항목 검증이 다시 적용됩니다. dns를 false에서 true로 변경 시, DNS에 필요한 데이터 외의 모든 항목은 자동 초기화됩니다. 당일 일차(현재 진행 중인 일차)에만 수정이 가능합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "sl_12345",
"dayIndex": 7,
"date": "2025-05-10",
"dns": false,
"lot": 1715299700000,
"aet": 1715329800000,
"tstMinutes": 465,
"sleepEfficiency": 0.92,
"solMinutes": 30,
"wasoMinutes": 15,
"sleepQuality": 3,
"positiveFactorIds": [1, 3, 5],
"negativeFactorIds": [2, 4],
"pill": true,
"napMinutes": 20,
"positiveCustomFactors": ["좋은 베개"],
"negativeCustomFactors": ["옆방 소음"],
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540,
"isTemporary": false,
"createdAt": 1715311800000,
"updatedAt": 1715313600000
}
  • 오류 응답 (404 Not Found)
{
"code": 10040,
"message": "SLEEP_LOG_NOT_FOUND",
"detail": "해당 일차의 수면 기록을 찾을 수 없습니다."
}

2.3 수면 기록 조회 API (일차별)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/logs/day-index/{dayIndex}
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "sl_12345",
"dayIndex": 7,
"date": "2025-05-10",
"dns": false,
"lot": 1748300400000,
"aet": 1748332800000,
"tstMinutes": 465,
"sleepEfficiency": 0.92,
"solMinutes": 30,
"wasoMinutes": 15,
"sleepQuality": 3,
"positiveFactorIds": [1, 3, 5],
"negativeFactorIds": [2, 4],
"pill": true,
"napMinutes": 20,
"positiveCustomFactors": ["좋은 베개"],
"negativeCustomFactors": ["옆방 소음"],
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540,
"isTemporary": false,
"createdAt": 1715311800000,
"updatedAt": 1715313600000
}

참고:

  • tstMinutes(총 수면 시간)와 sleepEfficiency(수면 효율)는 시스템에서 자동 계산됩니다.
  • date는 사용자 시간대 기준 날짜 문자열(YYYY-MM-DD)입니다.
  • lot, aet, createdAt, updatedAt은 Unix timestamp(밀리초) 형식입니다.
  • 오류 응답 (404 Not Found)
{
"code": 10040,
"message": "SLEEP_LOG_NOT_FOUND",
"detail": "해당 일차의 수면 기록을 찾을 수 없습니다."
}

2.4 수면 기록 조회 API (일차 범위)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/logs/day-index-range
  • 쿼리 파라미터:
    • startDayIndex: 시작 일차
    • endDayIndex: 종료 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"items": [
{
"sleepLog": {
"id": "1b09aed9-ed4a-4c0c-ac9e-0450cf1dfc70",
"dayIndex": 1,
"date": "2025-06-12",
"dns": false,
"lot": 1749650400000,
"aet": 1749679200000,
"tstMinutes": 480,
"sleepEfficiency": 1,
"solMinutes": 0,
"wasoMinutes": 0,
"sleepQuality": 4,
"positiveFactorIds": [3, 4],
"negativeFactorIds": [3, 4],
"pill": true,
"napMinutes": 30,
"positiveCustomFactors": ["충분한 운동", "따뜻한 샤워"],
"negativeCustomFactors": [],
"timezone": {
"id": "Asia/Seoul",
"offsetInMinutes": 540
},
"isTemporary": false,
"createdAt": 1749716192050,
"updatedAt": 1749716343687
},
"goalAdherence": null
},
{
"sleepLog": {
"id": "e4abdcc0-be20-42d2-ba57-fc8e77b4221e",
"dayIndex": 2,
"date": "2025-06-17",
"dns": false,
"lot": 1750082400000,
"aet": 1750114800000,
"tstMinutes": 505,
"sleepEfficiency": 0.93519,
"solMinutes": 15,
"wasoMinutes": 20,
"sleepQuality": 4,
"positiveFactorIds": [1],
"negativeFactorIds": [3],
"pill": false,
"napMinutes": 30,
"positiveCustomFactors": [],
"negativeCustomFactors": [],
"timezone": {
"id": "Asia/Seoul",
"offsetInMinutes": 540
},
"isTemporary": false,
"createdAt": 1750145181477,
"updatedAt": 1750145773922
},
"goalAdherence": null
},
{
"sleepLog": {
"id": "b70a376b-c548-488d-a9b1-450222a3c314",
"dayIndex": 3,
"date": "2025-06-18",
"dns": false,
"lot": 1750183200000,
"aet": 1750194000000,
"tstMinutes": 145,
"sleepEfficiency": 0.80556,
"solMinutes": 15,
"wasoMinutes": 20,
"sleepQuality": 4,
"positiveFactorIds": [3, 4],
"negativeFactorIds": [2],
"pill": false,
"napMinutes": 30,
"positiveCustomFactors": ["충분한 운동", "따뜻한 샤워"],
"negativeCustomFactors": ["늦은 카페인 섭취", "스마트폰 사용"],
"timezone": {
"id": "Asia/Seoul",
"offsetInMinutes": 540
},
"isTemporary": false,
"createdAt": 1750211600306,
"updatedAt": 1750224769996
},
"goalAdherence": null
},
{
"sleepLog": {
"id": "80117adb-d727-462c-8e84-f60b5180e398",
"dayIndex": 9,
"date": "2025-06-24",
"dns": true,
"lot": null,
"aet": null,
"tstMinutes": null,
"sleepEfficiency": null,
"solMinutes": null,
"wasoMinutes": null,
"sleepQuality": null,
"positiveFactorIds": [],
"negativeFactorIds": [2],
"pill": false,
"napMinutes": 30,
"positiveCustomFactors": [],
"negativeCustomFactors": [],
"timezone": {
"id": "Asia/Seoul",
"offsetInMinutes": 540
},
"isTemporary": false,
"createdAt": 1750754142818,
"updatedAt": 1750755467951
},
"goalAdherence": {
"id": "4b5a87d5-2c8d-436a-a591-220238e1294c",
"targetDayIndex": 9,
"targetDate": "2025-06-24",
"sleepGoalId": "dsfdsafdsafdasfasdf",
"lotSuccess": false,
"aetSuccess": false,
"createdAt": 1750753836510,
"updatedAt": 1750753831032
}
}
],
"count": 4,
"startDayIndex": 1,
"endDayIndex": 9
}

2.5 임시 수면 기록 저장 API

  • HTTP 메서드: POST
  • 경로: /v1/sleep/logs/temporary
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"dayIndex": 7,
"lot": 1715300400000,
"sleepQuality": 4,
"pill": false,
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540
}

참고: 임시 수면 기록은 최소한 lot, aet, sleepQuality, pill 중 하나 이상의 정보가 필요합니다. 일차(dayIndex)는 필수로 지정해야 합니다.

응답 (Response)

  • 성공 응답 (201 Created)
{
"id": "sl_12345",
"dayIndex": 7,
"date": "2025-05-10",
"dns": false,
"lot": 1715300400000,
"sleepQuality": 4,
"pill": false,
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540,
"isTemporary": true,
"createdAt": 1715311800000,
"updatedAt": 1715311800000
}

2.6 임시 수면 기록 완성 API

  • HTTP 메서드: PUT
  • 경로: /v1/sleep/logs/temporary/complete/day-index/{dayIndex}
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"dns": false,
"aet": 1715329800000,
"solMinutes": 30,
"wasoMinutes": 15,
"positiveFactorIds": [1, 3, 5],
"negativeFactorIds": [2],
"napMinutes": 20
}

참고: 이 API는 기존 임시 기록을 완전한 수면 기록으로 전환합니다. 필수 항목 중 누락된 항목을 모두 포함해야 합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "sl_12345",
"dayIndex": 7,
"date": "2025-05-10",
"dns": false,
"lot": 1715300400000,
"aet": 1715329800000,
"tstMinutes": 450,
"sleepEfficiency": 0.9,
"solMinutes": 30,
"wasoMinutes": 15,
"sleepQuality": 4,
"positiveFactorIds": [1, 3, 5],
"negativeFactorIds": [2],
"pill": false,
"napMinutes": 20,
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540,
"isTemporary": false,
"createdAt": 1715311800000,
"updatedAt": 1715315400000
}
  • 오류 응답 (404 Not Found)
{
"code": 10045,
"message": "TEMPORARY_SLEEP_LOG_NOT_FOUND",
"detail": "해당 일차의 임시 수면 기록을 찾을 수 없습니다."
}

수면 목표 및 rTIB API

📌 구현 순서: 수면 기록 API 구현 후 진행합니다.

수면 목표 및 rTIB API는 수면 목표 조회, rTIB(권장 침대 체류 시간) 계산 및 제공, 목표 기상 시각 설정 등의 기능을 제공합니다. rTIB 계산은 직전 7일간의 유효한 수면 기록을 기반으로 수행됩니다.

3.1 수면 목표 조회 API (일차별)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/goals/day-index/{dayIndex}
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "sg_12345",
"targetDayIndex": 8,
"targetLOT": 1715295600000,
"targetAET": 1715324400000,
"rTIBMinutes": 480,
"goalType": "RTIB_ALGORITHM"
}
  • 오류 응답 (404 Not Found)
{
"code": 10041,
"message": "SLEEP_GOAL_NOT_FOUND",
"detail": "해당 일차의 수면 목표를 찾을 수 없습니다."
}

3.2 수면 목표 조회 API (일차 범위)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/goals/day-index-range
  • 쿼리 파라미터:
    • startDayIndex: 시작 일차
    • endDayIndex: 종료 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"items": [
{
"id": "sg_12345",
"targetDayIndex": 8,
"targetLOT": 1715295600000,
"targetAET": 1715324400000,
"rTIBMinutes": 480,
"goalType": "RTIB_ALGORITHM"
},
{
"id": "sg_12346",
"targetDayIndex": 9,
"targetLOT": 1715382000000,
"targetAET": 1715410800000,
"rTIBMinutes": 480,
"goalType": "SYSTEM"
}
],
"count": 2,
"startTargetDayIndex": 8,
"endTargetDayIndex": 9
}
  • 오류 응답 (400 Bad Request)
{
"code": 10002,
"message": "INVALID_PARAMETERS",
"detail": "잘못된 파라미터입니다. startDayIndex는 endDayIndex보다 작거나 같아야 합니다."
}
  • 오류 응답 (400 Bad Request - 일차 범위 초과)
{
"code": 10012,
"message": "INVALID_DAY_INDEX",
"detail": "유효하지 않은 일차 값입니다."
}

3.3 목표 기상 시각 설정 API

  • HTTP 메서드: PATCH
  • 경로: /v1/sleep/goals/target-wake-time
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

중요: 이 API는 rTIB를 처방받은 당일에 사용하며, 다음 일차(내일)의 목표 수면 시간을 설정하는 용도입니다. 목표 기상 시각 변경 시 목표 취침 시각도 연동되어 자동으로 계산됩니다.

rTIB 처방은 일반적으로 다음과 같은 흐름으로 이루어집니다:

  1. 사용자가 7일차에 수면 기록을 작성하면, 최소 4개 이상의 유효한 수면 기록이 확보된 경우 즉시 rTIB가 계산됩니다.
  2. 이 계산된 rTIB는 8일차부터 적용될 수면 목표를 위한 것입니다.
  3. 사용자는 7일차에 처방받은 rTIB에 대해 목표 기상 시각을 설정할 수 있으며, 이렇게 설정된 목표는 8일차부터 적용됩니다.

예를 들어, 현재 7일차(dayIndex: 7)에 rTIB 처방을 받았다면, 이 API를 통해 8일차(dayIndex: 8)의 목표 기상 시각을 설정합니다.

요청 (Request)

{
"targetAET": "07:30",
"targetDayIndex": 8,
"targetDate": "2025-05-11"
}

참고:

  • targetDayIndex: 목표를 적용할 다음 일차(현재 일차 + 1)
  • targetDate: 목표가 적용될 실제 날짜 (YYYY-MM-DD 형식)
  • targetAET: 설정하고자 하는 목표 기상 시각 (HH:MM 형식)

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "sg_12345",
"targetDayIndex": 8,
"targetDate": "2025-05-11",
"targetLOT": 1715385000000,
"targetAET": 1715412600000,
"rTIBInMinutes": 480,
"goalType": "USER",
"timezoneId": "Asia/Seoul",
"timezoneOffset": 540,
"createdAt": 1715225400000,
"updatedAt": 1715315400000
}
  • 오류 응답 (400 Bad Request)
{
"code": 10016,
"message": "TARGET_WAKE_TIME_CHANGE_NOT_ALLOWED",
"detail": "목표 기상 시각은 rTIB 처방을 받은 당일에만 다음 일차를 위해 설정할 수 있습니다."
}

3.4 최근 수면 목표 조회 API (사용자용)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/goals/users/me/latest
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "sg_12345",
"targetDayIndex": 8,
"targetLOT": 1715295600000,
"targetAET": 1715324400000,
"rTIBMinutes": 480,
"goalType": "RTIB_ALGORITHM"
}
  • 오류 응답 (404 Not Found)
{
"code": 10041,
"message": "SLEEP_GOAL_NOT_FOUND",
"detail": "수면 목표를 찾을 수 없습니다."
}

3.5 최근 수면 목표 조회 API (관리자용)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/goals/users/{userId}/latest
  • Headers:
    • Authorization: Bearer {accessToken}

중요: 이 API는 관리자 및 서비스 계정만 접근 가능합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"goal": {
"id": "sg_12345",
"targetDayIndex": 8,
"targetLOT": 1715295600000,
"targetAET": 1715324400000,
"rTIBMinutes": 480,
"goalType": "RTIB_ALGORITHM"
}
}
  • 오류 응답 (404 Not Found)
{
"code": 10044,
"message": "USER_NOT_FOUND",
"detail": "사용자를 찾을 수 없습니다."
}
  • 오류 응답 (404 Not Found)
{
"code": 10041,
"message": "SLEEP_GOAL_NOT_FOUND",
"detail": "해당 사용자의 수면 목표를 찾을 수 없습니다."
}

3.7 rTIB 조회 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/rtib/day-index/{dayIndex}
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "rtib_123",
"dayIndex": 7,
"date": "2025-05-10",
"rTIB": 480,
"calculationBasis": {
"avgTstMinutes": 450,
"avgSe": 0.9,
"avgDse": 500,
"startDayIndex": 1,
"endDayIndex": 6,
"validLogCount": 7,
"isFirstRtib": false
},
"calculatedOnSleepLogCreation": false,
"createdAt": 1715225400000
}
  • 오류 응답 (404 Not Found)
{
"code": 10042,
"message": "RTIB_RECOMMENDATION_NOT_FOUND",
"detail": "해당 일차의 rTIB 처방을 찾을 수 없습니다."
}

3.8 rTIB 계산 자격 확인 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/rtib/eligibility
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"eligible": true,
"reason": "FOLLOW_UP_RTIB_ELIGIBLE",
"details": {
"lastRtibDayIndex": 1,
"daysSinceLastRtib": 7,
"validLogsCount": 6
}
}
  • 성공 응답 (자격 없음) (200 OK)
{
"eligible": false,
"reason": "INSUFFICIENT_DATA",
"details": {
"lastRtibDayIndex": 1,
"daysSinceLastRtib": 7,
"validLogsCount": 3,
"requiredLogs": 5
}
}

3.9 수면 목표 달성 여부 조회 API (일차별)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/goal-adherence/day-index/{dayIndex}
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": "adh_12345",
"dayIndex": 7,
"date": "2025-05-10",
"sleepGoalId": "sg_12345",
"bedTimeGoalMet": true,
"wakeTimeGoalMet": false,
"createdAt": 1715315400000,
"updatedAt": 1715315400000,
"goal": {
"targetLOT": 1715295600000,
"targetAET": 1715324400000
},
"actual": {
"lot": 1715299700000,
"aet": 1715329800000
}
}

3.10 수면 목표 달성 여부 조회 API (일차 범위)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/goal-adherence/day-index-range
  • 쿼리 파라미터:
    • startDayIndex: 시작 일차
    • endDayIndex: 종료 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"items": [
{
"id": "adh_12345",
"dayIndex": 7,
"date": "2025-05-10",
"bedTimeGoalMet": true,
"wakeTimeGoalMet": false,
"goal": {
"targetLOT": 1715295600000,
"targetAET": 1715324400000
},
"actual": {
"lot": 1715299700000,
"aet": 1715329800000
}
},
{
"id": "adh_12346",
"dayIndex": 8,
"date": "2025-05-11",
"bedTimeGoalMet": true,
"wakeTimeGoalMet": true,
"goal": {
"targetLOT": 1715382000000,
"targetAET": 1715410800000
},
"actual": {
"lot": 1715380700000,
"aet": 1715409100000
}
}
],
"count": 2,
"startDayIndex": 7,
"endDayIndex": 8
}

수면 통계 API

📌 구현 순서: 수면 기록 및 목표 API 구현 후 진행합니다.

수면 통계 API는 주차별 수면 데이터 통계 및 다양한 시간 범위의 수면 데이터를 제공합니다. 주차는 연속된 7일 단위이며, 시작 일차(dayIndex)를 기준으로 합니다.

4.1 주차별 종합 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"userCycleId": "uc_456",
"startDayIndex": 7,
"endDayIndex": 13,
"se": {
"dailyData": [
{ "dayIndex": 7, "date": "2025-05-10", "value": 0.9 },
{ "dayIndex": 8, "date": "2025-05-11", "value": 0.94 },
{ "dayIndex": 9, "date": "2025-05-12", "value": 0.88 },
{ "dayIndex": 10, "date": "2025-05-13", "value": 0.92 },
{ "dayIndex": 11, "date": "2025-05-14", "value": 0.85 },
{ "dayIndex": 12, "date": "2025-05-15", "value": null },
{ "dayIndex": 13, "date": "2025-05-16", "value": 0.91 }
],
"average": 0.9,
"categories": {
"poor": 1,
"moderate": 3,
"good": 2
}
},
"sleepQuality": {
"dailyData": [
{ "dayIndex": 7, "date": "2025-05-10", "value": 3 },
{ "dayIndex": 8, "date": "2025-05-11", "value": 4 },
{ "dayIndex": 9, "date": "2025-05-12", "value": 3 },
{ "dayIndex": 10, "date": "2025-05-13", "value": 4 },
{ "dayIndex": 11, "date": "2025-05-14", "value": 2 },
{ "dayIndex": 12, "date": "2025-05-15", "value": null },
{ "dayIndex": 13, "date": "2025-05-16", "value": 3 }
],
"distribution": {
"1": { "count": 0, "percentage": 0 },
"2": { "count": 1, "percentage": 16.7 },
"3": { "count": 3, "percentage": 50.0 },
"4": { "count": 2, "percentage": 33.3 },
"5": { "count": 0, "percentage": 0 }
}
},
"tstMinutes": {
"dailyData": [
{ "dayIndex": 7, "date": "2025-05-10", "value": 450 },
{ "dayIndex": 8, "date": "2025-05-11", "value": 480 },
{ "dayIndex": 9, "date": "2025-05-12", "value": 440 },
{ "dayIndex": 10, "date": "2025-05-13", "value": 460 },
{ "dayIndex": 11, "date": "2025-05-14", "value": 420 },
{ "dayIndex": 12, "date": "2025-05-15", "value": 0 },
{ "dayIndex": 13, "date": "2025-05-16", "value": 455 }
],
"average": 450.8,
"min": 420,
"max": 480
},
"sleepMedication": {
"dailyData": [
{ "dayIndex": 7, "date": "2025-05-10", "value": true },
{ "dayIndex": 8, "date": "2025-05-11", "value": false },
{ "dayIndex": 9, "date": "2025-05-12", "value": false },
{ "dayIndex": 10, "date": "2025-05-13", "value": false },
{ "dayIndex": 11, "date": "2025-05-14", "value": true },
{ "dayIndex": 12, "date": "2025-05-15", "value": true },
{ "dayIndex": 13, "date": "2025-05-16", "value": false }
],
"totalDays": 3,
"percentage": 42.9
},
"solMinutes": {
"dailyData": [
{ "dayIndex": 7, "date": "2025-05-10", "value": 30 },
{ "dayIndex": 8, "date": "2025-05-11", "value": 20 },
{ "dayIndex": 9, "date": "2025-05-12", "value": 35 },
{ "dayIndex": 10, "date": "2025-05-13", "value": 25 },
{ "dayIndex": 11, "date": "2025-05-14", "value": 40 },
{ "dayIndex": 12, "date": "2025-05-15", "value": null },
{ "dayIndex": 13, "date": "2025-05-16", "value": 30 }
],
"average": 30,
"min": 20,
"max": 40
},
"napMinutes": {
"dailyData": [
{ "dayIndex": 7, "date": "2025-05-10", "value": 20 },
{ "dayIndex": 8, "date": "2025-05-11", "value": 0 },
{ "dayIndex": 9, "date": "2025-05-12", "value": 30 },
{ "dayIndex": 10, "date": "2025-05-13", "value": 0 },
{ "dayIndex": 11, "date": "2025-05-14", "value": 15 },
{ "dayIndex": 12, "date": "2025-05-15", "value": 45 },
{ "dayIndex": 13, "date": "2025-05-16", "value": 0 }
],
"average": 15.7,
"count": 110
},
"sleepFactors": {
"positive": {
"topFactors": [
{ "id": 3, "title": "좋은 기분", "count": 4, "percentage": 66.7 },
{ "id": 1, "title": "야외에서의 운동", "count": 3, "percentage": 50.0 },
{ "id": 5, "title": "이완 운동", "count": 2, "percentage": 33.3 }
],
"dailyData": [
{
"dayIndex": 7,
"date": "2025-05-10",
"factors": [
{ "id": 1, "title": "야외에서의 운동" },
{ "id": 3, "title": "좋은 기분" },
{ "id": 5, "title": "이완 운동" }
]
},
{ "dayIndex": 8, "date": "2025-05-11", "factors": [{ "id": 3, "title": "좋은 기분" }] },
{
"dayIndex": 9,
"date": "2025-05-12",
"factors": [
{ "id": 1, "title": "야외에서의 운동" },
{ "id": 3, "title": "좋은 기분" }
]
},
{ "dayIndex": 10, "date": "2025-05-13", "factors": [{ "id": 4, "title": "낮 동안의 햇빛" }] },
{
"dayIndex": 11,
"date": "2025-05-14",
"factors": [
{ "id": 1, "title": "야외에서의 운동" },
{ "id": 5, "title": "이완 운동" }
]
},
{ "dayIndex": 12, "date": "2025-05-15", "factors": [] },
{ "dayIndex": 13, "date": "2025-05-16", "factors": [{ "id": 3, "title": "좋은 기분" }] }
]
},
"negative": {
"topFactors": [
{ "id": 2, "title": "스트레스나 걱정", "count": 5, "percentage": 71.4 },
{ "id": 4, "title": "저녁에 카페인/알코올 섭취", "count": 2, "percentage": 28.6 },
{ "id": 5, "title": "통증이나 불편함", "count": 1, "percentage": 14.3 }
],
"dailyData": [
{
"dayIndex": 7,
"date": "2025-05-10",
"factors": [
{ "id": 2, "title": "스트레스나 걱정" },
{ "id": 4, "title": "저녁에 카페인/알코올 섭취" }
]
},
{ "dayIndex": 8, "date": "2025-05-11", "factors": [{ "id": 2, "title": "스트레스나 걱정" }] },
{ "dayIndex": 9, "date": "2025-05-12", "factors": [{ "id": 2, "title": "스트레스나 걱정" }] },
{ "dayIndex": 10, "date": "2025-05-13", "factors": [{ "id": 5, "title": "통증이나 불편함" }] },
{
"dayIndex": 11,
"date": "2025-05-14",
"factors": [
{ "id": 2, "title": "스트레스나 걱정" },
{ "id": 4, "title": "저녁에 카페인/알코올 섭취" }
]
},
{ "dayIndex": 12, "date": "2025-05-15", "factors": [{ "id": 2, "title": "스트레스나 걱정" }] },
{ "dayIndex": 13, "date": "2025-05-16", "factors": [] }
]
}
},
"goalAdherence": {
"dailyData": [
{
"dayIndex": 7,
"targetLOT": 1715295600000,
"actualBedTime": 1715299700000,
"bedTimeGoalMet": true,
"targetAET": 1715324400000,
"actualWakeTime": 1715329800000,
"wakeTimeGoalMet": false
},
{
"dayIndex": 8,
"targetLOT": 1715382000000,
"actualBedTime": 1715380700000,
"bedTimeGoalMet": true,
"targetAET": 1715410800000,
"actualWakeTime": 1715409100000,
"wakeTimeGoalMet": true
},
{
"dayIndex": 9,
"targetLOT": 1715468400000,
"actualBedTime": 1715470400000,
"bedTimeGoalMet": true,
"targetAET": 1715497200000,
"actualWakeTime": 1715498400000,
"wakeTimeGoalMet": true
},
{
"dayIndex": 10,
"targetLOT": 1715554800000,
"actualBedTime": 1715553400000,
"bedTimeGoalMet": true,
"targetAET": 1715583600000,
"actualWakeTime": 1715582400000,
"wakeTimeGoalMet": true
},
{
"dayIndex": 11,
"targetLOT": 1715641200000,
"actualBedTime": 1715643600000,
"bedTimeGoalMet": false,
"targetAET": 1715670000000,
"actualWakeTime": 1715665600000,
"wakeTimeGoalMet": true
},
{
"dayIndex": 12,
"targetLOT": 1715727600000,
"actualBedTime": null,
"bedTimeGoalMet": null,
"targetAET": 1715756400000,
"actualWakeTime": null,
"wakeTimeGoalMet": null
},
{
"dayIndex": 13,
"targetLOT": 1715814000000,
"actualBedTime": 1715815800000,
"bedTimeGoalMet": true,
"targetAET": 1715842800000,
"actualWakeTime": 1715843500000,
"wakeTimeGoalMet": true
}
],
"bedTimeMetCount": 5,
"wakeTimeMetCount": 5,
"totalDaysWithGoal": 6
}
}

4.2 수면 효율 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/efficiency
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 se 부분과 동일한 형식

4.3 수면의 질 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/quality
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 sleepQuality 부분과 동일한 형식

4.4 총 수면 시간 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/tst
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 tst 부분과 동일한 형식

4.5 수면제 복용 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/medication
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 sleepMedication 부분과 동일한 형식

4.6 SOL 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/sol
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 sol 부분과 동일한 형식

4.7 낮잠 시간 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/nap-time
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 napTime 부분과 동일한 형식

4.8 수면 영향 요인 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/factors
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 sleepFactors 부분과 동일한 형식

4.9 목표 달성 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/weekly/goal-adherence
  • 쿼리 파라미터:
    • startDayIndex: 주차 시작 일차
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK): 위 응답의 goalAdherence 부분과 동일한 형식

4.10 사용자 지정 범위 통계 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/statistics/custom-range
  • 쿼리 파라미터:
    • startDayIndex: 시작 일차 (필수)
    • endDayIndex: 종료 일차 (옵션)
    • aggregationType: 집계 유형 (옵션, 기본값: "DAILY", 가능한 값: "DAILY", "WEEKLY", "MONTHLY", "QUARTERLY")
  • Headers:
    • Authorization: Bearer {accessToken}

참고: 이 API는 백엔드 시스템의 유연한 데이터 조회 요구사항을 지원하기 위한 것으로, 특정 일차 범위를 지정하여 데이터를 조회하거나 특정 집계 단위로 데이터를 제공합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"userCycleId": "uc_456",
"startDayIndex": 1,
"endDayIndex": 30,
"aggregationType": "WEEKLY",
"data": [
{
"startDayIndex": 1,
"endDayIndex": 7,
"averageTstMinutes": 445.8,
"averageSe": 0.91,
"medicationDays": 2,
"goalAdherence": {
"bedTimeMetCount": 5,
"wakeTimeMetCount": 6,
"totalDaysWithGoal": 7
}
},
{
"startDayIndex": 8,
"endDayIndex": 14,
"averageTstMinutes": 450.8,
"averageSe": 0.9,
"medicationDays": 3,
"goalAdherence": {
"bedTimeMetCount": 5,
"wakeTimeMetCount": 5,
"totalDaysWithGoal": 6
}
},
{
"startDayIndex": 15,
"endDayIndex": 21,
"averageTstMinutes": 460.0,
"averageSe": 0.92,
"medicationDays": 1,
"goalAdherence": {
"bedTimeMetCount": 6,
"wakeTimeMetCount": 6,
"totalDaysWithGoal": 7
}
},
{
"startDayIndex": 22,
"endDayIndex": 28,
"averageTstMinutes": 455.5,
"averageSe": 0.93,
"medicationDays": 2,
"goalAdherence": {
"bedTimeMetCount": 5,
"wakeTimeMetCount": 6,
"totalDaysWithGoal": 7
}
},
{
"startDayIndex": 29,
"endDayIndex": 30,
"averageTstMinutes": 470.0,
"averageSe": 0.94,
"medicationDays": 0,
"goalAdherence": {
"bedTimeMetCount": 2,
"wakeTimeMetCount": 2,
"totalDaysWithGoal": 2
}
}
],
"summary": {
"averageTstMinutes": 452.9,
"minTstMinutes": 420,
"maxTstMinutes": 485,
"averageSe": 0.92,
"totalMedicationDays": 8,
"medicationPercentage": 26.7,
"averageBedTimeAdherence": 0.77,
"averageWakeTimeAdherence": 0.83
}
}

4.11 관리자용 사용자 데이터 접근 API

  • HTTP 메서드: GET
  • 경로: /v1/sleep/admin/data/{userId}
  • 쿼리 파라미터:
    • startDate: 시작 날짜 (YYYY-MM-DD, 옵션)
    • endDate: 종료 날짜 (YYYY-MM-DD, 옵션)
    • startDayIndex: 시작 일차 (옵션)
    • endDayIndex: 종료 일차 (옵션)
    • includeStatistics: 통계 포함 여부 (기본값: false)
  • Headers:
    • Authorization: Bearer {accessToken}

중요: 이 API는 관리자 및 서비스 계정만 접근 가능합니다. 시스템은 관리자의 데이터 접근에 대한 감사 로그를 기록합니다.

응답 (Response)

  • 성공 응답 (200 OK): 수면 기록, 목표, rTIB 처방 및 통계 정보를 포함하는 종합 데이터

데이터 관리 및 개인정보 보호 API

📌 구현 순서: 핵심 기능 구현 후 GDPR 준수를 위해 구현합니다.

이 API들은 GDPR 준수 및 데이터 보관 정책 요구사항을 지원하기 위해 관리자 또는 사용자가 데이터 생명주기를 관리하는 기능을 제공합니다.

5.1 사용자 데이터 아카이빙 API (관리자용)

  • HTTP 메서드: POST
  • 경로: /v1/sleep/admin/users/{userId}/archive
  • Headers:
    • Authorization: Bearer {adminAccessToken}

참고: 비활성 상태로 1년 이상 경과한 사용자의 데이터를 콜드 스토리지로 이전합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"status": "ARCHIVED",
"archivedAt": 1735689600000
}
  • 오류 응답 (404 Not Found)
{
"code": 10044,
"message": "USER_NOT_FOUND",
"detail": "사용자를 찾을 수 없습니다."
}
  • 오류 응답 (400 Bad Request)
{
"code": 10101,
"message": "ARCHIVING_NOT_ALLOWED",
"detail": "활성 상태이거나 아카이빙 조건(비활성 1년 경과)을 만족하지 않아 아카이빙할 수 없습니다."
}
  • 오류 응답 (500 Server Error)
{
"code": 10100,
"message": "ARCHIVING_FAILED",
"detail": "데이터 아카이빙 중 오류가 발생했습니다."
}

5.2 사용자 데이터 복원 API (관리자용)

  • HTTP 메서드: POST
  • 경로: /v1/sleep/admin/users/{userId}/restore
  • Headers:
    • Authorization: Bearer {adminAccessToken}

참고: 콜드 스토리지에 아카이빙된 사용자 데이터를 주 데이터베이스로 복원합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"status": "ACTIVE",
"restoredAt": 1735776000000
}
  • 오류 응답 (404 Not Found)
{
"code": 10102,
"message": "ARCHIVED_DATA_NOT_FOUND",
"detail": "아카이빙된 사용자 데이터를 찾을 수 없습니다."
}
  • 오류 응답 (500 Server Error)
{
"code": 10103,
"message": "RESTORATION_FAILED",
"detail": "데이터 복원 중 오류가 발생했습니다."
}

5.3 사용자 데이터 영구 삭제 API (관리자용)

  • HTTP 메서드: DELETE
  • 경로: /v1/sleep/admin/users/{userId}/data
  • Headers:
    • Authorization: Bearer {adminAccessToken}

주의: 이 작업은 되돌릴 수 없습니다. 주 데이터베이스 및 콜드 스토리지에서 사용자 데이터를 영구 삭제합니다.

응답 (Response)

  • 성공 응답 (204 No Content)

  • 오류 응답 (500 Server Error)

{
"code": 10104,
"message": "DELETION_FAILED",
"detail": "데이터 삭제 중 오류가 발생했습니다."
}

5.4 사용자 데이터 익명화 API (관리자용)

  • HTTP 메서드: POST
  • 경로: /v1/sleep/admin/users/{userId}/anonymize
  • Headers:
    • Authorization: Bearer {adminAccessToken}

참고: 사용자의 개인 식별 정보를 제거하고 통계 분석 등을 위해 데이터를 보존합니다.

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"status": "ANONYMIZED",
"anonymizedAt": 1735862400000
}
  • 오류 응답 (500 Server Error)
{
"code": 10105,
"message": "ANONYMIZATION_FAILED",
"detail": "데이터 익명화 중 오류가 발생했습니다."
}

5.5 내 데이터 추출 요청 API (사용자용)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/users/me/data-export
  • 쿼리 파라미터:
    • format: 추출 형식 (기본값: "JSON", 가능한 값: "JSON", "CSV")
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"message": "Data export started. You will be notified when it is ready.",
"exportId": "export_abc123"
}
  • 오류 응답 (400 Bad Request)
{
"code": 10107,
"message": "INVALID_EXPORT_FORMAT",
"detail": "지원되지 않는 추출 형식입니다. (JSON 또는 CSV 사용)"
}
  • 오류 응답 (500 Server Error)
{
"code": 10106,
"message": "EXPORT_FAILED",
"detail": "데이터 추출 시작 중 오류가 발생했습니다."
}

5.6 특정 사용자 데이터 추출 요청 API (관리자용)

  • HTTP 메서드: GET
  • 경로: /v1/sleep/admin/users/{userId}/data-export
  • 쿼리 파라미터:
    • format: 추출 형식 (기본값: "JSON", 가능한 값: "JSON", "CSV")
  • Headers:
    • Authorization: Bearer {adminAccessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"message": "Data export started for user user_123.",
"exportId": "export_def456"
}

오류 코드

Sleep 도메인 API에서 사용하는 오류 코드는 다음과 같습니다:

HTTP 상태 코드오류 코드메시지설명대응 방법
50010000SERVER_ERROR서버 내부 오류서버 로그 확인 및 시스템 관리자에게 문의
40010001MISSING_REQUIRED_FIELDS필수 입력 항목이 누락되었습니다누락된 필드를 확인하고 모든 필수 항목을 포함하여 다시 요청
40010002INVALID_PARAMETERS잘못된 파라미터입니다파라미터 값과 형식을 확인하여 올바른 값으로 다시 요청
40010003INVALID_FORMAT입력 형식이 유효하지 않습니다올바른 형식으로 데이터 제공(시간, 날짜 등)
40010004INVALID_TIMEZONE유효하지 않은 시간대 ID올바른 시간대 ID 사용(예: "Asia/Seoul")
40010005INVALID_SLEEP_QUALITY유효하지 않은 수면의 질 값1-5 사이의 정수 값 사용
40010006INVALID_TIME_RANGE유효하지 않은 시간 범위시작 시간이 종료 시간보다 이전인지 확인
40010007INVALID_FACTOR_ID유효하지 않은 영향 요인 ID존재하는 영향 요인 ID 사용
40010008TOO_MANY_CUSTOM_FACTORS사용자 정의 요인이 너무 많습니다최대 10개까지만 입력
40010009SLEEP_TIME_VALIDATION_FAILED수면 시간 검증에 실패했습니다잠자리에 든 시각(LOT)은 18:00 이후여야 하고, 일어난 시각(AET)은 LOT보다 이후여야 함
40010010DATE_VALIDATION_FAILED날짜 검증에 실패했습니다수면 기록은 당일 일차에만 생성/수정 가능합니다.
40310011TREATMENT_SUSPENDED치료 활동 일시 정지 상태입니다치료 활동 재개 후 다시 시도
40010012INVALID_DAY_INDEX유효하지 않은 일차 값존재하는 치료 주기 일차 값 사용
40010013INVALID_RTIB유효하지 않은 rTIB 값유효한 rTIB 처방 ID 사용
40010014INVALID_TST계산된 총 수면 시간(TST)과 제공된 값이 일치하지 않습니다올바른 TST 값 입력 또는 필드 제거
40010015UNEXPECTED_SLEEP_DATADNS=true인 경우 수면 관련 데이터를 입력할 수 없습니다DNS=true일 때는 lot, aet, solMinutes, wasoMinutes, tstMinutes 필드 제거
40010016TARGET_WAKE_TIME_CHANGE_NOT_ALLOWED목표 기상 시각 변경이 허용되지 않습니다rTIB 처방일 당일 일차에만 변경 가능
40010020CUSTOM_FACTOR_TOO_LONG사용자 정의 요인이 너무 깁니다각 항목은 최대 100자까지 입력 가능
40310030INSUFFICIENT_PERMISSIONS권한이 충분하지 않습니다필요한 권한을 확인하고 적절한 계정 사용
40410040SLEEP_LOG_NOT_FOUND수면 기록을 찾을 수 없습니다날짜 또는 ID 확인
40410041SLEEP_GOAL_NOT_FOUND수면 목표를 찾을 수 없습니다날짜 또는 ID 확인
40410042RTIB_RECOMMENDATION_NOT_FOUNDrTIB 처방을 찾을 수 없습니다날짜 또는 ID 확인
40410043SLEEP_GOAL_ADHERENCE_NOT_FOUND수면 목표 달성 기록을 찾을 수 없습니다날짜 또는 ID 확인
40410044USER_NOT_FOUND사용자를 찾을 수 없습니다사용자 ID 확인
40410045TEMPORARY_SLEEP_LOG_NOT_FOUND임시 수면 기록을 찾을 수 없습니다날짜 확인 또는 임시 기록 먼저 생성
50010050STATISTICS_CALCULATION_FAILED통계 계산에 실패했습니다서버 로그 확인 및 시스템 관리자에게 문의
40010051INSUFFICIENT_DATA_FOR_STATISTICS통계를 계산하기 위한 데이터가 충분하지 않습니다더 많은 수면 기록 입력 후 다시 시도
40910090SLEEP_LOG_ALREADY_EXISTS해당 날짜에 이미 수면 기록이 존재합니다기존 기록 수정 또는 다른 날짜 사용
40910091SLEEP_GOAL_ALREADY_EXISTS해당 날짜에 이미 수면 목표가 존재합니다기존 목표 수정 또는 다른 날짜 사용
42910092RATE_LIMIT_EXCEEDED요청 횟수가 제한을 초과했습니다잠시 후 다시 시도
50010100ARCHIVING_FAILED데이터 아카이빙 중 오류가 발생했습니다.서버 로그 확인 및 시스템 관리자에게 문의
40010101ARCHIVING_NOT_ALLOWED아카이빙 조건(비활성 1년 경과)을 만족하지 않아 아카이빙할 수 없습니다.사용자 상태 및 마지막 활동 시간 확인
40410102ARCHIVED_DATA_NOT_FOUND아카이빙된 사용자 데이터를 찾을 수 없습니다.사용자 ID 및 아카이브 상태 확인
50010103RESTORATION_FAILED데이터 복원 중 오류가 발생했습니다.서버 로그 확인 및 시스템 관리자에게 문의
50010104DELETION_FAILED데이터 삭제 중 오류가 발생했습니다.서버 로그 확인 및 시스템 관리자에게 문의
50010105ANONYMIZATION_FAILED데이터 익명화 중 오류가 발생했습니다.서버 로그 확인 및 시스템 관리자에게 문의
50010106EXPORT_FAILED데이터 추출 중 오류가 발생했습니다.서버 로그 확인 및 시스템 관리자에게 문의
40010107INVALID_EXPORT_FORMAT지원되지 않는 추출 형식입니다.요청 파라미터 확인 (JSON 또는 CSV 사용)
50010099UNKNOWN_SLEEP_ERROR알 수 없는 수면 도메인 오류가 발생했습니다서버 로그 확인 및 시스템 관리자에게 문의

변경 이력

버전날짜작성자변경 내용
0.1.02025-05-05bok@weltcorp.com최초 작성
0.2.02025-05-10bok@weltcorp.com시간 검증, 날짜 검증 관련 API 설명 추가
0.3.02025-05-15bok@weltcorp.com임시 수면 기록 관련 API 추가
0.4.02025-05-20bok@weltcorp.com주차별 통계 API, 사용자 지정 범위 통계 API 추가
0.5.02025-05-25bok@weltcorp.com관리자용 데이터 접근 API 추가
0.6.02025-05-30bok@weltcorp.comlot, aet를 Unix timestamp(밀리초) 형식으로 변경
0.7.02025-05-31bok@weltcorp.com오류 코드를 6000번대 체계로 변경
0.8.02025-06-01bok@weltcorp.com수면 기록 생성/수정 API에 일차(day-index) 기반 엔드포인트 추가
0.9.02025-06-02bok@weltcorp.com날짜(date) 기반 API 제거, 일차(day-index) 기반 API로 통일
0.10.02025-06-03bok@weltcorp.com수면 기록 수정 API의 HTTP 메서드를 PUT에서 PATCH로 변경 (부분 업데이트 명확화)
0.11.02025-06-04bok@weltcorp.com요청 body에 날짜(date) 필드 추가 및 설명 보완
0.12.02025-06-05bok@weltcorp.com목표 기상 시각 설정 API 설명 개선 - 다음 일차 목표 설정 흐름 명확화
0.13.02025-06-06bok@weltcorp.comrTIB 처방 시점 및 적용 흐름 명확화 - 7일차 처방, 8일차 적용 명시
0.14.02025-06-07bok@weltcorp.com요청 body에서 날짜(date) 필드 제거, 일차(dayIndex)만 사용하도록 변경
0.15.02025-05-13bok@weltcorp.comGDPR 준수 및 데이터 관리 API 추가 (아카이빙, 복원, 삭제, 익명화, 추출) 및 관련 오류 코드 추가
0.16.02025-05-23dalia@weltcorp.com수면 기록 생성 API 관련 누락된 오류 코드 추가 및 Request, Response 수정
0.17.02025-05-27dalia@weltcorp.com에러 코드 변경 및 수면기록 생성 API Request 수정
0.18.02025-07-28bok@weltcorp.com최근 수면 목표 조회 API 추가 (사용자용 및 관리자용), 사용자용은 /users/me 패턴 적용, 모든 수면 목표 API 응답 형식 통일