제7장

제7장: 현장 통합과 구현 — 현장진단·웨어러블·환경 모니터링

WIA-BIO-011 레코드가 혈당 스트립, CGM 패치, 측방유동 판독기, 현장 수질 센서에서 출발하여 게이트웨이와 서비스를 거쳐 전자건강기록에 이르는 경로를 따라가며, 그 과정에서 v1.0 데이터 모델과 SDK가 어디에서 보완을 필요로 하는지 정리한다.

7.0 이 장의 범위와 읽는 법

제1장부터 제6장까지는 부품을 만들었다. 화학과 물리, 성능 지표, 레코드 타입, SDK와 CLI, 그리고 운영 프로토콜이다. 이 장은 그 부품을 제품 안에 넣는다. 먼저 규격 §8이 꼽는 네 가지 응용 계열, 곧 혈당 모니터링, 심장 표지자, 감염병 검사, 환경 모니터링을 차례로 살펴본다. 이어서 데이터가 기기를 떠나 게이트웨이와 서비스를 거쳐 전자건강기록(EHR)에 들어가는 경로를 따라간다.

이 장은 이 책에서 통합 단계에 해당한다. 저장소에는 spec/PHASE-4-INTEGRATION.md라는 파일이 있지만, 이 파일은 범용 템플릿 문서이다. 다른 표준의 식별자(WIA-BIO-010)가 적혀 있고, 제목이 파일 이름과 맞지 않으며, 품질 기준값은 본 규격과 충돌한다. 이 장은 그 파일에서 일반적인 보안 문구와 비규범적 부속서 J(배포 토폴로지)만 가져다 쓰며, 둘 다 쓰일 때마다 그 성격을 밝힌다. 규제 승인, 임상 검증 연구, 적합성 증거는 의도적으로 제8장으로 미룬다.

이 장에는 세 종류의 서술이 섞여 있다.

7.1 혈당 측정기와 연속혈당측정기

포도당은 이 분야 전체의 기준 응용이며, WIA-BIO-011의 기본값도 포도당을 염두에 두고 정해졌다. SDK의 GOX_KM 33 mM과 효소 온도계수 3 %/°C는 포도당 산화효소를 기준으로 한 기본값이다. 같은 분석물 아래에 성격이 전혀 다른 두 제품이 있고, 둘은 데이터 모델에 서로 다른 부담을 준다.

7.1.1 스트립형 혈당 측정기

규격 §8.1은 자가 혈당 측정기를 세 가지 수치로 기술한다. 시료량 0.3–1 µL, 측정 범위 1.1–33.3 mM(20–600 mg/dL), 응답 시간 5–10초이다. 각 수치는 곧 설계 제약이다. 시료가 1 µL에도 못 미치면 정밀도를 좌우하는 것은 효소층보다 시료 충전부인 경우가 많다. 덜 채워진 스트립은 낮은 전류를 내며, 측정기는 이를 결과로 내보내지 말고 거부해야 한다. 약 30배에 이르는 보고 범위는 많은 효소 전극의 선형 구간보다 넓으므로(제1장), 측정기는 확산 제한막과 매개체를 써서 선형성을 넓힌다. 읽기 시간이 짧기 때문에 많은 측정기는 정상 상태를 기다리지 않고 시료가 채워진 뒤 정해진 시점의 전류를 읽는다.

전혈에는 완충액에서 하는 벤치 교정으로는 드러나지 않는 매트릭스 효과, 곧 적혈구 용적률(hematocrit)이 더해진다. 적혈구는 부피를 차지하고 전극으로의 확산을 늦추므로, 같은 혈장 포도당 농도에서도 적혈구 용적률에 따라 전류가 달라진다. 측정기는 예를 들어 시료의 다른 전기적 성질을 추가로 측정하여 이를 보정한다. WIA-BIO-011 v1.0의 MeasurementRequest에는 적혈구 용적률이나 그 밖의 매트릭스 공변량을 담을 필드가 없다. 판독기가 이런 값을 측정한다면 통합 담당자가 레코드 옆에 따로 실어 보내야 한다(§7.5의 어댑터 패턴 참조).

WIA 데이터 모델에서 스트립 측정 한 번은 MeasurementResult 하나이다. 센서 설정은 type: 'electrochemical', electrochemicalType: 'amperometric', biorecognitionElement: 'glucose-oxidase'(또는 탈수소효소를 나타내는 문자열. BiorecognitionElement | EnzymeType | string 합집합 타입이 이를 허용한다), sampleType: 'blood'이다. 결과의 concentrationUnit은 교정의 linearRange.unit에서 온다. 내부 저장은 mmol/L로 하고 표시할 때만 변환하면(§7.6) 반올림 오차의 한 부류를 피할 수 있다.

7.1.2 연속혈당측정기

연속혈당측정기(CGM)는 피하 조직에 삽입하는 소형 전류법 효소 전극이다. 규격 §8.1은 측정 간격 1–5분, 센서 수명 7–14일을 제시한다. 이 데이터를 어떻게 다뤄야 하는지는 생리학적·공학적 사실 세 가지가 결정한다.

규격에 있는 CGM 정확도 문구("Clarke Error Grid Zone A 90 %")는 출처가 제시되어 있지 않으므로 이 책에서는 쓰지 않는다. 혈당 시스템의 정확도 평가는 올바른 참고 문헌과 함께 제8장에서 다룬다.

