본문으로 건너뛰기

Medical Statement API 엔드포인트

목차

1. 엔드포인트 접근 권한 매트릭스

엔드포인트System AdminMedical ProfessionalSupportRegular User
POST /v1/medical-statement/upload자신만
GET /v1/medical-statement/{id}/status자신만
GET /v1/medical-statement/me/statements자신만
POST /v1/medical-statement/{id}/analyze
GET /v1/medical-statement/{id}/analysis자신만
POST /v1/medical-statement/{id}/analysis/retry
GET /v1/medical-statement/review/queue자신만
POST /v1/medical-statement/{id}/review/start자신만
POST /v1/medical-statement/{id}/review/approve자신만
POST /v1/medical-statement/{id}/review/reject자신만
POST /v1/medical-statement/{id}/review/re-review
GET /v1/medical-statement/{id}/access-code/temporary자신만
GET /v1/medical-statement/{id}/access-code/final자신만
POST /v1/medical-statement/access-code/validate
GET /v1/medical-statement/statistics/processing
GET /v1/medical-statement/statistics/reviewer/{reviewerId}자신만

참고:

  • ✓: 접근 가능
  • ✘: 접근 불가
  • (자신만): 자신의 데이터에만 접근 가능

2. 진료비 세부산정 내역서 업로드 API

📌 기술 구현 문서: TBD

진료비 세부산정 내역서 업로드 API는 환자가 진료비 세부산정 내역서를 촬영하거나 갤러리에서 선택하여 업로드하는 기능을 제공합니다.

주요 특징:

  • 멀티파트 업로드: 이미지 파일과 메타데이터를 함께 전송
  • 실시간 검증: 업로드 시 파일 형식, 크기, 품질 검증
  • 자동 최적화: 업로드된 이미지 자동 압축 및 최적화
  • 즉시 코드 발급: 업로드 완료 시 임시 액세스 코드 즉시 생성
  • 비동기 분석: LLM 분석 작업을 백그라운드에서 처리

2.1 진료비 세부산정 내역서 업로드

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/upload
  • Headers:
    • Content-Type: multipart/form-data
    • Authorization: Bearer {{appToken}}
  • Form Data:
    • files: File[] (필수) - 진료비 세부산정 내역서 이미지 파일들
    • deviceId: string (필수) - 디바이스 식별자

설명: 환자가 진료비 세부산정 내역서를 업로드하는 엔드포인트입니다. 업로드 완료 시 즉시 임시 액세스 코드를 발급하고, LLM 분석 작업을 백그라운드에서 시작합니다.

요청 (Request)

POST /v1/medical-statement/upload
Content-Type: multipart/form-data
Authorization: Bearer {{appToken}}

--boundary123
Content-Disposition: form-data; name="files"; filename="medical_statement.jpg"
Content-Type: image/jpeg

[이미지 바이너리 데이터]
--boundary123
Content-Disposition: form-data; name="deviceId"

device_12345
--boundary123--

응답 (Response)

성공 응답 (201 Created):

{
"success": true,
"medicalStatementId": "ms_abc123def456",
"temporaryAccessCode": "TEMP_789XYZ",
"processingStatus": "ANALYZING",
"estimatedAnalysisTime": 30,
"uploadedAt": 1712048400000
}

오류 응답:

  • 400 Bad Request (파일 형식 오류):
{
"success": false,
"error": "INVALID_FILE_FORMAT",
"message": "지원하지 않는 파일 형식입니다. JPEG, PNG만 지원됩니다.",
"supportedFormats": ["JPEG", "PNG"]
}
  • 400 Bad Request (파일 크기 초과):
{
"success": false,
"error": "FILE_TOO_LARGE",
"message": "파일 크기가 너무 큽니다. 최대 10MB까지 업로드 가능합니다.",
"maxFileSize": 10485760
}
  • 401 Unauthorized (App Token 무효):
{
"success": false,
"error": "INVALID_APP_TOKEN",
"message": "유효하지 않은 앱 토큰입니다."
}

2.2 업로드 상태 확인

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/{id}/status
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

응답 (Response)

성공 응답 (200 OK):

