본문으로 건너뛰기

Agent Treatment Flow 도메인 모델

데이터 저장 규칙

Agent Treatment Flow는 CBT-I 기반 불면증 치료 프로세스를 관리하는 핵심 도메인으로서 다음의 데이터 저장 규칙을 따릅니다:

스키마 분리 원칙

  • 개인정보 관련 데이터는 private 스키마에 저장되어야 합니다.
  • 비개인정보 데이터는 agent_treatment_flow 스키마에 저장되어야 합니다.
  • 개인정보 포함 여부에 따라 위 규칙을 우선적으로 적용합니다.

Agent Treatment Flow 도메인의 개인정보 분류

  • 개인정보 (private 스키마):
    • TreatmentProcess: userId와 연결된 치료 프로세스 데이터
    • TreatmentPhase: 개인별 치료 단계 진행 데이터
    • TreatmentHypothesis: 개인별 치료 가설
    • TreatmentRoadmap: 개인 맞춤형 치료 로드맵
    • AgentTaskDefinition, TaskExecution: 개인별 치료 과제 및 수행 기록
    • AgentWeeklyEvaluation: 개인별 주간 평가 결과
  • 비개인정보 (agent_treatment_flow 스키마):
    • MessageTemplate: 메시지 템플릿 (다국어 지원)
    • TreatmentProtocolTemplate: 표준 치료 프로토콜
    • PhaseTransitionRule: 단계 전환 규칙
    • TaskTemplate: 치료 과제 템플릿
    • AgentMessage: 생성된 메시지 (Agent Board로 전달)

Agent Message 저장 정책

  • agent_treatment_flow 스키마: 생성된 Agent 메시지는 agent_treatment_flow 스키마에 저장됩니다.
  • 이유: Agent Message는 생성 후 Agent Board로 전달되어 관리되며, 메시지 자체는 치료 도메인의 일부입니다.
  • 데이터 흐름: Treatment Flow (생성) → agent_treatment_flow 스키마 (저장) → Agent Board (전달 및 추적)

User 도메인과의 협력

  • 치료 주기 관리: User 도메인이 UserCycle의 생명주기(시작, 종료, 일시정지 등)를 관리합니다.
  • 치료 프로세스 관리: Agent Treatment Flow는 UserCycle이 시작되면 TreatmentProcess를 생성하여 해당 주기 동안의 치료 전략과 진행을 관리합니다.
  • 상태 동기화: UserCycle이 suspended되면 TreatmentProcess도 PAUSED 상태로 전환됩니다.

데이터 보관 정책

치료 데이터 저장

  • 영구 저장: 모든 치료 관련 데이터(TreatmentProcess, Phase, Hypothesis 등)는 PostgreSQL의 private 스키마에 영구 저장됩니다.
  • 이유: 치료 효과 분석, 의료 기록 보존 의무, 장기적인 연구 목적을 위해 필요합니다.
  • 아카이빙: 치료 종료 후 1년이 지난 데이터는 별도 아카이브 테이블로 이동

생성된 메시지 저장

  • 임시 저장: AgentMessage는 생성 후 agent_treatment_flow 스키마에 저장되며, Agent Board 전달 확인 후 7일간 보관됩니다.
  • 이유: Agent Board가 메시지의 실제 전달과 추적을 담당하므로, Treatment Flow는 생성 이력만 관리합니다.
  • 메타데이터 영구 보존: 메시지 본문은 삭제되더라도 생성 이력과 메타데이터는 영구 보존됩니다.

임시 상태 (Redis)

  • Phase 전환 상태: 진행 중인 단계 전환 작업
  • 일일 Task 큐: 생성 대기 중인 일일 과제
  • LLM 요청 캐시: 비용 절감을 위한 LLM 응답 캐시

GDPR 및 개인정보보호 준수

  • 데이터 최소화: 치료에 필수적인 데이터만 수집 및 저장
  • 가명화: userId는 해시 처리되어 저장
  • 삭제 요청: 사용자 요청 시 개인 식별 가능 데이터 완전 삭제 (단, 익명화된 통계 데이터는 보존)
  • 접근 제어: 행 수준 보안(RLS) 적용으로 사용자별 데이터 격리

기존 데이터 저장 규칙 (레거시)

  • private 스키마: 치료 전략, 가설, 로드맵 등 치료 프로세스 데이터를 저장합니다.
  • agent_treatment_flow 스키마: 생성된 Agent 메시지와 메타데이터를 저장합니다.