7.1.3 CGM 데이터 흐름을 WIA 레코드에 옮기기

CGM 데이터 흐름을 담는 자연스러운 그릇은 TimeSeries이다. 여기에는 id, sensorId, analyte, TimeSeriesPoint 객체의 배열(time, value, unit, 그리고 선택적인 단일 quality 플래그), 선택적 patientId와 studyId를 담는 열린 metadata 객체가 있다. 각 측정점은 measureAnalyte로 만들 수 있지만, 2주 동안 5분마다 SDK를 부르는 단순한 반복문은 v1.0의 네 가지 동작에 걸린다. 표 7.1에 이를 정리하였다.

표 7.1 — CGM 통합에 영향을 주는 v1.0 SDK 동작
SDK 동작14일 CGM에 미치는 영향이 책의 권고
calibrateSensor는 validUntil을 교정 후 24시간으로 정하고, 그 뒤에는 measureAnalyte가 BIO004를 던진다교정을 새로 하지 않으면 첫날 이후의 모든 측정이 실패한다공장 교정 센서라면 공장 파라미터로 CalibrationData 객체를 만들고 validUntil을 착용 기간 종료 시점으로 정한 뒤 MeasurementRequest.calibration으로 넘긴다. 체내 재교정을 한다면 새 교정마다 별도 레코드로 저장한다
createSensor는 인식 요소 문자열에 "ase"가 들어 있으면 기본 수명 180일과 maxMeasurements: 1000을 부여한다만료 검사(BIO007)는 패치를 떼고 몇 달이 지나서야 작동한다. 1,000회는 5분 간격 14일의 측정 횟수 4,032회에 크게 못 미치지만, v1.0은 이 횟수를 강제하지 않는다lifetime.expirationDate를 삽입 시각에 표시 착용 기간을 더한 값으로 덮어쓰고, maxMeasurements를 측정 간격에 맞춘다
온도 보정은 신호를 1 + 0.03(T − 25)로 나누며, |T − 25| > 10 °C이면 temperature-out-of-range를 붙인다체내 측정 부위 온도 37 °C를 넘기면 신호가 1.36으로 나뉘고 플래그가 항상 붙는다하드코딩된 25 °C가 아니라 교정이 적용되는 온도를 기준으로 보정한다(아래 참조)
linearRange.min보다 낮은 결과에는 below-lod가 붙고, qualityFlags에는 항상 'ok'가 남는다임상적으로 가장 중요한 낮은 값이, 실제로는 최저 표준 아래일 뿐인데 검출 한계 미만으로 표시될 수 있다linearRange.min을 기기의 검증된 하한으로 정하고, 측정점의 단일 quality 플래그는 심각도 순으로 고르되 다른 플래그가 있으면 'ok'는 무시한다

온도 행은 수치로 확인해 둘 만하다. SDK는 모든 교정의 기준 온도를 25 °C로 간주한다. 그러나 체내 삽입 센서의 공장 교정은 애초에 체내 조건에서 유효하도록 만들어진다. 통합 담당자가 측정 부위 온도로 예컨대 37 °C를 넘기면 SDK는 신호를 1.36으로 나누고, 보고 농도는 (절편이 작을 때) 약 4분의 1 줄어든다. 보정 자체가 만들어 낸 오차이다. 반대로 아무 값도 넘기지 않으면 SDK는 25 °C로 가정하여 보정을 하지 않고, 결과에 temperature: 25를 기록한다. 이 역시 사실이 아니다. 두 경우 모두 받아들일 수 없다. 이 책은 얇은 어댑터를 권한다. 어댑터가 교정 자체의 기준 온도를 기준으로 보정을 적용하고, SDK가 신호를 건드리지 않도록 temperature: 25로 measureAnalyte를 부른 다음, 실제 온도를 결과에 다시 써 넣는 방식이다. 제3장에서 지적했듯 규격은 보정을 곱셈으로 쓰고 SDK는 나눗셈을 하므로, 어댑터는 어느 규약을 쓰는지 문서로 밝혀야 한다.

// 이 책의 권고이며 @wia/bio-011 v1.0의 일부가 아니다.
import { BiosensorSDK, MeasurementResult, QualityFlag, TimeSeriesPoint } from '@wia/bio-011';

const SEVERITY: QualityFlag[] = [
  'sensor-expired', 'calibration-expired', 'above-range', 'below-lod',
  'below-loq', 'interference-detected', 'high-noise', 'drift-detected',
  'temperature-out-of-range', 'ok',
];

function worstFlag(flags: QualityFlag[]): QualityFlag {
  const real = flags.filter(f => f !== 'ok');
  if (real.length === 0) return 'ok';
  return SEVERITY.find(f => real.includes(f)) ?? real[0];
}

function measureCgmPoint(
  sdk: BiosensorSDK, sensorId: string, rawSignal: number,
  siteTempC: number, calTempC: number, alphaPerC = 0.03,
): { result: MeasurementResult; point: TimeSeriesPoint } {
  // 교정 온도를 기준으로 보정한다(SDK와 같은 나눗셈 규약).
  const corrected = rawSignal / (1 + alphaPerC * (siteTempC - calTempC));
  const result = sdk.measureAnalyte({ sensorId, signal: corrected, temperature: 25 });
  result.signal = rawSignal;            // 원신호를 레코드에 남긴다
  result.correctedSignal = corrected;
  result.temperature = siteTempC;       // 실제 온도를 다시 기록한다
  const point: TimeSeriesPoint = {
    time: result.timestamp, value: result.concentration,
    unit: result.concentrationUnit, quality: worstFlag(result.qualityFlags),
  };
  return { result, point };
}

