본문으로 건너뛰기

Software Design Document (SDD)

SleepQ 디지털 치료기기의 소프트웨어 상세 설계 문서입니다.

1. 시스템 설계 개요​

1.1 설계 목적​

본 문서는 SleepQ 시스템의 상세 설계 명세를 정의하여 개발팀이 일관성 있게 구현할 수 있도록 가이드를 제공합니다.

1.2 설계 원칙​

  • 모듈성: 독립적이고 재사용 가능한 컴포넌트 설계
  • 테스트 가능성: 단위 테스트 및 통합 테스트 용이성
  • 유지보수성: 명확한 인터페이스 및 문서화
  • 성능: 효율적인 알고리즘 및 데이터 구조 사용

2. 모듈 상세 설계​

SleepQ는 안전성 등급 A에 해당하는 소프트웨어 의료기기로서 주요 기능에 대해서만 상세 설계를 진행한다.

2.1 사용자 관리 모듈​

2.1.1 인증 서비스 (AuthService)​

액세스 코드 검증 기능 상세 설계​
항목내용
SRS ID
기능 명칭액세스 코드 검증
소속 클래스AuthService, AccessCodeValidator
관련 EndpointPOST /auth/access-code/validate
입력 데이터- accessCode: string (8자리 일회용 코드)
- email: string (선택사항)
- deviceInfo: object (기기 정보)
출력 데이터- isValid: boolean
- accessToken: string (JWT)
- user: UserProfile
- expiresIn: number
주요 알고리즘- 액세스 코드 유효성 검증
- 사용 기한 및 횟수 확인
- 사용자 계정 생성 또는 연결
- JWT 토큰 생성 (RS256)
예외 처리- 잘못된 코드: 400 Bad Request
- 만료된 코드: 410 Gone
- 이미 사용된 코드: 409 Conflict
테스트 조건- 유효한 액세스 코드 입력 → 토큰 발급 성공
- 만료된 코드 입력 → 오류 반환
- 형식 오류 코드 → 검증 실패
호출 구조Mobile App → Load Balancer → API Server → AuthService → AccessCodeValidator → Database
로그 처리- 인증 시도 기록 (info)
- 실패 사유 기록 (warn)
- 토큰 발급 이벤트 (info)
JWT 토큰 갱신 기능 상세 설계​
항목내용
SRS ID
기능 명칭JWT 토큰 갱신
소속 클래스AuthService, TokenManager
관련 EndpointPOST /auth/token/refresh
입력 데이터- refreshToken: string (갱신용 토큰)
출력 데이터- accessToken: string (새 JWT)
- expiresIn: number (만료 시간)
주요 알고리즘- Refresh 토큰 유효성 검증
- 토큰 블랙리스트 확인
- 새 Access 토큰 생성
- 토큰 로테이션 처리
예외 처리- 유효하지 않은 토큰: 401 Unauthorized
- 만료된 토큰: 401 Unauthorized
- 블랙리스트 토큰: 403 Forbidden
테스트 조건- 유효한 Refresh 토큰 → 새 토큰 발급
- 만료된 토큰 → 재로그인 요구
- 동시 갱신 요청 → 동시성 제어 확인
호출 구조Client → Load Balancer → AuthService → Redis Cache → TokenManager
로그 처리- 토큰 갱신 요청 (debug)
- 갱신 성공/실패 (info/warn)
- 보안 이벤트 기록 (audit log)

2.1.2 사용자 프로필 서비스 (UserProfileService)​

사용자 프로필 업데이트 기능 상세 설계​
항목내용
SRS ID
기능 명칭사용자 프로필 업데이트
소속 클래스UserProfileService, UserValidator
관련 EndpointPUT /users/profile
입력 데이터- firstName: string
- lastName: string
- timezone: string
- language: string
- preferences: object
출력 데이터- user: UserProfile (업데이트된 프로필)
- updatedFields: string[] (변경된 필드 목록)
주요 알고리즘- 입력 데이터 유효성 검증
- 변경 사항 추적
- 개인정보 암호화 (AES-256)
- 데이터베이스 트랜잭션 처리
예외 처리- 유효하지 않은 데이터: 400 Bad Request
- 권한 부족: 403 Forbidden
- 사용자 없음: 404 Not Found
테스트 조건- 정상 업데이트 → 성공 응답
- 잘못된 시간대 → 검증 실패
- 동시 업데이트 → 최신 우선 적용
호출 구조Mobile App → Load Balancer → API Server → UserProfileService → UserValidator → Database
로그 처리- 프로필 변경 이벤트 (info)
- 변경 전후 값 기록 (audit)
- 검증 실패 사유 (warn)
동의서 관리 기능 상세 설계​
항목내용
SRS ID
기능 명칭동의서 버전 관리
소속 클래스UserProfileService, ConsentManager
관련 EndpointPUT /users/current/consent
입력 데이터- consentType: string (privacy/terms/marketing)
- version: string
- accepted: boolean
- timestamp: datetime
출력 데이터- consentId: string
- status: string (accepted/rejected)
- effectiveDate: datetime
주요 알고리즘- 동의서 버전 확인
- 이전 동의 이력 조회
- 법적 요구사항 검증
- 동의 철회 가능 여부 확인
예외 처리- 필수 동의 거부: 422 Unprocessable Entity
- 잘못된 버전: 400 Bad Request
- 이미 처리됨: 409 Conflict
테스트 조건- 신규 동의 → 기록 생성
- 동의 철회 → 서비스 제한 확인
- 버전 업데이트 → 재동의 요청
호출 구조Client → Load Balancer → API Server → ConsentManager → Audit Service → Database
로그 처리- 동의 상태 변경 (audit)
- 법적 준수 기록 (compliance)
- 타임스탬프 기록 (info)