1. 엔티티 관계도 (ERD)

2. 엔티티

2.1 TreatmentProcess

/**
* UserCycle에 대한 치료 프로세스 확장 정보
* User 도메인의 UserCycle과 1:1 관계를 가지며, 치료 전략과 진행 상태를 관리
*/
interface TreatmentProcess {
userCycleId: string; // UserCycle ID (PK이자 FK, 1:1 관계)
currentPhase: PhaseType; // 현재 진행 중인 단계
settings: TreatmentSettings; // 치료 설정
metrics: ProcessMetrics; // 전체 지표
lastPhaseTransition: Date; // 마지막 단계 전환 시간
updatedAt: Date;

// UserCycle의 상태는 필요시 JOIN으로 조회
// status, userId, createdAt 등은 UserCycle에서 관리
}

// TreatmentProcessStatus는 제거 (UserCycle의 status와 isSuspended 사용)

2.2 TreatmentPhase

/**
* P1-P5 각 치료 단계를 나타내는 엔티티
*/
interface TreatmentPhase {
id: string; // 단계 ID (UUID)
userCycleId: string; // UserCycle ID (FK)
phaseType: PhaseType; // P1-P5
inputData: PhaseInput; // 단계 입력 데이터
outputData: PhaseOutput; // 단계 출력 데이터
status: PhaseStatus; // 단계 상태
iteration: number; // 반복 횟수 (P3, P4 재진입 시)
startedAt: Date;
completedAt?: Date;
}

enum PhaseType {
P1_INITIAL_ASSESSMENT = 'P1',
P2_HYPOTHESIS_REFINEMENT = 'P2',
P3_TREATMENT_ROADMAP = 'P3',
P4_DAILY_COACHING = 'P4',
P5_WEEKLY_EVALUATION = 'P5',
}

enum PhaseStatus {
PENDING = 'PENDING',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
}

2.3 TreatmentHypothesis

/**
* P2에서 생성되는 치료 가설 엔티티
*/
interface TreatmentHypothesis {
id: string; // 가설 ID (UUID)
phaseId: string; // P2 단계 ID
type: HypothesisType; // 가설 유형
description: string; // 가설 설명
evidence: Evidence[]; // 근거 데이터
confidence: number; // 신뢰도 (0-1)
priority: number; // 우선순위
isActive: boolean; // 활성 상태
validationStatus?: ValidationStatus;
createdAt: Date;
}

enum HypothesisType {
SLEEP_ONSET = 'SLEEP_ONSET',
SLEEP_MAINTENANCE = 'SLEEP_MAINTENANCE',
EARLY_AWAKENING = 'EARLY_AWAKENING',
SLEEP_QUALITY = 'SLEEP_QUALITY',
DAYTIME_IMPACT = 'DAYTIME_IMPACT',
}

2.4 TreatmentRoadmap

/**
* P3에서 생성되는 치료 로드맵 엔티티
*/
interface TreatmentRoadmap {
id: string; // 로드맵 ID (UUID)
userCycleId: string; // UserCycle ID (FK)
version: string; // 버전 (예: "1.0.0", 재설계 시 증가)
phases: RoadmapPhase[]; // 치료 단계들
milestones: Milestone[]; // 주요 이정표
coreNarrative: string; // 핵심 서사
strategies: TreatmentStrategy[]; // 치료 전략
estimatedDuration: number; // 예상 기간 (주)
createdAt: Date;
updatedAt: Date;
}

2.5 AgentMessage

/**
* 생성된 Agent 메시지 엔티티
* 생성 후 즉시 Agent Board로 전송되며, 이후의 상태 추적은 Agent Board가 담당
*/
interface AgentMessage {
id: string; // 메시지 ID (UUID)
userCycleId: string; // User 도메인의 UserCycle ID
phaseId?: string; // 단계 ID (선택)
type: AgentMessageType; // 메시지 유형
priority: MessagePriority; // 우선순위
content: ContentBody; // 메시지 본문
metadata: ContentMetadata; // 메타데이터
displayRules: DisplayRules; // 표시 규칙
createdAt: Date;
scheduledFor?: Date; // 예약 시간
displayedAt?: Date; // 실제 표시 시간 (Agent Board에서 피드백)
interactionData?: InteractionData; // 상호작용 데이터 (Agent Board에서 피드백)

// status는 Agent Board에서 관리 (PENDING → DELIVERED → VIEWED → INTERACTED 등)
}