worstFlag의 심각도 순서 자체도 이 책의 권고이다. v1.0은 플래그 값 열 가지를 정의하지만 그 사이의 우선순위는 정하지 않는다. TimeSeriesPoint는 플래그를 하나만 담을 수 있고 그 선택이 임상의가 보는 그래프를 결정하므로, 제품 팀은 자체 순서를 정해 문서화하고 안정적으로 유지해야 한다. 이렇게 만든 데이터 흐름은 전송 형식으로는 아래 조각과 같다. 날짜는 UTC 기준 ISO 8601이고, 단위는 모든 측정점에 명시되며, 추가 메타데이터 키는 TimeSeries.metadata가 허용하는 인덱스 시그니처를 이용한다. 모든 값은 예시이다.

{
  "id": "TS-CGM-0001",
  "sensorId": "BS-1767225600000-k3v9q2x7a",
  "analyte": "glucose",
  "metadata": {
    "patientId": "P-5c1e9b",
    "sampleMatrix": "interstitial-fluid",
    "insertedAt": "2026-01-05T08:00:00Z",
    "intervalMinutes": 5,
    "calibrationMode": "factory"
  },
  "data": [
    { "time": "2026-01-05T10:00:00Z", "value": 6.4, "unit": "mmol/L", "quality": "ok" },
    { "time": "2026-01-05T10:05:00Z", "value": 6.9, "unit": "mmol/L", "quality": "ok" },
    { "time": "2026-01-05T10:10:00Z", "value": 7.3, "unit": "mmol/L", "quality": "high-noise" },
    { "time": "2026-01-05T10:15:00Z", "value": 7.8, "unit": "mmol/L", "quality": "ok" }
  ]
}

sampleMatrix 키에 주목하라. BiosensorConfig.sampleType 열거형에는 blood, serum, plasma, urine, saliva, water, food, environmental이 있지만 간질액은 없다. 그래서 CGM 통합에는 고를 수 있는 올바른 열거값이 없다. 매트릭스를 메타데이터에 기록하는 것은 임시방편이며, 열거형에 'interstitial-fluid'와 'sweat'를 추가하는 것은 향후 개정의 분명한 후보이다.

7.2 심장 표지자와 그 밖의 면역분석 현장진단

심장 표지자는 규격 §8의 두 번째 응용 계열이다. 이들은 매우 낮은 농도로 존재하는 단백질이므로 효소 전극이 아니라 항체 기반 면역센서로 측정하며, 결과는 그냥 보고하는 것이 아니라 임상 판단 기준값에 비추어 해석해야 한다.

7.2.1 트로포닌

규격 §8.2는 심장 트로포닌 I를 샌드위치 면역분석 형식으로 기술하며, 목표 LOD 1 pg/mL와 측정 시간 10–15분을 제시한다. 샌드위치 형식(제1장)은 고정화된 포획 항체와 표지된 검출 항체 사이에 분석물을 붙잡으므로 특이성이 좋고 신호가 농도에 따라 증가한다. 한편 알려진 실패 양상도 있다. 분석물 농도가 극단적으로 높으면 두 항체가 각각 따로 포화되어 샌드위치가 적게 형성되고 신호가 다시 떨어진다. 이 "고용량 후크 효과(high-dose hook effect)" 때문에 매우 낮은 신호가 항상 낮은 농도를 뜻하지는 않으며, 1단계 샌드위치 기기는 이 효과에 대한 특성 평가가 필요하다.

단위에는 주의가 필요하다. 검사실 트로포닌 결과는 흔히 ng/L로 보고되는 반면, 예전의 현장진단 문헌은 ng/mL를 쓴다. 1 pg/mL는 1 ng/L이고, 1 ng/mL는 1,000 ng/L이다. 따라서 규격의 목표값 0.001 ng/mL는 1 ng/L이다. 모든 레코드에 단위 문자열을 명시하지 않고 두 단위를 섞는 시스템은 1,000배 틀리게 된다.

규격은 "임상 기준값" 0.04 ng/mL도 제시하지만, 이 책은 그 수치를 쓰지 않는다. 현재의 고감도 트로포닌 분석법은 건강한 인구의 99번째 백분위수 참고 상한을 판단 기준으로 쓰며, 그 값은 분석법마다 다르다. 데이터 표준이 하드코딩할 수 있는 보편적 트로포닌 기준값은 없다. 같은 이유로 트로포닌의 임상 해석은 흔히 한 번의 값뿐 아니라 연속 검체 사이의 변화에도 의존한다. POCTestResult는 검체 하나를 기술하므로, 연속 해석은 patient.id와 timestamp로 연결된 여러 레코드로부터 구성해야 한다.

7.2.2 나트륨이뇨펩티드

B형 나트륨이뇨펩티드(BNP)에 대해 규격은 임상 범위 0–5,000 pg/mL, 심부전 기준값 100 pg/mL, 응답 시간 약 15분을 제시한다. 100 pg/mL는 BNP의 배제(rule-out) 기준으로 널리 쓰이는 값이지만, 여기서도 판단 기준값은 데이터 형식이 아니라 분석법과 그 사용 목적에 속한다. BNP와 그 N-말단 단편인 NT-proBNP는 참고값이 다른 별개의 분자이므로, analyte 문자열에는 둘 중 무엇을 측정했는지 적어야 한다.

