수면 기록 생성 API
개요
수면 기록 생성 API는 사용자의 일일 수면 데이터를 저장하고 관리하는 기능을 제공합니다. 수면 기록은 수면 여부(DNS), 잠자리에 든 시각, 일어난 시각, 수면의 질, 영향 요인 등의 정보를 포함하며, 사용자의 수면 패턴 분석과 rTIB(Recommended Time In Bed) 계산의 기반 데이터로 활용됩니다.
수면 기록 유형
수면 기록은 수면 여부에 따라 다음과 같이 구분됩니다:
- DNS (Did Not Sleep) = false: 잠을 잔 경우
- 필수 항목:
lot,aet,sleepQuality,solMinutes,wasoMinutes,pill,napMinutes - 영향 요인:
positiveFactorIds와positiveCustomFactors중 하나 이상,negativeFactorIds와negativeCustomFactors중 하나 이상 필요
- 필수 항목:
- DNS (Did Not Sleep) = true: 전혀 잠을 자지 못한 경우
- 필수 항목:
pill,napMinutes - 영향 요인:
negativeFactorIds와negativeCustomFactors중 하나 이상 필요 - 입력 불가 항목:
lot,aet,sleepQuality,solMinutes,wasoMinutes,positiveFactorIds,positiveCustomFactors,tstMinutes
- 필수 항목:
수면 지표 자동 계산
시스템은 수면 기록 생성 시 다음 지표를 자동으로 계산합니다:
- TST (Total Sleep Time): 총 수면 시간 = TIB - SOL - WASO (분 단위)
- SE (Sleep Efficiency): 수면 효율 = TST / TIB (0~1 사이의 값)
제약사항
- 수면 기록은 당일 일차(현재 진행 중인 dayIndex)에만 생성 가능
- 치료 활동이 일시 정지된 상태에서는 생성 불가
- 동일한 일차에 중복 생성 불가
- LOT(잠자리에 든 시각)는 전날 18:00 이후여야 함 (어제 자정부터 1080분 이후)
- LOT, AET는 현재 시간 이전이어야 함 (어제 자정부터 현재까지의 경과 분 범위 내)
- 사용자 지정 요인에서 빈 문자열("")은 없는 값으로 취급
수면 기록 생성
사용자의 일일 수면 기록을 생성합니다.
- HTTP Method:
POST - Path:
/v1/sleep/logs/day-index - 인증: 액세스 토큰 (
accessToken) 필요
Headers
| Header | Type | Description | Required |
|---|---|---|---|
Content-Type | application/json | 요청 본문 형식을 지정합니다. | Yes |
Authorization | Bearer {accessToken} | 사용자 인증을 통해 발급받은 액세스 토큰입니다. | Yes |
Accept-Language | de-DE, en-US, ko-KR | 오류 메시지의 언어를 지정합니다. 지역 코드를 포함한 형식(예: de-DE, en-US, ko-KR)만 지원합니다. | No |
Request Body
잠을 잔 경우 (DNS = false) 예시:
{
"dayIndex": 10,
"dns": false,
"pill": false,
"negativeFactorIds": [2],
"napMinutes": 30,
"lot": 1380,
"aet": 1920,
"sleepQuality": 4,
"solMinutes": 30,
"wasoMinutes": 0,
"positiveFactorIds": [3, 4],
"positiveCustomFactors": ["충분한 운동", "따뜻한 샤워"],
"negativeCustomFactors": ["늦은 카페인 섭취", "스마트폰 사용"],
"tstMinutes": 510
}
전혀 잠을 자지 못한 경우 (DNS = true) 예시:
{
"dayIndex": 7,
"dns": true,
"negativeFactorIds": [2, 4],
"pill": false,
"napMinutes": 0
}
| 필드 | 타입 | 설명 |
|---|---|---|
dayIndex | number | 치료 주기 일차 (현재 진행 중인 일차만 허용) |
dns | boolean | Did Not Sleep 여부 (전혀 잠을 자지 못했는지) |
lot | number | 잠자리에 든 시각 (어제 자정부터의 경과 분, DNS=false인 경우에만) |
aet | number | 일어난 시각 (어제 자정부터의 경과 분, DNS=false인 경우에만) |
sleepQuality | number | 수면의 질 (1점: 매우 나쁨 ~ 5점: 매우 좋음) |
solMinutes | number | 잠들기까지 걸린 시간 (분, 기본값: 0) |
wasoMinutes | number | 수면 중 깬 시간 총합 (분, 기본값: 0) |
positiveFactorIds | number[] | 긍정적 영향 요인 ID 목록 (사전 정의된 요인) |
negativeFactorIds | number[] | 부정적 영향 요인 ID 목록 (사전 정의된 요인) |
pill | boolean | 수면제 복용 여부 |
napMinutes | number | 낮잠 시간 (분, 기본값: 0) |
positiveCustomFactors | string[] | 사용자 지정 긍정적 요인 (최대 10개, 각 100자 이내) |
negativeCustomFactors | string[] | 사용자 지정 부정적 요인 (최대 10개, 각 100자 이내) |
tstMinutes | number | 총 수면 시간 (분, 선택사항, 제공 시 계산값과 일치해야 함) |
긍정적 영향 요인 (Positive Factors)
⚠️ 참고: 아래 요인 목록은 임시 데이터이며, 최종 확정된 사항이 아닙니다.
| ID | 독일어 | 한국어 |
|---|---|---|
| 1 | Keine | 없음 |
| 2 | Bewegung an der frischen Luft | 야외에서의 운동 |
| 3 | Gute Stimmung | 좋은 기분 |
| 4 | Sonnenlicht am Tag | 낮 동안의 햇빛 |
| 5 | Entspannungsübung | 이완 운동 |
| 6 | Entspannte Abendroutine | 편안한 저녁 루틴 |
부정적 영향 요인 (Negative Factors)
⚠️ 참고: 아래 요인 목록은 임시 데이터이며, 최종 확정된 사항이 아닙니다.
| ID | 독일어 | 한국어 |
|---|---|---|
| 1 | Keine | 없음 |
| 2 | Stress oder Sorgen | 스트레스나 걱정 |
| 3 | Spätes Arbeiten/Aktivität | 늦은 시간 업무/활동 |
| 4 | Koffein/Alkohol am Abend | 저녁에 카페인/알코올 섭취 |
| 5 | Schmerz oder Unwohlsein | 통증이나 불편함 |
| 6 | Unruhige Schlafumgebung (Licht, Lärm, Hitze) | 불안한 수면 환경 (빛, 소음, 열) |
Responses
| HTTP Status Code | 설명 | Error Code(s) |
|---|---|---|
201 Created | 성공 | - |
400 Bad Request | 잘못된 요청 (필수 필드 누락, 시간 유효성 검증 실패, TST 불일치, 수면 데이터 오류) | 10001, 10009, 10014, 10015, 10017 |
403 Forbidden | 권한 없음 (치료 활동 일시 정지, 날짜 제약 위반) | 10010, 10011, 10012 |
409 Conflict | 리소스 충돌 (이미 존재하는 수면 기록) | 10090 |
500 Internal Server Error | 서버 내부 오류 | 10000 |
201 Created - 성공
수면 기록 생성 성공 (수면 목표가 있는 경우, 목표 달성 정보 포함):
{
"sleepLog": {
"id": "80117adb-d727-462c-8e84-f60b5180e398",
"dayIndex": 9,
"dns": false,
"lot": 1380,
"aet": 1920,
"tstMinutes": 450,
"sleepEfficiency": 0.9375,
"solMinutes": 0,
"wasoMinutes": 30,
"sleepQuality": 4,
"positiveFactorIds": [3, 4],
"negativeFactorIds": [2],
"pill": false,
"napMinutes": 30,
"positiveCustomFactors": ["충분한 운동", "따뜻한 샤워"],
"negativeCustomFactors": [],
"isTemporary": false,
"createdAt": 1750754142818,
"updatedAt": 1750754142818
},
"goalAdherence": {
"id": "adh_12345",
"targetDayIndex": 8,
"sleepGoalId": "sg_12345",
"lotSuccess": true,
"aetSuccess": false,
"createdAt": 1715315400000,
"updatedAt": 1715315400000
}
}
수면 기록 생성 성공 (수면 목표가 없는 경우, 목표 달성 정보 없음):
{
"sleepLog": {
"id": "80117adb-d727-462c-8e84-f60b5180e398",
"dayIndex": 9,
"dns": false,
"lot": 1380,
"aet": 1920,
"tstMinutes": 450,
"sleepEfficiency": 0.9375,
"solMinutes": 0,
"wasoMinutes": 30,
"sleepQuality": 4,
"positiveFactorIds": [3, 4],
"negativeFactorIds": [2],
"pill": false,
"napMinutes": 30,
"positiveCustomFactors": ["충분한 운동", "따뜻한 샤워"],
"negativeCustomFactors": [],
"isTemporary": false,
"createdAt": 1750754142818,
"updatedAt": 1750754142818
},
"goalAdherence": null
}
| 필드 | 타입 | 설명 |
|---|---|---|
sleepLog | object | 생성된 수면 기록 정보 |
sleepLog.id | string | 수면 기록 고유 ID |
sleepLog.dayIndex | number | 치료 주기 일차 |
sleepLog.dns | boolean | Did Not Sleep 여부 |
sleepLog.lot | number | 잠자리에 든 시각 (어제 자정부터의 경과 분, DNS=false인 경우에만) |
sleepLog.aet | number | 일어난 시각 (어제 자정부터의 경과 분, DNS=false인 경우에만) |
sleepLog.tstMinutes | number | 총 수면 시간 (분, 시스템 계산값) |
sleepLog.sleepEfficiency | number | 수면 효율 (0~1, 시스템 계산값) |
sleepLog.solMinutes | number | 잠들기까지 걸린 시간 (분) |
sleepLog.wasoMinutes | number | 수면 중 깬 시간 총합 (분) |
sleepLog.sleepQuality | number | 수면의 질 (1점: 매우 나쁨 ~ 5점: 매우 좋음) |
sleepLog.positiveFactorIds | array | 긍정적 영향 요인 ID 목록 |
sleepLog.negativeFactorIds | array | 부정적 영향 요인 ID 목록 |
sleepLog.pill | boolean | 수면제 복용 여부 |
sleepLog.napMinutes | number | 낮잠 시간 (분) |
sleepLog.positiveCustomFactors | array | 사용자 지정 긍정적 요인 |
sleepLog.negativeCustomFactors | array | 사용자 지정 부정적 요인 |
sleepLog.isTemporary | boolean | 임시 기록 여부 (항상 false) |
sleepLog.createdAt | number | 생성 시각 (Unix timestamp in milliseconds, Kotlin: Long, Swift: Int64) |
sleepLog.updatedAt | number | 수정 시각 (Unix timestamp in milliseconds, Kotlin: Long, Swift: Int64) |
goalAdherence | object | 수면 목표 달성 정보 (수면 목표가 있는 경우에만 포함) |
goalAdherence.id | string | 목표 달성 기록 고유 ID |
goalAdherence.targetDayIndex | number | 치료 주기 일차 |
goalAdherence.sleepGoalId | string | 수면 목표 ID |
goalAdherence.lotSuccess | boolean | 목표 취침 시각 달성 여부 (±30분 이내) |
goalAdherence.aetSuccess | boolean | 목표 기상 시각 달성 여부 (±30분 이내) |
goalAdherence.createdAt | number | 생성 시각 (Unix timestamp in milliseconds, Kotlin: Long, Swift: Int64) |
goalAdherence.updatedAt | number | 수정 시각 (Unix timestamp in milliseconds, Kotlin: Long, Swift: Int64) |
400 Bad Request - 잘못된 요청
예시: DNS=false일 때 필수 필드 누락 (MISSING_REQUIRED_FIELDS - 10001)
{
"code": 10001,
"message": "MISSING_REQUIRED_FIELDS",
"detail": "dns=false인 경우 필수 항목이 누락되었습니다.",
"metadata": {
"fields": ["sleepQuality", "lot", "aet"],
"context": "dns=false인 경우 필수 항목"
}
}
예시: 시간 유효성 검증 실패 (SLEEP_TIME_VALIDATION_FAILED - 10009)
{
"code": 10009,
"message": "SLEEP_TIME_VALIDATION_FAILED",
"detail": "잠자리에 든 시각은 어제 18:00 이후여야 합니다 (사용자 시간대 기준)",
"metadata": {
"lot": 1050,
"reason": "잠자리에 든 시각은 어제 18:00 이후여야 합니다 (사용자 시간대 기준)"
}
}
예시: TST 불일치 (INVALID_TST - 10014)
{
"code": 10014,
"message": "INVALID_TST",
"detail": "계산된 총 수면 시간(450분)과 제공된 값(480분)이 일치하지 않습니다",
"metadata": {
"calculated": 450,
"provided": 480
}
}
예시: DNS=true일 때 수면 데이터 포함 (UNEXPECTED_SLEEP_DATA - 10015)
{
"code": 10015,
"message": "UNEXPECTED_SLEEP_DATA",
"detail": "DNS=true인 경우 수면 관련 데이터를 입력할 수 없습니다.",
"metadata": {
"unexpectedFields": ["lot", "aet", "sleepQuality"]
}
}
예시: "없음" 선택 시 사용자 지정 요인 입력 (INVALID_CUSTOM_FACTORS - 10017)
{
"code": 10017,
"message": "INVALID_CUSTOM_FACTORS",
"detail": "긍정적 영향 요인에 '없음'이 선택된 경우 사용자 지정 긍정적 요인을 입력할 수 없습니다.",
"metadata": {
"factorType": "positive",
"selectedFactorIds": [1],
"invalidCustomFactors": ["좋은 베개", "편안한 음악"]
}
}
{
"code": 10017,
"message": "INVALID_CUSTOM_FACTORS",
"detail": "부정적 영향 요인에 '없음'이 선택된 경우 사용자 지정 부정적 요인을 입력할 수 없습니다.",
"metadata": {
"factorType": "negative",
"selectedFactorIds": [1],
"invalidCustomFactors": ["스트레스"]
}
}
403 Forbidden - 권한 없음
예시: 날짜 제약 위반 (DATE_VALIDATION_FAILED - 10010)
{
"code": 10010,
"message": "DATE_VALIDATION_FAILED",
"detail": "수면 기록은 당일 일차에 한해서만 생성/수정이 가능합니다."
}
예시: 치료 활동 일시 정지 (TREATMENT_SUSPENDED - 10011)
{
"code": 10011,
"message": "TREATMENT_SUSPENDED",
"detail": "현재 이 사용자의 치료가 중단된 상태입니다"
}
예시: 잘못된 일차 (INVALID_DAY_INDEX - 10012)
{
"code": 10012,
"message": "INVALID_DAY_INDEX",
"detail": "예상 일차는 8이지만 7를 받았습니다"
}
409 Conflict - 리소스 충돌
예시: 중복 기록 (SLEEP_LOG_ALREADY_EXISTS - 10090)
{
"code": 10090,
"message": "SLEEP_LOG_ALREADY_EXISTS",
"detail": "7일차에 대한 수면 기록이 이미 존재합니다"
}
500 Internal Server Error - 서버 내부 오류
예시: 일반 서버 오류 (SERVER_ERROR - 10000)
{
"code": 10000,
"message": "SERVER_ERROR",
"detail": "서버 내부 오류가 발생했습니다."
}
설명
- 이 API는 사용자의 일일 수면 패턴을 기록하고 분석하기 위한 핵심 기능입니다.
- 수면 여부(DNS)에 따라 입력해야 하는 필수 필드가 다르며, 시스템이 자동으로 검증합니다.
- 데이터 활용:
- 생성된 수면 기록은 rTIB(권장 침대 시간) 계산의 기반 데이터로 사용됩니다.
- 7일 주기로 수집된 수면 데이터를 분석하여 개인 맞춤형 수면 목표를 제공합니다.