본문으로 건너뛰기

Medical Statement 도메인 모델

데이터 저장 규칙

  • 개인정보 관련 데이터는 private 스키마에 저장되어야 합니다.
  • 비개인정보 데이터는 medical_statement 스키마에 저장되어야 합니다.
  • 개인정보 포함 여부에 따라 위 규칙을 우선적으로 적용합니다.
  • Medical Statement 도메인에서는 MedicalStatementRecord, AnalysisResult, VerificationProcess, AccessCodeRequest 등 사용자 ID와 연결된 데이터는 모두 개인정보로 취급하여 private 스키마에 저장합니다.
  • 사용자와 연결되지 않은 데이터(LLMModel, AnalysisTemplate, DocumentType 등)만 medical_statement 스키마에 저장합니다.

1. 엔티티 관계도 (ERD)

2. 엔티티

2.1 MedicalStatementRecord

interface MedicalStatementRecord {
id: string;
userId: string;
userCycleId: string;
originalImageUrl: string;
optimizedImageUrl?: string;
documentType: DocumentType;
processingStatus: ProcessingStatus;
imageMetadata: ImageMetadata;
deviceId: string;
uploadedAt: Date;
createdAt: Date;
updatedAt: Date;

// 관계
analysisResult?: AnalysisResult;
verificationProcess?: VerificationProcess;
processingHistories: ProcessingHistory[];
accessCodeRequest?: AccessCodeRequest;
}

enum ProcessingStatus {
UPLOADED = 'UPLOADED',
ANALYZING = 'ANALYZING',
ANALYSIS_COMPLETED = 'ANALYSIS_COMPLETED',
ANALYSIS_FAILED = 'ANALYSIS_FAILED',
PENDING_REVIEW = 'PENDING_REVIEW',
UNDER_REVIEW = 'UNDER_REVIEW',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
ARCHIVED = 'ARCHIVED',
}

enum DocumentType {
MEDICAL_EXPENSE_STATEMENT = 'MEDICAL_EXPENSE_STATEMENT',
PRESCRIPTION = 'PRESCRIPTION',
DIAGNOSIS_CERTIFICATE = 'DIAGNOSIS_CERTIFICATE',
OTHER = 'OTHER',
}

2.2 AnalysisResult

interface AnalysisResult {
id: string;
medicalStatementId: string;
llmModelId: string;
extractedData: ExtractedMedicalData;
structuredResult: StructuredAnalysisResult;
confidenceScore: number;
analysisStatus: AnalysisStatus;
errorMessage?: string;
processingTimeMs: number;
analyzedAt: Date;
createdAt: Date;
updatedAt: Date;

// 관계
medicalStatement: MedicalStatementRecord;
llmModel: LLMModel;
confidenceDetails: AnalysisConfidence[];
}

enum AnalysisStatus {
PENDING = 'PENDING',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
RETRYING = 'RETRYING',
}

2.3 VerificationProcess

interface VerificationProcess {
id: string;
medicalStatementId: string;
reviewerId?: string;
verificationStatus: VerificationStatus;
decision?: VerificationDecision;
rejectionReason?: string;
reviewerComments?: string;
assignedAt?: Date;
reviewedAt?: Date;
deadlineAt?: Date;
createdAt: Date;
updatedAt: Date;

// 관계
medicalStatement: MedicalStatementRecord;
reviewer?: MedicalProfessional;
reviewHistories: ReviewHistory[];
}

enum VerificationStatus {
PENDING_ASSIGNMENT = 'PENDING_ASSIGNMENT',
ASSIGNED = 'ASSIGNED',
IN_REVIEW = 'IN_REVIEW',
COMPLETED = 'COMPLETED',
EXPIRED = 'EXPIRED',
}

enum VerificationDecision {
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
NEEDS_MORE_INFO = 'NEEDS_MORE_INFO',
}

2.4 AccessCodeRequest