7.2.3 면역분석 결과의 기록

이런 검사에는 맨 MeasurementResult보다 POCTestResult가 알맞다. 이 레코드는 testType(여기서는 'cardiac-marker'), 수치 value와 unit, interpretation(정량 검사라면 normal, abnormal, borderline), 선택적 referenceRange와 cutoff, 기기 정보(serialNumber, lotNumber, expirationDate), 그리고 합격 여부와 품질 플래그를 담는 작은 qualityControl 블록을 더한다.

실무에서는 두 가지 빈틈이 문제가 된다. 첫째, cutoff는 단순한 숫자이다. 단위(레코드의 unit을 따른다고 암묵적으로 가정할 뿐이다)도, 출처도 기록되지 않는다. 이 책의 권고는 다음과 같다. 분석법에 표시된 판단 기준값은 기기 또는 제품 설정에 보관하고, 로트 번호로 분석법을 명확히 식별하며, 판독 앱이 일반적인 값으로 대체하는 일이 절대 없게 한다. 둘째, v1.0은 정량 결과가 언제 borderline인지 정의하지 않는다. 제품이 이 값을 쓴다면 사용설명서에서 기준값 주변의 회색 구간을 정의하고, 앱은 정확히 그 정의를 구현해야 한다.

7.3 감염병 측방유동 검사

규격 §8.3은 측방유동 검사의 예로 두 가지를 든다. SARS-CoV-2 뉴클레오캡시드 항원 검사와, Plasmodium 젖산 탈수소효소(pLDH) 또는 히스티딘 풍부 단백질 2(HRP2)를 표적으로 하는 말라리아 검사이다. 측방유동 스트립에는 눈으로 보는 선을 숫자로 바꿔 주는 광학 판독기나 휴대전화 앱이 점점 더 많이 짝지어진다.

7.3.1 항원 검사와 분자 검사

PCR 같은 분자 검사는 표적 핵산을 증폭하므로 처음 존재하는 사본이 매우 적어도 검출할 수 있다. 측방유동 항원 검사에는 증폭 단계가 없다. 바이러스 단백질을 선 위에 포획하고 색 표지나 형광 표지로 보이게 할 뿐이다. 그 결과는 구조적이다. 항원 검사의 LOD는 분자 검사보다 몇 자릿수 높으며, 항원량이 많을 때 가장 신뢰할 수 있다. 규격에 있는 항원 검사 LOD(밀리리터당 바이러스 사본 수)와 임상 민감도·특이도 범위는 뒷받침하는 출처가 없으므로 여기서는 쓰지 않는다. 통합에서 중요한 것은 항원 검사 음성이 분자 검사 음성보다 무게가 가볍다는 점이며, 그래서 레코드에는 검사 방법이 반드시 적혀 있어야 한다.

7.3.2 말라리아 항원 검사

HRP2는 Plasmodium falciparum만 만든다. 반면 pLDH 검사는 사람에게 감염되는 모든 종을 검출하도록, 또는 특정 종만 검출하도록 설계할 수 있다. HRP2는 치료가 성공한 뒤에도 한동안 혈중에 남으므로 감염이 사라진 뒤에도 HRP2 검사가 양성으로 남을 수 있고, hrp2/hrp3 유전자가 결실된 원충은 위음성을 일으킬 수 있다. 규격은 목표 LOD 5–50 parasites/µL와 결과까지 15–20분을 제시한다. 통합의 교훈은 트로포닌과 같다. 결과의 임상적 의미가 표적에 달려 있으므로, analyte 문자열에는 정확한 표적(예: "P. falciparum HRP2" 또는 "pan-Plasmodium LDH")을 적어야 한다.

7.3.3 판독기에서 해석까지

측방유동 판독기는 검사선과 대조선의 세기를 측정한다. 흔히 쓰는 방법은 검사선 대 대조선(T/C) 비를 계산하여 제품 검증 때 정한 문턱값과 비교하는 것이다. 양성 문턱값을 옮기면 임상 민감도와 임상 특이도가 서로 맞바뀐다. 문턱값을 낮추면 진양성을 더 많이 잡는 대신 위양성도 늘어난다. 문턱값을 정확히 어디에 둘지는 임상 검증에서 결정할 문제이며(제8장), 데이터 표준이 정할 수 있는 것이 아니다. 통합에서 반드시 맞춰야 하는 것은 판독 결과를 interpretation 열거값과 QC 블록에 대응시키는 방식이며, 표 7.2에 정리하였다.

표 7.2 — 측방유동 판독 결과를 POCTestResult에 대응시키기(이 책의 권고)
판독 결과interpretationqualityControl.passed비고
대조선이 없거나 최소 세기에 못 미침indeterminatefalse무효 검사이다. 결과를 음성으로 표시해서는 절대 안 된다
대조선 유효, T/C가 하한 문턱값 미만negativetrue나중에 검토할 수 있도록 T/C 값을 value에 기록한다
대조선 유효, T/C가 두 문턱값 사이(제품이 회색 구간을 정의한 경우)indeterminatetrue재검 여부는 사용설명서가 정한다
대조선 유효, T/C가 양성 문턱값 이상positivetrue결과를 로트까지 추적할 수 있도록 로트와 판독기 일련번호를 남긴다
기기 또는 키트의 유효기간 경과보고하지 않음false판독 전에 거부한다. device.expirationDate 참조

