ovok.measurements
Build, save and read measurements as FHIR Observations, with an offline queue.
- Stable unknown
- Release candidate since 0.4.49-rc.4
- Development since 0.4.49-dev.517+4645a0a
ovok.measurements turns a typed measurement into FHIR Observations, saves them safely and reads the latest values back. Patient apps call it for the signed-in user; a server machine client can call it with an explicit patientId.
Save a measurement
save builds the Observations and sends them as one conditional-create transaction, so a retry cannot duplicate a reading.
import { MeasurementTypeKey } from '@ovok/core';
const result = await ovok.measurements.save({
measurement: { measurementTypeKey: MeasurementTypeKey.heartRate, heartRate: 70 },
});
if (result.status === 'queued') {
console.log('Saved for later', result.queueId);
}- Without
patientId, the reading belongs to the signed-in profile. result.statusis'saved'(with the serverresponsebundle) or'queued'.buildreturns the Observations without saving.saveObservationssaves Observations you built yourself, main observation first.- If the server refuses or leaves out an observation, the save throws an
OvokErrorwith the refused status; see errors and retries. - Observations are
final, carry a FHIR category (vital-signs, orlaboratoryfor glucose and urine), code quantities in UCUM, and are dated by the measurement'srecordedAtunless you passeffectiveDateTime. - A reading of several observations (a blood pressure, a pulse oximeter reading, an ECG, a urine strip) ends with a group observation whose
hasMemberpoints at the others: a blood pressure's is the FHIR panel 85354-9 with the pressures as components, a urine strip's is 24357-6, and the rest use the code systemhttps://sdk.ovok.com/fhir/CodeSystem/measurement-type. The other observations keep their codes and links, andobservationsToMeasurementsreads either shape. Readings saved before groups existed get theirs fromscripts/backfill-reading-groups.mjs(a dry run unless--apply). - A measurement's
memorySlot(the monitor's user) is kept on its first observation. An ECG needs itsduration; without it the save throws.
Retry queued readings
A connection failure queues the reading in storage and returns { status: 'queued' }. Flush the queue when the device is back online.
const outcome = await ovok.measurements.offlineQueue.flush();
console.log(outcome.saved, outcome.queued, outcome.exhausted);- The queue only sends readings for the account that queued them.
- The default storage is in memory. Pass persistent
storageto the client to keep readings across restarts. flush({ includeExhausted: true })also retries readings that ran out of retries;resetExhausted: truegives them a fresh set first.
Save many readings at once
saveObservationGroups saves a monitor's stored readings in as few requests as fit. Each group is one reading with its main observation first.
await ovok.measurements.saveObservationGroups(groups, { identifierSystems: [APP_READING_SYSTEM] });- It is not queued offline.
- A request with one reading is a transaction, atomic when the project enables FHIR transactions. A request with several is sent as two batches, every main observation first, so a reading's other observations never point at one that wasn't saved. If it fails, some readings may already be saved; saving them again is safe.
- A main observation that matches several saved copies counts as saved.
- It stops, without sending the rest, if another account signs in between requests.
identifierSystemsnames the identifiers that make a reading unique;replace: trueoverwrites a reading saved under the same identifiers.
Read the latest readings
const codes = ovok.measurements.codesFor([MeasurementTypeKey.heartRate]);
const newest = await ovok.measurements.latest({ me: true, codes: codes.split(',') });
const bundle = await ovok.measurements.lastn(patientId, { code: codes, max: 50, _elements: 'code,effectiveDateTime' });latestreturns the newest observation per code for yourself (me: true) or a patient (me: falsewithpatientId).lastnreturns the newestmaxobservations per code in one$lastnrequest and passes other search parameters on.lastForPatientreadspatient/{patientId}/observation.
Measurement categories
MeasurementTypeKey has these keys: babySleep, bloodGlucose, bloodOxygenPulseRate, bloodPressure, bodyWeight, cosinussMultiParam, ecg, heartRate, heartRateVariability, lipidPanel, photoUpload, respiratoryRate, respiratoryTherapy, restingHeartRate, spirometryPanel, stepCount, symptomQuestionnaire, temperature, urineAnalysis, vo2Max, walkingHeartRateAverage and the deprecated uricAcid. The measurement type list gives each key's value, and the pages under measurements describe each type's fields.
Reference
- measurements API reference: every method and type.
- ovok.patient for reading a patient's saved records.
Last updated on