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.0 | 2025-01-03 | bok@weltcorp.com | 최초 작성 - 한국 진료비 세부산정 내역서 분석 시스템 도메인 모델 정의 |