feat(hospital): 정렬을 자세마다 — 부착 위치·재부착 확인·정렬 폴더·labdb 세션을 자세별로
임상 프로토콜은 자세마다 정렬을 처음부터 다시 한다(2026-10-01 확인): Supine 정렬 →
Supine 0~100% → Sitting 정렬 → Sitting 0~100% …. 앱은 환자당 한 번이었다 — Sitting 에서
다시 정렬하면 같은 `align/` 의 원시 파일이 덮이고 labdb 세션 ID 도 같아 섞였다.
· AppState: 부착 위치·근거·기준 채널·재부착 결과를 자세별 맵(AnchorState)으로. 기존
접근자(anchorCm 등)는 지금 자세의 항목을 읽고 쓴다. 환자·프로브가 바뀌면 전 자세를
비운다(clearAllAnchors).
· 저장: `align/` → `align_{자세}/`. 업로드 대상 탐색은 옛 `align` 과 `align_*` 전부.
labdb 601 세션 이름에 자세 꼬리(`…_align_sitting_HHmm`), 요약에 `posture`.
· 정렬 화면: 자세 칩은 첫 위치를 재고 나면 잠근다(폴더·세션의 조건이다). 바꾸려면
[처음부터 다시 정렬].
· 병원 화면: 환자명 → 자세 → 정렬 카드 순(자세가 정렬보다 위). 카드가 그 자세의 상태를
보인다 — "Sitting 부착 위치 미정렬" / "✓ Sitting 부착 위치 3cm 확정".
시험: 자세별 폴더 대상 탐색 · 세션 이름 자세 꼬리. 전체 190건 · failures 0.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -39,42 +39,57 @@ class AppState(private val context: Context) {
|
||||
* 연결 화면까지 엉뚱한 곳으로 보낸다.
|
||||
*/
|
||||
/**
|
||||
* 정렬로 정한 부착 위치(cm). 병원 임상 모드가 표시·기록에 쓴다.
|
||||
* 한 자세의 부착 위치와 딸린 것. **자세마다 따로 산다**(2026-10-01 — 임상 프로토콜이
|
||||
* 자세마다 정렬을 다시 한다). 네 값은 같이 넣고 같이 비운다 — 하나만 남으면 그 순간부터
|
||||
* 어긋난다(환자가 바뀌었는데 재부착 확인이 ✓ 로 남는 식).
|
||||
*
|
||||
* 자세·용량이 바뀌어도 이 위치는 **고정**이라 한 환자 동안 유지된다.
|
||||
* 환자가 바뀜면 다시 정렬해야 하므로 병원 모드에서 환자명을 바꿀 때 비운다.
|
||||
* @property cm 정렬로 정한 부착 위치. 그 자세의 전 용량에서 고정.
|
||||
* @property basis 누가 정했는지. null = 정렬을 거치지 않았다. 정렬은 실제 인체에서 끝까지
|
||||
* 안 맞을 수 있어 진행을 막지 않으므로, 알고리즘이 고른 자리와 사람이 고른 자리를
|
||||
* 나중에 가를 유일한 단서다.
|
||||
* @property refChannels 정렬 좌우 확인 창(없으면 확인 측정)에서 잡힌 채널 CH0~3 —
|
||||
* 재부착 확인([com.medithings.vesiscan.managers.ReattachCheck])의 기준. null = 기준 없음.
|
||||
* @property reattach 재부착 확인 결과. null = 아직 안 했다.
|
||||
*/
|
||||
var anchorCm: Int? by mutableStateOf(null)
|
||||
data class AnchorState(
|
||||
val cm: Int? = null,
|
||||
val basis: com.medithings.vesiscan.managers.AnchorBasis? = null,
|
||||
val refChannels: List<Boolean>? = null,
|
||||
val reattach: com.medithings.vesiscan.managers.ReattachCheck.Result? = null,
|
||||
)
|
||||
|
||||
/**
|
||||
* [anchorCm] 을 **누가** 정했는지. null = 정렬을 거치지 않았다.
|
||||
*
|
||||
* 정렬은 실제 인체에서 끝까지 안 맞을 수 있어 진행을 막지 않는다. 그래서 위치만
|
||||
* 들고 다니면 알고리즘이 고른 자리와 사람이 고른 자리가 한 덩어리로 쌓이고, 나중에
|
||||
* 정확도 검증의 모집단을 가려낼 수 없다. **항상 [anchorCm] 과 같이 비우고 같이
|
||||
* 넣는다** — 하나만 남으면 그 순간부터 둘이 어긋난다.
|
||||
*/
|
||||
var anchorBasis: com.medithings.vesiscan.managers.AnchorBasis? by mutableStateOf(null)
|
||||
/** 자세별 부착 위치. [clinicalPosture] 가 가리키는 항목을 아래 접근자가 읽고 쓴다. */
|
||||
val anchors = androidx.compose.runtime.mutableStateMapOf<
|
||||
com.medithings.vesiscan.models.ClinicalPosture, AnchorState>()
|
||||
|
||||
/**
|
||||
* 정렬 **확인 측정**에서 잡힌 채널(CH0~3). 재부착 확인([ReattachCheck])의 기준.
|
||||
* null = 기준 없음 — 사람이 고른 위치이거나 확인 측정 전에 진행했다.
|
||||
*/
|
||||
var anchorRefChannels: List<Boolean>? by mutableStateOf(null)
|
||||
private fun anchorNow(): AnchorState = anchors[clinicalPosture] ?: AnchorState()
|
||||
private fun updateAnchor(f: (AnchorState) -> AnchorState) { anchors[clinicalPosture] = f(anchorNow()) }
|
||||
|
||||
/** 재부착 확인 결과. null = 아직 안 했다. 부착 위치와 같이 비운다. */
|
||||
var anchorReattach: com.medithings.vesiscan.managers.ReattachCheck.Result? by mutableStateOf(null)
|
||||
/** 지금 자세의 부착 위치(cm). 병원 임상 모드가 표시·기록에 쓴다. */
|
||||
var anchorCm: Int?
|
||||
get() = anchorNow().cm
|
||||
set(v) = updateAnchor { it.copy(cm = v) }
|
||||
|
||||
/**
|
||||
* 부착 위치와 딸린 것(근거·기준 채널·재부착 확인)을 **한꺼번에** 비운다.
|
||||
* 하나만 남으면 그 순간부터 서로 어긋난다 — 환자가 바뀌었는데 재부착 확인이 ✓ 로 남는 식.
|
||||
*/
|
||||
fun clearAnchor() {
|
||||
anchorCm = null
|
||||
anchorBasis = null
|
||||
anchorRefChannels = null
|
||||
anchorReattach = null
|
||||
}
|
||||
/** 지금 자세의 [AnchorState.basis]. */
|
||||
var anchorBasis: com.medithings.vesiscan.managers.AnchorBasis?
|
||||
get() = anchorNow().basis
|
||||
set(v) = updateAnchor { it.copy(basis = v) }
|
||||
|
||||
/** 지금 자세의 [AnchorState.refChannels]. */
|
||||
var anchorRefChannels: List<Boolean>?
|
||||
get() = anchorNow().refChannels
|
||||
set(v) = updateAnchor { it.copy(refChannels = v) }
|
||||
|
||||
/** 지금 자세의 [AnchorState.reattach]. */
|
||||
var anchorReattach: com.medithings.vesiscan.managers.ReattachCheck.Result?
|
||||
get() = anchorNow().reattach
|
||||
set(v) = updateAnchor { it.copy(reattach = v) }
|
||||
|
||||
/** 지금 자세의 부착 위치와 딸린 것을 비운다. */
|
||||
fun clearAnchor() { anchors.remove(clinicalPosture) }
|
||||
|
||||
/** 전 자세를 비운다 — 환자가 바뀌거나 프로브가 바뀔 때(빔 각도가 달라 정렬이 무효). */
|
||||
fun clearAllAnchors() { anchors.clear() }
|
||||
|
||||
/**
|
||||
* 병원 임상 자세. **정렬 화면과 병원 모드가 같은 값을 봐야 한다.**
|
||||
|
||||
Reference in New Issue
Block a user