enum AgentMessageType {
TASK = 'TASK',
MESSAGE = 'MESSAGE',
QUESTION = 'QUESTION',
INSIGHT = 'INSIGHT',
ALERT = 'ALERT',
PRESCRIPTION = 'PRESCRIPTION',
// 10가지 구체적인 메시지 유형
SLEEPQ_INTRO = 'SLEEPQ_INTRO', // 슬립큐 소개
SLEEP_LOG_PROMPT = 'SLEEP_LOG_PROMPT', // 수면로그 작성하기
SLEEP_PRESCRIPTION_GUIDE = 'SLEEP_PRESCRIPTION_GUIDE', // 권장 취침시간 처방 안내
WAKE_TIME_ALERT = 'WAKE_TIME_ALERT', // 기상 시각 안내
BEDTIME_PREPARATION = 'BEDTIME_PREPARATION', // 취침 준비 안내
DAILY_PROGRAM_GUIDE = 'DAILY_PROGRAM_GUIDE', // 오늘의 치료 프로그램 안내
TREATMENT_PROGRESS = 'TREATMENT_PROGRESS', // 나의 치료 현황
FINAL_ANALYSIS_RESULT = 'FINAL_ANALYSIS_RESULT', // 최종 설문 분석 결과 안내
SERVICE_EXPIRATION = 'SERVICE_EXPIRATION', // 서비스 사용 만료 안내
THERAPEUTIC_TASK = 'THERAPEUTIC_TASK', // 치료적 Task 메시지
}

enum MessagePriority {
CRITICAL = 'CRITICAL',
HIGH = 'HIGH',
MEDIUM = 'MEDIUM',
LOW = 'LOW',
}

/**
* 메시지별 특수 처리 규칙
*/
interface MessageSpecialRules {
mustConfirm?: boolean; // 반드시 확인해야 하는지
reappearAfterOthers?: boolean; // 다른 메시지 처리 후 재노출 필요
queueAtMidnight?: boolean; // 자정에 Queue 처리 필요
requiresNotification?: boolean; // 푸시 알림 동반 필요
minimumWeek?: number; // 최소 노출 주차 제한
triggerCondition?: string; // 노출 조건 설명
}

2.6 AgentTaskDefinition

/**
* 로드맵에 정의된 Task 명세
*/
interface AgentTaskDefinition {
id: string; // Task 정의 ID
roadmapId: string; // 로드맵 ID
phaseIndex: number; // Phase 내 순서
type: AgentTaskType; // Task 유형
specification: TaskSpec; // Task 명세
completionCriteria: CompletionCriteria;
estimatedDuration: number; // 예상 소요시간 (분)
dependencies?: string[]; // 선행 Task ID
createdAt: Date;
}

enum AgentTaskType {
COGNITIVE_APPROACH = 'COGNITIVE_APPROACH',
BEHAVIORAL_INDUCTION = 'BEHAVIORAL_INDUCTION',
EMOTION_EXPLORATION = 'EMOTION_EXPLORATION',
FEEDBACK_LOOP = 'FEEDBACK_LOOP',
}

2.7 TaskExecution

/**
* Task 수행 기록 엔티티
*/
interface TaskExecution {
id: string; // 수행 ID
taskId: string; // Task 정의 ID
messageId?: string; // 관련 메시지 ID (선택)
userId: string; // 수행자 ID
startedAt: Date; // 시작 시간
completedAt?: Date; // 완료 시간
response?: any; // 사용자 응답
performanceScore?: number; // 수행 점수
feedback?: string; // 사용자 피드백
}

3. 값 객체

3.1 PhaseInput/Output

// P1 입력/출력
interface P1Input {
sleepRecords: SleepRecordSummary[];
questionnaireResponses: QuestionnaireResponse[];
userProfile: UserProfile;
}

interface P1Output {
humanReview: {
keyInsights: string[];
concernAreas: string[];
recommendations: string[];
};
systemProcessing: {
patterns: SleepPattern[];
metrics: SleepMetrics;
riskFactors: RiskFactor[];
};
patientPresentation: {
summary: string;
focusAreas: string[];
nextSteps: string[];
};
}

