Clinical UI Review

이 문서는 TypeScript/React clinical monitoring UI를 사람이 검토할 때 확인해야 하는 기준입니다. 자동 테스트는 회귀를 빠르게 잡는 guard이고, manual review는 clinical labeling, alarm communication, browser behavior가 제품 의도와 맞는지 확인하는 단계입니다.

1. 목적

현재 예제는 실제 의료기기 UI가 아니지만, clinician-facing SaMD 화면을 만들 때 필요한 검토 경계를 미리 보여줍니다.

Manual review의 목적은 아래를 확인하는 것입니다.

  • alarm severity와 visual tone이 오해 없이 구분되는가
  • audible alarm 요청과 browser permission 상태가 화면에서 명확한가
  • acknowledge/mute action이 clinical action처럼 보이고 audit trail과 연결되는가
  • stale snapshot, data quality warning, model/policy/preprocessing provenance가 숨겨지지 않는가
  • Storybook fixture와 runtime API 화면이 같은 clinical language를 쓰는가

2. 자동 gate와 manual review의 경계

자동 gate가 확인하는 항목은 아래입니다.

Gate Covers
Unit test view model mapper, alarm sound state, browser audio adapter cleanup
Component test role, live region, disabled action state, numeric status text
Storybook Vitest story render와 play function interaction
Storybook contract/browser smoke 필수 clinical story, browser DOM role, keyboard order, acknowledge/mute transition
Visual smoke warning/critical/acknowledged/muted alarm 상태가 실제 픽셀 차이로 남는지
Browser audio smoke user gesture 이후 Web Audio oscillator start/stop/close path

Manual review가 확인해야 하는 항목은 아래입니다.

Review area Why manual
Clinical copy 문구가 제품 claim처럼 읽히는지, limitation이 충분한지 판단해야 함
Alarm labeling warning/critical/suppressed가 의료진에게 같은 의미로 읽히는지 확인해야 함
Sound permission browser별 autoplay/permission UX가 자동 smoke만으로 충분히 설명되지 않음
Alarm fatigue visual/audio 강조가 지나치거나 부족한지 사람 검토가 필요함
Accessibility reading order 자동 axe와 role check를 통과해도 실제 screen reader 흐름 검토가 필요함
Color/contrast semantics 색상만으로 severity를 전달하지 않는지 확인해야 함

3. Review checklist

3-1. Storybook 상태

아래 story를 직접 확인합니다.

  • normal monitoring snapshot
  • warning alarm with visual banner
  • critical alarm with audible request
  • acknowledged critical alarm
  • muted alarm
  • stale data
  • alarm action failure
  • interactive alarm workflow play check

확인 기준은 아래입니다.

  • warning과 critical tone이 명확히 다릅니다.
  • acknowledged/muted 상태가 active audible alarm처럼 보이지 않습니다.
  • stale snapshot은 current alarm보다 먼저 operational risk로 보입니다.
  • data quality warning은 risk score를 가리지 않지만 충분히 눈에 띕니다.
  • model, policy, preprocessing provenance가 확인 가능합니다.

3-2. Alarm labeling

Alarm labeling은 severity, sound state, action state를 같은 의미로 보여줘야 합니다. 색상이나 소리만으로 의미를 전달하면 안 됩니다.

확인 기준은 아래입니다.

State Required labeling
Warning audible WARNING alarm, sound requested, audible requested가 구분되어 보임
Critical audible CRITICAL alarm, immediate attention copy, assertive live region이 함께 존재
Acknowledged critical severity는 유지되지만 acknowledged, sound suppressed, visual only가 보임
Muted alarm muted, sound suppressed, visual only가 보이고 active audible alarm처럼 보이지 않음
Action failure monitoring snapshot error와 다른 alarm action error로 보임

Review evidence는 Storybook story name, screenshot 또는 screen recording, 확인한 browser, reviewer, 날짜를 남깁니다. 이 evidence는 regulatory artifact가 아니라, UI state language가 의도와 맞았는지 다음 PR에서 비교할 수 있게 하는 engineering record입니다.

3-3. Browser audio

Browser audio는 자동 재생 정책의 영향을 받습니다. Review는 아래 흐름으로 확인합니다.

  1. browser에서 Storybook 또는 local app을 엽니다.
  2. user gesture가 필요한 경우 sound enable action을 수행합니다.
  3. critical audible alarm 상태에서 sound requested 표시를 확인합니다.
  4. acknowledge 후 sound suppressed와 acknowledged 상태를 확인합니다.
  5. mute 후 muted 상태와 sound suppressed 상태를 확인합니다.
  6. browser가 audio를 막을 때 UI가 silent failure처럼 보이지 않는지 확인합니다.

이 예제는 sound pressure level, alarm priority hierarchy, IEC 60601-1-8 적합성을 검증하지 않습니다. 제품 단계에서는 별도 alarm safety requirement와 labeling review가 필요합니다.

Browser permission 상태는 최소 아래처럼 기록합니다.

Browser state Expected UI evidence
User gesture 전 sound가 자동 재생되지 않고 silent failure처럼 보이지 않음
User gesture 후 critical audible alarm에서 sound requested 상태가 명확함
Browser blocked or unavailable alarm 자체가 사라지지 않고 visual alarm과 action은 유지됨
Acknowledge/mute 후 Web Audio stop path와 sound suppressed labeling이 함께 확인됨

3-4. Alarm action

Acknowledge와 mute는 단순 button state가 아니라 clinical action입니다.

확인 기준은 아래입니다.

  • action button accessible name이 명확합니다.
  • action pending 또는 loading 중 중복 클릭이 방지됩니다.
  • acknowledge 후 audible request가 사라집니다.
  • mute 후 muted state가 표시됩니다.
  • action 실패는 monitoring snapshot fetch 실패와 다른 alert로 보입니다.
  • storage-backed demo에서는 alarm audit event가 PostgreSQL에 append됩니다.