2.2 치료 플로우 모듈​

2.2.1 학습 컨텐츠 서비스 (LearningService)​

학습 콘텐츠 번들 조회 기능 상세 설계​
항목내용
SRS ID
기능 명칭학습 콘텐츠 번들 조회
소속 클래스LearningService, BundleManager
관련 EndpointGET /v1/learning/bundles/{bundleId}
입력 데이터- bundleId: string (번들 ID)
- language: string (언어 코드: ko-KR, de-DE, en-US)
- includeLessons: boolean (레슨 포함 여부)
- includeQuizzes: boolean (퀴즈 포함 여부)
출력 데이터- bundleId: string
- version: string
- sessions: Session[] (세션 및 레슨 정보)
- quizzes: Quiz[] (퀴즈 정보)
- language: string (응답 언어)
주요 알고리즘- 번들 캐시 확인 및 업데이트
- 언어별 콘텐츠 번역 처리
- 세션-레슨 계층 구조 구성
- 효율적인 캐싱을 위한 번들 ID 기반 관리
예외 처리- 번들 없음: 404 Not Found
- 잘못된 언어 코드: 400 Bad Request
- 권한 부족: 403 Forbidden
테스트 조건- 신규 번들 조회 → 전체 데이터 반환
- 동일 번들 재조회 → 캐시 활용
- 언어 변경 → 번역된 콘텐츠 제공
호출 구조Mobile App → Load Balancer → API Server → LearningService → BundleManager → Cache/Database
로그 처리- 번들 조회 요청 (info)
- 캐시 히트/미스 (debug)
- 번들 버전 정보 (info)
일일 콘텐츠 조회 기능 상세 설계​
항목내용
SRS ID
기능 명칭일일 추천 콘텐츠 조회
소속 클래스LearningService, DailyContentService
관련 EndpointGET /v1/learning/daily/content
입력 데이터- userId: string
- date: string (YYYY-MM-DD, 선택)
- timezone: string (사용자 시간대)
출력 데이터- date: string (조회 날짜)
- recommendedLesson: Lesson (추천 레슨)
- alternativeLessons: Lesson[] (대체 레슨)
- dayIndex: number (치료 일차)
- completionStatus: string
주요 알고리즘- dayIndex 기반 레슨 매칭
- 사용자 진행 상태 확인
- 45일 프로그램 label 매핑
- 대체 콘텐츠 추천 로직
예외 처리- 사용자 없음: 404 Not Found
- 치료 기간 외: 204 No Content
- 잘못된 날짜: 400 Bad Request
테스트 조건- 정상 일차 → 해당 레슨 추천
- 이미 완료 → 다음 레슨 추천
- 치료 종료 → 빈 응답
호출 구조Mobile App → Load Balancer → API Server → DailyContentService → UserCycleService → Database
로그 처리- 일일 콘텐츠 요청 (info)
- 추천 레슨 ID (info)
- dayIndex 매핑 (debug)
학습 진행률 조회 기능 상세 설계​
항목내용
SRS ID
기능 명칭전체 학습 진행률 조회
소속 클래스LearningService, ProgressService
관련 EndpointGET /v1/learning/progress
입력 데이터- userId: string (사용자 ID)
출력 데이터- completedLessons: number
- totalLessons: number (42개)
- progressPercentage: number
- lastCompletedAt: timestamp
- currentDay: number
주요 알고리즘- 완료 레슨 수 계산
- 진행률 백분율 계산
- 현재 치료 일차 확인
- 최근 학습 시간 추적
예외 처리- 사용자 없음: 404 Not Found
- 학습 기록 없음: 200 OK (0% 진행률)
테스트 조건- 신규 사용자 → 0% 진행률
- 일부 완료 → 정확한 백분율
- 전체 완료 → 100% 진행률
호출 구조Mobile App → Load Balancer → API Server → ProgressService → Database
로그 처리- 진행률 조회 (info)
- 완료 레슨 수 (debug)
레슨 완료 처리 기능 상세 설계​
항목내용
SRS ID
기능 명칭레슨 완료 처리
소속 클래스LearningService, CompletionService
관련 EndpointPOST /v1/learning/lessons/{lessonId}/complete
입력 데이터- lessonId: string (레슨 ID)
- completedAt: timestamp (완료 시간)
출력 데이터- success: boolean
- nextLessonId: string (다음 해금된 레슨)
- unlockedAt: timestamp
- totalProgress: number
주요 알고리즘- 레슨 완료 상태 업데이트
- 다음 레슨 자동 해금 처리
- 46번 레슨 특별 처리 (90일 후 해금)
- 진행률 재계산
예외 처리- 이미 완료됨: 400 Bad Request
- 레슨 미해금: 403 Forbidden
- 레슨 없음: 404 Not Found
테스트 조건- 정상 완료 → 다음 레슨 해금
- 45번 완료 → 46번 90일 대기
- 중복 완료 → 오류 반환
호출 구조Mobile App → Load Balancer → API Server → CompletionService → UnlockService → Database
로그 처리- 레슨 완료 이벤트 (info)
- 다음 레슨 해금 (info)
- 진행률 업데이트 (debug)
퀴즈 응답 제출 기능 상세 설계​
항목내용
SRS ID
기능 명칭퀴즈 응답 제출
소속 클래스LearningService, QuizService
관련 EndpointPOST /v1/learning/quiz/{quizId}/answers
입력 데이터- quizId: string (퀴즈 ID)
- answer: string (사용자 답변)
- lessonId: string (관련 레슨)
- timeSpent: number (소요 시간)
출력 데이터- isCorrect: boolean
- correctAnswer: string
- explanation: string (해설)
- score: number
- attemptCount: number
주요 알고리즘- 정답 검증 처리
- 점수 계산 및 저장
- 재시도 횟수 추적
- 학습 통계 업데이트
예외 처리- 퀴즈 없음: 404 Not Found
- 잘못된 답변 형식: 400 Bad Request
- 제한 초과: 429 Too Many Requests
테스트 조건- 정답 입력 → 점수 획득
- 오답 입력 → 해설 제공
- 여러 시도 → 기록 누적
호출 구조Mobile App → Load Balancer → API Server → QuizService → Database → Analytics
로그 처리- 퀴즈 응답 제출 (info)
- 정답 여부 (info)
- 퀴즈 통계 업데이트 (debug)