// P2 입력/출력
interface P2Input {
p1Output: P1Output;
additionalData?: any;
}

interface P2Output {
hypotheses: TreatmentHypothesis[];
primaryFocus: string;
mechanismModel: MechanismModel;
strengths: PatientStrength[];
}

// P3 입력/출력
interface P3Input {
p2Output: P2Output;
constraints?: TreatmentConstraints;
}

interface P3Output {
roadmap: TreatmentRoadmap;
phases: RoadmapPhase[];
estimatedTimeline: Timeline;
successCriteria: SuccessCriteria[];
}

// P4 입력/출력
interface P4Input {
roadmap: TreatmentRoadmap;
dailyContext: DailyContext;
previousTasks: TaskExecution[];
}

interface P4Output {
dailyTasks: AgentMessage[];
adjustments?: RoadmapAdjustment[];
insights?: DailyInsight[];
}

// P5 입력/출력
interface P5Input {
weeklyData: WeeklyData;
taskPerformance: TaskPerformanceMetrics;
patientFeedback: PatientFeedback[];
}

interface P5Output {
evaluation: AgentWeeklyEvaluation;
decision: P5Decision;
recommendations: string[];
adjustmentPlan?: AdjustmentPlan;
}

3.2 Core Narrative Components

interface CoreNarrative {
mainTheme: string; // 주요 테마
personalStory: string; // 개인 스토리
motivations: string[]; // 동기 요소
barriers: string[]; // 장애 요소
aspirations: string[]; // 목표와 열망
communicationStyle: {
tone: 'formal' | 'casual' | 'supportive' | 'direct';
preferredChannels: string[];
avoidanceTopics: string[];
};
}

3.3 Agent Message Components

interface ContentBody {
// 템플릿 방식 (변수 치환 지원)
titleTemplate: MessageTemplate;
bodyTemplate: MessageTemplate;

// 레거시 지원 (직접 문자열)
title?: string;
body?: string;

actions?: Action[];
}

/**
* 다국어 지원 메시지 템플릿
*/
interface MessageTemplate {
// 템플릿 ID (번역 키)
templateId: string;

// 메시지 타입
messageType: string;

// 템플릿 내용
template: string;

// 템플릿 변수
variables?: Record<string, any>;
}

// 예시:
// {
// templateId: "sleepq_intro_title",
// messageType: "SLEEPQ_INTRO",
// template: "{{userName}}님, 슬립큐와 함께 불면증 치료를 시작합니다!",
// variables: { userName: "홍길동" }
// }

interface Action {
type: 'primary' | 'secondary' | 'dismiss';
labelTemplate: MessageTemplate; // 버튼 레이블도 다국어 지원
target: string;
payload?: any;
}

interface ContentMetadata {
category?: string; // 카테고리
phase: PhaseType;
clinicalIntent: string;
expectedOutcome: string;
generatedBy: string;
generationContext: any;
version: string;
}

interface DisplayRules {
maxDisplayCount?: number; // 최대 표시 횟수
expiresAt?: ZonedDateTime; // 만료 시간 (타임존 포함)
}

interface InteractionData {
actionType: string;
timestamp: Date;
context?: any;
result?: any;
}

3.4 Metrics and Analytics

interface ProcessMetrics {
overallProgress: number; // 0-100
sleepEfficiencyTrend: Trend;
taskCompletionRate: number;
engagementScore: number;
clinicalOutcomes: ClinicalMetrics;
}

interface Trend {
direction: 'improving' | 'stable' | 'declining';
magnitude: number;
confidence: number;
}

interface ClinicalMetrics {
isi: number; // 불면증 심각도 지수
sleepEfficiency: number;
sleepLatency: number;
waso: number; // Wake After Sleep Onset
tst: number; // Total Sleep Time
}

interface AgentWeeklyEvaluation {
sleepImprovement: ImprovementMetric;
taskPerformance: PerformanceMetric;
psychologicalWellbeing: WellbeingMetric;
overallStatus: 'SUCCESS' | 'BARRIER' | 'MISMATCH' | 'CRITICAL_ISSUE';
}

interface ImprovementMetric {
percentageChange: number;
isSignificant: boolean;
areas: string[];
}

interface PerformanceMetric {
completionRate: number;
qualityScore: number;
consistency: number;
}

interface WellbeingMetric {
mood: number;
energy: number;
motivation: number;
}

