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:
2026-07-10 11:25:26 +09:00
parent b822b49fc6
commit 60b630d3de
5 changed files with 367 additions and 32 deletions
+122
View File
@@ -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. 지원