판독기를 쓰는 말라리아 검사의 레코드는 다음과 같은 모습이 된다. T/C 값, 문턱값, 모든 식별자는 예시이며, 특히 기준값 0.10은 예시일 뿐 권장값이 아니다.

{
  "id": "POC-20260112-0042",
  "testType": "infectious-disease",
  "analyte": "P. falciparum HRP2",
  "value": 0.42,
  "unit": "T/C ratio",
  "interpretation": "positive",
  "cutoff": 0.10,
  "timestamp": "2026-01-12T06:41:18Z",
  "patient": { "id": "P-a81f07" },
  "qualityControl": { "passed": true, "flags": ["ok"] },
  "operator": "OP-017",
  "device": {
    "serialNumber": "RDR-00391",
    "lotNumber": "LOT-2511-B",
    "expirationDate": "2027-03-31T00:00:00Z"
  }
}

"T/C ratio"는 어떤 공식 단위 체계에도 속하지 않는 단위이며, 무차원 판독값일 뿐이다. 이런 레코드를 건강기록으로 내보낼 때(§7.6)는 정량 농도가 아니라, 비율을 보조 데이터로 곁들인 코드화된 정성 결과로 보내야 한다.

7.4 환경·식품 모니터링

규격 §8.4와 §10.3의 벤치마크 표는 표준의 범위를 진료 현장 밖으로 넓힌다. 수질 목표(E. coli LOD 1–10 CFU/100 mL, 중금속 1–100 ppb, 농약 0.1–10 ppb)와 식품 안전 목표(아플라톡신 LOD 0.1 ppb, 범위 0.1–100 ppb, 결과까지 5–10분)가 그것이다. 이 값들은 응용 부류에 대한 규격의 목표값이지 특정 기기의 성능이 아니다. 같은 절은 대기질 항목으로 CO, NO₂, O₃, 미세먼지, VOC도 나열한다. 이들은 보통 화학식 가스 센서나 광학식 입자 계수기로 측정하며, 생물학적 인식 요소가 없어 BiorecognitionElement 열거형 밖에 있다. 이 장은 이들을 다루지 않는다.

7.4.1 효소 저해를 이용한 농약 검출

유기인계와 카바메이트계 농약은 아세틸콜린에스테라제(AChE)를 저해하며, AChE는 SDK의 EnzymeType 목록에 'acetylcholinesterase'로 들어 있다. 저해형 바이오센서는 시료에 노출되기 전과 후의 효소 활성을 측정하고, 저해율을 I% = (A₀ − A)/A₀ × 100으로 보고한다. 여기서 A₀는 시료가 없을 때의 활성, A는 시료와 배양한 뒤의 활성이다. 이 원리에서 두 가지 특징이 나온다. 첫째, 센서는 특정 화합물 하나가 아니라 저해제 부류 전체에 반응하므로, 별도 방법으로 농약을 특정하지 않는 한 결과는 "AChE 저해 활성"(또는 기준 화합물 환산값)으로 보고해야 한다. 둘째, 오염이 심할수록 신호가 줄어든다. v1.0 measureAnalyte의 역산은 신호 대 농도의 직선 교정을 가정한다. 저해 교정은 제한된 범위 안에서만 그렇게 표현할 수 있으며, 기울기의 부호는 음이다.

실무상의 함정이 하나 있다. 'acetylcholinesterase'에는 "ase"라는 글자가 들어 있으므로, createSensor는 이런 센서에 기본 수명 180일과 측정 1,000회를 부여한다. 저해 센서는 일회용 스트립인 경우가 많고, 저해 화학 반응 상당수는 비가역적이다. 통합 담당자는 제품에 맞게 lifetime을 명시적으로 설정해야 한다.

7.4.2 중금속, 세균, 곰팡이독소

"ppb"는 뜻이 모호하므로 단위로 저장해서는 안 된다. 물에서는 보통 µg/L를, 고체 식품에서는 보통 µg/kg을 뜻하므로, 레코드에는 µg/L 또는 µg/kg을 명시해야 한다. 중금속 바이오센서(효소 저해형, DNA 기반, 전세포형)는 금속의 자유·생체이용 가능 분획에 반응하며, 이 분획은 pH, 경도, 유기물에 따라 달라진다. 따라서 총 금속량을 재는 실험실 방법과 값이 다른 데에는 정당한 이유가 있을 수 있다. 세균 표적은 집락형성단위(CFU)로 센다. 100 mL당 한 자릿수 CFU에 도달하려면 대개 시료를 먼저 농축해야 하며, 그 농축 단계는 방법 기술에 포함되어야 한다. 곡물의 아플라톡신은 오염이 로트 안에 고르지 않게 분포하므로, 센서 자체보다 시료 채취와 추출이 변동의 대부분을 차지하는 경우가 많다.

7.4.3 무인 현장 운용

강이나 처리장에 놓아 둔 센서는 벤치 프로토콜이 한 번도 만나지 않는 조건에 노출된다. 표 7.3은 주요 문제와 그것이 WIA 레코드에서 어떻게 나타나는지를 정리한다.

