feat(align): 좌우 확인 완료 순간의 마지막 프레임 창을 align 에 저장하고 601 로 올린다

좌우 정렬은 연속 스트리밍이라 그동안 아무것도 저장하지 않았다. "맞췄다"고 확인한 그
자리의 파형·IMU 가 파일에 없으니 나중에 좌우 판정을 대조할 길이 없었다(2026-09-30 요청).

  · 좌우 루프가 마지막 프레임 창(LateralGuide.required = 10, 판정 1회에 쓰는 수)을
    파형+IMU 짝으로 들고 있다가, [좌우 확인 완료]에서 부착 위치 cm 으로
    `align_{n}cm_lateral.csv` · `align_{n}cm_lateral_imu.csv` 를 쓴다.
    다시 시작·처음부터 다시 정렬 때는 창을 비운다.
  · HospitalRunStore: 파일 종류를 AlignFileKind(SWEEP/CONFIRM/LATERAL) 로 —
    `confirm: Boolean` 대신. 같은 cm 이라도 종류가 다르면 다른 파일이다.
  · AlignLabdbPayload: `_lateral` 을 phase=lateral 로 올린다(탐색 → 확인 → 좌우 순).
    positions_measured 는 sweep 만, confirm_positions 는 confirm 만, lateral_frames 추가.
    미업로드 대상 판정(raw = sweep)은 그대로.
  · 문서(LABDB_DATATYPES.md) 601 phase·params·IMU 파일명 갱신.

시험: HospitalRunStoreAlignFilesTest 4건 신규, 페이로드 2건·대상 판정 1건 추가 — 80건 통과.
실기(프로브 필요)는 다음 임상에서 확인.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 11:01:04 +09:00
parent 9665216aad
commit c8964927ce
7 changed files with 216 additions and 37 deletions
+10 -5
View File
@@ -172,7 +172,9 @@ IMU 는 2026-09-21 이후 업로드분부터 `sensor.imu` 로 들어옵니다(
| `protocol` | string | `"hospital_align_2026"` 고정 |
| `subject` | string | 환자 식별자 |
| `save_name` | string | 저장 폴더명 |
| `positions_measured` | int | 측정한 위치 수 |
| `positions_measured` | int | 측정한 위치 수 (탐색 `sweep` 만) |
| `confirm_positions` | int | 확인 측정한 위치 수 |
| `lateral_frames` | int | 좌우 확인 완료 순간에 남긴 프레임 수 (2026-09-30~). 0 = 좌우 미확인 또는 옛 앱 |
| `cycles_total` | int | = `recordCount` |
| `upload_reason` | string | `"nurse_review"` — 사람이 올린 세션 표시 |
| `device`, `firmware_version`, `hw_preset` | string | |
@@ -317,8 +319,11 @@ IMU 는 2026-09-21 이후 업로드분부터 `sensor.imu` 로 들어옵니다(
| `gx` · `gy` · `gz` | **dps** (도/초) | 각속도 3축. 정지 시 ≈ 0 |
- 600 에서는 한 `repeat_idx` 가 한 레코드이고, 그 회차의 샘플이 `imu_samples` 에 배열로 들어갑니다.
- 601 에서는 한 `cycle_idx` 가 한 레코드입니다. `phase`(sweep/confirm)별로 따로 들어가며,
**확인 측정의 IMU 가 탐색 측정 것을 덮지 않습니다.**
- 601 에서는 한 `cycle_idx` 가 한 레코드입니다. `phase`(sweep/confirm/lateral)별로 따로
들어가며, **확인 측정의 IMU 가 탐색 측정 것을 덮지 않습니다.**
- `phase: "lateral"` (2026-09-30~) 은 간호사가 "좌우 확인 완료"를 누른 순간의 **마지막
프레임 창**(판정 1회에 쓰는 10프레임)입니다. `align_cm` 은 부착 위치(best + 오프셋)이고,
`cycle_idx` 는 그 창 안의 순서입니다. 좌우 정렬 판정을 나중에 대조하는 데 씁니다.
## ⚠ 없으면 `sensor` 는 빈 객체입니다 — 0 으로 채우지 마십시오
@@ -355,9 +360,9 @@ IMU 는 2026-09-21 이후 업로드분부터 `sensor.imu` 로 들어옵니다(
scan_id,timestamp,repeat_idx,sample_idx,ax_g,ay_g,az_g,gx_dps,gy_dps,gz_dps
→ scan_id 로 파형 CSV 와 잇습니다
601 align_{n}cm_imu.csv · align_{n}cm_confirm_imu.csv
601 align_{n}cm_imu.csv · align_{n}cm_confirm_imu.csv · align_{n}cm_lateral_imu.csv
cycle_idx,sample_idx,ax_g,ay_g,az_g,gx_dps,gy_dps,gz_dps
→ 파형과 같은 파일명 규칙(confirm 분리)을 그대로 따릅니다
→ 파형과 같은 파일명 규칙(confirm/lateral 분리)을 그대로 따릅니다
```
파형 행(`meta + s0..s99`)을 넓히지 않은 이유: 그 헤더는 이미 올라간 데이터와 파서가