{
"medicalStatementId": "ms_abc123def456",
"processingStatus": "UNDER_REVIEW",
"uploadedAt": 1712048400000,
"analysisCompletedAt": 1712048430000,
"currentStep": {
"step": "MEDICAL_REVIEW",
"description": "의료진이 검토 중입니다",
"estimatedCompletionTime": 1712134800000
},
"timeline": [
{
"status": "UPLOADED",
"timestamp": 1712048400000,
"description": "진료비 세부산정 내역서 업로드 완료"
},
{
"status": "ANALYZING",
"timestamp": 1712048405000,
"description": "AI 분석 시작"
},
{
"status": "ANALYSIS_COMPLETED",
"timestamp": 1712048430000,
"description": "AI 분석 완료"
},
{
"status": "PENDING_REVIEW",
"timestamp": 1712048435000,
"description": "의료진 검토 대기 중"
},
{
"status": "UNDER_REVIEW",
"timestamp": 1712048500000,
"description": "의료진 검토 시작"
}
]
}

2.3 진료비 세부산정 내역서 목록 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/me/statements
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Query Parameters:
    • status: ProcessingStatus (선택) - 특정 상태 필터
    • page: number (선택, 기본값: 1) - 페이지 번호
    • pageSize: number (선택, 기본값: 10) - 페이지 크기

응답 (Response)

성공 응답 (200 OK):

{
"items": [
{
"id": "ms_abc123def456",
"documentType": "MEDICAL_EXPENSE_STATEMENT",
"processingStatus": "APPROVED",
"uploadedAt": 1712048400000,
"reviewedAt": 1712134800000,
"hasTemporaryCode": true,
"hasFinalCode": true,
"imageMetadata": {
"fileName": "medical_statement.jpg",
"fileSize": 2048576,
"width": 1920,
"height": 1080
}
}
],
"metadata": {
"totalCount": 1,
"currentPage": 1,
"pageSize": 10,
"totalPages": 1
}
}

3. LLM 분석 API

📌 기술 구현 문서: TBD

LLM 분석 API는 업로드된 진료비 세부산정 내역서를 인공지능으로 분석하는 기능을 제공합니다.

3.1 분석 시작

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/{id}/analyze
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

요청 (Request)

{
"llmModelId": "gpt-4-vision-preview",
"analysisTemplate": "korean_medical_expense_v1",
"priority": "NORMAL"
}

응답 (Response)

성공 응답 (202 Accepted):

{
"success": true,
"analysisId": "analysis_xyz789",
"estimatedCompletionTime": 30,
"queuePosition": 3
}

3.2 분석 결과 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/{id}/analysis
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

응답 (Response)

성공 응답 (200 OK):

{
"analysisId": "analysis_xyz789",
"status": "COMPLETED",
"confidenceScore": 0.92,
"analyzedAt": 1712048430000,
"processingTimeMs": 25000,
"extractedData": {
"patientName": "홍길동",
"hospitalName": "서울대학교병원",
"treatmentDate": "2024-04-01",
"totalAmount": 150000,
"insuranceCoverage": 105000,
"patientPayment": 45000,
"treatmentCodes": ["A1234", "B5678"],
"diagnosisCodes": ["M79.1"]
},
"structuredResult": {
"isValidMedicalStatement": true,
"documentQuality": "EXCELLENT",
"extractedFields": {
"patientInfo": "완전",
"treatmentInfo": "완전",
"costInfo": "완전"
},
"missingFields": [],
"anomalies": [],
"recommendedAction": "APPROVE"
},
"confidenceDetails": [
{
"fieldName": "patientName",
"confidence": 0.98,
"reason": "명확한 한글 이름 인식"
},
{
"fieldName": "totalAmount",
"confidence": 0.95,
"reason": "숫자 형식 정확"
}
]
}

3.3 분석 재시도

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/{id}/analysis/retry
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

요청 (Request)

{
"reason": "ANALYSIS_FAILED",
"newModelId": "gpt-4-turbo"
}

응답 (Response)

성공 응답 (202 Accepted):

{
"success": true,
"newAnalysisId": "analysis_retry_456",
"retryCount": 2,
"estimatedCompletionTime": 30
}

4. 의료진 검증 API

📌 기술 구현 문서: TBD

의료진 검증 API는 의료진이 LLM 분석 결과를 검토하고 승인/거부 결정을 내리는 기능을 제공합니다.