2.2.2 수면 일기 서비스 (SleepDiaryService)​

수면 기록 생성 기능 상세 설계​
항목내용
SRS ID
기능 명칭수면 기록 생성 (당일 일차)
소속 클래스SleepDiaryService, SleepValidator
관련 EndpointPOST /v1/sleep/logs/day-index
입력 데이터- dayIndex: number (당일 일차)
- dns: boolean (전혀 못 잤는지)
- lot: timestamp (잠자리에 든 시각, 18:00 이후)
- aet: timestamp (일어난 시각)
- sleepQuality: number (1-5)
- solMinutes: number (입면 지연 시간)
- wasoMinutes: number (중간 각성 시간)
- pill: boolean (수면제 복용)
- napMinutes: number (낮잠 시간)
- negativeFactorIds: array
- positiveFactorIds: array
출력 데이터- sleepLog: object (생성된 수면 기록)
- tstMinutes: number (총 수면 시간)
- sleepEfficiency: number (수면 효율)
- goalAdherence: object (목표 달성 여부)
- date: string (YYYY-MM-DD)
주요 알고리즘- 당일 일차만 생성/수정 가능 검증
- LOT 18:00 이후 검증
- 5분 단위 시간 검증
- TST 자동 계산 (TIB - SOL - WASO)
- 수면 효율 계산 (TST/TIB)
- 목표 달성 여부 평가
예외 처리- 당일 아님: 400 DATE_VALIDATION_FAILED
- 시간 오류: 400 SLEEP_TIME_VALIDATION_FAILED
- 중복 기록: 409 SLEEP_LOG_ALREADY_EXISTS
- 치료 정지: 403 TREATMENT_SUSPENDED
- DNS=true일 때 수면 데이터: 400 UNEXPECTED_SLEEP_DATA
테스트 조건- 당일 일차 → 저장 성공
- 과거 일차 → 오류 반환
- LOT 18:00 이전 → 검증 실패
- DNS=true → 수면 데이터 제외
호출 구조Mobile App → Load Balancer → API Server → SleepDiaryService → Validator → Database → GoalAdherence
로그 처리- 수면 기록 생성 (info)
- 일차 검증 (debug)
- TST/효율 계산 (debug)
- 목표 달성 평가 (info)
수면 목표 조회 기능 상세 설계​
항목내용
SRS ID
기능 명칭수면 목표 조회 (일차별)
소속 클래스SleepGoalService, GoalManager
관련 EndpointGET /v1/sleep/goals/day-index/{dayIndex}
입력 데이터- dayIndex: number (조회할 일차)
- userId: string (인증 토큰에서 추출)
출력 데이터- id: string (목표 ID)
- targetDayIndex: number
- targetLOT: timestamp (목표 취침 시각)
- targetAET: timestamp (목표 기상 시각)
- rTIBMinutes: number (권장 침대 체류 시간)
- goalType: string (RTIB_ALGORITHM/USER/SYSTEM)
주요 알고리즘- 일차별 목표 조회
- rTIB 적용 여부 확인
- 사용자 설정 목표 확인
- 시스템 기본값 적용
- 목표 타입 구분 (rTIB 알고리즘/사용자 설정/시스템)
예외 처리- 목표 없음: 404 SLEEP_GOAL_NOT_FOUND
- 잘못된 일차: 400 INVALID_DAY_INDEX
- 권한 없음: 403 INSUFFICIENT_PERMISSIONS
테스트 조건- rTIB 처방 후 → rTIB 목표 반환
- 사용자 설정 → USER 타입 반환
- 목표 없음 → 404 오류
호출 구조Mobile App → Load Balancer → API Server → GoalManager → Database → Cache
로그 처리- 목표 조회 요청 (info)
- 목표 타입 (debug)
- 캐시 히트/미스 (debug)
rTIB 계산 및 조회 기능 상세 설계​
항목내용
SRS ID
기능 명칭rTIB 계산 및 조회
소속 클래스RTIBService, RTIBCalculator
관련 EndpointGET /v1/sleep/rtib/day-index/{dayIndex}
입력 데이터- dayIndex: number (rTIB 처방 일차)
- userId: string (인증 토큰에서 추출)
출력 데이터- id: string (rTIB ID)
- dayIndex: number
- date: string (YYYY-MM-DD)
- rTIB: number (권장 침대 체류 시간, 분)
- calculationBasis: object (계산 근거)
- avgTstMinutes: number (평균 총 수면 시간)
- avgSe: number (평균 수면 효율)
- validLogCount: number (유효 기록 수)
- isFirstRtib: boolean
- calculatedOnSleepLogCreation: boolean
주요 알고리즘- 직전 7일 수면 기록 수집
- DNS 제외한 유효 기록 필터링
- 평균 TST 계산
- rTIB = avgTST / 0.9 (목표 효율 90%)
- 최소 4개 이상 기록 필요
- 7일차마다 자동 계산
예외 처리- 데이터 부족: 400 INSUFFICIENT_DATA
- rTIB 없음: 404 RTIB_RECOMMENDATION_NOT_FOUND
- 계산 실패: 500 STATISTICS_CALCULATION_FAILED
테스트 조건- 7일 전체 기록 → 정상 계산
- 4-6개 기록 → 부분 계산
- 4개 미만 → 계산 불가
- 첫 rTIB → isFirstRtib: true
호출 구조Mobile App → Load Balancer → API Server → RTIBCalculator → Database → Pub/Sub
로그 처리- rTIB 계산 시작 (info)
- 유효 기록 수 (debug)
- 계산 결과 (info)
- 처방 생성 이벤트 (info)
목표 기상 시각 설정 기능 상세 설계​
항목내용
SRS ID
기능 명칭목표 기상 시각 설정 (rTIB 처방일)
소속 클래스SleepGoalService, WakeTimeManager
관련 EndpointPATCH /v1/sleep/goals/target-wake-time
입력 데이터- targetAET: string (HH:MM 형식)
- targetDayIndex: number (다음 일차)
- targetDate: string (YYYY-MM-DD)
출력 데이터- id: string (목표 ID)
- targetDayIndex: number
- targetDate: string
- targetLOT: timestamp (계산된 취침 시각)
- targetAET: timestamp (설정된 기상 시각)
- rTIBInMinutes: number
- goalType: string (USER)
- timezoneId: string
- timezoneOffset: number
주요 알고리즘- rTIB 처방 당일 검증
- 다음 일차 목표 설정
- targetLOT = targetAET - rTIB
- 목표 타입을 USER로 변경
- 시간대 정보 적용
예외 처리- 처방일 아님: 400 TARGET_WAKE_TIME_CHANGE_NOT_ALLOWED
- 잘못된 시간: 400 INVALID_FORMAT
- 잘못된 시간대: 400 INVALID_TIMEZONE
테스트 조건- rTIB 처방일 → 설정 성공
- 비처방일 → 오류 반환
- LOT 자동 계산 검증
- 다음 일차 검증
호출 구조Mobile App → Load Balancer → API Server → WakeTimeManager → Database → Scheduler
로그 처리- 기상 시각 설정 (info)
- 취침 시각 계산 (debug)
- 스케줄러 등록 (info)

