docs: v7 (2026-07-10) 반영 — msp 제거, 6-stage alignment, mtb queue fix, labdb 자동 재시도
이번 세션 대량 변경 사항을 5개 문서에 반영. 각 문서마다 stale 이던
섹션을 갱신하거나 신규 섹션 추가.
USER_GUIDE.md
- Sensor Alignment 를 V1 (3-stage) / V2 (6-stage) 로 재구성
- V2 6-stage 표 + relaxed mode / soft hint 설명
- GREEN 진입 5초 hold + 10-strike 리셋 완화 명시
- "최적의 위치입니다!" 문구 반영
docs/BLE_PROTOCOL_REFERENCE.md
- msp 명령 취소선 처리 + mim 신규 명령 문서화
- Watchdog timeout 25초 연장 명시 (2.5)
- §2.6 신규: firmware VBTFW0121 mls mode 0 freeze 취약점 +
앱 측 3-layer 회피 (isMtbBusy / mtb 3초 timeout / 자동 재연결)
VesiScan_Android_Pipeline_Summary.md
- v7 (2026-07-10) 섹션 신규 추가 — BLE / Alignment / UI / labdb /
tools 5개 카테고리로 변경 사항 정리
- 권장 펌웨어 표기 VBTFW0116 → VBTFW0120+ 로 갱신
labdb.md
- §12b 신규: 앱 측 Auto Retry Policy — endMeasurement 자동 업로드
조건 완화, LabdbAutoRetry object, UI 배너, 재시도 안전성
tools/README.md
- labdb_upload.py 섹션 신규 — 사용법 / 폴더 구조 / 재실행 안전성 /
buildPayload 로직 / 활용 예 정리
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1512,6 +1512,128 @@ async function upload(key, session) {
|
||||
|
||||
|
||||
|
||||
\## 12b. 앱 측 Auto Retry Policy (Android app, 2026-07-09)
|
||||
|
||||
|
||||
|
||||
Android 앱 (VesiScan-Basic demo-final / tab-navigation / cloud-mvp) 은 매
|
||||
|
||||
session 마다 사용자가 Upload 버튼을 누르지 않아도 되도록 **자동 업로드 +
|
||||
|
||||
재시도 큐** 를 내장합니다.
|
||||
|
||||
|
||||
|
||||
\### 12b.1 endMeasurement 자동 업로드
|
||||
|
||||
|
||||
|
||||
Clinical 세션 종료 시 (`ClinicalSessionStore.endMeasurement()`) `apiKey` 가
|
||||
|
||||
등록되어 있으면 (`LabdbCredentials.isRegistered`) 무조건 `LabdbUploader.
|
||||
|
||||
uploadAsync(context, folder)` 를 호출. **fire-and-forget** 이므로 응답 대기
|
||||
|
||||
없이 다음 화면으로 진행.
|
||||
|
||||
|
||||
|
||||
\- 이전 정책: `lastStatus == "active"` 조건 필요 → 상태 갱신 안 된 첫 진입 시
|
||||
|
||||
자동 업로드 skip 되던 문제.
|
||||
|
||||
\- 2026-07-09 이후: `isRegistered` 만 체크. 서버가 401/403 을 반환하면 상위
|
||||
|
||||
로직에서 status 재조회.
|
||||
|
||||
|
||||
|
||||
\### 12b.2 LabdbAutoRetry object (`app/src/main/java/.../labdb/LabdbAutoRetry.kt`)
|
||||
|
||||
|
||||
|
||||
Clinical Home 진입 시 (`LaunchedEffect(Unit)`) `retryPending(context)` 자동
|
||||
|
||||
호출. 로직:
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
1. LabdbCredentials.isRegistered 확인 → 없으면 no-op
|
||||
|
||||
2. ClinicalSessionStore.recentFinalizedFolders (tab-nav/cloud-mvp) 또는
|
||||
|
||||
listOfNotNull(lastFinalizedFolder) (demo-final) 스캔
|
||||
|
||||
3. labdb_upload.json 마커 없는 폴더만 pending
|
||||
|
||||
4. 순차 (병렬 X) LabdbUploader.uploadBlocking 실행
|
||||
|
||||
5. 결과: labdb_upload.json (성공) / labdb_upload_error.json (실패)
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
\### 12b.3 UI 배너
|
||||
|
||||
|
||||
|
||||
Clinical Home 상단:
|
||||
|
||||
\- 진행 중 (`pendingCount > 0` 또는 `uploadingName != null`):
|
||||
|
||||
파란 배너 "자동 업로드 진행 중 · 남은 세션 N · <folderName>"
|
||||
|
||||
\- 완료 (`lastResultMessage != null`):
|
||||
|
||||
초록/주황 배너 "N uploaded, M failed" + 확인 버튼
|
||||
|
||||
|
||||
|
||||
\### 12b.4 State 노출
|
||||
|
||||
|
||||
|
||||
```kotlin
|
||||
|
||||
object LabdbAutoRetry {
|
||||
|
||||
val pendingCount: MutableIntState // UI 배너 카운트
|
||||
|
||||
val uploadingName: MutableState<String?> // 현재 업로드 중 폴더
|
||||
|
||||
val lastResultMessage: MutableState<String?> // 완료 후 결과 요약
|
||||
|
||||
fun retryPending(context: Context) // 트리거
|
||||
|
||||
fun dismissResult() // 배너 확인
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
\### 12b.5 재시도 안전성
|
||||
|
||||
|
||||
|
||||
\- 이미 업로드된 폴더 (`labdb_upload.json` 있음) 는 skip
|
||||
|
||||
\- 실패 폴더는 `labdb_upload_error.json` 만 남기고 다음 진입 시 재시도
|
||||
|
||||
\- 네트워크 순간 이슈 → 다음 진입에서 자동 복구
|
||||
|
||||
\- 앱 종료 후 재실행 → `ensureHistoryLoaded` 로 recent 폴더 복원 → 재시도
|
||||
|
||||
|
||||
|
||||
\---
|
||||
|
||||
|
||||
|
||||
\## 13. 지원
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user