CLINICAL: Dev 모드 한정 임상 R&D 측정 세션 메뉴 추가
회사 내 알고리즘 개발용 임상 시험(3 devices × 3 postures × 6 steps = 54 measurements
per subject)을 위한 데이터 라벨링/라우팅/zip 자동화. Dev 모드 켠 경우에만 노출.
신규 파일:
- models/ClinicalSession.kt — ClinicalDevice/Posture/Step 모델 + 완료 추적
- services/ClinicalSessionStore.kt — 전역 세션 store + 폴더 라우팅 + meta.json + zip
- ui/views/clinical/ClinicalHomeView.kt — 세션 메타 입력 다이얼로그 + 9-conditions
그리드 + 6 steps + Mark Complete + End Session(zip) 화면
로거 라우팅 (세션 존재 시 자동 분기):
- AdcCsvLogger: sessionRoot/{device}_{posture}/{step}/adc.csv +
CSV에 clinical_label 컬럼 추가 (S001_A_SUPINE_ALIGN_0CM 형태)
- MeasurementLogService: 내부 filesDir → Downloads/VesiScan_Events/ 영구 이동.
세션 시 step 폴더의 events.jsonl/placements.jsonl로 분기.
BuildConfig 대신 PackageInfo로 versionName/versionCode 정확 주입.
보관 90일 → 365일 (R&D 장기 보관)
- BleDebugLogger: step 변경 감지해서 ble.log 파일 자동 전환
UI/라우팅:
- AppScreen.CLINICAL_HOME + MainActivity Crossfade/BackHandler 분기
- HomeView에 dev 모드 한정 보라색 "Clinical Mode (Dev)" 버튼
- 측정 화면(PlacementGuide/PiezoMonitoring) Back 시 임상 세션 활성 → ClinicalHome 복귀
Placement 구조화:
- PlacementGuideView가 logService.logPlacement() 호출 시 urineLens/cv/phase/score
추가 인자 전달 → placements.jsonl에 구조화 기록
데이터 구조 (한 세션당):
Downloads/VesiScan_Sessions/{S001_2026-05-28_14:30}/
├─ meta.json
├─ A_SUPINE/align_0cm/{adc.csv, placements.jsonl, ble.log}
├─ A_SUPINE/align_1cm/...
├─ ...
├─ A_SUPINE/bv/{adc.csv, events.jsonl, ble.log}
├─ A_SITTING/... (총 9 conditions × 6 steps)
└─ session.zip (End Session 시 자동 생성)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ import com.example.medilightv2android.ui.views.registration.RegistrationView
|
||||
import com.example.medilightv2android.ui.views.consent.ConsentView
|
||||
import com.example.medilightv2android.ui.views.reminder.ReminderSettingsView
|
||||
import com.example.medilightv2android.ui.views.sensorselect.SensorSelectView
|
||||
import com.example.medilightv2android.ui.views.clinical.ClinicalHomeView
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -89,15 +90,23 @@ fun MedilightApp(modifier: Modifier = Modifier) {
|
||||
)
|
||||
}
|
||||
|
||||
// 다른 화면에서 뒤로가기 = 바로 전 화면
|
||||
// 다른 화면에서 뒤로가기 = 바로 전 화면
|
||||
BackHandler(enabled = appState.currentScreen != AppScreen.HOME
|
||||
&& appState.currentScreen != AppScreen.PIN_ENTRY) {
|
||||
when (appState.currentScreen) {
|
||||
// 메인 플로우: Home → DeviceScan → Personalization → Placement → Monitoring
|
||||
AppScreen.DEVICE_SCAN -> appState.currentScreen = AppScreen.HOME
|
||||
AppScreen.PIEZO_PERSONALIZATION -> appState.currentScreen = AppScreen.DEVICE_SCAN
|
||||
AppScreen.PLACEMENT_GUIDE -> appState.backFromPlacementGuide()
|
||||
AppScreen.PIEZO_MONITORING -> appState.currentScreen = AppScreen.PLACEMENT_GUIDE
|
||||
// 임상 모드면 측정 후 ClinicalHome으로 복귀
|
||||
AppScreen.PLACEMENT_GUIDE ->
|
||||
if (com.example.medilightv2android.services.ClinicalSessionStore.currentSession != null)
|
||||
appState.currentScreen = AppScreen.CLINICAL_HOME
|
||||
else appState.backFromPlacementGuide()
|
||||
AppScreen.PIEZO_MONITORING ->
|
||||
if (com.example.medilightv2android.services.ClinicalSessionStore.currentSession != null)
|
||||
appState.currentScreen = AppScreen.CLINICAL_HOME
|
||||
else appState.currentScreen = AppScreen.PLACEMENT_GUIDE
|
||||
AppScreen.CLINICAL_HOME -> appState.currentScreen = AppScreen.HOME
|
||||
// 모니터링 하위 화면 → 모니터링
|
||||
AppScreen.MEASUREMENT_HISTORY -> appState.currentScreen = AppScreen.PIEZO_MONITORING
|
||||
AppScreen.VOIDING_DIARY -> appState.currentScreen = AppScreen.PIEZO_MONITORING
|
||||
@@ -144,6 +153,7 @@ fun MedilightApp(modifier: Modifier = Modifier) {
|
||||
AppScreen.REMINDER_SETTINGS -> ReminderSettingsView(
|
||||
onBack = { appState.backToMonitoring() }
|
||||
)
|
||||
AppScreen.CLINICAL_HOME -> ClinicalHomeView(appState)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user