2.3 모바일 앱 관리 모듈​

2.3.1 앱 강제 업데이트 처리​

앱 버전 검증 및 강제 업데이트 기능 상세 설계​
항목내용
SRS ID
기능 명칭앱 강제 업데이트 기능
소속 클래스VersionMiddleware, AppConfigService
관련 EndpointGET /mobile/app-settings (모든 API 요청 시 헤더 검증)
입력 데이터- 앱 플랫폼 (iOS/Android)
- 앱 버전
- 사용 중단 여부 설정 값
출력 데이터- 허용 여부 (200 OK or 426 Upgrade Required)
- 업데이트 안내 메시지
주요 알고리즘- 요청 헤더의 앱 버전 확인
- 플랫폼별 최소 허용 버전과 비교
- 강제 업데이트 설정 여부 판단
예외 처리- 버전 없음: 400 Bad Request
- 낮은 버전: 426 Upgrade Required 반환 + 업데이트 안내
테스트 조건- 최소 허용 버전 미만 → 업데이트 강제 확인
- 정상 버전 → 통과 확인
호출 구조모든 API 요청에 VersionMiddleware가 선행 적용
업데이트 필요 시 요청 차단
로그 처리- 차단된 요청, 버전 불일치 기록 (warn, info)

2.4 설문 및 평가 모듈​

2.4.1 설문 관리 서비스 (QuestionnaireService)​

