SOL(Sleep Onset Latency) Chain of Debate 도메인 모델
중요 변경사항 (v0.5.0): SOL CoD 도메인의 명확성과 다른 도메인과의 구분을 위해 주요 테이블명을 리네이밍했습니다:
RecommendationSet→SOLRecommendationSetRecommendation→SOLRecommendationModelPerformanceMetrics→SOLModelPerformanceMetricsRecommendationCategory→SOLRecommendationCategory이 변경으로 SOL 관련 권장사항과 성능 지표가 다른 도메인의 유사한 엔티티와 명확히 구분됩니다.
데이터 저장 규칙
- SOL 예측 결과, 전문가 분석 내용, 토론 기록, 개인맞춤형 SOL 개선 권장사항 등 사용자와 직접적으로 관련된 민감 데이터는
private스키마에 저장합니다. - AI 모델 성능 지표, 토론 품질 지표 등 일반 시스템 설정/모니터링 데이터는
sleep_onset_latency_cod스키마에 저장합니다. - 모든 시간 관련 데이터는
TimeMachine도메인에서 제공하는 시간을 기준으로 저장하고 처리해야 합니다. 스케줄링 시스템은 TimeMachine 가상시간과 실제 시간의 이중 체계를 지원합니다.
용어 주의: 이 문서에서
solScore는 항상 "예측된 SOL(분)"을 의미합니다. 수면 일지에서 수집한 실제 관찰값은 Sleep 도메인의 원시 데이터 필드를 사용해 관리하며, 예측 파이프라인에서는 혼동을 피하기 위해 동일 명칭을 사용하지 않습니다.
1. 엔티티 관계도 (ERD)
2. 주요 엔티티 정의
2.1 PredictionSchedule (예측 스케줄링)
취침목표시간 기반 자동 예측 스케줄링을 관리하는 엔티티입니다.
주요 속성:
bedtimeGoal: Sleep 도메인에서 조회한 사용자의 취침목표시간scheduledTriggerTime: 취침목표시간에서 1시간을 뺀 예측 실행 예정 시간status: 스케줄 상태 (SCHEDULED, TRIGGERED, COMPLETED, FAILED, CANCELLED)retryCount: 실패 시 재시도 횟수 추적 (최대 2회)
비즈니스 규칙:
- 취침목표시간 변경 시 기존 스케줄은 CANCELLED 상태로 변경
- 예측 실패 시 10분 후 1차 재시도, 30분 후 2차 재시도
- 2차 재시도도 실패 시 다음 날 동일 시간으로 재스케줄링
2.2 SOLPrediction (SOL 예측)
Chain of Debate를 통한 SOL(Sleep Onset Latency) 예측 결과를 저장하는 메인 엔티티입니다.
주요 속성:
solScore: 예측된 SOL 점수 (0-120분)confidenceScore: 예측 신뢰도 점수 (0.0-1.0)dataCompleteness: 분석에 사용된 데이터 완성도 정보questionnaireIncluded: 설문 데이터 포함 여부participatingAgentCount: 참여 에이전트 수 (3개 또는 4개)
데이터 완성도 구조:
{
"sleepDays": 7,
"questionnaireData": true,
"learningData": true,
"totalDataScore": 0.85,
"dataQualityFactors": {
"sleepDataCoverage": 0.9,
"questionnaireCompleteness": 0.8,
"learningDataCompleteness": 0.75,
"appUsageDataAvailability": 0.6
}
}
2.3 DebateSession (토론 세션)
Chain of Debate 토론 전체 세션을 관리하는 엔티티입니다.
주요 속성:
maxAllowedRounds: 참여 에이전트 수에 따른 최대 라운드 수consensusThreshold: 합의 임계값 (3개 에이전트: 0.67, 4개 에이전트: 0.75)outcome: 토론 결과 (CONSENSUS, MAJORITY_DECISION, TIMEOUT, FAILED)
토론 품질 지표 구조:
{
"averageRoundTime": 8500,
"opinionVariance": 0.3,
"convergenceRate": 0.7,
"participationBalance": 0.85
}
2.4 ExpertAnalysis (전문가 분석)
개별 전문가 에이전트의 분석 결과를 저장하는 엔티티입니다.
주요 속성:
agentType: 에이전트 타입 (SLEEP_PATTERN, PSYCHOLOGICAL_STATE, CBTI, DIGITAL_ENVIRONMENT, MELATONIN_SYSTEM)analysisResult: 에이전트별 상세 분석 결과promptUsed: 사용된 프롬프트 템플릿 정보 (버전 관리용)
에이전트별 특수 요구사항:
Digital Environment Analyst 데이터 제약사항:
- DTA Wide 앱 내 활동 로그만 수집 가능 (타사 앱 데이터 접근 불가)
- 시스템 레벨 스크린 타임 데이터 수집 불가
- 앱 내 치료 도구 사용 패턴, 학습 콘텐츠 접근 패턴에 집중
Melatonin System Analyst 데이터 요구사항:
- 멜라토닌시스템분석전문가는 일주기 리듬 관련 데이터 확보 시에만 참여합니다.
- 필수 데이터: 수면/기상 시간 패턴 (최소 7일)
- 권장 데이터: 빛 노출 패턴, 운동 기록, 카페인/알코올 섭취, 식이 정보
- 데이터 부족 시 분석 신뢰도 자동 하향 조정됩니다.
SOL 분석 결과 구조:
{
"solAssessment": {
"predictedSOL": 35,
"factors": ["sleep_onset_patterns", "psychological_state", "sleep_environment"]
},
"keyFindings": [
"SOL이 평균 대비 10분 길음",
"입면 시간이 점진적으로 증가하는 패턴"
],
"concernAreas": ["prolonged_sleep_onset", "pre_sleep_anxiety"],
"positiveIndicators": ["consistent_bedtime", "good_sleep_environment"]
}
2.5 SOLRecommendationSet (SOL 권장사항 집합)
SOL 예측 결과를 바탕으로 생성된 수면잠복기 개선 권장사항을 관리하는 엔티티입니다.
주요 속성:
treatmentPhase: 사용자의 치료 단계 (EARLY, MID, LATE)primaryCategory: 주요 권장사항 카테고리priorityRanking: 권장사항 우선순위 순서
SOL 개선 권장사항 구조:
{
"sol_reduction_techniques": [
{
"technique": "progressive_muscle_relaxation",
"priority": 1,
"rationale": "SOL 단축을 위한 긴장 완화 필요"
}
],
"sleep_hygiene": [
{
"area": "pre_sleep_routine",
"suggestions": ["avoid_screens", "calming_activities"]
}
]
}
3. 열거형 (Enums) 정의
3.1 예측 관련 열거형
enum PredictionTriggerType {
AUTO_SCHEDULE = 'AUTO_SCHEDULE', // 자동 스케줄링 트리거
MANUAL_REQUEST = 'MANUAL_REQUEST', // 사용자 수동 요청
RETRY = 'RETRY' // 실패 후 재시도
}
enum PredictionStatus {
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
TIMEOUT = 'TIMEOUT'
}
enum ScheduleStatus {
SCHEDULED = 'SCHEDULED', // 스케줄 등록됨
TRIGGERED = 'TRIGGERED', // 트리거 실행됨
COMPLETED = 'COMPLETED', // 예측 완료됨
FAILED = 'FAILED', // 예측 실패함
CANCELLED = 'CANCELLED' // 스케줄 취소됨
}
3.2 토론 관련 열거형
enum DebateOutcome {
CONSENSUS = 'CONSENSUS', // 합의 도달
MAJORITY_DECISION = 'MAJORITY_DECISION', // 다수결 결정
TIMEOUT = 'TIMEOUT', // 시간 초과
FAILED = 'FAILED' // 토론 실패
}
enum RoundStatus {
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
TIMEOUT = 'TIMEOUT'
}
3.3 에이전트 관련 열거형
enum ExpertAgentType {
SLEEP_PATTERN = 'SLEEP_PATTERN', // 수면패턴분석전문가
PSYCHOLOGICAL_STATE = 'PSYCHOLOGICAL_STATE', // 심리상태분석전문가
CBTI = 'CBTI', // CBT-I수면행동전문가
DIGITAL_ENVIRONMENT = 'DIGITAL_ENVIRONMENT', // 디지털수면환경전문가
MELATONIN_SYSTEM = 'MELATONIN_SYSTEM', // 멜라토닌시스템분석전문가
OVERALL = 'OVERALL' // 전체 시스템 (성능 지표용)
}
enum AnalysisStatus {
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
TIMEOUT = 'TIMEOUT'
}
3.4 SOL 권장사항 관련 열거형
enum SOLRecommendationCategory {
CBTI = 'CBTI', // 인지행동치료
SLEEP_HYGIENE = 'SLEEP_HYGIENE', // 수면 위생
ENVIRONMENT = 'ENVIRONMENT', // 수면 환경
LIFESTYLE = 'LIFESTYLE' // 생활습관
}
enum EvidenceType {
SLEEP_DATA = 'SLEEP_DATA', // 수면 데이터
QUESTIONNAIRE_DATA = 'QUESTIONNAIRE_DATA', // 설문 데이터
LEARNING_DATA = 'LEARNING_DATA', // 학습 진도 및 참여 데이터
APP_USAGE_DATA = 'APP_USAGE_DATA', // DTA Wide 앱 내 활동 로그
HISTORICAL_TREND = 'HISTORICAL_TREND' // 과거 트렌드 데이터
}
4. 성능 최적화를 위한 인덱스 설계
4.1 주요 쿼리 패턴별 인덱스
-- 사용자별 SOL 예측 히스토리 조회
CREATE INDEX idx_prediction_user_date ON SOLPrediction(userId, predictionDate DESC);
-- 스케줄링 시스템 쿼리
CREATE INDEX idx_schedule_trigger_time ON PredictionSchedule(scheduledTriggerTime, status);
CREATE INDEX idx_schedule_user_status ON PredictionSchedule(userId, status);
-- 성능 모니터링 쿼리
CREATE INDEX idx_performance_agent_date ON SOLModelPerformanceMetrics(agentType, evaluationDate DESC);
CREATE INDEX idx_performance_prediction ON SOLModelPerformanceMetrics(predictionId);
-- 토론 분석 쿼리
CREATE INDEX idx_debate_session_prediction ON DebateSession(predictionId);
CREATE INDEX idx_expert_opinion_round_agent ON ExpertOpinion(debateRoundId, agentType);
4.2 복합 인덱스 최적화
-- 사용자의 치료주기별 SOL 예측 결과 조회
CREATE INDEX idx_prediction_user_cycle_date ON SOLPrediction(userId, userCycleId, predictionDate DESC);
-- 에이전트별 성능 트렌드 분석
CREATE INDEX idx_analysis_agent_status_time ON ExpertAnalysis(agentType, status, createdAt DESC);
-- 실패한 스케줄 재시도 처리
CREATE INDEX idx_schedule_retry ON PredictionSchedule(status, nextRetryTime) WHERE status = 'FAILED';
5. 데이터 보관 및 아카이빙 정책
5.1 데이터 생명주기 관리
- 활성 데이터: 최근 6개월 예측 결과 → 고성능 스토리지
- 아카이브 데이터: 6개월~5년 데이터 → 콜드 스토리지 (압축/암호화)
- 삭제 대상: 5년 경과 또는 사용자 요청 → 영구 삭제
5.2 GDPR 준수 데이터 처리
- 개인식별정보: 모든 예측 결과에서 사용자 ID 연결
- 익명화 처리: 연구 목적 사용 시 사용자 식별자 제거
- 데이터 이동성: JSON/CSV 형태로 추출 가능한 구조
6. 입력 데이터 인터페이스 정의
6.1 수면 목표 데이터 인터페이스
SOL 예측 시스템에서 사용자의 수면 목표 달성률과 목표-실제 갭 분석을 위한 데이터 구조:
/**
* 사용자 수면 목표 데이터
* Sleep-WIR 도메인의 수면 목표 및 달성 여부 정보
*/
interface SleepGoalData {
/** 목표 날짜 (ISO 8601 형식) */
targetDate: string;
/** 목표 취침 시간 (HH:mm 형식) */
lightsOutTime: string;
/** 목표 기상 시간 (HH:mm 형식) */
sleepEndTime: string;
/** 목표 수면 지속 시간 (분) */
durationInMinutes: number;
/** 취침 시간 목표 달성 여부 */
lightsOutGoalSuccess: boolean;
/** 기상 시간 목표 달성 여부 */
wakeTimeGoalSuccess: boolean;
/** 목표 대비 실제 취침 시간 차이 (분, 양수: 늦음, 음수: 빠름) */
lightsOutGoalGapMinutes?: number;
/** 목표 대비 실제 기상 시간 차이 (분, 양수: 늦음, 음수: 빠름) */
wakeTimeGoalGapMinutes?: number;
/** 목표 생성 시간 */
createdAt: {
seconds: number;
nanoseconds: number;
};
}
/**
* SOL 예측에 사용되는 수면 목표 요약 데이터
*/
interface SleepGoalSummary {
/** 전체 목표 달성률 (0.0 ~ 1.0) */
goalAchievementRate: number;
/** 취침 시간 목표 달성률 (0.0 ~ 1.0) */
lightsOutGoalSuccessRate: number;
/** 기상 시간 목표 달성률 (0.0 ~ 1.0) */
wakeTimeGoalSuccessRate: number;
/** 목표 준수 일관성 (0.0 ~ 1.0) */
goalAdherenceConsistency: number;
/** 평균 목표-실제 갭 (절댓값, 분) */
averageGoalActualGap: number;
/** 최근 연속 목표 달성 일수 */
recentGoalSuccessStreak: number;
/** 목표 데이터가 존재하는 일수 */
dataPoints: number;
}
6.2 확장된 수면 데이터 요약 인터페이스
기존 SleepDataSummary에 수면 목표 관련 필드 추가:
/**
* SOL 예측을 위한 확장된 수면 데이터 요약
* (기존 필드 + 수면 목표 관련 필드)
*/
interface EnhancedSleepDataSummary {
// 기존 수면 데이터 필드들
averageSOL: number;
recentSOLTrend: number[];
sleepEfficiency: number;
bedtimeConsistency: number;
totalSleepTime: number;
dataPoints: number;
// 새로 추가된 수면 목표 관련 필드들
goalAchievementRate: number; // 전체 목표 달성률 (0-1)
lightsOutGoalSuccessRate: number; // 취침시간 목표 달성률 (0-1)
wakeTimeGoalSuccessRate: number; // 기상시간 목표 달성률 (0-1)
goalAdherenceConsistency: number; // 목표 준수 일관성 (0-1)
averageGoalActualGap: number; // 평균 목표-실제 차이 (분)
recentGoalSuccessStreak: number; // 최근 연속 달성 일수
}
6.3 데이터 수집 흐름
-
SleepDataAdapter가 다음 Query들을 병렬로 실행:
GetLlmFriendlySleepLogByDayIndexQuery: 실제 수면 기록GetLlmFriendlySleepGoalByDayIndexQuery: 수면 목표 설정GetLlmFriendlySleepGoalSuccessByDayIndexQuery: 목표 달성 여부
-
목표 달성률 계산: 지정된 기간 내 목표 달성 일수 / 전체 일수
-
목표-실제 갭 계산: |목표시간 - 실제시간| 의 평균값
-
일관성 점수 계산: 연속 달성일 및 달성률 변동성 기반
7. Prisma Schema
generator client {
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["sleep_onset_latency_cod", "private"]
}
// --- Enums ---
// 예측 트리거 유형
enum PredictionTriggerType {
AUTO_SCHEDULE @map("AUTO_SCHEDULE")
MANUAL_REQUEST @map("MANUAL_REQUEST")
RETRY @map("RETRY")
@@schema("sleep_onset_latency_cod")
}
// 예측 상태
enum PredictionStatus {
IN_PROGRESS @map("IN_PROGRESS")
COMPLETED @map("COMPLETED")
FAILED @map("FAILED")
TIMEOUT @map("TIMEOUT")
@@schema("sleep_onset_latency_cod")
}
// 스케줄 상태
enum ScheduleStatus {
SCHEDULED @map("SCHEDULED")
TRIGGERED @map("TRIGGERED")
COMPLETED @map("COMPLETED")
FAILED @map("FAILED")
CANCELLED @map("CANCELLED")
@@schema("sleep_onset_latency_cod")
}
// 토론 결과
enum DebateOutcome {
CONSENSUS @map("CONSENSUS")
MAJORITY_DECISION @map("MAJORITY_DECISION")
TIMEOUT @map("TIMEOUT")
FAILED @map("FAILED")
@@schema("sleep_onset_latency_cod")
}
// 라운드 상태
enum RoundStatus {
IN_PROGRESS @map("IN_PROGRESS")
COMPLETED @map("COMPLETED")
TIMEOUT @map("TIMEOUT")
@@schema("sleep_onset_latency_cod")
}
// 전문가 에이전트 유형
enum ExpertAgentType {
SLEEP_PATTERN @map("SLEEP_PATTERN")
PSYCHOLOGICAL_STATE @map("PSYCHOLOGICAL_STATE")
CBTI @map("CBTI")
DIGITAL_ENVIRONMENT @map("DIGITAL_ENVIRONMENT")
OVERALL @map("OVERALL")
@@schema("sleep_onset_latency_cod")
}
// 분석 상태
enum AnalysisStatus {
IN_PROGRESS @map("IN_PROGRESS")
COMPLETED @map("COMPLETED")
FAILED @map("FAILED")
TIMEOUT @map("TIMEOUT")
@@schema("sleep_onset_latency_cod")
}
// SOL 권장사항 카테고리
enum SOLRecommendationCategory {
CBTI @map("CBTI")
SLEEP_HYGIENE @map("SLEEP_HYGIENE")
ENVIRONMENT @map("ENVIRONMENT")
LIFESTYLE @map("LIFESTYLE")
@@schema("sleep_onset_latency_cod")
}
// 증거 유형
enum EvidenceType {
SLEEP_DATA @map("SLEEP_DATA")
QUESTIONNAIRE_DATA @map("QUESTIONNAIRE_DATA")
LEARNING_DATA @map("LEARNING_DATA")
APP_USAGE_DATA @map("APP_USAGE_DATA")
HISTORICAL_TREND @map("HISTORICAL_TREND")
@@schema("sleep_onset_latency_cod")
}
// 사용자 주기 상태 (참조용)
enum UserCycleStatus {
ACTIVE
INACTIVE
ARCHIVED
@@schema("sleep_onset_latency_cod")
}
// --- private 스키마 (사용자 민감 데이터) ---
// 예측 스케줄링 테이블
model PredictionSchedule {
id String @id @default(uuid())
userId String @map("user_id")
userCycleId String @map("user_cycle_id")
bedtimeGoal DateTime @map("bedtime_goal") @db.Timestamptz
scheduledTriggerTime DateTime @map("scheduled_trigger_time") @db.Timestamptz
actualTriggerTime DateTime? @map("actual_trigger_time") @db.Timestamptz
status ScheduleStatus @default(SCHEDULED)
retryCount Int @default(0) @map("retry_count")
failureReason String? @map("failure_reason")
nextRetryTime DateTime? @map("next_retry_time") @db.Timestamptz
timezoneId String @default("Europe/Berlin") @map("timezone_id")
timezoneOffset Int @default(60) @map("timezone_offset")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// 관계
solPredictions SOLPrediction[]
// 인덱스
@@index([userId])
@@index([userCycleId])
@@index([scheduledTriggerTime, status])
@@index([status, nextRetryTime])
@@map("prediction_schedule")
@@schema("private")
}
// SOL 예측 메인 테이블
model SOLPrediction {
id String @id @default(uuid())
userId String @map("user_id")
userCycleId String @map("user_cycle_id")
predictionScheduleId String? @map("prediction_schedule_id")
predictionDate DateTime @map("prediction_date") @db.Date
startTime DateTime @map("start_time") @db.Timestamptz
endTime DateTime? @map("end_time") @db.Timestamptz
processingTimeMs Int? @map("processing_time_ms")
triggerType PredictionTriggerType @map("trigger_type")
solScore Float? @map("sol_score") @db.Real
confidenceScore Float? @map("confidence_score") @db.Real
dataCompleteness Json @map("data_completeness")
questionnaireIncluded Boolean @default(false) @map("questionnaire_included")
learningDataIncluded Boolean @default(false) @map("learning_data_included")
learningEngagement String? @map("learning_engagement")
participatingAgentCount Int @map("participating_agent_count")
status PredictionStatus @default(IN_PROGRESS)
failureReason String? @map("failure_reason")
rawPredictionData Json? @map("raw_prediction_data")
timezoneId String @default("Europe/Berlin") @map("timezone_id")
timezoneOffset Int @default(60) @map("timezone_offset")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// 관계
predictionSchedule PredictionSchedule? @relation(fields: [predictionScheduleId], references: [id])
debateSessions DebateSession[]
expertAnalyses ExpertAnalysis[]
recommendationSets SOLRecommendationSet[]
// 인덱스
@@index([userId])
@@index([userCycleId])
@@index([userId, predictionDate])
@@index([userCycleId, predictionDate])
@@index([status])
@@map("sol_prediction")
@@schema("private")
}
// 토론 세션 테이블
model DebateSession {
id String @id @default(uuid())
predictionId String @map("prediction_id")
totalRounds Int @map("total_rounds")
maxAllowedRounds Int @map("max_allowed_rounds")
consensusThreshold Float @map("consensus_threshold") @db.Real
finalConsensusScore Float? @map("final_consensus_score") @db.Real
consensusReached Boolean @default(false) @map("consensus_reached")
startTime DateTime @map("start_time") @db.Timestamptz
endTime DateTime? @map("end_time") @db.Timestamptz
totalDebateTimeMs Int? @map("total_debate_time_ms")
outcome DebateOutcome @map("outcome")
debateQualityMetrics Json @map("debate_quality_metrics")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// 관계
prediction SOLPrediction @relation(fields: [predictionId], references: [id])
debateRounds DebateRound[]
// 인덱스
@@index([predictionId])
@@map("debate_session")
@@schema("private")
}
// 토론 라운드 테이블
model DebateRound {
id String @id @default(uuid())
debateSessionId String @map("debate_session_id")
roundNumber Int @map("round_number")
startTime DateTime @map("start_time") @db.Timestamptz
endTime DateTime? @map("end_time") @db.Timestamptz
roundTimeMs Int? @map("round_time_ms")
consensusScore Float? @map("consensus_score") @db.Real
roundSummary Json @map("round_summary")
status RoundStatus @default(IN_PROGRESS)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// 관계
debateSession DebateSession @relation(fields: [debateSessionId], references: [id])
expertOpinions ExpertOpinion[]
// 인덱스
@@index([debateSessionId, roundNumber])
@@map("debate_round")
@@schema("private")
}
// 전문가 의견 테이블
model ExpertOpinion {
id String @id @default(uuid())
debateRoundId String @map("debate_round_id")
agentType ExpertAgentType @map("agent_type")
solScore Float @map("sol_score") @db.Real
confidence Float @map("confidence") @db.Real
reasoning Json @map("reasoning")
evidenceData Json @map("evidence_data")
responseTimeMs Int @map("response_time_ms")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
// 관계
debateRound DebateRound @relation(fields: [debateRoundId], references: [id])
// 인덱스
@@index([debateRoundId, agentType])
@@map("expert_opinion")
@@schema("private")
}
// 전문가 분석 테이블
model ExpertAnalysis {
id String @id @default(uuid())
predictionId String @map("prediction_id")
agentType ExpertAgentType @map("agent_type")
solScore Float @map("sol_score") @db.Real
confidenceScore Float @map("confidence_score") @db.Real
analysisResult Json @map("analysis_result")
inputDataSummary Json @map("input_data_summary")
promptUsed Json @map("prompt_used")
processingTimeMs Int @map("processing_time_ms")
llmModel String @map("llm_model")
llmVersion String @map("llm_version")
status AnalysisStatus @default(IN_PROGRESS)
failureReason String? @map("failure_reason")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// 관계
prediction SOLPrediction @relation(fields: [predictionId], references: [id])
analysisEvidence AnalysisEvidence[]
// 인덱스
@@index([predictionId, agentType])
@@index([agentType, status])
@@map("expert_analysis")
@@schema("private")
}
// 분석 증거 테이블
model AnalysisEvidence {
id String @id @default(uuid())
expertAnalysisId String @map("expert_analysis_id")
type EvidenceType @map("type")
dataSource String @map("data_source")
evidenceData Json @map("evidence_data")
relevanceScore Float @map("relevance_score") @db.Real
description String @map("description")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
// 관계
expertAnalysis ExpertAnalysis @relation(fields: [expertAnalysisId], references: [id])
// 인덱스
@@index([expertAnalysisId])
@@index([type])
@@map("analysis_evidence")
@@schema("private")
}
// SOL 권장사항 세트 테이블
model SOLRecommendationSet {
id String @id @default(uuid())
predictionId String @map("prediction_id")
recommendations Json @map("recommendations")
totalRecommendations Int @map("total_recommendations")
priorityRanking Json @map("priority_ranking")
expectedImpact Json @map("expected_impact")
primaryCategory SOLRecommendationCategory @map("primary_category")
treatmentPhase String @map("treatment_phase")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// 관계
prediction SOLPrediction @relation(fields: [predictionId], references: [id])
individualRecommendations SOLRecommendation[]
// 인덱스
@@index([predictionId])
@@index([primaryCategory])
@@map("sol_recommendation_set")
@@schema("private")
}
// 개별 SOL 권장사항 테이블
model SOLRecommendation {
id String @id @default(uuid())
recommendationSetId String @map("recommendation_set_id")
category SOLRecommendationCategory @map("category")
title String @map("title")
description String @map("description")
priority Int @map("priority")
expectedImpact Float @map("expected_impact") @db.Real
rationale String @map("rationale")
actionSteps Json @map("action_steps")
estimatedTimeToEffect Int @map("estimated_time_to_effect")
difficulty String @map("difficulty")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
// 관계
recommendationSet SOLRecommendationSet @relation(fields: [recommendationSetId], references: [id])
// 인덱스
@@index([recommendationSetId])
@@index([category, priority])
@@map("sol_recommendation")
@@schema("private")
}
// --- sleep_onset_latency_cod 스키마 (시스템 설정/모니터링) ---
// SOL 모델 성능 지표 테이블
model SOLModelPerformanceMetrics {
id String @id @default(uuid())
predictionId String? @map("prediction_id")
agentType ExpertAgentType @map("agent_type")
accuracyScore Float? @map("accuracy_score") @db.Real
responseTimeMs Int @map("response_time_ms")
consistencyScore Float? @map("consistency_score") @db.Real
performanceData Json @map("performance_data")
evaluationDate DateTime @map("evaluation_date") @db.Date
evaluationMethod String @map("evaluation_method")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
// 인덱스
@@index([predictionId])
@@index([agentType, evaluationDate])
@@index([evaluationDate])
@@map("sol_model_performance_metrics")
@@schema("sleep_onset_latency_cod")
}
// --- 시뮬레이션 관련 엔티티 (private 스키마) ---
// 시뮬레이션 세션 관리
model SimulationSession {
id String @id @default(uuid())
userId String @map("user_id")
userCycleId String @map("user_cycle_id")
sessionName String? @map("session_name")
startDayIndex Int @map("start_day_index")
endDayIndex Int @map("end_day_index")
simulationType SimulationType @map("simulation_type")
status SimulationStatus @map("status")
totalPredictions Int @map("total_predictions")
completedPredictions Int @map("completed_predictions")
failedPredictions Int @default(0) @map("failed_predictions")
// 시뮬레이션 매개변수
parameters Json @map("parameters")
// 전체 시뮬레이션 지표
accuracyMae Float? @map("accuracy_mae") @db.Real
accuracyRmse Float? @map("accuracy_rmse") @db.Real
accuracyMape Float? @map("accuracy_mape") @db.Real
accuracyWithin15min Float? @map("accuracy_within_15min") @db.Real
// 성능 지표
averageExecutionTime Float? @map("average_execution_time") @db.Real
totalExecutionTime Float? @map("total_execution_time") @db.Real
successRate Float? @map("success_rate") @db.Real
// 토론 지표
averageDebateRounds Float? @map("average_debate_rounds") @db.Real
averageConsensusScore Float? @map("average_consensus_score") @db.Real
// 오류 정보
errorMessage String? @map("error_message")
errorDetails Json? @map("error_details")
// 시간 정보
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
startedAt DateTime? @map("started_at") @db.Timestamptz
completedAt DateTime? @map("completed_at") @db.Timestamptz
failedAt DateTime? @map("failed_at") @db.Timestamptz
// 관계
predictions SimulationPrediction[]
// 인덱스
@@index([userId])
@@index([status])
@@index([simulationType])
@@index([createdAt])
@@map("simulation_session")
@@schema("private")
}
// 시뮬레이션 예측 결과
model SimulationPrediction {
id String @id @default(uuid())
sessionId String @map("session_id")
dayIndex Int @map("day_index")
// 예측 결과
predictedSOL Float @map("predicted_sol") @db.Real
actualSOL Float? @map("actual_sol") @db.Real
confidenceScore Float @map("confidence_score") @db.Real
// 정확도 지표
absoluteError Float? @map("absolute_error") @db.Real
percentageError Float? @map("percentage_error") @db.Real
squaredError Float? @map("squared_error") @db.Real
isWithinThreshold Boolean? @map("is_within_threshold")
// 토론 정보
participantAgents String[] @map("participant_agents")
debateRounds Int @map("debate_rounds")
consensusScore Float @map("consensus_score") @db.Real
debateDuration Float @map("debate_duration") @db.Real
// 성능 지표
executionTimeMs Int @map("execution_time_ms")
dataQualityScore Float @map("data_quality_score") @db.Real
// 에이전트별 개별 예측 (JSON 형태로 저장)
agentPredictions Json @map("agent_predictions")
// 분석 근거 및 증거 자료
analysisEvidence Json @map("analysis_evidence")
// 시간 정보
predictedAt DateTime @map("predicted_at") @db.Timestamptz
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
// 관계
simulationSession SimulationSession @relation(fields: [sessionId], references: [id])
// 인덱스
@@index([sessionId])
@@index([dayIndex])
@@index([sessionId, dayIndex])
@@index([predictedAt])
@@map("simulation_prediction")
@@schema("private")
}
// 시뮬레이션 비교 분석 (예측값 vs 실제값)
model SimulationComparison {
id String @id @default(uuid())
sessionId String @map("session_id")
comparisonType String @map("comparison_type") // "daily", "weekly", "overall"
// 비교 기간
startDayIndex Int @map("start_day_index")
endDayIndex Int @map("end_day_index")
// 정확도 지표
mae Float @map("mae") @db.Real
rmse Float @map("rmse") @db.Real
mape Float @map("mape") @db.Real
accuracyRate Float @map("accuracy_rate") @db.Real
// 추세 분석
improvementRate Float? @map("improvement_rate") @db.Real
trendDirection String? @map("trend_direction") // "improving", "declining", "stable"
// 에이전트별 성능
agentPerformance Json @map("agent_performance")
// 상세 비교 데이터
comparisonDetails Json @map("comparison_details")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
// 인덱스
@@index([sessionId])
@@index([comparisonType])
@@index([sessionId, comparisonType])
@@map("simulation_comparison")
@@schema("private")
}
// --- 열거형 타입 (시뮬레이션 관련) ---
enum SimulationType {
BACKTESTING // 완료된 치료 주기 데이터로 백테스팅
SEQUENTIAL // 순차적 일일 예측 시뮬레이션
BATCH // 여러 사용자 배치 시뮬레이션
A_B_TEST // A/B 테스트용 시뮬레이션
@@map("SimulationType")
}
enum SimulationStatus {
PENDING // 시뮬레이션 대기 중
QUEUED // 큐에서 대기 중
RUNNING // 실행 중
PAUSED // 일시 중지
COMPLETED // 완료
FAILED // 실패
CANCELLED // 취소됨
@@map("SimulationStatus")
}
8. 변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-08-31 | bok@weltcorp.com | 최초 작성 (취침시간 기반 스케줄링, 예측 전용 테이블, 조건부 워크플로우 반영) |
| 0.2.0 | 2025-09-01 | bok@weltcorp.com | Prisma 스키마 추가 (10개 모델, 9개 열거형, 스키마 분리 적용) |
| 0.3.0 | 2025-09-01 | bok@weltcorp.com | Learning 데이터 통합 및 Digital Environment 제약사항 반영 - learningDataIncluded, learningEngagement 필드 추가, EvidenceType에 LEARNING_DATA/APP_USAGE_DATA 추가 |
| 0.4.0 | 2025-09-01 | bok@weltcorp.com | 시뮬레이션 엔티티 모델 추가 - SimulationSession, SimulationPrediction, SimulationComparison 모델 및 관련 열거형 타입 정의 |
| 0.5.0 | 2025-09-02 | bok@weltcorp.com | SOL 도메인 명확성 개선을 위한 테이블 리네이밍 - RecommendationSet → SOLRecommendationSet, Recommendation → SOLRecommendation, ModelPerformanceMetrics → SOLModelPerformanceMetrics, RecommendationCategory → SOLRecommendationCategory |
| 0.6.0 | 2025-09-08 | bok@weltcorp.com | 수면 목표 데이터 인터페이스 추가 - SleepGoalData, SleepGoalSummary, EnhancedSleepDataSummary 인터페이스 정의, 수면 목표 달성률 기반 분석을 위한 데이터 수집 흐름 명시 |