dw.jang d401740210 feat(clinical): 병원 임상 화면 재구성 · 조합은 복부 두께로 · 레퍼런스 고정
## 화면을 두 덩어리로 나눴다

    환자명 → 부착 위치 정렬 → 자세 → 방광 채움 → 반복 횟수 → 복부 두께 →
    [측정 시작] → BV 카드
    ──────────────────────── 구분선 ────────────────────────
    수동 확인 — 저장되지 않습니다
    프로브 파라미터 주입 → [1회 측정]/[연속 측정] → BV → 마지막 측정 → 6채널

종전에는 BV 측정 구간이 [측정 시작] **위에** 있어 프로토콜 흐름 한가운데 끼어 있었다.
수동 측정 값은 저장도 업로드도 안 되는데, 한 흐름으로 붙어 있으면 조작자가 그것을
프로토콜의 한 단계로 착각한다. 구분선과 "저장되지 않습니다" 한 줄을 넣었다.

프로토콜 BV 카드는 실행이 끝난 뒤에도 남긴다(caption 이 "직전 회차"→"마지막 회차").
방광을 비우기 전에 방금 받은 값이 말이 되는지 한 번 더 볼 수 있어야 한다.

## 6조합 순회 → 복부 두께 2택

    40mm 이하   1.8MHz c3                 →  n회
    40mm 초과   1.8MHz c3 · 2.3MHz c3     →  2n회

cycle 은 3 고정. 한 단계 20회 × 6조합 = 120회가 환자를 너무 오래 눕힌다.

조작자에게 freq·cycle 을 고르게 하지 않는 것이 핵심이다. 눈으로 보고 답할 수 있는
것은 복부 두께이고, 조합은 거기서 따라 나온다(AbdomenThickness).

## 진행 판정: 개수 비교 → 집합 비교 (여기가 제일 위험했다)

`EXPECTED_COMBINATIONS = 6` 으로 **개수**를 세고 있었다. 그대로 두면 요구 조합이 1~2개인
지금 어떤 단계도 영원히 PARTIAL 로 남는다. 그런데 단순히 6을 2로 바꾸면 더 나쁘다 —
2.3MHz 를 두 번 채운 것과 1.8·2.3 을 각각 채운 것이 같은 숫자가 되어, 두꺼운 환자의
단계가 완료로 잡히고 **그 자리에서 1.8MHz 를 영원히 놓친다.**

`scanProgress(patient, day, expected)` 로 기대 집합을 받아 `containsAll` 로 본다.
expected 가 비면 완료라고 말하지 않는다 — `containsAll(emptySet)` 은 항상 true 라
가드가 없으면 아무것도 안 잰 단계까지 완료가 된다. 옛 6조합 데이터는 두 집합 모두의
상위집합이므로 계속 완료로 읽힌다(과거 데이터가 뒤집히면 간호사가 다 다시 잰다).

## 완료 칩을 초록 → 회색

초록은 "좋은 상태"로 읽혀 조작자가 거기서 멈춘다. 실제 의미는 "이미 받았으니 다음으로
가라"다. 아직 안 받은 칩이 눈에 들어와야 한다 — 남은 일이 어디인지가 그 줄의 존재
이유다. 누를 수는 있게 둔다(파형이 이상해 다시 재는 경우).

## 레퍼런스 알고리즘 스위치 제거

병원 임상의 값은 최종 보고본 하나여야 한다. 스위치가 있으면 화면을 본 사람과 기록을
읽는 사람이 서로 다른 경로의 숫자를 같은 값이라고 믿을 수 있고, 그 착오는 기록의
알고리즘 라벨을 일일이 확인해야만 드러난다. 두 경로 비교는 테스트가 맡는다
(ClinicalBvTest · AlgoPathReportTest).

## 기록

매니페스트에 `abdomen_thickness` / `abdomen_thickness_label`. 조합만 남기면 "왜 1개만
돌았나"를 나중에 답할 수 없다 — 시간이 없어 끊은 것과 얇아서 하나면 됐던 것이 구분되지
않는다. LABDB_DATATYPES.md 에 "한 조건에 세션 1개인 것이 정상"을 박았다.

테스트 114개 통과(진행 판정 12개 전면 재작성). HospitalProgressTest 가 과거 격자를
손으로 적지 않고 HOSPITAL_COMBINATIONS 를 참조한다 — 둘이 갈리면 "과거 데이터는 계속
완료로 읽힌다"는 보장이 거짓이 된다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 15:33:07 +09:00
S
Description
No description provided
20 MiB
Languages
Kotlin 97.1%
Python 2.9%