interface AccessCodeRequest {
id: string;
userId: string;
userCycleId: string;
medicalStatementId: string;
temporaryAccessCode: string;
finalAccessCode?: string;
requestStatus: AccessCodeRequestStatus;
requestedAt: Date;
approvedAt?: Date;
expiresAt?: Date;
createdAt: Date;
updatedAt: Date;

// 관계
medicalStatement: MedicalStatementRecord;
}

enum AccessCodeRequestStatus {
TEMPORARY_ISSUED = 'TEMPORARY_ISSUED',
PENDING_APPROVAL = 'PENDING_APPROVAL',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
EXPIRED = 'EXPIRED',
}

2.5 ProcessingHistory

interface ProcessingHistory {
id: string;
medicalStatementId: string;
eventType: ProcessingEventType;
status: ProcessingStatus;
description: string;
metadata?: Record<string, any>;
timestamp: Date;
createdAt: Date;

// 관계
medicalStatement: MedicalStatementRecord;
}

enum ProcessingEventType {
UPLOADED = 'UPLOADED',
ANALYSIS_STARTED = 'ANALYSIS_STARTED',
ANALYSIS_COMPLETED = 'ANALYSIS_COMPLETED',
ANALYSIS_FAILED = 'ANALYSIS_FAILED',
SUBMITTED_FOR_REVIEW = 'SUBMITTED_FOR_REVIEW',
REVIEWER_ASSIGNED = 'REVIEWER_ASSIGNED',
REVIEW_STARTED = 'REVIEW_STARTED',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
ARCHIVED = 'ARCHIVED',
}

2.6 ReviewHistory

interface ReviewHistory {
id: string;
verificationProcessId: string;
reviewerId: string;
action: ReviewAction;
comments?: string;
previousState: Record<string, any>;
newState: Record<string, any>;
actionAt: Date;
createdAt: Date;

// 관계
verificationProcess: VerificationProcess;
reviewer: MedicalProfessional;
}

enum ReviewAction {
ASSIGNED = 'ASSIGNED',
STARTED = 'STARTED',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
COMMENTED = 'COMMENTED',
REASSIGNED = 'REASSIGNED',
}

2.7 LLMModel

interface LLMModel {
id: string;
name: string;
version: string;
provider: string;
configuration: LLMConfiguration;
isActive: boolean;
createdAt: Date;
updatedAt: Date;

// 관계
analysisResults: AnalysisResult[];
}

2.8 AnalysisTemplate

interface AnalysisTemplate {
id: string;
name: string;
documentType: string;
promptTemplate: string;
expectedFields: Record<string, any>;
isActive: boolean;
createdAt: Date;
updatedAt: Date;

// 관계
analysisResults: AnalysisResult[];
}

2.9 MedicalProfessional

interface MedicalProfessional {
id: string;
accountId: string;
licenseNumber: string;
specialization: string;
isActive: boolean;
createdAt: Date;
updatedAt: Date;

// 관계
verificationProcesses: VerificationProcess[];
reviewHistories: ReviewHistory[];
}

3. 값 객체 (Value Objects)

3.1 ImageMetadata

interface ImageMetadata {
fileName: string;
fileSize: number;
width: number;
height: number;
format: string;
checksum: string;
uploadMethod: 'CAMERA' | 'GALLERY';
}

3.2 ExtractedMedicalData

interface ExtractedMedicalData {
patientName?: string;
patientId?: string;
hospitalName?: string;
treatmentDate?: Date;
totalAmount?: number;
insuranceCoverage?: number;
patientPayment?: number;
treatmentCodes?: string[];
diagnosisCodes?: string[];
rawText: string;
}

3.3 StructuredAnalysisResult

interface StructuredAnalysisResult {
isValidMedicalStatement: boolean;
documentQuality: DocumentQuality;
extractedFields: Record<string, any>;
missingFields: string[];
anomalies: string[];
recommendedAction: RecommendedAction;
}

enum DocumentQuality {
EXCELLENT = 'EXCELLENT',
GOOD = 'GOOD',
FAIR = 'FAIR',
POOR = 'POOR',
}