4.1 검토 대기열 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/review/queue
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Query Parameters:
    • assignedToMe: boolean (선택, 기본값: false) - 나에게 할당된 것만 조회
    • status: VerificationStatus (선택) - 특정 상태 필터
    • page: number (선택, 기본값: 1)
    • pageSize: number (선택, 기본값: 20)

응답 (Response)

성공 응답 (200 OK):

{
"items": [
{
"verificationProcessId": "vp_123abc",
"medicalStatementId": "ms_abc123def456",
"status": "ASSIGNED",
"assignedAt": 1712048500000,
"deadlineAt": 1712221300000,
"priority": "NORMAL",
"analysisResult": {
"confidenceScore": 0.92,
"recommendedAction": "APPROVE",
"documentQuality": "EXCELLENT"
},
"patientInfo": {
"maskedName": "홍**",
"uploadedAt": 1712048400000
}
}
],
"metadata": {
"totalCount": 5,
"currentPage": 1,
"pageSize": 20,
"totalPages": 1
},
"summary": {
"pendingAssignment": 2,
"assigned": 3,
"inReview": 0,
"overdue": 0
}
}

4.2 검토 시작

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/{id}/review/start
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

응답 (Response)

성공 응답 (200 OK):

{
"success": true,
"verificationProcessId": "vp_123abc",
"reviewStartedAt": 1712048600000,
"deadlineAt": 1712221300000,
"medicalStatement": {
"id": "ms_abc123def456",
"originalImageUrl": "https://storage.googleapis.com/signed-url...",
"optimizedImageUrl": "https://storage.googleapis.com/signed-url-optimized...",
"uploadedAt": 1712048400000,
"imageMetadata": {
"width": 1920,
"height": 1080,
"fileSize": 2048576
}
},
"analysisResult": {
"confidenceScore": 0.92,
"extractedData": {
"patientName": "홍길동",
"hospitalName": "서울대학교병원",
"treatmentDate": "2024-04-01",
"totalAmount": 150000,
"insuranceCoverage": 105000,
"patientPayment": 45000
},
"recommendedAction": "APPROVE"
}
}

4.3 진료비 세부산정 내역서 승인

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/{id}/review/approve
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

요청 (Request)

{
"comments": "분석 결과가 정확하며 유효한 진료비 세부산정 내역서로 확인됩니다.",
"verifiedFields": [
"patientName",
"hospitalName",
"treatmentDate",
"totalAmount"
]
}

응답 (Response)

성공 응답 (200 OK):

{
"success": true,
"verificationProcessId": "vp_123abc",
"decision": "APPROVED",
"reviewedAt": 1712048700000,
"finalAccessCode": "FINAL_ABC123XYZ",
"reviewerComments": "분석 결과가 정확하며 유효한 진료비 세부산정 내역서로 확인됩니다."
}

4.4 진료비 세부산정 내역서 거부

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/{id}/review/reject
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

요청 (Request)

{
"rejectionReason": "IMAGE_QUALITY_POOR",
"comments": "이미지가 흐릿하여 내용을 정확히 확인할 수 없습니다. 더 선명한 이미지로 재업로드해 주세요.",
"suggestedActions": [
"더 밝은 조명에서 촬영",
"카메라 흔들림 방지",
"문서 전체가 화면에 들어오도록 촬영"
]
}

응답 (Response)

성공 응답 (200 OK):

{
"success": true,
"verificationProcessId": "vp_123abc",
"decision": "REJECTED",
"reviewedAt": 1712048700000,
"rejectionReason": "IMAGE_QUALITY_POOR",
"reviewerComments": "이미지가 흐릿하여 내용을 정확히 확인할 수 없습니다. 더 선명한 이미지로 재업로드해 주세요.",
"canReupload": true
}

4.5 재검토 요청

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/{id}/review/re-review
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

요청 (Request)

{
"reason": "ADDITIONAL_INFORMATION_PROVIDED",
"additionalInfo": "환자가 추가 설명을 제공했습니다.",
"priority": "HIGH"
}

응답 (Response)

성공 응답 (200 OK):

{
"success": true,
"newVerificationProcessId": "vp_456def",
"requestedAt": 1712048800000,
"estimatedReviewTime": 1712135200000
}

5. 액세스 코드 API

📌 기술 구현 문서: TBD