설문 응답 제출 기능 상세 설계​
항목내용
SRS ID
기능 명칭설문 응답 데이터 제출 및 평가
소속 클래스QuestionnaireService, ScoreCalculator
관련 EndpointPOST /questionnaires/{id}/responses
입력 데이터- questionnaireId: string
- responses: Answer[]
- completedAt: datetime
- round: number
출력 데이터- submissionId: string
- score: ScoreResult
- interpretation: string
- severity: string
주요 알고리즘- 응답 완전성 검증
- 설문별 점수 계산 (ISI, PHQ-9, GAD-7 등)
- 임상적 해석 생성
- 심각도 평가
예외 처리- 불완전한 응답: 422 Unprocessable Entity
- 잘못된 설문 ID: 404 Not Found
- 중복 제출: 409 Conflict
테스트 조건- 모든 문항 응답 → 점수 계산
- 부분 응답 → 검증 실패
- 점수별 해석 정확성 확인
호출 구조Mobile App → Load Balancer → API Server → QuestionnaireService → ScoreCalculator → Database
로그 처리- 설문 제출 기록 (info)
- 점수 및 평가 결과 (info)
- 임상적 알림 필요 시 (warn)

2.5 이완 및 치료 모듈​

2.5.1 이완 컨텐츠 서비스 (RelaxationService)​

이완 세션 기록 기능 상세 설계​
항목내용
SRS ID
기능 명칭이완 세션 사용 기록 및 효과 평가
소속 클래스RelaxationService, SessionRecorder
관련 EndpointPOST /relaxation/sessions
입력 데이터- contentId: string
- sessionDuration: number
- completionStatus: string
- effectivenessRating: number (1-10)
- technique: string
출력 데이터- sessionId: string
- insights: SessionInsights
- recommendations: string[]
- achievements: Achievement[]
주요 알고리즘- 세션 완료율 계산
- 효과성 추세 분석
- 선호 기법 파악
- 다음 컨텐츠 추천
예외 처리- 잘못된 컨텐츠 ID: 404 Not Found
- 비정상 세션 시간: 400 Bad Request
- 서버 오류: 500 Internal Server Error
테스트 조건- 정상 완료 → 기록 저장
- 중단된 세션 → 부분 기록
- 반복 사용 → 패턴 분석
호출 구조Client → Load Balancer → API Server → RelaxationService → Database → Analytics
로그 처리- 세션 시작/종료 (info)
- 효과성 평가 기록 (info)
- 사용 패턴 분석 (debug)

3. 데이터베이스 설계​

3.1 데이터베이스 스키마 구조​

SleepQ 시스템은 PostgreSQL 데이터베이스를 사용하며, 데이터 보안과 규정 준수를 위해 다음과 같은 스키마로 분리됩니다:

  • private 스키마: 개인정보(PII) 및 민감 데이터 저장 (GDPR 준수)
  • auth 스키마: 인증 관련 시스템 설정 데이터
  • sleep 스키마: 수면 요인 등 비개인정보 설정 데이터
  • learning 스키마: 학습 콘텐츠, 세션, 퀴즈 등 시스템 데이터
  • questionnaire 스키마: 설문 정의, 문항, 점수 계산 규칙
  • mobile 스키마: 모바일 앱 설정 및 버전 관리
  • operation 스키마: 내부 운영자 및 의료진 데이터

3.2 도메인별 엔티티 관계 다이어그램 (ERD)​

3.2.1 Auth 도메인 ERD​

3.2.2 User 도메인 ERD​

3.2.3 Sleep 도메인 ERD​

3.2.4 Learning 도메인 ERD​

3.2.5 Questionnaire 도메인 ERD​

3.2.6 Mobile 도메인 ERD​

3.2.7 Relaxation 도메인 ERD​

3.2.8 IAM 도메인 ERD​

3.2.9 Agent 도메인 ERD​

3.2.10 관계형 데이터 구조 요약​

  • 사용자 중심 설계: User 엔티티를 중심으로 모든 도메인이 연결
  • 치료 주기 관리: UserCycle이 Sleep, Learning, Questionnaire, Relaxation 도메인과 연동
  • 권한 관리: IAM 도메인의 Role-Permission 모델로 세밀한 접근 제어
  • 다중 스키마 분리: 개인정보(private), 시스템 데이터(각 도메인 스키마), 운영 데이터(operation)의 명확한 분리
  • 이력 관리: 주요 엔티티별 변경 이력 추적 (UserStatusHistory, AppSettingsHistory, AgentConversation 등)
  • 다국어 지원: Translation 테이블을 통한 다국어 콘텐츠 관리 (Learning, Questionnaire, Relaxation)
  • Agent 기반 상호작용: AI 에이전트를 통한 개인화된 치료 지원

3.3 데이터 저장 전략​

3.3.1 인덱싱 전략​

주요 인덱스 설계​
  • User 테이블

    • UNIQUE INDEX: email (로그인 조회)
    • INDEX: status, userType (사용자 필터링)
    • INDEX: createdAt DESC (최신 가입자 조회)
  • SleepLog 테이블

    • INDEX: userId, userCycleId, date DESC (사용자별 수면 기록 조회)
    • INDEX: userCycleId, dayIndex (치료 주기별 일차 조회)
    • INDEX: createdAt DESC (최신 기록 조회)
  • QuestionnaireResponse 테이블

    • INDEX: userId, questionnaireType, roundNumber (사용자별 설문 조회)
    • INDEX: completedAt DESC (최근 완료 설문 조회)
  • LearningProgress 테이블

    • INDEX: userId, userCycleId, status (학습 진도 조회)
    • INDEX: lessonId, completedAt (레슨별 완료 통계)