enum RecommendedAction {
APPROVE = 'APPROVE',
REJECT = 'REJECT',
NEEDS_HUMAN_REVIEW = 'NEEDS_HUMAN_REVIEW',
REQUEST_BETTER_IMAGE = 'REQUEST_BETTER_IMAGE',
}

3.4 LLMConfiguration

interface LLMConfiguration {
model: string;
temperature: number;
maxTokens: number;
topP: number;
frequencyPenalty: number;
presencePenalty: number;
systemPrompt: string;
userPromptTemplate: string;
}

3.5 VerificationCriteria

interface VerificationCriteria {
requiredFields: string[];
minimumConfidence: number;
documentQualityThreshold: DocumentQuality;
specialChecks: string[];
}

3.6 ProcessingMetrics

interface ProcessingMetrics {
uploadTimeMs: number;
analysisTimeMs: number;
reviewTimeMs: number;
totalProcessingTimeMs: number;
retryCount: number;
errorCount: number;
}

4. 집계 (Aggregates)

  • 진료비 세부산정 내역서 처리(MedicalStatementProcessing)

    • Root: MedicalStatementRecord
    • Entities: AnalysisResult, ProcessingHistory
    • Value Objects: ImageMetadata, ExtractedMedicalData, ProcessingMetrics
  • 검증 프로세스(VerificationProcess)

    • Root: VerificationProcess
    • Entities: ReviewHistory
    • Value Objects: VerificationCriteria
  • 액세스 코드 관리(AccessCodeManagement)

    • Root: AccessCodeRequest
    • Value Objects: AccessCodeInfo
  • LLM 분석 엔진(LLMAnalysisEngine)

    • Root: LLMModel
    • Entities: AnalysisTemplate
    • Value Objects: LLMConfiguration

5. 도메인 서비스

5.1 MedicalStatementUploadService

interface MedicalStatementUploadService {
uploadMedicalStatement(files: MulterFile[], deviceId: string): Promise<MedicalStatementRecord>;
validateImageFile(file: MulterFile): Promise<boolean>;
optimizeImage(imageUrl: string): Promise<string>;
extractImageMetadata(file: MulterFile): Promise<ImageMetadata>;
generateUploadUrl(fileName: string): Promise<string>;
checkUploadQuota(userId: string): Promise<boolean>;
}

5.2 LLMAnalysisService

interface LLMAnalysisService {
analyzeDocument(medicalStatementId: string): Promise<AnalysisResult>;
generateAnalysisPrompt(imageUrl: string, template: AnalysisTemplate): Promise<string>;
parseAnalysisResponse(response: string): Promise<StructuredAnalysisResult>;
calculateConfidenceScore(result: StructuredAnalysisResult): Promise<number>;
retryAnalysis(medicalStatementId: string, retryCount: number): Promise<AnalysisResult>;
getAvailableModels(): Promise<LLMModel[]>;
switchToFallbackModel(originalModelId: string): Promise<LLMModel>;
}

5.3 VerificationService

interface VerificationService {
submitForReview(medicalStatementId: string): Promise<VerificationProcess>;
assignReviewer(verificationProcessId: string, reviewerId?: string): Promise<VerificationProcess>;
startReview(verificationProcessId: string, reviewerId: string): Promise<VerificationProcess>;
approveStatement(verificationProcessId: string, reviewerId: string, comments?: string): Promise<VerificationProcess>;
rejectStatement(verificationProcessId: string, reviewerId: string, reason: string, comments?: string): Promise<VerificationProcess>;
requestReReview(verificationProcessId: string, reason: string): Promise<VerificationProcess>;
getReviewQueue(reviewerId?: string): Promise<VerificationProcess[]>;
updateReviewDeadline(verificationProcessId: string, newDeadline: Date): Promise<VerificationProcess>;
escalateOverdueReview(verificationProcessId: string): Promise<VerificationProcess>;
}

5.4 AccessCodeManagementService