interface P5Decision {
action: 'PROCEED_AS_PLANNED' | 'TRIGGER_P4_ADJUSTMENT' | 'LOOP_BACK_TO_P3' | 'TRIGGER_DUAL_CHANNEL_ALERT';
rationale: string;
specificAdjustments?: any;
}

3.5 Treatment Components

interface TreatmentSettings {
timezone: string;
preferredLanguage: string;
notificationPreferences: {
enablePush: boolean;
quietHoursStart?: string;
quietHoursEnd?: string;
};
treatmentIntensity: 'light' | 'moderate' | 'intensive';
customParameters?: any;
}

interface Evidence {
source: 'questionnaire' | 'sleep_record' | 'user_input' | 'analysis';
data: any;
confidence: number;
timestamp: Date;
}

interface ValidationStatus {
isValidated: boolean;
validatedAt?: Date;
validatedBy?: string;
notes?: string;
}

interface RoadmapPhase {
weekNumber: number;
goals: string[];
tasks: string[]; // Task IDs
expectedOutcomes: string[];
successCriteria: string[];
}

interface Milestone {
name: string;
targetWeek: number;
criteria: string[];
reward?: string;
}

interface TreatmentStrategy {
type: 'cognitive' | 'behavioral' | 'relaxation' | 'education';
name: string;
description: string;
frequency: string;
priority: number;
}

interface TaskSpec {
instructions: string[];
materials?: string[];
duration: number;
difficulty: 1 | 2 | 3 | 4 | 5;
adaptations?: any;
}

interface CompletionCriteria {
type: 'time' | 'response' | 'performance';
threshold: any;
evaluation: string;
}

4. 집계 (Aggregates)

TreatmentProcess 집계

  • 루트: TreatmentProcess
  • 엔티티: TreatmentPhase, AgentMessage
  • 값 객체: TreatmentSettings, ProcessMetrics, CoreNarrative
  • 불변식:
    • UserCycle과 1:1 관계 (userCycleId가 PK이자 FK)
    • UserCycle이 존재할 때만 TreatmentProcess 생성 가능
    • 한 번에 하나의 Phase만 활성 상태여야 함
    • P1은 반드시 첫 번째 Phase여야 함
    • Critical Issue 발생 시 즉시 상태 변경
    • UserCycle의 상태에 따라 동작 (ACTIVE일 때만 진행 가능)

TreatmentRoadmap 집계

  • 루트: TreatmentRoadmap
  • 엔티티: AgentTaskDefinition
  • 값 객체: RoadmapPhase, Milestone, TreatmentStrategy
  • 불변식:
    • 최소 3개의 Phase 포함
    • 각 Phase는 3-5개의 Task 포함
    • Task 간 의존성은 순환 참조 불가
    • 전체 예상 기간은 현실적이어야 함

AgentMessage 집계

  • 루트: AgentMessage
  • 값 객체: ContentBody, ContentMetadata, DisplayRules
  • 불변식:
    • Critical 우선순위는 즉시 전달
    • 야간 시간대 메시지는 큐에 저장
    • 중복 메시지 방지
    • 표시 규칙 충돌 해결

5. 도메인 서비스

5.1 TreatmentOrchestrationService

interface TreatmentOrchestrationService {
/**
* UserCycle이 시작될 때 치료 프로세스를 초기화하고 P1을 시작
*/
initiateTreatmentProcess(userCycleId: string, settings: TreatmentSettings): Promise<TreatmentProcess>;

/**
* 현재 Phase를 완료하고 다음 Phase로 전환
*/
transitionPhase(userCycleId: string, phaseOutput: PhaseOutput): Promise<TreatmentPhase>;

/**
* P5 평가 결과에 따른 의사결정 실행
*/
executeP5Decision(userCycleId: string, decision: P5Decision): Promise<void>;

/**
* 치료 프로세스 상태 조회 (UserCycle 상태 포함)
*/
getTreatmentProcessWithCycleStatus(userCycleId: string): Promise<TreatmentProcessWithStatus>;
}

5.2 MessageGenerationService