복합 인덱스 최적화​
  • 카디널리티가 높은 컬럼을 앞에 배치
  • WHERE 절에 자주 사용되는 컬럼 우선 배치
  • ORDER BY 절에 사용되는 컬럼 포함

3.3.2 파티셔닝 전략​

날짜 기반 파티셔닝​
  • SleepLog: 월별 파티션 (3개월 이상 데이터 아카이빙)
  • AuditLog: 월별 파티션 (6개월 이상 데이터 BigQuery 이관)
  • AgentConversation: 분기별 파티션
사용자 기반 샤딩 (확장 시)​
  • 사용자 ID 해시 기반 수평 분할
  • 지역별 데이터 로컬리티 고려

3.3.3 캐싱 전략​

Redis 캐싱 계층​
  • 사용자 프로필: TTL 1시간
  • 수면 목표: TTL 24시간
  • 학습 진도: TTL 30분
  • 설문 번들: TTL 7일
  • 이완 콘텐츠 메타데이터: TTL 24시간
캐시 무효화 정책​
  • Write-through 캐싱: 데이터 변경 시 즉시 캐시 업데이트
  • 이벤트 기반 무효화: Pub/Sub 통한 캐시 동기화

3.3.4 데이터 무결성​

제약 조건​
  • 외래 키 제약: CASCAde/RESTRICT 정책 적용
  • CHECK 제약:
    • SleepLog: lot < aet (취침 시각 < 기상 시각)
    • SleepEfficiency: 0 <= value <= 1
    • SleepQuality: 1 <= value <= 5
  • UNIQUE 제약:
    • User.email
    • Group.name
    • Role.name
트랜잭션 관리​
  • ACID 특성 보장을 위한 트랜잭션 래핑
  • Optimistic Locking: version 컬럼 활용
  • 데드락 방지를 위한 일관된 잠금 순서
트리거 및 스토어드 프로시저​
  • updatedAt 자동 업데이트 트리거
  • 수면 효율 자동 계산 트리거
  • 데이터 정합성 검증 프로시저

4. API 설계​

4.1 주요 API 엔드포인트 목록​

4.1.1 인증 및 세션 관리 (Auth Domain)​

API메서드경로설명
액세스 코드 검증POST/auth/access-code/validate일회성 액세스 코드 유효성 검증
사용자 로그인POST/auth/login사용자 인증 및 JWT 토큰 발급
토큰 갱신POST/auth/token/refreshJWT 토큰 갱신
로그아웃POST/auth/logout사용자 로그아웃 및 세션 무효화
앱 보안 인증POST/auth/app/challenge앱 무결성 검증을 위한 챌린지 생성
앱 인증 완료POST/auth/app/complete-challenge앱 보안 인증 완료 처리

4.1.2 사용자 관리 (User Domain)​

API메서드경로설명
사용자 프로필 조회GET/users/profile사용자 프로필 정보 조회
프로필 업데이트PUT/users/profile사용자 프로필 정보 수정
현재 사용자 정보GET/users/current현재 사용자 상태 및 치료 정보
동의서 업데이트PUT/users/current/consent사용자 동의서 상태 업데이트
서비스 일시중단POST/users/suspend치료 서비스 일시 중단
서비스 재개POST/users/resume치료 서비스 재개

4.1.3 수면 관리 (Sleep Domain)​

API메서드경로설명
수면 목표 설정POST/sleep/goals사용자별 수면 목표 설정
수면 기록 제출POST/sleep/logs일일 수면 기록 데이터 제출
수면 기록 조회GET/sleep/logs기간별 수면 기록 조회
현재 수면 기록GET/sleep/logs/current오늘 수면 기록 조회
수면 기록 수정PUT/sleep/logs/{id}기존 수면 기록 수정

4.1.4 설문 관리 (Questionnaire Domain)​

API메서드경로설명
현재 설문 조회GET/questionnaires/current현재 라운드 설문 조회
설문 응답 제출POST/questionnaires/{id}/responses설문 응답 데이터 제출
응답 이력 조회GET/questionnaires/responses설문 응답 이력 조회

4.1.5 학습 컨텐츠 (Learning Domain)​

API메서드경로설명
학습 컨텐츠 조회GET/learning/content개인별 맞춤 학습 컨텐츠 목록
학습 진도 기록POST/learning/progress학습 컨텐츠 진도 기록
진도 현황 조회GET/learning/progress학습 진도 현황 조회

4.1.6 이완 컨텐츠 (Relaxation Domain)​

API메서드경로설명
이완 컨텐츠 조회GET/relaxation/content이완 기법별 컨텐츠 목록
이완 세션 기록POST/relaxation/sessions이완 세션 사용 기록

4.1.7 권한 관리 (IAM Domain)​

API메서드경로설명
사용자 권한 조회GET/iam/permissions현재 사용자 권한 정보

4.1.8 모바일 설정 (Mobile Domain)​

API메서드경로설명
앱 설정 조회GET/mobile/app-settings앱 설정 및 피처 플래그 조회
설정 업데이트POST/mobile/settings/update모바일 설정 업데이트

4.1.9 AI 치료 관리 (Agent Treatment Flow Domain)​