interface AccessCodeManagementService {
generateTemporaryAccessCode(medicalStatementId: string): Promise<AccessCodeRequest>;
generateFinalAccessCode(medicalStatementId: string): Promise<AccessCodeRequest>;
validateAccessCode(code: string): Promise<AccessCodeValidation>;
expireTemporaryCode(accessCodeRequestId: string): Promise<void>;
getAccessCodeStatus(medicalStatementId: string): Promise<AccessCodeRequest>;
renewAccessCode(accessCodeRequestId: string): Promise<AccessCodeRequest>;
}

5.5 MedicalStatementQueryService

interface MedicalStatementQueryService {
getMedicalStatement(id: string): Promise<MedicalStatementRecord | null>;
getUserMedicalStatements(userId: string): Promise<MedicalStatementRecord[]>;
getMedicalStatementsByStatus(status: ProcessingStatus): Promise<MedicalStatementRecord[]>;
searchMedicalStatements(criteria: SearchCriteria): Promise<PaginatedResult<MedicalStatementRecord>>;
getMedicalStatementWithAnalysis(id: string): Promise<MedicalStatementWithAnalysis>;
getProcessingStatistics(dateRange: DateRange): Promise<ProcessingStatistics>;
}

5.6 NotificationService

interface NotificationService {
sendAnalysisCompletionNotification(userId: string, medicalStatementId: string): Promise<void>;
sendApprovalNotification(userId: string, accessCode: string): Promise<void>;
sendRejectionNotification(userId: string, reason: string): Promise<void>;
sendReviewAssignmentNotification(reviewerId: string, medicalStatementId: string): Promise<void>;
sendDeadlineReminderNotification(reviewerId: string, verificationProcessId: string): Promise<void>;
}

6. 도메인 이벤트

6.1 진료비 세부산정 내역서 처리 관련 이벤트

interface MedicalStatementUploadedEvent {
medicalStatementId: string;
userId: string;
deviceId: string;
uploadedAt: Date;
imageMetadata: ImageMetadata;
timestamp: Date;
}

interface LLMAnalysisStartedEvent {
medicalStatementId: string;
analysisId: string;
llmModelId: string;
startedAt: Date;
timestamp: Date;
}

interface LLMAnalysisCompletedEvent {
medicalStatementId: string;
analysisId: string;
confidenceScore: number;
processingTimeMs: number;
completedAt: Date;
timestamp: Date;
}

interface LLMAnalysisFailedEvent {
medicalStatementId: string;
analysisId: string;
errorMessage: string;
retryCount: number;
failedAt: Date;
timestamp: Date;
}

interface TemporaryAccessCodeGeneratedEvent {
medicalStatementId: string;
userId: string;
accessCode: string;
expiresAt: Date;
timestamp: Date;
}

6.2 검증 프로세스 관련 이벤트

interface MedicalStatementSubmittedForReviewEvent {
medicalStatementId: string;
verificationProcessId: string;
submittedAt: Date;
timestamp: Date;
}

interface ReviewerAssignedEvent {
verificationProcessId: string;
reviewerId: string;
assignedAt: Date;
deadlineAt: Date;
timestamp: Date;
}

interface MedicalStatementApprovedEvent {
medicalStatementId: string;
verificationProcessId: string;
reviewerId: string;
approvedAt: Date;
timestamp: Date;
}

interface MedicalStatementRejectedEvent {
medicalStatementId: string;
verificationProcessId: string;
reviewerId: string;
rejectionReason: string;
rejectedAt: Date;
timestamp: Date;
}

interface FinalAccessCodeGeneratedEvent {
medicalStatementId: string;
userId: string;
accessCode: string;
generatedAt: Date;
timestamp: Date;
}

6.3 데이터 관리 관련 이벤트

interface MedicalStatementArchivedEvent {
medicalStatementId: string;
archivedAt: Date;
reason: string;
timestamp: Date;
}

interface DataRetentionPolicyAppliedEvent {
affectedRecords: number;
policyType: string;
appliedAt: Date;
timestamp: Date;
}

interface AuditLogCreatedEvent {
entityType: string;
entityId: string;
action: string;
performedBy: string;
timestamp: Date;
}

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

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

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

// Enums
enum ProcessingStatus {
UPLOADED
ANALYZING
ANALYSIS_COMPLETED
ANALYSIS_FAILED
PENDING_REVIEW
UNDER_REVIEW
APPROVED
REJECTED
ARCHIVED
}