표 7.3 — 현장 배치의 문제와 WIA-BIO-011 v1.0에서의 표현
문제중요한 이유v1.0에서의 표현이 책의 권고
온도 변동README는 효소 센서에 ±1 °C 제어를 요구하지만, 현장 수온은 하루에도 그보다 훨씬 크게 변할 수 있다SDK는 25 °C로 보정하고 ±10 °C를 넘을 때만 플래그를 붙인다측정마다 온도를 기록하고, 검증된 보정을 적용하며, 검증 구간 밖의 값에는 플래그를 붙인다
생물 오손과 표면 오염침착물이 확산을 늦추어 며칠에 걸쳐 감도를 떨어뜨린다drift-detected 플래그는 있으나 SDK가 설정하는 일은 없다주기적인 점검 표준으로 드리프트를 검출하고 어댑터에서 플래그를 설정한다
무인 교정매일 5점 교정을 할 사람이 현장에 없다교정은 24시간 뒤 만료된다(BIO004)전체 교정 사이에 기기 내장 블랭크와 점검 표준을 쓰고, 각 점검을 QC 결과로 기록한다
간헐적 연결네트워크 없이 몇 시간을 버텨도 측정값이 보존되어야 한다BatchMeasurement가 결과를 startedAt/completedAt으로 묶는다로컬에 버퍼링하고 배치로 올리며, 재시도 사이에 ID를 유지한다(§7.5)

7.5 기기에서 클라우드까지의 아키텍처

분석물이 무엇이든 연결형 바이오센서 제품에는 같은 세 구간이 있다. 화학을 숫자로 바꾸는 판독기, 판독기 및 네트워크와 통신하는 게이트웨이(흔히 휴대전화), 그리고 레코드를 저장·분석·전달하는 서비스이다. 그림 7.1은 이 사슬과 각 경계를 넘는 WIA 레코드 타입을 보여 준다.

판독기 전위가변기 / 광학부 ADC, 필터 시계, 로트, 일련번호 게이트웨이 / 휴대전화 BiosensorSDK 플래그, 버퍼링 시각 동기화(UTC) 서비스 저장, QC 검토 감사 로그, 접근 통제 가명 대응표 건강기록 관찰(observation) 단위, 참고 범위 기기 식별 원신호, 온도 MeasurementResult, BatchMeasurement, TimeSeries POCTestResult, 변환된 관찰 그림 7.1 — 판독기 → 게이트웨이 → 서비스 → 건강기록(이 책의 권고)

7.5.1 판독기

판독기는 물리적인 것을 모두 담당한다. 전위가변기 또는 광학 전단부, 아날로그 필터, 그리고 규격 §2.1.4가 언급하는 12–24비트 해상도의 ADC이다. 판독기는 뒤 구간이 복원할 수 없는 정보도 함께 보내야 한다. 곧 원신호, 온도, 로트, 판독기 일련번호, 타임스탬프이다. 최종 농도만 내보내는 판독기로는 제6장의 잔차 분석과 드리프트 분석을 할 수 없다.

7.5.2 SDK가 실행되는 위치

BiosensorSDK는 센서와 측정 결과를 메모리 안의 Map 객체에 보관하는 TypeScript 클래스이다. 영속 저장도, 전송 기능도, 동시성 제어도 없다. 실제로는 게이트웨이 앱이나 서비스 워커에 두고, 실행할 때마다 저장소에서 센서와 현재 CalibrationData를 불러오고 끝나면 결과를 저장하는 코드로 감싸는 것이 알맞다. v1.0은 평균, 중앙값, 표준편차, CV, 최솟값, 최댓값을 담는 statistics 블록을 가진 BatchMeasurement 타입을 정의하지만, SDK에는 이를 만드는 메서드가 없다. 배치를 쓰는 통합 담당자는 통계를 직접 계산하고, 그 실행의 QualityControlResult 레코드를 배치에 붙여야 한다.

7.5.3 식별자, 시각, 재시도

SDK 식별자는 로컬 시계와 짧은 난수 문자열로 만들어진다(센서는 BS-<epoch>-<rand>, 측정은 M-<epoch>-<rand>). 한 프로세스 안에서는 충분하지만 기기 맥락은 전혀 담고 있지 않다. 연결형 제품에 대한 이 책의 권고는 다음과 같다.

7.5.4 배포 토폴로지

템플릿 파일 PHASE-4-INTEGRATION.md에는 네 가지 참조 토폴로지를 나열한 비규범적 부속서 J가 있다. 일반론이지만 표 7.4에서 보듯 바이오센서 제품에 잘 대응된다. 어느 것도 WIA-BIO-011의 요구사항은 아니다.

표 7.4 — 부속서 J 토폴로지를 바이오센서 제품에 적용한 예(비규범적)
토폴로지(부속서 J)형태바이오센서 예통합 시 유의점
단일 테넌트 엣지조직마다 런타임 하나, 공유 상태 없음병원 자체의 현장 혈당 측정기 군과 원내 데이터 관리 시스템검증이 가장 단순하다. 교정·QC 레코드를 그 조직이 소유한다
멀티 테넌트 게이트웨이공유 런타임 하나, 요청 헤더로 테넌트 격리여러 의원에서 CGM 데이터를 받는 제조사의 클라우드 서비스테넌트 격리가 가명 대응표와 감사 로그까지 미쳐야 한다
연합 메시공유 디렉터리에 게시하는 대등한 런타임들현장 센서 결과를 공유하는 지역 상수도 사업자 네트워크참여자 사이에서 결과를 비교하기 전에 단위와 QC 플래그를 맞춘다
망 분리 배치실시간 연결 없음, 배치를 대역 외로 운반통신이 닿지 않는 지역의 현장 말라리아 검사를 기기가 거점에 돌아왔을 때 업로드배치 ID, 기기 시계, 로트 정보가 감사 추적 전체를 떠맡는다