interface MessageGenerationService {
/**
* LLM을 활용한 개인화 메시지 생성
*/
generatePersonalizedMessage(context: GenerationContext, template: MessageTemplate): Promise<AgentMessage>;

/**
* 일일 Task 세트 생성
*/
generateDailyTasks(roadmap: TreatmentRoadmap, dailyContext: DailyContext): Promise<AgentMessage[]>;

/**
* 긴급 알림 생성
*/
generateCriticalAlert(issue: CriticalIssue, patient: PatientContext): Promise<AgentMessage>;
}

5.3 ClinicalAnalysisService

interface ClinicalAnalysisService {
/**
* 수면 패턴 분석 및 인사이트 도출
*/
analyzeSleepPatterns(records: SleepRecord[]): Promise<SleepAnalysis>;

/**
* 치료 효과성 평가
*/
evaluateTreatmentEffectiveness(userCycleId: string, period: DateRange): Promise<EffectivenessReport>;

/**
* Critical Issue 스크리닝
*/
screenForCriticalIssues(content: string, context: PatientContext): Promise<CriticalIssueResult>;
}

5.4 PersonalizationService

interface PersonalizationService {
/**
* 핵심 서사 추출 및 업데이트
*/
extractCoreNarrative(patientData: PatientData): Promise<CoreNarrative>;

/**
* 메시지 톤 & 매너 조정
*/
adjustMessageTone(message: string, preferences: CommunicationPreferences): Promise<string>;

/**
* Task 난이도 최적화
*/
optimizeTaskDifficulty(taskHistory: TaskExecution[], currentTask: AgentTaskDefinition): Promise<AgentTaskDefinition>;
}

6. 도메인 이벤트

6.1 치료 프로세스 이벤트

interface TreatmentProcessStarted {
userCycleId: string;
timestamp: Date;
}
interface TreatmentProcessCompleted {
userCycleId: string;
outcome: string;
timestamp: Date;
}
interface TreatmentProcessPaused {
userCycleId: string;
reason: string;
timestamp: Date;
}
interface TreatmentProcessResumed {
userCycleId: string;
timestamp: Date;
}

6.2 Phase 전환 이벤트

interface PhaseTransitioned {
userCycleId: string;
fromPhase: PhaseType;
toPhase: PhaseType;
timestamp: Date;
}
interface P1Completed {
userCycleId: string;
output: P1Output;
timestamp: Date;
}
interface P2Completed {
userCycleId: string;
hypotheses: TreatmentHypothesis[];
timestamp: Date;
}
interface P3Completed {
userCycleId: string;
roadmapId: string;
timestamp: Date;
}
interface P5DecisionMade {
userCycleId: string;
decision: P5Decision;
timestamp: Date;
}

6.3 메시지 이벤트

interface MessageGenerated {
messageId: string;
type: AgentMessageType;
priority: MessagePriority;
timestamp: Date;
}
interface MessageDelivered {
messageId: string;
userId: string;
timestamp: Date;
}
interface MessageInteracted {
messageId: string;
action: string;
timestamp: Date;
}
interface CriticalAlertTriggered {
alertId: string;
issue: string;
severity: string;
timestamp: Date;
}

6.4 Task 수행 이벤트

interface TaskAssigned {
taskId: string;
userId: string;
dueDate: Date;
timestamp: Date;
}
interface TaskStarted {
executionId: string;
taskId: string;
timestamp: Date;
}
interface TaskCompleted {
executionId: string;
score: number;
timestamp: Date;
}
interface TaskSkipped {
taskId: string;
reason: string;
timestamp: Date;
}

7. 도메인 규칙

본 문서에서는 모델 구조에 대한 설명에 중점을 두고 있으며, 상세한 비즈니스 규칙은 Agent Treatment Flow 도메인 비즈니스 규칙 문서를 참조하세요.

주요 규칙 카테고리는 다음과 같습니다:

  1. 치료 프로세스 규칙: A-H-I-R 순환 모델, 5단계 치료 모듈, 단계 전환 규칙
  2. 메시지 생성 규칙: 우선순위, 개인화, 생성 시점, Task 유형별 규칙
  3. 안전성 규칙: Critical Issue 감지, 치료 경계 규칙
  4. 성능 규칙: 메시지 생성 성능, 분석 성능 규칙
  5. 데이터 활용 규칙: 데이터 수집, 분석 규칙
  6. Agent Board 연동 규칙: 메시지 전달, 피드백 수신 규칙

8. 데이터베이스 스키마 (Prisma)

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["private", "agent_treatment_flow"]
}