enum DocumentType {
MEDICAL_EXPENSE_STATEMENT
PRESCRIPTION
DIAGNOSIS_CERTIFICATE
OTHER
}

enum AnalysisStatus {
PENDING
IN_PROGRESS
COMPLETED
FAILED
RETRYING
}

enum VerificationStatus {
PENDING_ASSIGNMENT
ASSIGNED
IN_REVIEW
COMPLETED
EXPIRED
}

enum VerificationDecision {
APPROVED
REJECTED
NEEDS_MORE_INFO
}

enum AccessCodeRequestStatus {
TEMPORARY_ISSUED
PENDING_APPROVAL
APPROVED
REJECTED
EXPIRED
}

enum ProcessingEventType {
UPLOADED
ANALYSIS_STARTED
ANALYSIS_COMPLETED
ANALYSIS_FAILED
SUBMITTED_FOR_REVIEW
REVIEWER_ASSIGNED
REVIEW_STARTED
APPROVED
REJECTED
ARCHIVED
}

enum ReviewAction {
ASSIGNED
STARTED
APPROVED
REJECTED
COMMENTED
REASSIGNED
}

// 비개인정보 - medical_statement 스키마
model LLMModel {
id String @id @default(uuid())
name String
version String
provider String
configuration Json
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
analysisResults AnalysisResult[]

@@unique([name, version])
@@index([provider, isActive])
@@map("llm_models")
@@schema("medical_statement")
}

model AnalysisTemplate {
id String @id @default(uuid())
name String
documentType String @map("document_type")
promptTemplate String @map("prompt_template")
expectedFields Json @map("expected_fields")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
analysisResults AnalysisResult[]

@@index([documentType, isActive])
@@map("analysis_templates")
@@schema("medical_statement")
}

model DocumentType {
id String @id @default(uuid())
name String @unique
description String?
validationRules Json @map("validation_rules")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@index([isActive])
@@map("document_types")
@@schema("medical_statement")
}