API메서드경로설명
치료 단계 조회GET/agent-treatment-flow/current-stage현재 치료 단계 및 진행 상태
대화 세션 시작POST/agent-treatment-flow/sessionsAI 상담 대화 세션 시작
AI 상담 기록GET/agent-board/conversationsAI 상담 대화 기록 조회

4.2 API 공통 규칙​

4.2.1 인증 헤더​

  • Authorization: Bearer <JWT_TOKEN> (모든 인증 필요 API)
  • Content-Type: application/json
  • X-Client-Version: <APP_VERSION> (앱 버전)
  • X-Device-ID: <DEVICE_ID> (기기 식별자)

4.2.2 표준 HTTP 상태 코드​

  • 200 OK: 성공적인 요청 처리
  • 201 Created: 리소스 생성 성공
  • 400 Bad Request: 잘못된 요청 데이터
  • 401 Unauthorized: 인증 실패
  • 403 Forbidden: 권한 부족
  • 404 Not Found: 리소스 없음
  • 429 Too Many Requests: 요청 제한 초과
  • 500 Internal Server Error: 서버 오류

4.2.3 에러 응답 형식​

  • error.code: 오류 식별 코드
  • error.message: 사용자 친화적 오류 메시지
  • error.details: 상세 오류 정보 (선택사항)
  • timestamp: 오류 발생 시간
  • path: 요청 API 경로
  • correlationId: 추적용 상관관계 ID

4.2.4 페이지네이션​

  • page: 페이지 번호 (기본값: 1)
  • limit: 페이지당 항목 수 (기본값: 20, 최대: 100)
  • sortBy: 정렬 기준 필드
  • sortOrder: 정렬 순서 (asc/desc)

4.3 실시간 통신 (WebSocket)​

  • treatment-stage-changed: 치료 단계 변경 알림
  • sleep-reminder: 수면 관련 리마인더
  • goal-achievement: 목표 달성 알림
  • agent-message: AI 에이전트 메시지
  • system-notification: 시스템 공지사항

5. 핵심 알고리즘 설계​

5.1 수면 효율성 계산 알고리즘​

목적: 사용자의 수면 품질을 정량적으로 측정

계산 방식:

  1. 침대에 있던 총 시간 = 취침 시간부터 기상 시간까지의 총 시간
  2. 실제 수면 시간 = 총 시간 - 수면 잠복기 - 야간 각성 시간
  3. 수면 효율성 = (실제 수면 시간 / 침대에 있던 총 시간) × 100

임계값 기준:

  • 85% 이상: 양호한 수면 효율성
  • 75-84%: 보통 수면 효율성
  • 75% 미만: 개선 필요한 수면 효율성

5.2 개인화 추천 알고리즘​

목적: 사용자 수면 패턴 분석을 통한 맞춤형 치료 권장사항 제공

추천 기준:

5.2.1 수면 효율성 기반 추천​

  • 85% 미만: 수면 제한 요법 권장 (우선순위: 높음)
  • 75% 미만: 자극 제어 기법 추가 권장 (우선순위: 높음)

5.2.2 수면 잠복기 기반 추천​

  • 30분 이상: 이완 기법 훈련 권장 (우선순위: 중간)
  • 45분 이상: 인지 재구성 기법 권장 (우선순위: 높음)

5.2.3 야간 각성 기반 추천​

  • 주 3회 이상: 수면 위생 교육 강화 권장
  • 매일 발생: 의료진 상담 권장

5.3 치료 진행도 평가 알고리즘​

목적: 사용자의 치료 진행 상태를 종합적으로 평가

평가 요소:

  • 수면 기록 완성도: 주간 기록률 × 25%
  • 학습 컨텐츠 진도: 완료율 × 25%
  • 설문 응답 성실도: 응답 완전성 × 25%
  • 수면 개선도: 효율성 향상 정도 × 25%

단계 전환 기준:

  • 종합 점수 80% 이상: 다음 단계 진행 가능
  • 종합 점수 60-79%: 현재 단계 연장
  • 종합 점수 60% 미만: 개별 상담 필요

6. 오류 처리 및 안전성 설계​

6.1 오류 분류 체계​

오류 카테고리:

  • VALIDATION: 입력 데이터 유효성 검증 오류
  • AUTHENTICATION: 인증 관련 오류
  • AUTHORIZATION: 권한 부족 오류
  • BUSINESS_LOGIC: 비즈니스 로직 처리 오류
  • SYSTEM: 시스템 내부 오류
  • EXTERNAL_SERVICE: 외부 서비스 연동 오류

6.2 오류 처리 원칙​

  • 사용자 친화적 메시지: 기술적 세부사항 숨김
  • 상세 로깅: 디버깅을 위한 내부 로그 기록
  • 안전한 실패: 시스템 다운보다는 기능 제한
  • 추적 가능성: 고유 상관관계 ID를 통한 오류 추적

6.3 복구 메커니즘​

  • 자동 재시도: 일시적 네트워크 오류 대응
  • Graceful Degradation: 부분 기능 장애 시 핵심 기능 유지
  • 백업 데이터: 기본값 또는 캐시된 데이터 제공

7. 성능 최적화 설계​

7.1 캐싱 전략​

