@ovok/core 0.4.9 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +34 -1
  2. package/dist/client/change-history/index.d.ts +2 -0
  3. package/dist/client/change-history/index.js +18 -0
  4. package/dist/client/change-history/methods.d.ts +4 -0
  5. package/dist/client/change-history/methods.js +25 -0
  6. package/dist/client/change-history/types.d.ts +34 -0
  7. package/dist/client/change-history/types.js +2 -0
  8. package/dist/client/consent/index.d.ts +2 -0
  9. package/dist/client/consent/index.js +18 -0
  10. package/dist/client/consent/methods.d.ts +6 -0
  11. package/dist/client/consent/methods.js +20 -0
  12. package/dist/client/consent/types.d.ts +26 -0
  13. package/dist/client/consent/types.js +7 -0
  14. package/dist/client/errors/ovok-error-utils.d.ts +10 -0
  15. package/dist/client/errors/ovok-error-utils.js +150 -0
  16. package/dist/client/errors/ovok-error.d.ts +16 -0
  17. package/dist/client/errors/ovok-error.js +67 -122
  18. package/dist/client/notifications/index.d.ts +2 -0
  19. package/dist/client/notifications/index.js +18 -0
  20. package/dist/client/notifications/methods.d.ts +7 -0
  21. package/dist/client/notifications/methods.js +29 -0
  22. package/dist/client/notifications/types.d.ts +90 -0
  23. package/dist/client/notifications/types.js +2 -0
  24. package/dist/client/observation/services/uric-acid-service.js +3 -0
  25. package/dist/client/observation/types/UrineAnalytes.d.ts +2 -2
  26. package/dist/client/observation/types/UrineAnalytes.js +22 -1
  27. package/dist/client/observation/types/measurement/UrineAnalyzeMeasurement.d.ts +3 -0
  28. package/dist/client/ovok-client.d.ts +4 -1
  29. package/dist/client/ovok-client.js +14 -2
  30. package/dist/client/signals/methods.d.ts +15 -1
  31. package/dist/client/signals/methods.js +36 -0
  32. package/dist/client/signals/types.d.ts +16 -0
  33. package/dist/client/slim/methods.d.ts +20 -8
  34. package/dist/client/slim/methods.js +34 -1
  35. package/dist/client/slim/types.d.ts +51 -1
  36. package/dist/conformance/api-requirements.js +25 -1
  37. package/dist/conformance/capability-requirements.js +1 -1
  38. package/dist/hooks/account-hooks.d.ts +19 -0
  39. package/dist/hooks/account-hooks.js +92 -0
  40. package/dist/hooks/api-hooks.d.ts +1 -0
  41. package/dist/hooks/api-hooks.js +1 -0
  42. package/dist/hooks/index.d.ts +2 -0
  43. package/dist/hooks/index.js +31 -2
  44. package/dist/hooks/notification-hooks.d.ts +32 -0
  45. package/dist/hooks/notification-hooks.js +144 -0
  46. package/dist/hooks/notification-invalidation.d.ts +3 -0
  47. package/dist/hooks/notification-invalidation.js +23 -0
  48. package/dist/hooks/signals-alert-hooks.js +2 -0
  49. package/dist/index.d.ts +3 -0
  50. package/dist/index.js +3 -0
  51. package/package.json +1 -1
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./methods"), exports);
18
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,7 @@
1
+ import { OvokClient } from "../ovok-client";
2
+ import { CreateNotificationNote, NotificationNote, NotificationNotes, NotificationTargetKind, UpdateNotificationNote } from "./types";
3
+ export declare function createNotificationNote(this: OvokClient, body: CreateNotificationNote): Promise<NotificationNote>;
4
+ export declare function listNotificationNotes(this: OvokClient, kind: NotificationTargetKind, id: string): Promise<NotificationNotes>;
5
+ export declare function updateNotificationNote(this: OvokClient, noteId: string, body: UpdateNotificationNote): Promise<NotificationNote>;
6
+ export declare function patchNotificationNote(this: OvokClient, noteId: string, body: UpdateNotificationNote): Promise<NotificationNote>;
7
+ export declare function deleteNotificationNote(this: OvokClient, noteId: string): Promise<void>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNotificationNote = createNotificationNote;
4
+ exports.listNotificationNotes = listNotificationNotes;
5
+ exports.updateNotificationNote = updateNotificationNote;
6
+ exports.patchNotificationNote = patchNotificationNote;
7
+ exports.deleteNotificationNote = deleteNotificationNote;
8
+ const segment = (value) => encodeURIComponent(value);
9
+ const TARGET_PATH = {
10
+ oob: "oob",
11
+ alarm: "alarms",
12
+ medical: "medical",
13
+ alert: "raw-alerts",
14
+ };
15
+ function createNotificationNote(body) {
16
+ return this.post("/v1/slim/notifications/notes", body);
17
+ }
18
+ function listNotificationNotes(kind, id) {
19
+ return this.get(`/v1/slim/notifications/${TARGET_PATH[kind]}/${segment(id)}/notes`);
20
+ }
21
+ function updateNotificationNote(noteId, body) {
22
+ return this.put(`/v1/slim/notifications/notes/${segment(noteId)}`, body);
23
+ }
24
+ function patchNotificationNote(noteId, body) {
25
+ return this.patch(`/v1/slim/notifications/notes/${segment(noteId)}`, body);
26
+ }
27
+ async function deleteNotificationNote(noteId) {
28
+ await this.delete(`/v1/slim/notifications/notes/${segment(noteId)}`);
29
+ }
@@ -0,0 +1,90 @@
1
+ import { SlimNotification } from "../slim/types";
2
+ export type NotificationTargetKind = "oob" | "alarm" | "medical" | "alert";
3
+ export type NotificationNote = {
4
+ id: string;
5
+ target: {
6
+ kind: NotificationTargetKind;
7
+ id: string;
8
+ };
9
+ patientId: string | null;
10
+ text: string;
11
+ author: {
12
+ practitionerId: string | null;
13
+ name: string | null;
14
+ };
15
+ createdAt: string | null;
16
+ updatedAt: string | null;
17
+ };
18
+ export type NotificationNotes = {
19
+ total: number;
20
+ resources: NotificationNote[];
21
+ };
22
+ export type CreateNotificationNote = {
23
+ kind: NotificationTargetKind;
24
+ id: string;
25
+ text: string;
26
+ };
27
+ export type UpdateNotificationNote = {
28
+ text: string;
29
+ };
30
+ export type SlimAlarmType = "deviceAlarm" | "attention";
31
+ export type SlimAlarmSeverity = "RED" | "YELLOW" | "ATTENTION";
32
+ export type SlimAlarmStatus = "active" | "completed";
33
+ export type SlimAlarm = SlimNotification & {
34
+ alarm: {
35
+ episodeId: string;
36
+ severity: SlimAlarmSeverity;
37
+ type: SlimAlarmType;
38
+ text: string;
39
+ };
40
+ noteCount: number | null;
41
+ };
42
+ export type SlimAlarmQuery = {
43
+ type?: SlimAlarmType | readonly SlimAlarmType[];
44
+ severity?: SlimAlarmSeverity | readonly SlimAlarmSeverity[];
45
+ status?: SlimAlarmStatus;
46
+ patient?: string;
47
+ device?: string;
48
+ startDate?: string;
49
+ endDate?: string;
50
+ page?: number;
51
+ count?: number;
52
+ sort?: "newest" | "oldest";
53
+ };
54
+ export type SlimAlarmsPage = {
55
+ total: number;
56
+ page: number;
57
+ count: number;
58
+ resources: SlimAlarm[];
59
+ };
60
+ export type SlimRecentAlarms = {
61
+ recent: Array<Omit<SlimAlarm, "noteCount"> & {
62
+ noteCount: null;
63
+ }>;
64
+ total: number;
65
+ warm: false;
66
+ source: "medplum";
67
+ };
68
+ export type SlimRecentOutOfBed = {
69
+ recent: Array<SlimNotification & {
70
+ noteCount: null;
71
+ }>;
72
+ total: number;
73
+ warm: boolean;
74
+ source: "redis" | "medplum";
75
+ };
76
+ export type SlimMedicalNotificationsQuery = {
77
+ status?: "OPEN" | "CLOSED";
78
+ since?: string;
79
+ acknowledged?: boolean;
80
+ patient?: string;
81
+ codes?: readonly string[];
82
+ limit?: number;
83
+ cursor?: string;
84
+ };
85
+ export type SlimMedicalNotificationsPage = {
86
+ items: Array<SlimNotification & {
87
+ noteCount: number | null;
88
+ }>;
89
+ nextCursor: string | null;
90
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -175,4 +175,7 @@ UricAcidService.THRESHOLDS = {
175
175
  leu: { min: 0, max: 25 },
176
176
  sg: { min: 1.003, max: 1.03 },
177
177
  vc: {}, // Skip vitamin C from problem count
178
+ mal: {}, // No BC401 problem-count threshold is defined for this analyte.
179
+ cr: {},
180
+ uca: {},
178
181
  };
@@ -1,4 +1,4 @@
1
- export type UrineAnalyteKey = "uro" | "bil" | "ket" | "glu" | "pro" | "ph" | "bld" | "nit" | "leu" | "sg" | "vc";
1
+ export type UrineAnalyteKey = "uro" | "bil" | "ket" | "glu" | "pro" | "ph" | "bld" | "nit" | "leu" | "sg" | "vc" | "mal" | "cr" | "uca";
2
2
  export type UrineAnalyteDefinition = {
3
3
  key: UrineAnalyteKey;
4
4
  code: string;
@@ -9,7 +9,7 @@ export type UrineAnalyteDefinition = {
9
9
  unitCode?: string;
10
10
  };
11
11
  /**
12
- * LOINC mappings for the eleven values returned by Contec's BC401 strip.
12
+ * LOINC mappings for the analytes returned by Contec's BC401 strips.
13
13
  * These are exported so Native declarations and consuming apps can describe
14
14
  * the same analytes without maintaining a second, drifting table.
15
15
  */
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.URINE_ANALYTE_DEFINITIONS = void 0;
4
4
  /**
5
- * LOINC mappings for the eleven values returned by Contec's BC401 strip.
5
+ * LOINC mappings for the analytes returned by Contec's BC401 strips.
6
6
  * These are exported so Native declarations and consuming apps can describe
7
7
  * the same analytes without maintaining a second, drifting table.
8
8
  */
@@ -71,4 +71,25 @@ exports.URINE_ANALYTE_DEFINITIONS = [
71
71
  unit: "mg/dL",
72
72
  unitCode: "mg/dL",
73
73
  },
74
+ {
75
+ key: "mal",
76
+ code: "14957-5",
77
+ display: "Microalbumin",
78
+ unit: "mg/dL",
79
+ unitCode: "mg/dL",
80
+ },
81
+ {
82
+ key: "cr",
83
+ code: "2161-8",
84
+ display: "Creatinine",
85
+ unit: "mg/dL",
86
+ unitCode: "mg/dL",
87
+ },
88
+ {
89
+ key: "uca",
90
+ code: "3086-6",
91
+ display: "Urate",
92
+ unit: "mg/dL",
93
+ unitCode: "mg/dL",
94
+ },
74
95
  ];
@@ -14,6 +14,9 @@ export type UrineAnalyzeMeasurement = Measurement & {
14
14
  leu?: number;
15
15
  sg?: number;
16
16
  vc?: number;
17
+ mal?: number;
18
+ cr?: number;
19
+ uca?: number;
17
20
  urineValues: UrineAnalysisValue[];
18
21
  /** Time at which the analyzer recorded the strip. */
19
22
  recordedAt?: Date;
@@ -4,11 +4,14 @@ import { OvokPublicApiEndpoint } from "../conformance/capability";
4
4
  import * as aiFhirMethods from "./ai-fhir/methods";
5
5
  import * as authMethods from "./auth/methods";
6
6
  import * as botMethods from "./bot/methods";
7
+ import * as changeHistoryMethods from "./change-history/methods";
7
8
  import * as aiMethods from "./chat/ai/methods";
8
9
  import * as cmsMethods from "./cms/methods";
10
+ import * as consentMethods from "./consent/methods";
9
11
  import * as emailMethods from "./email";
10
12
  import * as experienceMethods from "./experience/methods";
11
13
  import * as inviteMethods from "./invites/methods";
14
+ import * as notificationMethods from "./notifications/methods";
12
15
  import * as observationMethods from "./observation/methods";
13
16
  import { GenerateObservationBodyParams } from "./observation/types/generate-observation-body/GenerateObservationBodyParams";
14
17
  import { OfflineMeasurementFlushOptions, OfflineMeasurementFlushResult, OfflineMeasurementQueueOptions } from "./offline";
@@ -63,7 +66,7 @@ export declare class OvokClient extends MedplumClient {
63
66
  */
64
67
  getSubscriptionManager(): SubscriptionManager;
65
68
  }
66
- type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof slimMethods & typeof emailMethods & typeof cmsMethods & typeof platformMethods & typeof experienceMethods & typeof inviteMethods & typeof patientMethods & typeof patientSharingMethods & typeof signalsMethods;
69
+ type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof slimMethods & typeof emailMethods & typeof cmsMethods & typeof changeHistoryMethods & typeof consentMethods & typeof platformMethods & typeof experienceMethods & typeof inviteMethods & typeof notificationMethods & typeof patientMethods & typeof patientSharingMethods & typeof signalsMethods;
67
70
  type Omitted<T> = Omit<T, "executeBot">;
68
71
  declare module "./ovok-client" {
69
72
  interface OvokClient extends Omitted<Methods> {
@@ -40,12 +40,16 @@ const capability_1 = require("../conformance/capability");
40
40
  const aiFhirMethods = __importStar(require("./ai-fhir/methods"));
41
41
  const authMethods = __importStar(require("./auth/methods"));
42
42
  const botMethods = __importStar(require("./bot/methods"));
43
+ const changeHistoryMethods = __importStar(require("./change-history/methods"));
43
44
  const aiMethods = __importStar(require("./chat/ai/methods"));
44
45
  const cmsMethods = __importStar(require("./cms/methods"));
46
+ const consentMethods = __importStar(require("./consent/methods"));
45
47
  const emailMethods = __importStar(require("./email"));
48
+ const ovok_error_1 = require("./errors/ovok-error");
46
49
  const rate_limit_error_1 = require("./errors/rate-limit-error");
47
50
  const experienceMethods = __importStar(require("./experience/methods"));
48
51
  const inviteMethods = __importStar(require("./invites/methods"));
52
+ const notificationMethods = __importStar(require("./notifications/methods"));
49
53
  const observationMethods = __importStar(require("./observation/methods"));
50
54
  const observation_bundle_utils_1 = require("./observation/observation-bundle-utils");
51
55
  const offline_1 = require("./offline");
@@ -78,12 +82,20 @@ class OvokClient extends core_1.MedplumClient {
78
82
  this.bindMethods(slimMethods);
79
83
  this.bindMethods(emailMethods);
80
84
  this.bindMethods(cmsMethods);
85
+ this.bindMethods(changeHistoryMethods);
86
+ this.bindMethods(consentMethods);
81
87
  this.bindMethods(platformMethods);
82
88
  this.bindMethods(experienceMethods);
83
89
  this.bindMethods(inviteMethods);
90
+ this.bindMethods(notificationMethods, (error) => (0, ovok_error_1.mapOvokApiError)((0, rate_limit_error_1.mapRateLimitError)(error), { includeAccessErrors: true }));
84
91
  this.bindMethods(patientMethods);
85
92
  this.bindMethods(patientSharingMethods);
86
- this.bindMethods(signalsMethods, (error) => (0, errors_1.mapSignalsError)((0, rate_limit_error_1.mapRateLimitError)(error), { signalsRequest: true }));
93
+ this.bindMethods(signalsMethods, (error) => {
94
+ const mapped = (0, errors_1.mapSignalsError)((0, rate_limit_error_1.mapRateLimitError)(error), {
95
+ signalsRequest: true,
96
+ });
97
+ return (0, errors_1.isSignalsError)(mapped) ? mapped : (0, ovok_error_1.mapOvokApiError)(mapped);
98
+ });
87
99
  this.clientStorage = config.storage;
88
100
  this.offlineQueueOptions = (_b = config.offlineQueue) !== null && _b !== void 0 ? _b : {};
89
101
  }
@@ -150,7 +162,7 @@ class OvokClient extends core_1.MedplumClient {
150
162
  async executeObservationBundle(bundle) {
151
163
  return (0, observation_bundle_utils_1.executeObservationBundle)(bundle, (request) => this.executeBatch(request));
152
164
  }
153
- bindMethods(methods, mapError = rate_limit_error_1.mapRateLimitError) {
165
+ bindMethods(methods, mapError = (error) => (0, ovok_error_1.mapOvokApiError)((0, rate_limit_error_1.mapRateLimitError)(error))) {
154
166
  for (const [name, method] of Object.entries(methods)) {
155
167
  const boundMethod = method.bind(this);
156
168
  this[name] = async (...args) => {
@@ -1,5 +1,6 @@
1
+ import { NotificationNote, NotificationNotes, UpdateNotificationNote } from "../notifications/types";
1
2
  import { OvokClient } from "../ovok-client";
2
- import { EnableSignalsResponse, SetSignalsThresholdBody, SignalsAlert, SignalsAlertsPage, SignalsAlertsQuery, SignalsRawAlert, SignalsRawAlertsPage, SignalsRawAlertsQuery, SignalsSettingsPatch, SignalsSettingsResponse, SignalsThreshold, SignalsThresholds } from "./types";
3
+ import { EnableSignalsResponse, SetSignalsThresholdBody, SignalsAlert, SignalsAlertsPage, SignalsAlertsQuery, SignalsRawAlert, SignalsRawAlertsPage, SignalsRawAlertsQuery, SignalsSettingsPatch, SignalsSettingsResponse, SignalsThreshold, SignalsThresholds, UnconfirmedLimits, RepushUnconfirmedLimitsResult } from "./types";
3
4
  /**
4
5
  * Enables Signals for an existing patient. The operation is idempotent; retry after 409 or 503.
5
6
  * Observations saved through Ovok are forwarded by the backend, so callers should not submit
@@ -7,12 +8,25 @@ import { EnableSignalsResponse, SetSignalsThresholdBody, SignalsAlert, SignalsAl
7
8
  */
8
9
  export declare function enableSignalsForPatient(this: OvokClient, patientId: string): Promise<EnableSignalsResponse>;
9
10
  export declare function getSignalsThresholds(this: OvokClient, patientId: string): Promise<SignalsThresholds>;
11
+ export declare function listUnconfirmedLimits(this: OvokClient): Promise<UnconfirmedLimits>;
12
+ export declare function repushUnconfirmedLimits(this: OvokClient): Promise<RepushUnconfirmedLimitsResult>;
10
13
  export declare function setSignalsThreshold(this: OvokClient, patientId: string, code: string, body: SetSignalsThresholdBody): Promise<SignalsThreshold>;
11
14
  export declare function removeSignalsThreshold(this: OvokClient, patientId: string, code: string, reason: string): Promise<void>;
12
15
  export declare function serializeSignalsAlertsQuery(query?: SignalsAlertsQuery | SignalsRawAlertsQuery, keys?: readonly string[]): string;
13
16
  export declare function listSignalsAlerts(this: OvokClient, query?: SignalsAlertsQuery): Promise<SignalsAlertsPage>;
14
17
  export declare function getSignalsAlert(this: OvokClient, episodeId: string): Promise<SignalsAlert>;
15
18
  export declare function acknowledgeSignalsAlert(this: OvokClient, episodeId: string): Promise<SignalsAlert>;
19
+ export declare function listSignalsAlertNotes(this: OvokClient, episodeId: string): Promise<NotificationNotes>;
20
+ export declare function createSignalsAlertNote(this: OvokClient, episodeId: string, body: {
21
+ text: string;
22
+ }): Promise<NotificationNote>;
23
+ export declare function listSignalsRawAlertNotes(this: OvokClient, alertId: string): Promise<NotificationNotes>;
24
+ export declare function createSignalsRawAlertNote(this: OvokClient, alertId: string, body: {
25
+ text: string;
26
+ }): Promise<NotificationNote>;
27
+ export declare function updateSignalsNote(this: OvokClient, noteId: string, body: UpdateNotificationNote): Promise<NotificationNote>;
28
+ export declare function patchSignalsNote(this: OvokClient, noteId: string, body: UpdateNotificationNote): Promise<NotificationNote>;
29
+ export declare function deleteSignalsNote(this: OvokClient, noteId: string): Promise<void>;
16
30
  /**
17
31
  * The project's individual Signals alerts, not episodes: works whether or not the project's
18
32
  * `episodicAlerts` is on. `acknowledged: false` lists what is still open for the practitioner.
@@ -2,12 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enableSignalsForPatient = enableSignalsForPatient;
4
4
  exports.getSignalsThresholds = getSignalsThresholds;
5
+ exports.listUnconfirmedLimits = listUnconfirmedLimits;
6
+ exports.repushUnconfirmedLimits = repushUnconfirmedLimits;
5
7
  exports.setSignalsThreshold = setSignalsThreshold;
6
8
  exports.removeSignalsThreshold = removeSignalsThreshold;
7
9
  exports.serializeSignalsAlertsQuery = serializeSignalsAlertsQuery;
8
10
  exports.listSignalsAlerts = listSignalsAlerts;
9
11
  exports.getSignalsAlert = getSignalsAlert;
10
12
  exports.acknowledgeSignalsAlert = acknowledgeSignalsAlert;
13
+ exports.listSignalsAlertNotes = listSignalsAlertNotes;
14
+ exports.createSignalsAlertNote = createSignalsAlertNote;
15
+ exports.listSignalsRawAlertNotes = listSignalsRawAlertNotes;
16
+ exports.createSignalsRawAlertNote = createSignalsRawAlertNote;
17
+ exports.updateSignalsNote = updateSignalsNote;
18
+ exports.patchSignalsNote = patchSignalsNote;
19
+ exports.deleteSignalsNote = deleteSignalsNote;
11
20
  exports.listSignalsRawAlerts = listSignalsRawAlerts;
12
21
  exports.getSignalsRawAlert = getSignalsRawAlert;
13
22
  exports.acknowledgeSignalsRawAlert = acknowledgeSignalsRawAlert;
@@ -25,6 +34,12 @@ function enableSignalsForPatient(patientId) {
25
34
  function getSignalsThresholds(patientId) {
26
35
  return this.get(`/v1/signals/patients/${segment(patientId)}/thresholds`);
27
36
  }
37
+ function listUnconfirmedLimits() {
38
+ return this.get("/signals/config/unconfirmed");
39
+ }
40
+ function repushUnconfirmedLimits() {
41
+ return this.post("/signals/config/unconfirmed/repush");
42
+ }
28
43
  function setSignalsThreshold(patientId, code, body) {
29
44
  return this.put(`/v1/signals/patients/${segment(patientId)}/thresholds/${segment(code)}`, body);
30
45
  }
@@ -65,6 +80,27 @@ function getSignalsAlert(episodeId) {
65
80
  function acknowledgeSignalsAlert(episodeId) {
66
81
  return this.post(`/v1/signals/alerts/${segment(episodeId)}/ack`);
67
82
  }
83
+ function listSignalsAlertNotes(episodeId) {
84
+ return this.get(`/v1/signals/alerts/${segment(episodeId)}/notes`);
85
+ }
86
+ function createSignalsAlertNote(episodeId, body) {
87
+ return this.post(`/v1/signals/alerts/${segment(episodeId)}/notes`, body);
88
+ }
89
+ function listSignalsRawAlertNotes(alertId) {
90
+ return this.get(`/v1/signals/raw-alerts/${segment(alertId)}/notes`);
91
+ }
92
+ function createSignalsRawAlertNote(alertId, body) {
93
+ return this.post(`/v1/signals/raw-alerts/${segment(alertId)}/notes`, body);
94
+ }
95
+ function updateSignalsNote(noteId, body) {
96
+ return this.put(`/v1/signals/notes/${segment(noteId)}`, body);
97
+ }
98
+ function patchSignalsNote(noteId, body) {
99
+ return this.patch(`/v1/signals/notes/${segment(noteId)}`, body);
100
+ }
101
+ async function deleteSignalsNote(noteId) {
102
+ await this.delete(`/v1/signals/notes/${segment(noteId)}`);
103
+ }
68
104
  /**
69
105
  * The project's individual Signals alerts, not episodes: works whether or not the project's
70
106
  * `episodicAlerts` is on. `acknowledged: false` lists what is still open for the practitioner.
@@ -25,6 +25,7 @@ export type SignalsAlert = {
25
25
  signalsPatientId: string;
26
26
  code: string;
27
27
  status: SignalsAlertStatus;
28
+ noteCount: number | null;
28
29
  [key: string]: unknown;
29
30
  };
30
31
  export type SignalsAlertsQuery = {
@@ -82,6 +83,7 @@ export type SignalsRawAlert = {
82
83
  /** The Signals client that acknowledged it (Ovok's), not a person: use `acknowledgedActor`. */
83
84
  acknowledgedBy: string | null;
84
85
  acknowledgedActor: SignalsAcknowledgedActor | null;
86
+ noteCount: number | null;
85
87
  [key: string]: unknown;
86
88
  };
87
89
  export type SignalsRawAlertsQuery = {
@@ -118,6 +120,20 @@ export type SignalsSettings = {
118
120
  throttleLimit: number | null;
119
121
  };
120
122
  export type SignalsTenantKind = "project" | "shared";
123
+ export type UnconfirmedLimitResident = {
124
+ patientId: string;
125
+ since: string | null;
126
+ reason: string | null;
127
+ };
128
+ export type UnconfirmedLimits = {
129
+ count: number;
130
+ residents: UnconfirmedLimitResident[];
131
+ };
132
+ export type RepushUnconfirmedLimitsResult = {
133
+ patients: number;
134
+ unconfirmed: number;
135
+ reason: string | null;
136
+ };
121
137
  export type SignalsSettingsResponse = {
122
138
  tenant: SignalsTenantKind;
123
139
  settings: SignalsSettings;
@@ -1,6 +1,7 @@
1
1
  import { Bundle, Resource } from "@medplum/fhirtypes";
2
+ import { SlimAlarmQuery, SlimAlarmsPage, SlimMedicalNotificationsPage, SlimMedicalNotificationsQuery, SlimRecentAlarms, SlimRecentOutOfBed } from "../notifications/types";
2
3
  import { OvokClient } from "../ovok-client";
3
- import { SlimAssignDevice, SlimCreateDevice, SlimCreateLocation, SlimCreatePatient, SlimDevice, SlimDeviceListItem, SlimDeviceListQuery, SlimDeviceTelemetry, SlimExportPdf, SlimExportPdfRequest, SlimLiveQuery, SlimLiveTelemetry, SlimLocation, SlimLocationQuery, SlimNotification, SlimNotificationsQuery, SlimNotificationsResponse, SlimObservationIds, SlimPage, SlimPatient, SlimPatientListItem, SlimPatientListQuery, SlimRecentNotificationsResponse, SlimSleepStatistics, SlimThreshold, SlimTrends, SlimUpdateDevice, SlimUpdateLocation, SlimUpdatePatient, SlimZone, SlimZoneDetail } from "./types";
4
+ import { SlimAssignDevice, SlimCreateDevice, SlimCreateLocation, SlimCreatePatient, SlimDevice, SlimDeviceListItem, SlimDeviceListQuery, SlimDeviceTelemetry, SlimExportPdf, SlimExportPdfRequest, SlimLiveQuery, SlimLiveTelemetry, SlimLocation, SlimLocationQuery, SlimNotification, SlimNotificationsQuery, SlimNotificationsResponse, SlimObservationIds, SlimPage, SlimPatient, SlimPatientListItem, SlimPatientListQuery, SlimRecentNotificationsResponse, SlimSleepStatistics, SlimThreshold, SlimThresholdSettingsUpdateV1, SlimThresholdV2, SlimThresholdV2Update, SlimPatientThresholdV2, SlimTrends, SlimUpdateDevice, SlimUpdateLocation, SlimUpdatePatient, SlimZone, SlimZoneDetail } from "./types";
4
5
  export declare function listSlimPatients(this: OvokClient, params?: SlimPatientListQuery): Promise<SlimPage<SlimPatientListItem>>;
5
6
  export declare function getSlimPatient(this: OvokClient, patientId: string): Promise<SlimPatient>;
6
7
  export declare function getSlimPatientEverything(this: OvokClient, patientId: string): Promise<Bundle<Resource>>;
@@ -22,22 +23,33 @@ export declare function listSlimEffectiveObservationIds(this: OvokClient): Promi
22
23
  export declare function listSlimLastObservationIds(this: OvokClient): Promise<Record<string, SlimObservationIds>>;
23
24
  export declare function getSlimDeviceEffectiveObservationIds(this: OvokClient, deviceId: string): Promise<Omit<SlimObservationIds, "batch">>;
24
25
  export declare function getSlimDeviceLastObservationIds(this: OvokClient, deviceId: string): Promise<SlimObservationIds>;
26
+ /** @deprecated Use listSlimOutOfBedNotifications, listSlimAlarms, or listSlimMedicalNotifications. */
25
27
  export declare function listSlimNotifications(this: OvokClient, params?: SlimNotificationsQuery): Promise<SlimNotificationsResponse>;
26
28
  export declare function getRecentSlimNotifications(this: OvokClient, count?: number): Promise<SlimRecentNotificationsResponse>;
29
+ export declare function listSlimAlarms(this: OvokClient, params?: SlimAlarmQuery): Promise<SlimAlarmsPage>;
30
+ export declare function acknowledgeSlimAlarm(this: OvokClient, notificationId: string): Promise<SlimNotification>;
31
+ export declare function getRecentSlimAlarms(this: OvokClient, count?: number): Promise<SlimRecentAlarms>;
32
+ export declare function getRecentAlarms(this: OvokClient, count?: number): Promise<SlimRecentAlarms>;
33
+ export declare function getRecentSlimOutOfBed(this: OvokClient, count?: number): Promise<SlimRecentOutOfBed>;
34
+ export declare function getRecentOutOfBed(this: OvokClient, count?: number): Promise<SlimRecentOutOfBed>;
27
35
  export declare function listSlimOutOfBedNotifications(this: OvokClient, params?: Omit<SlimNotificationsQuery, "type">): Promise<SlimNotificationsResponse>;
28
- export declare function listSlimMedicalNotifications(this: OvokClient, params?: SlimNotificationsQuery): Promise<SlimNotificationsResponse>;
36
+ export declare function listSlimMedicalNotifications(this: OvokClient, params?: SlimMedicalNotificationsQuery): Promise<SlimMedicalNotificationsPage>;
29
37
  export declare function getRecentSlimMedicalNotifications(this: OvokClient, count?: number): Promise<SlimRecentNotificationsResponse>;
30
38
  export declare function getSlimMedicalNotification(this: OvokClient, episodeId: string): Promise<SlimNotification>;
31
39
  export declare function acknowledgeSlimMedicalNotification(this: OvokClient, episodeId: string): Promise<SlimNotification>;
32
40
  export declare function acknowledgeSlimNotification(this: OvokClient, notificationId: string): Promise<SlimNotification>;
33
41
  export declare function getSlimThreshold(this: OvokClient): Promise<SlimThreshold>;
34
- export declare function updateSlimThreshold(this: OvokClient, body: Record<string, unknown>): Promise<SlimThreshold>;
42
+ export declare function updateSlimThreshold(this: OvokClient, body: {
43
+ settings: SlimThresholdSettingsUpdateV1;
44
+ }): Promise<SlimThreshold>;
35
45
  export declare function getSlimPatientThreshold(this: OvokClient, patientId: string): Promise<Record<string, unknown>>;
36
- export declare function updateSlimPatientThreshold(this: OvokClient, patientId: string, body: Record<string, unknown>): Promise<Record<string, unknown>>;
37
- export declare function getSlimThresholdV2(this: OvokClient): Promise<Record<string, unknown>>;
38
- export declare function updateSlimThresholdV2(this: OvokClient, body: Record<string, unknown>): Promise<Record<string, unknown>>;
39
- export declare function getSlimPatientThresholdV2(this: OvokClient, patientId: string): Promise<Record<string, unknown>>;
40
- export declare function updateSlimPatientThresholdV2(this: OvokClient, patientId: string, body: Record<string, unknown>): Promise<Record<string, unknown>>;
46
+ export declare function updateSlimPatientThreshold(this: OvokClient, patientId: string, body: {
47
+ settings: SlimThresholdSettingsUpdateV1;
48
+ }): Promise<Record<string, unknown>>;
49
+ export declare function getSlimThresholdV2(this: OvokClient): Promise<SlimThresholdV2>;
50
+ export declare function updateSlimThresholdV2(this: OvokClient, body: SlimThresholdV2Update): Promise<SlimThresholdV2>;
51
+ export declare function getSlimPatientThresholdV2(this: OvokClient, patientId: string): Promise<SlimPatientThresholdV2>;
52
+ export declare function updateSlimPatientThresholdV2(this: OvokClient, patientId: string, body: SlimThresholdV2Update): Promise<SlimPatientThresholdV2>;
41
53
  export declare function getSlimTrends(this: OvokClient, params: {
42
54
  patientId: string;
43
55
  startDate: string;
@@ -23,6 +23,12 @@ exports.getSlimDeviceEffectiveObservationIds = getSlimDeviceEffectiveObservation
23
23
  exports.getSlimDeviceLastObservationIds = getSlimDeviceLastObservationIds;
24
24
  exports.listSlimNotifications = listSlimNotifications;
25
25
  exports.getRecentSlimNotifications = getRecentSlimNotifications;
26
+ exports.listSlimAlarms = listSlimAlarms;
27
+ exports.acknowledgeSlimAlarm = acknowledgeSlimAlarm;
28
+ exports.getRecentSlimAlarms = getRecentSlimAlarms;
29
+ exports.getRecentAlarms = getRecentAlarms;
30
+ exports.getRecentSlimOutOfBed = getRecentSlimOutOfBed;
31
+ exports.getRecentOutOfBed = getRecentOutOfBed;
26
32
  exports.listSlimOutOfBedNotifications = listSlimOutOfBedNotifications;
27
33
  exports.listSlimMedicalNotifications = listSlimMedicalNotifications;
28
34
  exports.getRecentSlimMedicalNotifications = getRecentSlimMedicalNotifications;
@@ -52,7 +58,7 @@ const query = (params) => {
52
58
  const values = new URLSearchParams();
53
59
  for (const [key, value] of Object.entries(params)) {
54
60
  if (value !== undefined) {
55
- values.set(key, String(value));
61
+ values.set(key, Array.isArray(value) ? value.join(",") : String(value));
56
62
  }
57
63
  }
58
64
  const encoded = values.toString();
@@ -122,18 +128,45 @@ async function getSlimDeviceEffectiveObservationIds(deviceId) {
122
128
  async function getSlimDeviceLastObservationIds(deviceId) {
123
129
  return this.get(`/v1/slim/telemetry/${segment(deviceId)}/lastIds`);
124
130
  }
131
+ /** @deprecated Use listSlimOutOfBedNotifications, listSlimAlarms, or listSlimMedicalNotifications. */
125
132
  async function listSlimNotifications(params = {}) {
126
133
  return this.get(`/v1/slim/notifications${query(params)}`);
127
134
  }
128
135
  async function getRecentSlimNotifications(count) {
129
136
  return this.get(`/v1/slim/notifications/recent${query({ count })}`);
130
137
  }
138
+ async function listSlimAlarms(params = {}) {
139
+ return this.get(`/v1/slim/notifications/alarms${query(params)}`);
140
+ }
141
+ async function acknowledgeSlimAlarm(notificationId) {
142
+ return (await this.patch(`/v1/slim/notifications/${segment(notificationId)}/ack`, []));
143
+ }
144
+ async function getRecentSlimAlarms(count) {
145
+ return this.get(`/v1/slim/notifications/recent/alarms${query({ count })}`);
146
+ }
147
+ function getRecentAlarms(count) {
148
+ return getRecentSlimAlarms.call(this, count);
149
+ }
150
+ async function getRecentSlimOutOfBed(count) {
151
+ return this.get(`/v1/slim/notifications/recent/oob${query({ count })}`);
152
+ }
153
+ function getRecentOutOfBed(count) {
154
+ return getRecentSlimOutOfBed.call(this, count);
155
+ }
131
156
  async function listSlimOutOfBedNotifications(params = {}) {
132
157
  return this.get(`/v1/slim/notifications/oob${query(params)}`);
133
158
  }
134
159
  async function listSlimMedicalNotifications(params = {}) {
160
+ validateMedicalCodes(params.codes);
135
161
  return this.get(`/v1/slim/notifications/medical${query(params)}`);
136
162
  }
163
+ const MEDICAL_CODE = /^(?:\d{1,7}-\d|PI)$/;
164
+ function validateMedicalCodes(codes) {
165
+ if (codes !== undefined &&
166
+ (codes.length === 0 || codes.length > 32 || codes.some((code) => !MEDICAL_CODE.test(code)))) {
167
+ throw new TypeError("codes must contain at most 32 valid LOINC codes or PI.");
168
+ }
169
+ }
137
170
  async function getRecentSlimMedicalNotifications(count) {
138
171
  return this.get(`/v1/slim/notifications/recent/medical${query({ count })}`);
139
172
  }
@@ -172,6 +172,7 @@ export type SlimNotification = {
172
172
  status: string;
173
173
  authoredOn: string;
174
174
  type: string;
175
+ noteCount: number | null;
175
176
  [key: string]: unknown;
176
177
  };
177
178
  export type SlimNotificationsQuery = {
@@ -202,7 +203,56 @@ export type SlimThreshold = {
202
203
  projectId?: string;
203
204
  status: "active" | "retired";
204
205
  date?: string;
205
- settings: Record<string, unknown>;
206
+ settings: Record<string, SlimThresholdSettingV1>;
207
+ };
208
+ export type SlimThresholdModeV1 = "organization" | "patient";
209
+ export type SlimThresholdReadableModeV1 = SlimThresholdModeV1 | "patient-auto";
210
+ export type SlimThresholdSettingV1 = {
211
+ mode?: SlimThresholdReadableModeV1;
212
+ relative?: {
213
+ enabled: boolean;
214
+ [key: string]: unknown;
215
+ };
216
+ [key: string]: unknown;
217
+ };
218
+ export type SlimThresholdSettingUpdateV1 = Omit<SlimThresholdSettingV1, "mode"> & {
219
+ mode?: SlimThresholdModeV1;
220
+ };
221
+ export type SlimThresholdSettingsUpdateV1 = Record<string, SlimThresholdSettingUpdateV1>;
222
+ export type SlimThresholdV2Setting = {
223
+ mode: string;
224
+ deviationPercent: number | null;
225
+ baselineAverage: number | null;
226
+ effectiveBand: {
227
+ min: number;
228
+ max: number;
229
+ } | null;
230
+ [key: string]: unknown;
231
+ };
232
+ export type SignalsSyncStatus = {
233
+ status: "ok";
234
+ } | {
235
+ status: "pending";
236
+ reason: string;
237
+ } | {
238
+ status: "unverified";
239
+ reason: string;
240
+ } | null;
241
+ export type SlimThresholdV2 = {
242
+ id?: string;
243
+ projectId?: string;
244
+ status?: "active" | "retired";
245
+ date?: string;
246
+ settings: Record<string, SlimThresholdV2Setting>;
247
+ };
248
+ export type SlimPatientThresholdV2 = {
249
+ patientId: string;
250
+ settings: Record<string, SlimThresholdV2Setting>;
251
+ signalsSync: SignalsSyncStatus;
252
+ [key: string]: unknown;
253
+ };
254
+ export type SlimThresholdV2Update = {
255
+ settings: Record<string, Partial<SlimThresholdV2Setting>>;
206
256
  };
207
257
  export type SlimTrendPoint = {
208
258
  timestamp: string;