3-5. Visual state

Visual review는 “예쁜가”보다 “상태 차이가 임상적으로 오해 없이 보이는가”를 확인합니다.

확인 기준은 아래입니다.

  • warning과 critical이 같은 강조 수준으로 보이지 않습니다.
  • acknowledged/muted는 active audible alarm보다 낮은 urgency로 보입니다.
  • stale snapshot은 risk/alarm보다 먼저 operational risk로 읽힙니다.
  • action failure는 alarm banner 안에서 보이지만 alarm severity 자체와 섞이지 않습니다.
  • waveform, numeric tile, evidence panel이 alarm banner에 가려지지 않습니다.

자동 visual smoke는 warning/critical/acknowledged/muted 상태의 픽셀 차이를 확인합니다. Manual review는 그 차이가 실제 사용자에게 충분한지 판단합니다.

3-6. Accessibility

자동 smoke를 통과한 뒤에도 아래를 수동으로 확인합니다.

  • keyboard tab order가 acknowledge -> mute 흐름으로 자연스럽습니다.
  • alarm region이 screen reader에서 alert로 읽힙니다.
  • risk score와 severity가 색상만으로 전달되지 않습니다.
  • review queue item label이 subject와 priority를 함께 전달합니다.
  • waveform은 이미지를 보지 못해도 상태 요약을 잃지 않습니다.

3-7. Review evidence template

Manual review 결과는 아래 형식으로 PR comment, issue, 또는 release note에 남깁니다.

Clinical UI review
- Build or commit:
- Browser and OS:
- Storybook stories reviewed:
- Runtime path reviewed: Storybook / make demo/check / make demo/check/storage
- Audible permission result:
- Warning/Critical visual distinction:
- Suppressed state labeling:
- Alarm action failure labeling:
- Keyboard/screen reader notes:
- Remaining risk:

Evidence가 남아야 이후에 screenshot baseline, browser compatibility matrix, formal labeling review로 확장할 수 있습니다. 현재 예제에서는 이 template을 lightweight review record로 사용합니다.

3-8. Manual labeling 기준

Manual labeling review는 screenshot을 모으는 작업이 아니라, 화면 문구가 실제 clinical workflow에서 어떤 의미로 읽히는지 확인하는 작업입니다. 자동 테스트가 role, aria-live, data-severity를 확인하더라도 아래 판단은 사람이 해야 합니다.

Labeling target Review question
Alarm severity warning, critical, acknowledged, muted가 서로 다른 operational urgency로 읽히는가
Sound state sound requested, sound suppressed, browser blocked 상태가 alarm 자체와 섞이지 않는가
Risk wording risk score가 diagnosis나 treatment recommendation처럼 보이지 않는가
Data quality stale, dropout, excessive motion, low confidence가 현재 임상 상태와 구분되는가
Action wording acknowledge/mute가 단순 UI close가 아니라 audit trail에 남는 clinical action처럼 보이는가
Provenance model, policy, preprocessing version이 review 가능한 evidence로 보이는가

Manual labeling review는 최소 warning, critical audible, acknowledged critical, muted, stale data, alarm action failure story를 포함합니다. Runtime path는 make demo/check/storage로 한 번 확인해 Storybook fixture와 live API response가 같은 language를 쓰는지 확인합니다.

3-9. Visual baseline 전략

현재 visual smoke는 commit된 screenshot baseline을 사용하지 않고 같은 Chromium 실행 안에서 warning/critical/acknowledged/muted screenshot의 픽셀 차이를 비교합니다. 이 방식은 가볍고 self-hosted runner에서 운영하기 쉽지만, 제품 UI review의 최종 기준은 아닙니다.

다음 단계의 visual baseline은 아래 순서로 올립니다.

  1. Baseline 대상 story를 clinical state 중심으로 제한합니다.
  2. Baseline은 normal, warning, critical audible, acknowledged, muted, stale, action failure만 둡니다.
  3. OS/font 차이를 줄이기 위해 baseline capture는 같은 browser image와 같은 viewport에서 수행합니다.
  4. 허용 threshold는 디자인 변경을 숨기지 않을 만큼 낮게 두고, dynamic timestamp와 animation은 story fixture에서 고정합니다.
  5. Screenshot diff가 실패하면 자동으로 승인하지 않고 manual labeling review evidence를 요구합니다.

Visual baseline은 “예쁜지”를 보는 장치가 아니라, clinical state가 픽셀 수준에서 사라지거나 같은 urgency로 보이는 회귀를 잡는 장치입니다. 색상만 비교하면 부족하므로, baseline failure는 role, label, live region, keyboard order check 결과와 함께 해석합니다.

4. 실행 명령

자동 gate는 아래 명령으로 실행합니다.

make docs/storybook/check
pnpm --filter @tirosh/patient-risk-web test:storybook
node scripts/check-browser-alarm-audio.mjs

Live API와 runtime composition은 아래 명령으로 확인합니다.

make demo/check
make demo/check/storage

Manual review는 위 자동 gate가 통과한 뒤 수행합니다. 자동 gate가 실패하면 먼저 구현 또는 fixture drift를 고쳐야 합니다.

5. 범위 밖

아래는 현재 예제의 범위 밖입니다.

  • 실제 의료기기 alarm standard 적합성 검증
  • sound pressure level 측정
  • hospital device/browser compatibility matrix
  • formal clinical labeling approval
  • PHI 포함 화면 검토
  • full visual regression baseline 운영

이 항목들은 제품화 단계에서 별도 quality plan과 release checklist로 다룹니다.