액세스 코드 API는 진료비 세부산정 내역서 처리 과정에서 생성되는 임시 및 정식 액세스 코드를 관리합니다.

5.1 임시 액세스 코드 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/{id}/access-code/temporary
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

응답 (Response)

성공 응답 (200 OK):

{
"accessCode": "TEMP_789XYZ",
"status": "ACTIVE",
"generatedAt": 1712048400000,
"expiresAt": 1712221300000,
"isValid": true,
"relatedStatement": {
"id": "ms_abc123def456",
"processingStatus": "UNDER_REVIEW"
}
}

5.2 정식 액세스 코드 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/{id}/access-code/final
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • id: 진료비 세부산정 내역서 ID (필수)

응답 (Response)

성공 응답 (200 OK):

{
"accessCode": "FINAL_ABC123XYZ",
"status": "ACTIVE",
"generatedAt": 1712048700000,
"approvedAt": 1712048700000,
"approvedBy": "doctor_456",
"isValid": true,
"relatedStatement": {
"id": "ms_abc123def456",
"processingStatus": "APPROVED"
}
}

오류 응답 (404 Not Found):

{
"success": false,
"error": "FINAL_CODE_NOT_AVAILABLE",
"message": "정식 액세스 코드가 아직 생성되지 않았습니다. 의료진 승인이 완료되어야 합니다.",
"currentStatus": "UNDER_REVIEW"
}

5.3 액세스 코드 검증

  • HTTP 메서드: POST
  • 경로: /v1/medical-statement/access-code/validate
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {{accessToken}}

요청 (Request)

{
"accessCode": "FINAL_ABC123XYZ"
}

응답 (Response)

성공 응답 (200 OK):

{
"isValid": true,
"codeType": "FINAL",
"medicalStatementId": "ms_abc123def456",
"userId": "user_789",
"generatedAt": 1712048700000,
"approvedAt": 1712048700000,
"expiresAt": null
}

오류 응답 (400 Bad Request):

{
"success": false,
"error": "INVALID_ACCESS_CODE",
"message": "유효하지 않은 액세스 코드입니다.",
"isValid": false
}

6. 통계 및 관리 API

📌 기술 구현 문서: TBD

통계 및 관리 API는 진료비 세부산정 내역서 처리 현황과 검토자 성과를 모니터링하는 기능을 제공합니다.

6.1 처리 통계 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/statistics/processing
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Query Parameters:
    • fromDate: number (선택) - 조회 시작 날짜 (Unix timestamp)
    • toDate: number (선택) - 조회 종료 날짜 (Unix timestamp)
    • period: string (선택, 기본값: daily) - 통계 기간 (daily, weekly, monthly)

응답 (Response)

성공 응답 (200 OK):

{
"period": "daily",
"fromDate": 1712016000000,
"toDate": 1712102400000,
"overview": {
"totalUploaded": 150,
"totalAnalyzed": 145,
"totalApproved": 120,
"totalRejected": 25,
"pendingReview": 5,
"averageProcessingTimeMs": 1800000,
"averageAnalysisTimeMs": 25000,
"averageReviewTimeMs": 3600000
},
"dailyBreakdown": [
{
"date": "2024-04-01",
"uploaded": 45,
"analyzed": 43,
"approved": 35,
"rejected": 8,
"avgProcessingTime": 1650000
},
{
"date": "2024-04-02",
"uploaded": 52,
"analyzed": 50,
"approved": 42,
"rejected": 8,
"avgProcessingTime": 1750000
}
],
"analysisMetrics": {
"successRate": 96.7,
"averageConfidenceScore": 0.87,
"retryRate": 8.2,
"modelPerformance": [
{
"modelId": "gpt-4-vision-preview",
"usageCount": 120,
"successRate": 98.3,
"avgConfidence": 0.91
}
]
}
}

6.2 검토자 성과 조회

  • HTTP 메서드: GET
  • 경로: /v1/medical-statement/statistics/reviewer/{reviewerId}
  • Headers:
    • Authorization: Bearer {{accessToken}}
  • Path Parameters:
    • reviewerId: 검토자 ID (필수)
  • Query Parameters:
    • fromDate: number (선택) - 조회 시작 날짜
    • toDate: number (선택) - 조회 종료 날짜

응답 (Response)