model TreatmentProcess {
userCycleId String @id @map("user_cycle_id") // PK이자 FK (1:1 관계)
currentPhase String @map("current_phase")
settings Json
metrics Json
lastPhaseTransition DateTime @map("last_phase_transition")
updatedAt DateTime @updatedAt @map("updated_at")

// UserCycle 정보는 필요시 JOIN으로 조회
// status, userId, createdAt 등은 UserCycle에서 관리

phases TreatmentPhase[]
roadmap TreatmentRoadmap?
messages AgentMessage[]

@@map("treatment_processes")
@@schema("private")
}

model TreatmentPhase {
id String @id @default(uuid())
userCycleId String @map("user_cycle_id")
phaseType String @map("phase_type")
inputData Json @map("input_data")
outputData Json? @map("output_data")
status String
iteration Int @default(1)
startedAt DateTime @map("started_at")
completedAt DateTime? @map("completed_at")

process TreatmentProcess @relation(fields: [userCycleId], references: [userCycleId])
hypotheses TreatmentHypothesis[]

@@map("treatment_phases")
@@schema("private")
}

model TreatmentHypothesis {
id String @id @default(uuid())
phaseId String @map("phase_id")
type String
description String
evidence Json
confidence Float
priority Int
isActive Boolean @default(true) @map("is_active")
validationStatus String? @map("validation_status")
createdAt DateTime @default(now()) @map("created_at")

phase TreatmentPhase @relation(fields: [phaseId], references: [id])

@@map("treatment_hypotheses")
@@schema("private")
}

model TreatmentRoadmap {
id String @id @default(uuid())
userCycleId String @unique @map("user_cycle_id")
version String @default("1.0.0")
phases Json
milestones Json
coreNarrative String @map("core_narrative")
strategies Json
estimatedDuration Int @map("estimated_duration")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

process TreatmentProcess @relation(fields: [userCycleId], references: [userCycleId])
tasks AgentTaskDefinition[]

@@map("treatment_roadmaps")
@@schema("private")
}

model AgentMessage {
id String @id @default(uuid())
userCycleId String @map("user_cycle_id") // User 도메인 참조
phaseId String? @map("phase_id")
type String
priority String
content Json // ContentBody with MessageTemplate structure
metadata Json // includes language information
displayRules Json @map("display_rules")
createdAt DateTime @default(now()) @map("created_at")
scheduledFor DateTime? @map("scheduled_for")
displayedAt DateTime? @map("displayed_at") // Agent Board에서 피드백
interactionData Json? @map("interaction_data") // Agent Board에서 피드백
language String @default("ko") // 메시지 언어

process TreatmentProcess @relation(fields: [userCycleId], references: [userCycleId])
taskExecutions TaskExecution[]

@@index([userCycleId])
@@index([scheduledFor])
@@index([language])
@@map("agent_messages")
@@schema("agent_treatment_flow")
}

model AgentTaskDefinition {
id String @id @default(uuid())
roadmapId String @map("roadmap_id")
phaseIndex Int @map("phase_index")
type String
specification Json
completionCriteria Json @map("completion_criteria")
estimatedDuration Int @map("estimated_duration")
dependencies String[]
createdAt DateTime @default(now()) @map("created_at")

roadmap TreatmentRoadmap @relation(fields: [roadmapId], references: [id])
executions TaskExecution[]

@@map("task_definitions")
@@schema("private")
}

model TaskExecution {
id String @id @default(uuid())
taskId String @map("task_id")
messageId String? @map("message_id")
userId String @map("user_id")
startedAt DateTime @map("started_at")
completedAt DateTime? @map("completed_at")
response Json?
performanceScore Float? @map("performance_score")
feedback String?

task AgentTaskDefinition @relation(fields: [taskId], references: [id])
message AgentMessage? @relation(fields: [messageId], references: [id])

@@map("task_executions")
@@schema("private")
}

// ============================================
// agent_treatment_flow 스키마 - 비개인정보 데이터
// ============================================

model MessageTemplate {
id String @id @default(uuid())
templateId String @unique @map("template_id")
messageType String @map("message_type")
variables Json? // 템플릿에서 사용되는 변수 스키마
description String? @db.Text
isActive Boolean @default(true) @map("is_active")
version String @default("1.0.0")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
translations MessageTemplateTranslation[]

@@index([messageType, isActive])
@@map("message_templates")
@@schema("agent_treatment_flow")
}