// 개인정보 - private 스키마
model MedicalStatementRecord {
id String @id @default(uuid())
userId String @map("user_id")
userCycleId String @map("user_cycle_id")
originalImageUrl String @map("original_image_url")
optimizedImageUrl String? @map("optimized_image_url")
documentType DocumentType @map("document_type")
processingStatus ProcessingStatus @default(UPLOADED) @map("processing_status")
imageMetadata Json @map("image_metadata")
deviceId String @map("device_id")
uploadedAt DateTime @map("uploaded_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
analysisResult AnalysisResult?
verificationProcess VerificationProcess?
processingHistories ProcessingHistory[]
accessCodeRequest AccessCodeRequest?

@@index([userId, userCycleId])
@@index([processingStatus])
@@index([uploadedAt])
@@index([userId, processingStatus])
@@index([deviceId])
@@map("medical_statement_records")
@@schema("private")
}

model AnalysisResult {
id String @id @default(uuid())
medicalStatementId String @unique @map("medical_statement_id")
llmModelId String @map("llm_model_id")
extractedData Json @map("extracted_data")
structuredResult Json @map("structured_result")
confidenceScore Float @map("confidence_score")
analysisStatus AnalysisStatus @default(PENDING) @map("analysis_status")
errorMessage String? @map("error_message")
processingTimeMs Int @map("processing_time_ms")
analyzedAt DateTime? @map("analyzed_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
medicalStatement MedicalStatementRecord @relation(fields: [medicalStatementId], references: [id], onDelete: Cascade)
llmModel LLMModel @relation(fields: [llmModelId], references: [id])
confidenceDetails AnalysisConfidence[]

@@index([analysisStatus])
@@index([confidenceScore])
@@index([analyzedAt])
@@map("analysis_results")
@@schema("private")
}

model VerificationProcess {
id String @id @default(uuid())
medicalStatementId String @unique @map("medical_statement_id")
reviewerId String? @map("reviewer_id")
verificationStatus VerificationStatus @default(PENDING_ASSIGNMENT) @map("verification_status")
decision VerificationDecision? @map("decision")
rejectionReason String? @map("rejection_reason")
reviewerComments String? @map("reviewer_comments")
assignedAt DateTime? @map("assigned_at")
reviewedAt DateTime? @map("reviewed_at")
deadlineAt DateTime? @map("deadline_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
medicalStatement MedicalStatementRecord @relation(fields: [medicalStatementId], references: [id], onDelete: Cascade)
reviewer MedicalProfessional? @relation(fields: [reviewerId], references: [id])
reviewHistories ReviewHistory[]

@@index([verificationStatus])
@@index([reviewerId, verificationStatus])
@@index([deadlineAt])
@@index([assignedAt])
@@map("verification_processes")
@@schema("private")
}

model AccessCodeRequest {
id String @id @default(uuid())
userId String @map("user_id")
userCycleId String @map("user_cycle_id")
medicalStatementId String @unique @map("medical_statement_id")
temporaryAccessCode String @map("temporary_access_code")
finalAccessCode String? @map("final_access_code")
requestStatus AccessCodeRequestStatus @default(TEMPORARY_ISSUED) @map("request_status")
requestedAt DateTime @map("requested_at")
approvedAt DateTime? @map("approved_at")
expiresAt DateTime? @map("expires_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
medicalStatement MedicalStatementRecord @relation(fields: [medicalStatementId], references: [id], onDelete: Cascade)

@@index([userId, userCycleId])
@@index([temporaryAccessCode])
@@index([finalAccessCode])
@@index([requestStatus])
@@index([expiresAt])
@@map("access_code_requests")
@@schema("private")
}

model ProcessingHistory {
id String @id @default(uuid())
medicalStatementId String @map("medical_statement_id")
eventType ProcessingEventType @map("event_type")
status ProcessingStatus @map("status")
description String
metadata Json?
timestamp DateTime @map("timestamp")
createdAt DateTime @default(now()) @map("created_at")

// 관계
medicalStatement MedicalStatementRecord @relation(fields: [medicalStatementId], references: [id], onDelete: Cascade)

@@index([medicalStatementId, timestamp])
@@index([eventType])
@@index([status])
@@index([timestamp])
@@map("processing_histories")
@@schema("private")
}

model ReviewHistory {
id String @id @default(uuid())
verificationProcessId String @map("verification_process_id")
reviewerId String @map("reviewer_id")
action ReviewAction @map("action")
comments String?
previousState Json @map("previous_state")
newState Json @map("new_state")
actionAt DateTime @map("action_at")
createdAt DateTime @default(now()) @map("created_at")

// 관계
verificationProcess VerificationProcess @relation(fields: [verificationProcessId], references: [id], onDelete: Cascade)
reviewer MedicalProfessional @relation(fields: [reviewerId], references: [id])

@@index([verificationProcessId, actionAt])
@@index([reviewerId, actionAt])
@@index([action])
@@map("review_histories")
@@schema("private")
}

model MedicalProfessional {
id String @id @default(uuid())
accountId String @unique @map("account_id")
licenseNumber String @unique @map("license_number")
specialization String
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

// 관계
verificationProcesses VerificationProcess[]
reviewHistories ReviewHistory[]

@@index([licenseNumber])
@@index([specialization, isActive])
@@map("medical_professionals")
@@schema("private")
}

model AnalysisConfidence {
id String @id @default(uuid())
analysisResultId String @map("analysis_result_id")
fieldName String @map("field_name")
confidence Float
reason String?
createdAt DateTime @default(now()) @map("created_at")

// 관계
analysisResult AnalysisResult @relation(fields: [analysisResultId], references: [id], onDelete: Cascade)

@@index([analysisResultId, fieldName])
@@index([confidence])
@@map("analysis_confidences")
@@schema("private")
}

8. 변경 이력

버전날짜작성자변경 내용
0.1.02025-01-03bok@weltcorp.com최초 작성 - 한국 진료비 세부산정 내역서 분석 시스템 도메인 모델 정의