성공 응답 (200 OK):

{
"reviewerId": "reviewer_456",
"reviewerInfo": {
"name": "김의사",
"licenseNumber": "12345",
"specialization": "내과"
},
"period": {
"fromDate": 1712016000000,
"toDate": 1712102400000
},
"performance": {
"totalReviewed": 45,
"approved": 38,
"rejected": 7,
"approvalRate": 84.4,
"averageReviewTimeMs": 900000,
"onTimeCompletionRate": 95.6,
"overdueCount": 2
},
"dailyActivity": [
{
"date": "2024-04-01",
"reviewed": 12,
"approved": 10,
"rejected": 2,
"avgReviewTime": 850000
},
{
"date": "2024-04-02",
"reviewed": 15,
"approved": 13,
"rejected": 2,
"avgReviewTime": 920000
}
]
}

7. 오류 코드

코드메시지설명HTTP 상태 코드
12000번대: 진료비 세부산정 내역서 업로드 관련 오류
12001INVALID_FILE_FORMAT지원하지 않는 파일 형식입니다.400
12002FILE_TOO_LARGE파일 크기가 너무 큽니다.400
12003IMAGE_QUALITY_TOO_LOW이미지 품질이 너무 낮습니다.400
12004UPLOAD_QUOTA_EXCEEDED업로드 할당량을 초과했습니다.429
12005DEVICE_ID_REQUIRED디바이스 ID가 필요합니다.400
12006STORAGE_ERROR저장소 오류가 발생했습니다.500
12100번대: LLM 분석 관련 오류
12101ANALYSIS_IN_PROGRESS이미 분석이 진행 중입니다.409
12102ANALYSIS_FAILEDLLM 분석이 실패했습니다.500
12103INVALID_LLM_MODEL유효하지 않은 LLM 모델입니다.400
12104ANALYSIS_TIMEOUT분석 시간이 초과되었습니다.408
12105RETRY_LIMIT_EXCEEDED재시도 횟수를 초과했습니다.429
12106INSUFFICIENT_IMAGE_QUALITY이미지 품질이 분석에 부적합합니다.400
12200번대: 의료진 검증 관련 오류
12201UNAUTHORIZED_REVIEWER검토 권한이 없습니다.403
12202ALREADY_UNDER_REVIEW이미 다른 검토자가 검토 중입니다.409
12203REVIEW_DEADLINE_EXPIRED검토 마감일이 지났습니다.410
12204INVALID_DECISION유효하지 않은 검토 결정입니다.400
12205REJECTION_REASON_REQUIRED거부 시 거부 사유가 필요합니다.400
12206ALREADY_REVIEWED이미 검토가 완료된 진료비 세부산정 내역서입니다.409
12300번대: 액세스 코드 관련 오류
12301TEMPORARY_CODE_NOT_FOUND임시 액세스 코드를 찾을 수 없습니다.404
12302FINAL_CODE_NOT_AVAILABLE정식 액세스 코드가 아직 생성되지 않았습니다.404
12303ACCESS_CODE_EXPIRED액세스 코드가 만료되었습니다.410
12304INVALID_ACCESS_CODE유효하지 않은 액세스 코드입니다.400
12305CODE_GENERATION_FAILED액세스 코드 생성에 실패했습니다.500
12400번대: 데이터 관리 관련 오류
12401MEDICAL_STATEMENT_NOT_FOUND진료비 세부산정 내역서를 찾을 수 없습니다.404
12402ANALYSIS_RESULT_NOT_FOUND분석 결과를 찾을 수 없습니다.404
12403VERIFICATION_PROCESS_NOT_FOUND검증 프로세스를 찾을 수 없습니다.404
12404DATA_INTEGRITY_ERROR데이터 무결성 오류가 발생했습니다.500
12405ARCHIVE_OPERATION_FAILED아카이브 작업이 실패했습니다.500
12500번대: 권한 및 인증 관련 오류
12501INSUFFICIENT_PERMISSIONS권한이 부족합니다.403
12502MEDICAL_LICENSE_REQUIRED의료진 면허가 필요합니다.403
12503REVIEWER_NOT_ACTIVE비활성화된 검토자입니다.403
12504USER_CYCLE_NOT_FOUND사용자 주기를 찾을 수 없습니다.404

8. 변경 이력

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