model MessageTemplateTranslation {
id String @id @default(uuid())
templateId String @map("template_id")
language String
template String @db.Text
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
messageTemplate MessageTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)

@@unique([templateId, language])
@@index([language])
// 성능 최적화: 언어별 템플릿 조회용 (커버링 인덱스)
@@index([language, templateId])
@@map("message_template_translations")
@@schema("agent_treatment_flow")
}

model TreatmentProtocolTemplate {
id String @id @default(uuid())
name String @db.VarChar(100)
description String? @db.Text
targetCondition String @map("target_condition") // 대상 증상

// 프로토콜 구성
phases Json // P1-P5 표준 구성
strategies Json // 치료 전략
tasks Json // 표준 과제 목록

// 적용 조건
eligibilityCriteria Json @map("eligibility_criteria")
contraindications Json? // 금기사항

isActive Boolean @default(true) @map("is_active")
version String @default("1.0.0")
publishedAt DateTime? @map("published_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@map("treatment_protocol_templates")
@@schema("agent_treatment_flow")
}

model PhaseTransitionRule {
id String @id @default(uuid())
fromPhase String @map("from_phase")
toPhase String @map("to_phase")

// 전환 조건
conditions Json // 전환 필요 조건
evaluationLogic String @map("evaluation_logic") @db.Text // 평가 로직

// 전환 시 액션
requiredActions Json @map("required_actions")
notifications Json? // 알림 설정

priority Int @default(0) // 규칙 우선순위
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@unique([fromPhase, toPhase, priority])
@@map("phase_transition_rules")
@@schema("agent_treatment_flow")
}

model TaskTemplate {
id String @id @default(uuid())
code String @unique @db.VarChar(50)
name String @db.VarChar(100)
description String? @db.Text
category String @db.VarChar(50)

// 과제 구성
specification Json // 과제 명세
instructions Json // 수행 지침
completionCriteria Json @map("completion_criteria")

// 메타데이터
difficulty Int @default(3) // 1-5
estimatedDuration Int @map("estimated_duration") // 분
requiredFrequency String? @map("required_frequency") // daily, weekly 등

isActive Boolean @default(true) @map("is_active")
version String @default("1.0.0")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@index([category, isActive])
@@map("task_templates")
@@schema("agent_treatment_flow")
}

model AgentWeeklyEvaluation {
id String @id @default(uuid())
phaseId String @map("phase_id")
userCycleId String @map("user_cycle_id")
weekNumber Int @map("week_number")

// 평가 결과
sleepImprovement Json @map("sleep_improvement")
taskPerformance Json @map("task_performance")
wellbeingMetrics Json @map("wellbeing_metrics")
overallStatus String @map("overall_status")

// P5 결정
decision String
rationale String? @db.Text
adjustmentPlan Json? @map("adjustment_plan")

// 임상 노트
clinicalNotes String? @map("clinical_notes") @db.Text

createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@unique([userCycleId, weekNumber])
@@map("weekly_evaluations")
@@schema("private")
}

9. 변경 이력

버전날짜작성자변경 내용
1.0.02025-06-25bok@weltcorp.com최초 작성
2.0.02025-01-03bok@weltcorp.comUser 도메인과의 협력 관계 명확화, TreatmentProcess를 UserCycle의 확장으로 변경
2.1.02025-01-04bok@weltcorp.comContentBody interface 간소화 - sections 제거, 메타데이터 필드 정리
2.2.02025-01-04bok@weltcorp.comTreatmentProcess 리팩토링 - UserCycle과 1:1 관계로 변경, processId를 userCycleId로 대체
2.3.02025-01-04bok@weltcorp.comAgentMessage.status 필드 제거 - 메시지 상태 추적은 Agent Board의 책임으로 명확히 분리
2.4.02025-01-04bok@weltcorp.comversion 필드 타입 변경 - number에서 string으로 변경 (예: "1.0.0"), TreatmentRoadmap 및 스키마 템플릿 모델들 수정
2.5.02025-01-04bok@weltcorp.comContentType enum을 AgentMessageType으로 변경 - 다른 도메인과의 충돌 방지
2.6.02025-01-05bok@weltcorp.comMessageTemplate Translation 테이블 분리 - 다국어 지원을 별도 테이블로 관리 (Learning, Questionnaire 도메인과 일관성 유지)