Redis 캐싱 계층:

  • 사용자 프로필: 1시간 TTL, 로그인 시 갱신
  • 수면 분석 결과: 30분 TTL, 새 데이터 입력 시 무효화
  • 학습 컨텐츠: 24시간 TTL, 관리자 업데이트 시 갱신
  • 설문 스코어: 1시간 TTL, 응답 완료 시 갱신

7.2 데이터베이스 최적화​

파티셔닝 전략:

  • 월별 파티셔닝: 수면 기록 데이터를 월 단위로 분할
  • 읽기 복제본: 분석 쿼리는 읽기 전용 복제본으로 라우팅
  • 인덱스 최적화: 자주 사용되는 쿼리 패턴에 맞춘 복합 인덱스

7.3 API 성능 최적화​

  • 응답 압축: Gzip 압축을 통한 전송 데이터 크기 최소화
  • 페이지네이션: 대용량 데이터 조회 시 페이지 단위 분할
  • 비동기 처리: 시간이 오래 걸리는 작업은 백그라운드 처리

8. 보안 설계​

8.1 데이터 보호​

암호화 전략:

  • 전송 중 암호화: TLS 1.2+ 프로토콜 사용
  • 저장 중 암호화: AES-256-GCM 알고리즘 적용
  • 개인정보 암호화: 이름, 연락처 등 민감 정보 별도 암호화
  • 키 관리: Google Cloud Secret Manager 활용

8.2 접근 제어​

인증 및 권한:

  • 다단계 인증: JWT + 앱 보안 인증 조합
  • 최소 권한 원칙: 필요한 최소한의 권한만 부여
  • 세션 관리: 자동 토큰 만료 및 갱신
  • API 키 보안: 키 순환 및 접근 로그 모니터링

8.3 입력 검증​

데이터 유효성 검사:

  • 형식 검증: 날짜, 시간, 이메일 등 형식 확인
  • 범위 검증: 수면 품질 점수 1-10 범위 확인
  • SQL 주입 방지: 매개변수화된 쿼리 사용
  • XSS 방지: 사용자 입력 데이터 이스케이프 처리

9. 품질 보증 설계​

9.1 테스트 전략​

테스트 계층:

  • 단위 테스트: 개별 함수 및 메서드 테스트
  • 통합 테스트: API 엔드포인트 전체 플로우 테스트
  • 시스템 테스트: 전체 시스템 기능 검증
  • 성능 테스트: 부하 및 스트레스 테스트

9.2 테스트 시나리오​

핵심 테스트 케이스:

  • 수면 효율성 계산: 다양한 수면 패턴에 대한 정확성 검증
  • 개인화 추천: 사용자 프로필별 적절한 권장사항 생성
  • 데이터 무결성: 동시 접근 시 데이터 일관성 확인
  • 오류 처리: 예외 상황에서의 안전한 동작 확인

9.3 자동화 테스트​

  • CI/CD 파이프라인: 코드 커밋 시 자동 테스트 실행
  • 회귀 테스트: 새 기능 추가 시 기존 기능 영향도 확인
  • 데이터 검증: 실제 운영 데이터를 활용한 검증

10. 운영 및 배포 설계​

10.1 환경 관리​

환경별 구성:

  • Development: 개발 및 초기 테스트 환경
  • Staging: 실제 운영과 동일한 검증 환경
  • Production: 실제 서비스 운영 환경

10.2 배포 전략​

안전한 배포:

  • Blue-Green 배포: 무중단 서비스 전환
  • 카나리 배포: 소수 사용자 대상 사전 검증
  • 롤백 계획: 문제 발생 시 이전 버전으로 즉시 복구

10.3 설정 관리​

  • 환경 변수: 민감 정보는 환경 변수로 관리
  • 설정 검증: 배포 전 설정 값 유효성 확인
  • 변경 추적: 설정 변경 이력 기록 및 승인 프로세스

11. 모니터링 및 관찰성 설계​

11.1 성능 메트릭​

주요 지표:

  • 응답 시간: P95, P99, 평균 응답 시간
  • 처리량: 초당 요청 수 (RPS)
  • 오류율: 전체 요청 대비 오류 비율
  • 활성 사용자: 동시 접속 사용자 수

11.2 비즈니스 메트릭​

치료 효과 지표:

  • 수면 개선도: 치료 시작 대비 수면 효율성 개선 정도
  • 앱 사용률: 일일/주간 활성 사용자 비율
  • 컨텐츠 완주율: 학습 모듈 완료 비율
  • 설문 응답률: 정기 설문 참여 비율

11.3 알람 및 대응​

임계값 기반 알람:

  • 응답 시간 > 2초: 성능 저하 경고
  • 오류율 > 1%: 시스템 안정성 경고
  • DB 연결 실패: 즉시 긴급 알람
  • 수면 효율성 계산 오류: 핵심 기능 장애 알람

11.4 로그 관리​

  • 구조화된 로깅: JSON 형태의 일관된 로그 포맷
  • 중앙집중 수집: Cloud Logging → BigQuery 파이프라인
  • 보존 정책: 개인정보 관련 로그 자동 삭제 주기 설정
  • 검색 최적화: 로그 분석 및 트러블슈팅 지원

12. 변경 이력​

버전날짜작성자변경 내용
0.1.02025-08-07bok@weltcorp.com최초 작성