7.6 건강기록 통합

규격 §10.4와 README는 동반 표준으로 WIA-HEALTH(건강기록 통합)와 WIA-OMNI-API(범용 데이터 API)를 들지만, WIA-BIO-011 v1.0은 어느 쪽과의 대응도 정의하지 않는다. 따라서 이 절의 대응은 이 책의 해설이다. 여기서는 HL7 FHIR를 사용한다. FHIR의 Observation 리소스는 현재 건강기록 시스템에서 검사실·현장진단 결과를 받는 흔한 대상이고, 필드 단위로 대조할 수 있는 공개된 구조를 가지고 있기 때문이다.

7.6.1 필드 대응

표 7.5 — WIA 레코드를 HL7 FHIR Observation에 대응시키기(이 책의 권고)
WIA 필드Observation 요소설명
targetAnalyte / POCTestResult.analytecode자유 텍스트 분석물 이름으로는 부족하다. 검체와 방법에 맞춰 고른 LOINC 같은 용어 체계의 코드로 대응시킨다
concentration + concentrationUnit, 또는 value + unitvalueQuantityUCUM 단위 코드(mmol/L, mg/dL, ng/L, pg/mL)로 보낸다
interpretation(정성 검사)valueCodeableConcept 및/또는 interpretation양성/음성 결과는 수량이 아니라 코드값이다
referenceRange, cutoffreferenceRange단위를 포함하고, 범위가 어느 인구와 분석법에 적용되는지 밝힌다
timestampeffective[x]업로드 시각이 아니라 측정 시각이다
patient.id, metadata.patientIdsubject대응표를 보유한 조직 안에서만 가명을 실명으로 풀어 연결한다(§7.7)
device(일련번호, 로트, 유효기간), sensorIddevice 참조로트 번호가 있어야 로트 회수 때 영향받는 결과를 모두 찾을 수 있다
qualityFlags, qualityControlnote, statusQC에 불합격한 실행의 결과를 최종 관찰로 보내지 않는다

이렇게 대응시킨 혈당 측정기 결과는 아래 개요와 같다. LOINC 코드는 일부러 자리표시자로 남겨 두었다. 올바른 코드는 검체(모세혈관 혈액, 혈장, 간질액)와 방법에 따라 달라지며, 그 선택은 교과서가 아니라 제품의 용어 대응표가 맡을 일이다.

{
  "resourceType": "Observation",
  "status": "final",
  "code": {
    "coding": [{ "system": "http://loinc.org", "code": "<검체와 방법에 맞춰 고른 코드>" }],
    "text": "Glucose, capillary blood, meter"
  },
  "subject": { "reference": "Patient/<P-5c1e9b에서 풀어낸 값>" },
  "effectiveDateTime": "2026-01-05T07:32:10Z",
  "valueQuantity": {
    "value": 5.6, "unit": "mmol/L",
    "system": "http://unitsofmeasure.org", "code": "mmol/L"
  },
  "device": { "reference": "Device/<측정기 일련번호>" },
  "note": [{ "text": "WIA-BIO-011 qualityFlags: ok; calibration CAL-1767590400000" }]
}

7.6.2 단위와 환산

혈당은 여러 나라에서 mmol/L로, 다른 나라들에서는 mg/dL로 보고된다. 환산은 포도당의 몰질량 180.16 g/mol에서 나온다. 1 mmol/L = 18.016 mg/dL이며, 보통 ×18.0으로 반올림한다. 예를 들어 5.6 mmol/L는 약 101 mg/dL이고, 규격 §8.1의 측정 범위 상한 33.3 mmol/L는 600 mg/dL에 해당한다. 환산이 오류의 원천이 되지 않게 하는 규칙은 세 가지이다.

7.6.3 기기 측 표준

판독기와 게이트웨이 사이에서 개인용 건강기기는 자체 프로토콜보다 기존 상호운용 표준을 따르는 경우가 많다. ISO/IEEE 11073 개인 건강기기 계열(혈당 측정기 전문화 규격 ISO/IEEE 11073-10417 포함)과 Bluetooth SIG의 Glucose 프로파일 및 Continuous Glucose Monitoring 프로파일이 그 예이다. WIA-BIO-011은 이들을 참조하지 않으며 자체 전송 프로토콜도 정의하지 않는다(제6장에서 이 책의 "프로토콜"이 운영 프로토콜을 뜻하는 이유를 설명하였다). 원신호, 온도, 로트, 타임스탬프가 구간을 넘어 보존되기만 한다면 어느 것으로 데이터를 실어 보내도 된다.

7.7 보안과 개인정보 보호

바이오센서 결과는 건강 데이터이다. 유럽연합에서 건강에 관한 데이터는 GDPR상 특수 범주의 개인정보(제9조)이고, 미국에서는 적용 대상 기관과 그 업무 협력자가 다루는 식별 가능한 건강 정보가 HIPAA상 보호 대상 건강정보이다. WIA-BIO-011 v1.0은 자체 보안 요구사항을 정의하지 않는다. PHASE 템플릿 파일의 일반 문구는 저장 시 AES-256 암호화, 전송 시 TLS 1.3, 역할 기반 접근 통제, 다중 인증, 감사 로그를 나열한다. 이는 합리적인 기본 통제이며, 이 장은 이를 WIA-BIO-011 요구사항이 아니라 비규범적 맥락으로 다룬다.

