Clinical #1: Subject ID 자유입력 → Phantom/Human/ETC 카테고리 (회의 결정)
회의 결정: 자유 텍스트 ID 입력 대신 측정 대상을 PHANTOM/HUMAN/ETC 세
카테고리로 명확히 구분. JSON/labdb 저장 방식도 함께 변경.
데이터 모델 (ClinicalSession.kt):
- SubjectType enum 추가: PHANTOM / HUMAN / ETC
- val subjectId: String 제거 → val subjectType: SubjectType
- 폴더명: "{subjectId}_{...}" → "{SUBJECT_TYPE}_{...}"
예: PHANTOM_VBT26050202_SUPINE_ALIGN_0CM_2026-06-08_15-30-00
JSON 변경 (meta.json + measurement.json):
- "subject_id": "S001" → "subject_type": "PHANTOM"
labdb payload (LabdbUploader):
- params.subject_id → params.subject_type (서버는 free JSON이라 코드 변경 불필요)
UI (ClinicalHomeView):
- Subject ID OutlinedTextField 제거
- LabeledSegmented "Subject Type" 3개 버튼 (Phantom/Human/ETC)
- 마지막 선택 기억 (ClinicalSessionStore.lastSubjectType)
ClinicalLive 상단 sub line: "S=S001 · TV=300mL · Ab=22mm"
→ "Phantom · TV=300mL · Ab=22mm"
호환성: 기존 측정 폴더는 그대로. 새 폴더부터 새 형식 적용.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,7 +51,8 @@ object ClinicalSessionStore {
|
||||
/** 다음 측정 시 기본값으로 자동 채울 사용자 입력 — 같은 피험자/검사자 여러 측정 시 편의 */
|
||||
var lastExaminer: String = ""
|
||||
var lastNotes: String = ""
|
||||
var lastSubjectId: String = ""
|
||||
var lastSubjectType: com.example.medilightv2android.models.SubjectType =
|
||||
com.example.medilightv2android.models.SubjectType.PHANTOM
|
||||
var lastTrueVolumeMl: String = "" // 문자열로 보관 (입력 폼과 동일 형식)
|
||||
var lastAbdomenThicknessMm: String = ""
|
||||
|
||||
@@ -62,7 +63,7 @@ object ClinicalSessionStore {
|
||||
currentSession = session
|
||||
lastExaminer = session.examiner
|
||||
lastNotes = session.notes
|
||||
lastSubjectId = session.subjectId
|
||||
lastSubjectType = session.subjectType
|
||||
lastTrueVolumeMl = session.trueVolumeMl?.toString() ?: ""
|
||||
lastAbdomenThicknessMm = session.abdomenThicknessMm?.toString() ?: ""
|
||||
cyclesBuffer.clear()
|
||||
@@ -107,8 +108,9 @@ object ClinicalSessionStore {
|
||||
put("examiner", s.examiner)
|
||||
put("notes", s.notes)
|
||||
put("label", s.label)
|
||||
// 측정 대상 분류 (회의 결정: Phantom/Human/ETC)
|
||||
put("subject_type", s.subjectType.name)
|
||||
// 임상 시험 참값 (외부 측정기, vesiscan_test 프로토콜)
|
||||
if (s.subjectId.isNotBlank()) put("subject_id", s.subjectId)
|
||||
s.trueVolumeMl?.let { put("true_volume_ml", it) }
|
||||
s.abdomenThicknessMm?.let { put("abdomen_thickness_mm", it) }
|
||||
put("started_at", s.startedAt)
|
||||
@@ -179,7 +181,7 @@ object ClinicalSessionStore {
|
||||
// meta: writeMeta()와 동일 내용 포함 (단독 파일로 자족 가능)
|
||||
val meta = JSONObject().apply {
|
||||
put("data_type", DATA_TYPE)
|
||||
put("subject_id", s.subjectId)
|
||||
put("subject_type", s.subjectType.name)
|
||||
put("device_name", s.deviceName)
|
||||
put("posture", s.posture.name)
|
||||
put("step", s.step.name)
|
||||
|
||||
@@ -89,7 +89,7 @@ object LabdbUploader {
|
||||
put("step", meta.optString("step"))
|
||||
put("is_alignment", meta.optBoolean("is_alignment"))
|
||||
put("examiner", meta.optString("examiner"))
|
||||
meta.optString("subject_id").takeIf { it.isNotBlank() }?.let { put("subject_id", it) }
|
||||
meta.optString("subject_type").takeIf { it.isNotBlank() }?.let { put("subject_type", it) }
|
||||
if (meta.has("true_volume_ml")) put("true_volume_ml", meta.optDouble("true_volume_ml"))
|
||||
if (meta.has("abdomen_thickness_mm")) put("abdomen_thickness_mm", meta.optDouble("abdomen_thickness_mm"))
|
||||
meta.optString("firmware_version").takeIf { it.isNotBlank() }?.let { put("firmware_version", it) }
|
||||
|
||||
Reference in New Issue
Block a user