7.7.1 데이터 모델 안의 가명 식별자

v1.0 타입은 환자 신원을 두 곳에 담는다. POCTestResult.patient(id와 선택적 age, sex)와 TimeSeries.metadata.patientId이다. 어느 필드도 어떤 종류의 식별자를 담는지 밝히지 않는다. 이 책의 권고는 다음과 같다. 이 자리에는 가명을 넣고 이름, 국가 식별번호, 의무기록 번호는 절대 넣지 않는다. 가명과 실제 신원을 잇는 대응표는 환자를 책임지는 조직 안의, 별도 접근 통제를 갖춘 저장소에 둔다. 가명처리된 데이터도 GDPR상 여전히 개인정보이므로, 이 방식은 위험을 줄일 뿐 레코드를 규제 범위 밖으로 빼내지는 못한다.

다른 필드도 개인정보가 될 수 있다. operator는 직원을 식별하고, 가정용 측정기의 일련번호는 그 소유자를 식별하며, 촘촘한 CGM TimeSeries는 식사, 수면, 운동을 드러낸다. 최소화는 레코드 전체에 적용된다. age와 sex는 해석에 필요할 때(예: 참고 범위가 이에 따라 달라질 때)만 보내고, 시계열은 받는 쪽의 용도가 실제로 요구하는 해상도로 내보낸다.

7.7.2 구간별 통제

표 7.6 — 기기에서 기록까지 이어지는 사슬의 기본 통제(비규범적)
구간주요 위험통제
판독기 ↔ 게이트웨이엉뚱한 기기와의 페어링, 주입되거나 재전송된 측정값인증된 페어링, 측정값별 일련번호, 미등록 일련번호 기기의 측정값 거부
게이트웨이 저장소분실하거나 함께 쓰는 휴대전화로 이력 노출저장 시 암호화(예: 플랫폼 키 저장소를 통한 AES-256), 아직 업로드하지 않은 데이터만 보관
게이트웨이 ↔ 서비스도청, 서비스 위장인증서 검증을 포함한 TLS 1.3, 토큰 기반 클라이언트 인증(예: OAuth 2.0)
서비스지나치게 넓은 직원 접근, 흔적 없는 수정최소 권한 RBAC, 직원 MFA, 조회·수정·재교정·QC 무시 결정을 기록하는 추가 전용 감사 로그
서비스 ↔ 건강기록환자 오연결, 잘못된 단위가명은 내보내는 경계에서만 풀고, 보내기 전에 UCUM 단위와 값 범위를 검증

감사 로그에 대해서는 바이오센서에 특유한 지적을 하나 덧붙인다. 분석 시스템에서 가장 파급이 큰 수정은 결과 변경이 아니라 교정, QC 승인, 로트 정보의 변경이다. 잘못된 교정 하나가 그 뒤의 모든 결과를 소리 없이 옮겨 놓기 때문이다. 따라서 감사 추적은 환자에게 보이는 결과만큼이나 CalibrationData와 QualityControlResult 레코드도 꼼꼼히 다루어야 한다.

7.8 통합 점검표

표 7.7은 이 장의 내용을 통합 팀이 첫 파일럿 전에 하나씩 확인할 수 있는 점검표로 압축한 것이다. 모든 행은 앞서 설명한 v1.0 동작 위에 세운 이 책의 권고이며, 시험 가능한 항목은 제8장에서 검증 증거로 바뀐다.

표 7.7 — 파일럿 전 통합 점검표
#점검 항목문제가 되는 곳
1lifetime을 제품의 표시 착용 기간 또는 유통기한으로 명시적으로 설정했는가CGM, AChE 스트립(기본값 180일)
2교정 유효기간이 SDK의 24시간이 아니라 제품의 교정 모델과 일치하는가CGM, 무인 현장 센서
3온도 보정의 기준이 교정 온도이고, 실제 온도가 저장되는가CGM, 현장 센서
4linearRange.min이 검증된 하한과 같아서, 낮은 결과가 below-lod로 잘못 표시되지 않는가포도당(저혈당), 미량 오염물질
5TimeSeriesPoint마다 플래그 하나를 고르는 심각도 순서가 문서화되어 있는가CGM 그래프
6분석법별 기준값을 제품 설정에 두고, 일반적인 값을 쓰지 않는가트로포닌, BNP, 측방유동
7무효 대조선이 QC 불합격과 함께 indeterminate로 대응되는가측방유동
8모든 레코드에 단위가 명시되고, 내보낼 때 UCUM을 쓰며, "ppb"나 비율을 단위로 내보내지 않는가전체
9재시도 사이에 ID가 유지되고, 타임스탬프가 UTC이며, 측정 시각과 수신 시각이 모두 저장되는가모든 연결형 제품
10WIA 레코드에는 가명만 있고, 대응표는 따로 보관되며, 감사 로그가 교정과 QC를 포함하는가모든 임상 제품

이제 센서는 판독기에서 건강기록까지 가는 길을 무사히 통과하는 레코드를 만든다. 남은 질문은 센서와 구현이 실제로 표준을 충족하며, 판매할 시장의 규제도 충족한다는 것을 어떻게 증명하느냐이다. 그것이 제8장의 주제이다.