@hipnation-truth/sdk 0.15.3 → 0.16.1
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.
- package/dist/index.d.mts +90 -2
- package/dist/index.d.ts +90 -2
- package/dist/index.js +121 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +120 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.ts +1437 -33
- package/dist/react.js +191 -17
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { ConvexReactClient } from 'convex/react';
|
|
4
|
+
import * as convex_browser from 'convex/browser';
|
|
5
|
+
import { ConvexHttpClient } from 'convex/browser';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* React hooks for Truth SDK — reactive conversation + message data.
|
|
@@ -437,7 +439,7 @@ declare function useAppointment(id: string): any;
|
|
|
437
439
|
* Subscribe to an appointment by its Elation ID.
|
|
438
440
|
*/
|
|
439
441
|
declare function useAppointmentByElationId(elationId: string): any;
|
|
440
|
-
interface Physician {
|
|
442
|
+
interface Physician$1 {
|
|
441
443
|
_id: string;
|
|
442
444
|
elationId: number;
|
|
443
445
|
firstName?: string;
|
|
@@ -666,6 +668,277 @@ interface UseNotificationsResult {
|
|
|
666
668
|
}
|
|
667
669
|
declare function useNotifications(options: UseNotificationsOptions): UseNotificationsResult;
|
|
668
670
|
|
|
671
|
+
/**
|
|
672
|
+
* React hook for patient family-member lookup — Truth SDK.
|
|
673
|
+
*
|
|
674
|
+
* Replaces the CommHub Hasura `useFamilyMembersQuery` (backed by
|
|
675
|
+
* `queries/family_members.graphql`). Queries the Convex
|
|
676
|
+
* `patients:listFamilyMembers` function, which returns the set of
|
|
677
|
+
* patients that share a `familyId` OR share at least one phone number
|
|
678
|
+
* with the reference patient, excluding the reference patient themselves.
|
|
679
|
+
*
|
|
680
|
+
* Arguments mirror the Hasura `FamilyMembers` GraphQL query variables:
|
|
681
|
+
* - `familyId` → `$familyId` (Hint family/account id)
|
|
682
|
+
* - `phoneNumbers` → `$phoneNumbers` (patient's phone numbers)
|
|
683
|
+
* - `excludeHintId` → `$excludePatientId` (skip the reference patient)
|
|
684
|
+
*
|
|
685
|
+
* Must be used within a `<TruthProvider />`.
|
|
686
|
+
*
|
|
687
|
+
* @example
|
|
688
|
+
* ```tsx
|
|
689
|
+
* import { usePatientFamilyMembers } from '@hipnation-truth/sdk/react/patient-family';
|
|
690
|
+
*
|
|
691
|
+
* function FamilyPanel({ hintId, familyId, phones }: Props) {
|
|
692
|
+
* const { data: members, loading } = usePatientFamilyMembers({
|
|
693
|
+
* familyId,
|
|
694
|
+
* phoneNumbers: phones,
|
|
695
|
+
* excludeHintId: hintId,
|
|
696
|
+
* });
|
|
697
|
+
* if (loading) return <Spinner />;
|
|
698
|
+
* return members?.map((m) => <div key={m._id}>{m.firstName} {m.lastName}</div>);
|
|
699
|
+
* }
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Shape of a single patient row returned by `patients:listFamilyMembers`.
|
|
705
|
+
* Mirrors the fields CommHub's `FamilyMembersQuery` selected from Hasura:
|
|
706
|
+
* - `id` → `_id` (Convex document id)
|
|
707
|
+
* - `name` → `firstName + " " + lastName`
|
|
708
|
+
* - `hint_id` → `hintId`
|
|
709
|
+
* - `elation_id` → `elationId`
|
|
710
|
+
* - `family_id` → `familyId`
|
|
711
|
+
* - `phone_numbers` → `phones[].number`
|
|
712
|
+
*/
|
|
713
|
+
interface FamilyMemberRow {
|
|
714
|
+
_id: string;
|
|
715
|
+
_creationTime: number;
|
|
716
|
+
firstName: string;
|
|
717
|
+
lastName: string;
|
|
718
|
+
elationId?: string;
|
|
719
|
+
hintId?: string;
|
|
720
|
+
familyId?: string;
|
|
721
|
+
phones: Array<{
|
|
722
|
+
type?: string;
|
|
723
|
+
number: string;
|
|
724
|
+
}>;
|
|
725
|
+
membershipStatus?: string;
|
|
726
|
+
sources: string[];
|
|
727
|
+
lastSyncedAt: string;
|
|
728
|
+
}
|
|
729
|
+
/** Arguments for `usePatientFamilyMembers`. */
|
|
730
|
+
interface UsePatientFamilyMembersInput {
|
|
731
|
+
/**
|
|
732
|
+
* Hint family/account id — when present, all patients sharing this id
|
|
733
|
+
* are returned (matches the Hasura `family_id` column).
|
|
734
|
+
*
|
|
735
|
+
* BACKFILL NEEDED: `familyId` was added to the Convex `patients` schema
|
|
736
|
+
* in this PR. Existing patient rows will return empty for this branch
|
|
737
|
+
* until the Hint patient upsert path (upsertFromHint / basic-refresh)
|
|
738
|
+
* is updated to write this field, or a one-time backfill script runs.
|
|
739
|
+
* The phone-number fallback continues to work in the interim.
|
|
740
|
+
*/
|
|
741
|
+
familyId?: string | null;
|
|
742
|
+
/**
|
|
743
|
+
* Patient's phone numbers — patients sharing at least one phone number
|
|
744
|
+
* are included as family members (mirrors Hasura `phone_numbers._overlap`).
|
|
745
|
+
*/
|
|
746
|
+
phoneNumbers?: string[] | null;
|
|
747
|
+
/**
|
|
748
|
+
* Hint patient ID of the reference patient to exclude from results
|
|
749
|
+
* (mirrors Hasura `$excludePatientId`).
|
|
750
|
+
*/
|
|
751
|
+
excludeHintId?: string | null;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Subscribe to family members of a patient in real time.
|
|
755
|
+
*
|
|
756
|
+
* Returns all patients that share the same `familyId` OR share at least one
|
|
757
|
+
* phone number with the reference patient, sorted by name. The reference
|
|
758
|
+
* patient is excluded via `excludeHintId`.
|
|
759
|
+
*
|
|
760
|
+
* Pass `undefined` (or an object where all fields are undefined/null) to
|
|
761
|
+
* skip the query — returns `{ data: undefined, loading: false }`.
|
|
762
|
+
*
|
|
763
|
+
* @param input - Query inputs. The query is skipped if `input` is undefined
|
|
764
|
+
* or all fields are falsy.
|
|
765
|
+
*/
|
|
766
|
+
declare function usePatientFamilyMembers(input: UsePatientFamilyMembersInput | undefined): UseQueryResult<FamilyMemberRow[]>;
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* React hook for Truth SDK — reactive patient search.
|
|
770
|
+
*
|
|
771
|
+
* Wraps the `patients:search` Convex query so CommHub consumers
|
|
772
|
+
* (and other frontends) can search patients by name, phone, or email
|
|
773
|
+
* with live-updating results and optional office scoping, without
|
|
774
|
+
* managing Convex subscriptions themselves.
|
|
775
|
+
*
|
|
776
|
+
* **Hook contract:** returns `UseQueryResult<PatientSearchResult[]>`.
|
|
777
|
+
* - `data` is `undefined` while loading or when the query is skipped
|
|
778
|
+
* (empty `query` string or `query === undefined`).
|
|
779
|
+
* - `loading` is `true` only while a real subscription is in-flight.
|
|
780
|
+
* - `error` is reserved for SDK-side validation; Convex query errors
|
|
781
|
+
* propagate as React errors and should be caught with an error
|
|
782
|
+
* boundary.
|
|
783
|
+
*
|
|
784
|
+
* **Backed by `patients:search`** — added in agent-A-search.
|
|
785
|
+
* Multi-word queries split on whitespace; every token must match at
|
|
786
|
+
* least one of firstName / lastName / email / phone digits.
|
|
787
|
+
*
|
|
788
|
+
* Must be used within `<TruthProvider />` (see `./provider`).
|
|
789
|
+
*
|
|
790
|
+
* @example
|
|
791
|
+
* ```tsx
|
|
792
|
+
* import { usePatientSearch } from '@hipnation-truth/sdk/react/patient-search';
|
|
793
|
+
*
|
|
794
|
+
* function PatientPicker({ officeId }: { officeId?: string }) {
|
|
795
|
+
* const [query, setQuery] = useState('');
|
|
796
|
+
* const { data: patients, loading } = usePatientSearch({ query, officeId });
|
|
797
|
+
* return (
|
|
798
|
+
* <>
|
|
799
|
+
* <input value={query} onChange={e => setQuery(e.target.value)} />
|
|
800
|
+
* {loading && <Spinner />}
|
|
801
|
+
* {patients?.map(p => <PatientRow key={p.id} patient={p} />)}
|
|
802
|
+
* </>
|
|
803
|
+
* );
|
|
804
|
+
* }
|
|
805
|
+
* ```
|
|
806
|
+
*/
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* A single patient result from `patients:search`.
|
|
810
|
+
*
|
|
811
|
+
* Fields are normalised across the `patients` + `hintPatients` tables
|
|
812
|
+
* so callers get a flat, consistent object regardless of which source
|
|
813
|
+
* contributed the match.
|
|
814
|
+
*/
|
|
815
|
+
interface PatientSearchResult {
|
|
816
|
+
/** Convex `_id` of the matching `patients` or `hintPatients` row. */
|
|
817
|
+
id: string;
|
|
818
|
+
/** Hint patient id — present when the row originates from Hint. */
|
|
819
|
+
hintId: string | undefined;
|
|
820
|
+
firstName: string;
|
|
821
|
+
lastName: string;
|
|
822
|
+
/** ISO date string (YYYY-MM-DD) — undefined when not available. */
|
|
823
|
+
dob: string | undefined;
|
|
824
|
+
/** Email addresses associated with the patient. */
|
|
825
|
+
emails: string[];
|
|
826
|
+
/**
|
|
827
|
+
* Raw phone strings from the source table. Callers should
|
|
828
|
+
* strip non-digits for dialling; the first entry is the primary
|
|
829
|
+
* contact number.
|
|
830
|
+
*/
|
|
831
|
+
phones: string[];
|
|
832
|
+
/** Hint office id — present for Hint-sourced results. */
|
|
833
|
+
officeId: string | undefined;
|
|
834
|
+
/** Human-readable office name — present when officeId is set. */
|
|
835
|
+
officeName: string | undefined;
|
|
836
|
+
}
|
|
837
|
+
interface UsePatientSearchOptions {
|
|
838
|
+
/**
|
|
839
|
+
* The search term entered by the user. Multi-word queries are split
|
|
840
|
+
* on whitespace and every token must match. Pass `""` or `undefined`
|
|
841
|
+
* to skip the query and get `{ data: undefined, loading: false }`.
|
|
842
|
+
*/
|
|
843
|
+
query: string | undefined;
|
|
844
|
+
/**
|
|
845
|
+
* When supplied, restricts results to patients whose authoritative
|
|
846
|
+
* Hint office id matches. Maps to the `officeId` arg on the Convex
|
|
847
|
+
* query and uses the `hintPatients.by_officeId` index path.
|
|
848
|
+
*/
|
|
849
|
+
officeId?: string | null;
|
|
850
|
+
/**
|
|
851
|
+
* `"fuzzy"` (default) uses Convex full-text search indexes for name
|
|
852
|
+
* queries; `"exact"` uses a bounded scan-filter only. Most callers
|
|
853
|
+
* should leave this at the default.
|
|
854
|
+
*/
|
|
855
|
+
mode?: "fuzzy" | "exact";
|
|
856
|
+
/** Maximum number of results to return (server caps at 200). */
|
|
857
|
+
limit?: number;
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Subscribe to a live patient search backed by `patients:search` on the
|
|
861
|
+
* Truth Convex deployment.
|
|
862
|
+
*
|
|
863
|
+
* Results update reactively whenever the underlying `patients` or
|
|
864
|
+
* `hintPatients` tables change — no polling required.
|
|
865
|
+
*
|
|
866
|
+
* @param options - Search options (see `UsePatientSearchOptions`).
|
|
867
|
+
* @returns `UseQueryResult<PatientSearchResult[]>` — always defined
|
|
868
|
+
* once a non-empty `query` is provided and the subscription resolves.
|
|
869
|
+
*/
|
|
870
|
+
declare function usePatientSearch(options: UsePatientSearchOptions): UseQueryResult<PatientSearchResult[]>;
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Patient interfaces for the Truth SDK.
|
|
874
|
+
*/
|
|
875
|
+
/**
|
|
876
|
+
* Normalized patient record from the Truth platform.
|
|
877
|
+
*/
|
|
878
|
+
interface Patient {
|
|
879
|
+
/** Truth platform patient ID */
|
|
880
|
+
id: string;
|
|
881
|
+
/** Elation EHR patient ID (if linked) */
|
|
882
|
+
elationId?: string;
|
|
883
|
+
/** Hint EHR patient ID (if linked) */
|
|
884
|
+
hintId?: string;
|
|
885
|
+
/** Patient first name */
|
|
886
|
+
firstName: string;
|
|
887
|
+
/** Patient last name */
|
|
888
|
+
lastName: string;
|
|
889
|
+
/** Date of birth (ISO 8601 date string, e.g. "1990-01-15") */
|
|
890
|
+
dateOfBirth?: string;
|
|
891
|
+
/** Patient sex */
|
|
892
|
+
sex?: string;
|
|
893
|
+
/** Primary email address */
|
|
894
|
+
email?: string;
|
|
895
|
+
/** Primary phone number */
|
|
896
|
+
phone?: string;
|
|
897
|
+
/** Patient status in the system */
|
|
898
|
+
status: string;
|
|
899
|
+
/** Associated organization/tenant ID */
|
|
900
|
+
tenantId: string;
|
|
901
|
+
/** ISO 8601 timestamp of record creation */
|
|
902
|
+
createdAt: string;
|
|
903
|
+
/** ISO 8601 timestamp of last update */
|
|
904
|
+
updatedAt: string;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Options for listing patients.
|
|
908
|
+
*/
|
|
909
|
+
interface PatientListOptions {
|
|
910
|
+
/** Search patients by name, email, or phone */
|
|
911
|
+
search?: string;
|
|
912
|
+
/** Maximum number of results to return */
|
|
913
|
+
limit?: number;
|
|
914
|
+
/** Cursor for pagination */
|
|
915
|
+
cursor?: string;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* Bulk patient lookup by Convex ids.
|
|
920
|
+
*
|
|
921
|
+
* Backs the inbox card render in CommHub — one reactive subscription
|
|
922
|
+
* resolves names + office + EHR ids for the entire visible list
|
|
923
|
+
* instead of N per-row queries.
|
|
924
|
+
*
|
|
925
|
+
* Must be used within `<TruthProvider />`.
|
|
926
|
+
*/
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* Subscribe to a list of patients by their Convex ids. Returns a
|
|
930
|
+
* `Record<patientId, Patient>` for O(1) lookup at render time.
|
|
931
|
+
*
|
|
932
|
+
* Pass an empty array (or `undefined`) to skip the query. Missing ids
|
|
933
|
+
* are absent from the map (silently dropped server-side).
|
|
934
|
+
*/
|
|
935
|
+
declare function usePatientsByIds(ids: string[] | null | undefined): UseQueryResult<Record<string, Patient>>;
|
|
936
|
+
/**
|
|
937
|
+
* Bulk patient lookup by phone numbers (digits or formatted). Returns
|
|
938
|
+
* `Record<phoneDigits, Patient>` for O(1) lookup by digits-only key.
|
|
939
|
+
*/
|
|
940
|
+
declare function usePatientsByPhones(phones: string[] | null | undefined): UseQueryResult<Record<string, Patient>>;
|
|
941
|
+
|
|
669
942
|
interface TruthProviderProps {
|
|
670
943
|
/** Truth environment — determines which Convex deployment to connect to */
|
|
671
944
|
environment?: string;
|
|
@@ -693,6 +966,16 @@ interface Reminder {
|
|
|
693
966
|
triggeredAt?: string;
|
|
694
967
|
cancelledAt?: string;
|
|
695
968
|
}
|
|
969
|
+
interface ScheduleReminderInput {
|
|
970
|
+
conversationId: string;
|
|
971
|
+
remindAt: string | Date;
|
|
972
|
+
note?: string;
|
|
973
|
+
createdBy: string;
|
|
974
|
+
}
|
|
975
|
+
interface ScheduleReminderResult {
|
|
976
|
+
reminderId: string;
|
|
977
|
+
remindAt: string;
|
|
978
|
+
}
|
|
696
979
|
|
|
697
980
|
/**
|
|
698
981
|
* React hooks for conversation reminders — bulk lookup keyed by
|
|
@@ -1004,6 +1287,52 @@ interface TrackOptions {
|
|
|
1004
1287
|
occurredAt?: string;
|
|
1005
1288
|
}
|
|
1006
1289
|
|
|
1290
|
+
/**
|
|
1291
|
+
* Configuration interfaces for the Truth SDK.
|
|
1292
|
+
*/
|
|
1293
|
+
/**
|
|
1294
|
+
* Environment options for the Truth platform.
|
|
1295
|
+
*/
|
|
1296
|
+
declare const ENVIRONMENTS: {
|
|
1297
|
+
readonly local: "local";
|
|
1298
|
+
readonly staging: "staging";
|
|
1299
|
+
readonly stg: "stg";
|
|
1300
|
+
readonly sandbox: "sandbox";
|
|
1301
|
+
readonly uat: "uat";
|
|
1302
|
+
readonly production: "production";
|
|
1303
|
+
};
|
|
1304
|
+
type Environment = (typeof ENVIRONMENTS)[keyof typeof ENVIRONMENTS];
|
|
1305
|
+
/**
|
|
1306
|
+
* Configuration for initializing a TruthClient.
|
|
1307
|
+
*/
|
|
1308
|
+
interface TruthClientConfig {
|
|
1309
|
+
/** API key for authenticating with the Truth platform (e.g. "hn_live_...") */
|
|
1310
|
+
apiKey: string;
|
|
1311
|
+
/** Target environment */
|
|
1312
|
+
environment: Environment;
|
|
1313
|
+
/** Override the default Convex URL for data access */
|
|
1314
|
+
convexUrl?: string;
|
|
1315
|
+
/** Event source identifier (e.g. "communication-hub.backend") */
|
|
1316
|
+
source?: string;
|
|
1317
|
+
/** Git SHA or version string for event source versioning */
|
|
1318
|
+
sourceVersion?: string;
|
|
1319
|
+
/** Default tenant (organization) ID for events */
|
|
1320
|
+
tenantId?: string;
|
|
1321
|
+
/** Number of events to buffer before flushing (default: 25) */
|
|
1322
|
+
batchSize?: number;
|
|
1323
|
+
/** Interval in milliseconds between automatic flushes (default: 5000) */
|
|
1324
|
+
flushIntervalMs?: number;
|
|
1325
|
+
/** Base URL for the Truth API (overrides environment-based default) */
|
|
1326
|
+
apiBaseUrl?: string;
|
|
1327
|
+
/**
|
|
1328
|
+
* Auto-register the service worker and subscribe to web push on init.
|
|
1329
|
+
* Only applies in browser environments with Push API support.
|
|
1330
|
+
* Default: true.
|
|
1331
|
+
*/
|
|
1332
|
+
autoInitServiceWorker?: boolean;
|
|
1333
|
+
/** Path to the service worker file. Default: "/truth-sw.js" */
|
|
1334
|
+
serviceWorkerPath?: string;
|
|
1335
|
+
}
|
|
1007
1336
|
/**
|
|
1008
1337
|
* Actor context attached to tracked events.
|
|
1009
1338
|
*/
|
|
@@ -1011,6 +1340,14 @@ interface ActorContext {
|
|
|
1011
1340
|
actorId: string;
|
|
1012
1341
|
actorType: "user" | "system" | "webhook";
|
|
1013
1342
|
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Paginated result wrapper for list operations.
|
|
1345
|
+
*/
|
|
1346
|
+
interface PaginatedResult<T> {
|
|
1347
|
+
data: T[];
|
|
1348
|
+
cursor: string | null;
|
|
1349
|
+
hasMore: boolean;
|
|
1350
|
+
}
|
|
1014
1351
|
|
|
1015
1352
|
interface TruthTrackingContextValue {
|
|
1016
1353
|
track: <T extends EventType>(eventType: T, payload: EventPayloadMap[T], options?: TrackOptions) => void;
|
|
@@ -1036,6 +1373,66 @@ declare function TruthTrackingProvider({ environment, source, sourceVersion, ten
|
|
|
1036
1373
|
*/
|
|
1037
1374
|
declare function useTruth(): TruthTrackingContextValue;
|
|
1038
1375
|
|
|
1376
|
+
/**
|
|
1377
|
+
* UserSettingsResource — typed client for the Truth `userSettings` Convex
|
|
1378
|
+
* table. Exposes the one mutation CommHub's Settings screen needs:
|
|
1379
|
+
* `updateNotifications({ userId, notificationsEnabled })`.
|
|
1380
|
+
*
|
|
1381
|
+
* Server-side / imperative use:
|
|
1382
|
+
* truth.userSettings.updateNotifications({ userId, notificationsEnabled: true })
|
|
1383
|
+
*
|
|
1384
|
+
* Reactive React use lives in `@hipnation-truth/sdk/react` via
|
|
1385
|
+
* `useUserSettings`.
|
|
1386
|
+
*/
|
|
1387
|
+
|
|
1388
|
+
interface UserSettings {
|
|
1389
|
+
_id: string;
|
|
1390
|
+
userId: string;
|
|
1391
|
+
notificationsEnabled: boolean;
|
|
1392
|
+
createdAt: string;
|
|
1393
|
+
updatedAt: string;
|
|
1394
|
+
}
|
|
1395
|
+
interface UpdateNotificationsInput {
|
|
1396
|
+
userId: string;
|
|
1397
|
+
notificationsEnabled: boolean;
|
|
1398
|
+
}
|
|
1399
|
+
interface UpdateNotificationsResult {
|
|
1400
|
+
action: "inserted" | "updated";
|
|
1401
|
+
id: string;
|
|
1402
|
+
}
|
|
1403
|
+
declare class UserSettingsResource {
|
|
1404
|
+
private readonly convex;
|
|
1405
|
+
constructor(convex: ConvexHttpClient);
|
|
1406
|
+
/**
|
|
1407
|
+
* Upsert notification preferences for a user. Creates the row if it
|
|
1408
|
+
* doesn't exist; patches `notificationsEnabled` + `updatedAt` otherwise.
|
|
1409
|
+
*/
|
|
1410
|
+
updateNotifications(input: UpdateNotificationsInput): Promise<UpdateNotificationsResult>;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
/**
|
|
1414
|
+
* useUserSettings — reactive hook for per-user notification preferences
|
|
1415
|
+
* stored in the Truth `userSettings` Convex table.
|
|
1416
|
+
*
|
|
1417
|
+
* Must be used within `<TruthProvider />` (see `./provider`).
|
|
1418
|
+
*
|
|
1419
|
+
* @example
|
|
1420
|
+
* ```tsx
|
|
1421
|
+
* const { data: settings, loading } = useUserSettings(userId);
|
|
1422
|
+
* // settings?.notificationsEnabled — boolean or undefined (no row yet)
|
|
1423
|
+
* ```
|
|
1424
|
+
*/
|
|
1425
|
+
|
|
1426
|
+
/**
|
|
1427
|
+
* Subscribe to the `userSettings` row for `userId`. Returns `null` when
|
|
1428
|
+
* no row exists (treat as all-defaults). Returns `undefined` while the
|
|
1429
|
+
* Convex query is in-flight.
|
|
1430
|
+
*
|
|
1431
|
+
* Pass `null` or `undefined` as `userId` to skip the query (e.g. while
|
|
1432
|
+
* auth is loading).
|
|
1433
|
+
*/
|
|
1434
|
+
declare function useUserSettings(userId: string | null | undefined): UseQueryResult<UserSettings | null>;
|
|
1435
|
+
|
|
1039
1436
|
/**
|
|
1040
1437
|
* Appointment interfaces for the Truth SDK.
|
|
1041
1438
|
*/
|
|
@@ -1093,49 +1490,1056 @@ interface AppointmentListOptions {
|
|
|
1093
1490
|
}
|
|
1094
1491
|
|
|
1095
1492
|
/**
|
|
1096
|
-
*
|
|
1493
|
+
* AppointmentResource provides data access to normalized appointment records
|
|
1494
|
+
* backed by Convex.
|
|
1495
|
+
*/
|
|
1496
|
+
|
|
1497
|
+
declare class AppointmentResource {
|
|
1498
|
+
private readonly convex;
|
|
1499
|
+
constructor(convexClient: ConvexHttpClient);
|
|
1500
|
+
/**
|
|
1501
|
+
* Get an appointment by its Truth platform ID.
|
|
1502
|
+
*/
|
|
1503
|
+
get(id: string): Promise<Appointment | null>;
|
|
1504
|
+
/**
|
|
1505
|
+
* List appointments with optional filters, pagination, and limit.
|
|
1506
|
+
*/
|
|
1507
|
+
list(options?: AppointmentListOptions): Promise<PaginatedResult<Appointment>>;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
/**
|
|
1511
|
+
* AttachmentsResource — presigned S3 upload/download + Convex metadata.
|
|
1512
|
+
*
|
|
1513
|
+
* Replaces CommHub's base64-in-Postgres attachment flow:
|
|
1514
|
+
* 1. client.attachments.createUploadUrl(...) → presigned PUT URL
|
|
1515
|
+
* 2. Client PUTs bytes directly to S3
|
|
1516
|
+
* 3. client.attachments.record(...) → writes Convex metadata
|
|
1517
|
+
* 4. client.attachments.getDownloadUrl(s3Key) → presigned GET URL
|
|
1097
1518
|
*/
|
|
1519
|
+
|
|
1520
|
+
interface CreateUploadUrlInput {
|
|
1521
|
+
fileName: string;
|
|
1522
|
+
mimeType: string;
|
|
1523
|
+
size: number;
|
|
1524
|
+
conversationId?: string;
|
|
1525
|
+
}
|
|
1526
|
+
interface CreateUploadUrlResult {
|
|
1527
|
+
uploadUrl: string;
|
|
1528
|
+
s3Key: string;
|
|
1529
|
+
expiresIn: number;
|
|
1530
|
+
applicationId: string | null;
|
|
1531
|
+
}
|
|
1532
|
+
interface GetDownloadUrlResult {
|
|
1533
|
+
url: string;
|
|
1534
|
+
expiresIn: number;
|
|
1535
|
+
}
|
|
1536
|
+
interface RecordAttachmentInput {
|
|
1537
|
+
s3Key: string;
|
|
1538
|
+
fileName: string;
|
|
1539
|
+
mimeType: string;
|
|
1540
|
+
size: number;
|
|
1541
|
+
conversationId?: string;
|
|
1542
|
+
uploadedBy: string;
|
|
1543
|
+
}
|
|
1544
|
+
interface Attachment {
|
|
1545
|
+
_id: string;
|
|
1546
|
+
s3Key: string;
|
|
1547
|
+
fileName: string;
|
|
1548
|
+
mimeType: string;
|
|
1549
|
+
size: number;
|
|
1550
|
+
conversationId?: string;
|
|
1551
|
+
uploadedBy: string;
|
|
1552
|
+
createdAt: string;
|
|
1553
|
+
}
|
|
1554
|
+
declare class AttachmentsResource {
|
|
1555
|
+
private readonly baseUrl;
|
|
1556
|
+
private readonly apiKey;
|
|
1557
|
+
private readonly convex;
|
|
1558
|
+
constructor(apiBaseUrl: string, apiKey: string, convexClient: ConvexHttpClient);
|
|
1559
|
+
private post;
|
|
1560
|
+
createUploadUrl(input: CreateUploadUrlInput): Promise<CreateUploadUrlResult>;
|
|
1561
|
+
getDownloadUrl(s3Key: string, expiresIn?: number): Promise<GetDownloadUrlResult>;
|
|
1562
|
+
record(input: RecordAttachmentInput): Promise<{
|
|
1563
|
+
attachmentId: string;
|
|
1564
|
+
s3Key: string;
|
|
1565
|
+
}>;
|
|
1566
|
+
get(attachmentId: string): Promise<Attachment | null>;
|
|
1567
|
+
listByConversation(conversationId: string): Promise<Attachment[]>;
|
|
1568
|
+
/**
|
|
1569
|
+
* One-shot upload: presign → PUT to S3 → record in Convex → return a
|
|
1570
|
+
* 7-day signed download URL ready to embed in an outbound SMS. Caller
|
|
1571
|
+
* passes the resulting `downloadUrl` to `messages.dialpad.sendSms` (or
|
|
1572
|
+
* the new `messages.sendAttachmentMessage`) to actually deliver it.
|
|
1573
|
+
*
|
|
1574
|
+
* Replaces CommHub's NestJS `/send-attachment` controller in a single
|
|
1575
|
+
* SDK call — no base64 round-trip, no legacy `/attachments/:id/download`
|
|
1576
|
+
* REST endpoint required.
|
|
1577
|
+
*/
|
|
1578
|
+
upload(input: {
|
|
1579
|
+
file: Blob | ArrayBuffer | Uint8Array;
|
|
1580
|
+
fileName: string;
|
|
1581
|
+
mimeType: string;
|
|
1582
|
+
size: number;
|
|
1583
|
+
conversationId?: string;
|
|
1584
|
+
uploadedBy: string;
|
|
1585
|
+
/** Download URL TTL in seconds. Default 7 days. */
|
|
1586
|
+
downloadExpiresIn?: number;
|
|
1587
|
+
}): Promise<{
|
|
1588
|
+
attachmentId: string;
|
|
1589
|
+
s3Key: string;
|
|
1590
|
+
downloadUrl: string;
|
|
1591
|
+
}>;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1098
1594
|
/**
|
|
1099
|
-
*
|
|
1595
|
+
* ConversationsResource — write methods that hang off a specific
|
|
1596
|
+
* conversation: notes, tasks, outbound messages.
|
|
1597
|
+
*
|
|
1598
|
+
* Replaces CommHub's `truthConversationApi.ts` raw-fetch wrappers so
|
|
1599
|
+
* the frontend goes through a typed SDK surface instead of building
|
|
1600
|
+
* URLs by hand.
|
|
1601
|
+
*
|
|
1602
|
+
* All methods proxy the matching oRPC procedures (`/conversations/*`)
|
|
1603
|
+
* via Truth's application-key auth. Errors surface as
|
|
1604
|
+
* `ConversationsError` with a status code so callers can distinguish
|
|
1605
|
+
* transport failures (status=0) from API rejections (status>=400).
|
|
1100
1606
|
*/
|
|
1101
|
-
|
|
1102
|
-
|
|
1607
|
+
/** Address a conversation by either Convex `_id` or the phonePair. */
|
|
1608
|
+
interface ConversationAddress {
|
|
1609
|
+
conversationId?: string;
|
|
1610
|
+
phonePair?: string;
|
|
1611
|
+
}
|
|
1612
|
+
type ConversationTaskStatus = "pending" | "completed";
|
|
1613
|
+
type ConversationTaskPriority = "high" | "medium" | "low";
|
|
1614
|
+
interface CreateConversationNoteInput extends ConversationAddress {
|
|
1615
|
+
eventId?: string;
|
|
1616
|
+
author: string;
|
|
1617
|
+
content: string;
|
|
1618
|
+
status?: string;
|
|
1619
|
+
type?: string;
|
|
1620
|
+
}
|
|
1621
|
+
interface CreateConversationTaskInput extends ConversationAddress {
|
|
1622
|
+
eventId?: string;
|
|
1623
|
+
author: string;
|
|
1624
|
+
description: string;
|
|
1625
|
+
status?: ConversationTaskStatus;
|
|
1626
|
+
priority?: ConversationTaskPriority;
|
|
1627
|
+
assignee?: string;
|
|
1628
|
+
type?: string;
|
|
1629
|
+
}
|
|
1630
|
+
interface SetConversationTaskStatusInput {
|
|
1631
|
+
taskId: string;
|
|
1632
|
+
status: ConversationTaskStatus;
|
|
1633
|
+
resolvedBy?: string;
|
|
1634
|
+
}
|
|
1635
|
+
interface SendConversationMessageInput {
|
|
1636
|
+
fromNumber: string;
|
|
1637
|
+
toNumber: string;
|
|
1638
|
+
message?: string;
|
|
1639
|
+
media?: string;
|
|
1640
|
+
}
|
|
1641
|
+
interface SendConversationMessageResult {
|
|
1642
|
+
id: number;
|
|
1643
|
+
messageStatus: string;
|
|
1644
|
+
direction: string;
|
|
1645
|
+
}
|
|
1646
|
+
declare class ConversationNotesSubresource {
|
|
1647
|
+
private readonly post;
|
|
1648
|
+
constructor(post: <T>(path: string, body: unknown) => Promise<T>);
|
|
1649
|
+
/** Create a note on a conversation (addressed by id or phonePair). */
|
|
1650
|
+
create(input: CreateConversationNoteInput): Promise<{
|
|
1651
|
+
id: string;
|
|
1652
|
+
}>;
|
|
1653
|
+
}
|
|
1654
|
+
declare class ConversationTasksSubresource {
|
|
1655
|
+
private readonly post;
|
|
1656
|
+
constructor(post: <T>(path: string, body: unknown) => Promise<T>);
|
|
1657
|
+
/** Create a task on a conversation. */
|
|
1658
|
+
create(input: CreateConversationTaskInput): Promise<{
|
|
1659
|
+
id: string;
|
|
1660
|
+
}>;
|
|
1661
|
+
/** Mark a task pending or completed. */
|
|
1662
|
+
setStatus(input: SetConversationTaskStatusInput): Promise<{
|
|
1663
|
+
ok: true;
|
|
1664
|
+
}>;
|
|
1665
|
+
}
|
|
1666
|
+
declare class ConversationMessagesSubresource {
|
|
1667
|
+
private readonly post;
|
|
1668
|
+
constructor(post: <T>(path: string, body: unknown) => Promise<T>);
|
|
1669
|
+
/**
|
|
1670
|
+
* Send an outbound SMS / MMS via the typed `sendMessage` oRPC procedure.
|
|
1671
|
+
*
|
|
1672
|
+
* Prefer this over the generic Dialpad proxy (`messages.dialpad.sendSms`)
|
|
1673
|
+
* — this hits the validated Truth route and consistently surfaces
|
|
1674
|
+
* `ConversationsError` on failure.
|
|
1675
|
+
*/
|
|
1676
|
+
send(input: SendConversationMessageInput): Promise<SendConversationMessageResult>;
|
|
1677
|
+
}
|
|
1678
|
+
declare class ConversationsResource {
|
|
1679
|
+
readonly notes: ConversationNotesSubresource;
|
|
1680
|
+
readonly tasks: ConversationTasksSubresource;
|
|
1681
|
+
readonly messages: ConversationMessagesSubresource;
|
|
1682
|
+
/** 30s upstream timeout — matches NotesResource for consistency. */
|
|
1683
|
+
private static readonly REQUEST_TIMEOUT_MS;
|
|
1684
|
+
private readonly baseUrl;
|
|
1685
|
+
private readonly apiKey;
|
|
1686
|
+
private readonly convex;
|
|
1687
|
+
constructor(apiBaseUrl: string, apiKey: string, convex?: convex_browser.ConvexHttpClient);
|
|
1688
|
+
/**
|
|
1689
|
+
* Mark a conversation read for the calling user (zeroes unreadCount,
|
|
1690
|
+
* stamps `lastReadAt`). Calls the public Convex `markRead` mutation
|
|
1691
|
+
* which enforces self-tenancy on the auth identity.
|
|
1692
|
+
*/
|
|
1693
|
+
markRead(input: {
|
|
1694
|
+
conversationId: string;
|
|
1695
|
+
userId: string;
|
|
1696
|
+
}): Promise<{
|
|
1697
|
+
ok: true;
|
|
1698
|
+
}>;
|
|
1699
|
+
/**
|
|
1700
|
+
* Mark a conversation unread for the calling user (sets unreadCount=1).
|
|
1701
|
+
*/
|
|
1702
|
+
markUnread(input: {
|
|
1703
|
+
conversationId: string;
|
|
1704
|
+
userId: string;
|
|
1705
|
+
}): Promise<{
|
|
1706
|
+
updated: true;
|
|
1707
|
+
}>;
|
|
1708
|
+
/**
|
|
1709
|
+
* Zero unread on every conversation the user has reads for, except
|
|
1710
|
+
* those whose `providerPhone` is in `excludedProviderPhones`.
|
|
1711
|
+
*/
|
|
1712
|
+
clearAllUnread(input: {
|
|
1713
|
+
userId: string;
|
|
1714
|
+
excludedProviderPhones?: string[];
|
|
1715
|
+
}): Promise<{
|
|
1716
|
+
cleared: number;
|
|
1717
|
+
}>;
|
|
1718
|
+
private postRequest;
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
/**
|
|
1722
|
+
* Dialpad resource — typed access to Truth's Dialpad proxy endpoints.
|
|
1723
|
+
*
|
|
1724
|
+
* @example
|
|
1725
|
+
* ```ts
|
|
1726
|
+
* const sms = await truth.messages.dialpad.sendSms({ from_number, to_number, message });
|
|
1727
|
+
* const call = await truth.messages.dialpad.initiateCall(userId, phoneNumber);
|
|
1728
|
+
* await truth.messages.dialpad.hangupCall(callId);
|
|
1729
|
+
* const url = await truth.messages.dialpad.authenticateVoicemail(voicemailLink);
|
|
1730
|
+
* ```
|
|
1731
|
+
*/
|
|
1732
|
+
interface SendSmsParams {
|
|
1733
|
+
from_number: string;
|
|
1734
|
+
to_number: string;
|
|
1735
|
+
message?: string;
|
|
1736
|
+
media?: string | string[];
|
|
1737
|
+
}
|
|
1738
|
+
interface SendSmsResponse {
|
|
1103
1739
|
id: string;
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1740
|
+
message_status: string;
|
|
1741
|
+
[key: string]: unknown;
|
|
1742
|
+
}
|
|
1743
|
+
interface InitiateCallResponse {
|
|
1744
|
+
call_id: number;
|
|
1745
|
+
[key: string]: unknown;
|
|
1746
|
+
}
|
|
1747
|
+
interface CallStatusResponse {
|
|
1748
|
+
state: string;
|
|
1749
|
+
[key: string]: unknown;
|
|
1750
|
+
}
|
|
1751
|
+
interface DialpadUser {
|
|
1752
|
+
id: number;
|
|
1753
|
+
emails: string[];
|
|
1754
|
+
first_name?: string;
|
|
1755
|
+
last_name?: string;
|
|
1756
|
+
[key: string]: unknown;
|
|
1757
|
+
}
|
|
1758
|
+
interface DialpadNumberInfo {
|
|
1759
|
+
user_id?: number;
|
|
1760
|
+
type?: string;
|
|
1761
|
+
[key: string]: unknown;
|
|
1762
|
+
}
|
|
1763
|
+
declare class DialpadResource {
|
|
1764
|
+
private readonly baseUrl;
|
|
1765
|
+
private readonly apiKey;
|
|
1766
|
+
constructor(apiBaseUrl: string, apiKey: string);
|
|
1767
|
+
/**
|
|
1768
|
+
* Send an SMS or MMS message via Dialpad.
|
|
1769
|
+
*/
|
|
1770
|
+
sendSms(params: SendSmsParams): Promise<SendSmsResponse>;
|
|
1771
|
+
/**
|
|
1772
|
+
* Initiate an outbound call from a Dialpad user to a phone number.
|
|
1773
|
+
*/
|
|
1774
|
+
initiateCall(userId: number, phoneNumber: string): Promise<InitiateCallResponse>;
|
|
1775
|
+
/**
|
|
1776
|
+
* Hang up an active call.
|
|
1777
|
+
*/
|
|
1778
|
+
hangupCall(callId: number): Promise<void>;
|
|
1779
|
+
/**
|
|
1780
|
+
* Alias for `hangupCall` — mirrors the CommHub `endCall` action name so
|
|
1781
|
+
* the SDK swap is a direct rename.
|
|
1782
|
+
*/
|
|
1783
|
+
endCall(callId: number): Promise<void>;
|
|
1784
|
+
/**
|
|
1785
|
+
* Send an MMS with a pre-uploaded attachment. Takes the S3 key returned
|
|
1786
|
+
* by `client.attachments.createUploadUrl(...)` + PUT, fetches a short-
|
|
1787
|
+
* lived download URL, and hands it to Dialpad as `media[]`.
|
|
1788
|
+
*
|
|
1789
|
+
* Replaces CommHub's `sendAttachment` Hasura Action (which stored bytes
|
|
1790
|
+
* as base64 in Postgres and served them through a GET endpoint).
|
|
1791
|
+
*/
|
|
1792
|
+
sendAttachmentWithUrl(params: {
|
|
1793
|
+
from_number: string;
|
|
1794
|
+
to_number: string;
|
|
1795
|
+
mediaUrl: string;
|
|
1796
|
+
message?: string;
|
|
1797
|
+
}): Promise<SendSmsResponse>;
|
|
1798
|
+
/**
|
|
1799
|
+
* Get the status of a call.
|
|
1800
|
+
*/
|
|
1801
|
+
getCallStatus(callId: number): Promise<CallStatusResponse | null>;
|
|
1802
|
+
/**
|
|
1803
|
+
* Get a Dialpad user by their user ID.
|
|
1804
|
+
*/
|
|
1805
|
+
getUser(userId: string | number): Promise<DialpadUser | null>;
|
|
1806
|
+
/**
|
|
1807
|
+
* Find a Dialpad user by email.
|
|
1808
|
+
*/
|
|
1809
|
+
getUserByEmail(email: string): Promise<DialpadUser | null>;
|
|
1810
|
+
/**
|
|
1811
|
+
* Find a Dialpad user by phone number.
|
|
1812
|
+
*/
|
|
1813
|
+
getUserByPhoneNumber(phoneNumber: string): Promise<DialpadUser | null>;
|
|
1814
|
+
/**
|
|
1815
|
+
* Get information about a Dialpad phone number.
|
|
1816
|
+
*/
|
|
1817
|
+
getNumberInfo(phoneNumber: string): Promise<DialpadNumberInfo | null>;
|
|
1818
|
+
/**
|
|
1819
|
+
* Authenticate a voicemail download URL. Truth appends the Dialpad API key,
|
|
1820
|
+
* follows redirects, and returns the clean URL for client-side playback.
|
|
1821
|
+
*/
|
|
1822
|
+
authenticateVoicemail(voicemailLink: string): Promise<string | null>;
|
|
1823
|
+
private get;
|
|
1824
|
+
private post;
|
|
1825
|
+
private put;
|
|
1826
|
+
}
|
|
1827
|
+
declare class MessagesResource {
|
|
1828
|
+
readonly dialpad: DialpadResource;
|
|
1829
|
+
private readonly baseUrl;
|
|
1830
|
+
private readonly apiKey;
|
|
1831
|
+
constructor(apiBaseUrl: string, apiKey: string);
|
|
1832
|
+
/**
|
|
1833
|
+
* Get an authenticated URL for a Dialpad voicemail recording.
|
|
1834
|
+
*
|
|
1835
|
+
* Replaces CommHub's `getAuthenticatedVoicemailUrl` Hasura mutation
|
|
1836
|
+
* (which proxied to the legacy NestJS backend). Truth appends the
|
|
1837
|
+
* Dialpad API key, follows redirects, strips the key from the final
|
|
1838
|
+
* URL, and returns it for client-side audio playback.
|
|
1839
|
+
*
|
|
1840
|
+
* @param voicemailLink The raw Dialpad voicemail download URL (value
|
|
1841
|
+
* of the `voicemail_link` field on the call event row).
|
|
1842
|
+
* @returns An object with `url` (clean playback URL) and `expiresAt`
|
|
1843
|
+
* (ISO-8601 timestamp, ~5 min from request time, informational only).
|
|
1844
|
+
*/
|
|
1845
|
+
getVoicemailUrl(voicemailLink: string): Promise<{
|
|
1846
|
+
url: string;
|
|
1847
|
+
expiresAt: string;
|
|
1848
|
+
}>;
|
|
1849
|
+
/**
|
|
1850
|
+
* End a Dialpad call via the typed oRPC procedure (POST hangup, with
|
|
1851
|
+
* 404→`alreadyEnded` so the UI doesn't flash an error on a natural
|
|
1852
|
+
* race). Replaces CommHub's `useEndCallMutation` Hasura action.
|
|
1853
|
+
*
|
|
1854
|
+
* Prefer this over `messages.dialpad.endCall` which goes through the
|
|
1855
|
+
* generic proxy (PUT, no 404 handling).
|
|
1856
|
+
*/
|
|
1857
|
+
endCall(callId: number | string): Promise<{
|
|
1858
|
+
ok: true;
|
|
1859
|
+
alreadyEnded: boolean;
|
|
1860
|
+
}>;
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
/**
|
|
1864
|
+
* EHR proxy resource — typed access to Truth's EHR proxy endpoints.
|
|
1865
|
+
*
|
|
1866
|
+
* Provides per-provider proxy methods so consumers never construct
|
|
1867
|
+
* proxy URLs manually.
|
|
1868
|
+
*
|
|
1869
|
+
* @example
|
|
1870
|
+
* ```ts
|
|
1871
|
+
* const patient = await truth.ehr.elation.get('/patients/123/');
|
|
1872
|
+
* const notes = await truth.ehr.elation.post('/non_visit_notes/', noteData);
|
|
1873
|
+
* const hintPatient = await truth.ehr.hint.get('/provider/patients/456');
|
|
1874
|
+
* ```
|
|
1875
|
+
*/
|
|
1876
|
+
declare class EhrProviderProxy {
|
|
1877
|
+
private readonly baseUrl;
|
|
1878
|
+
private readonly provider;
|
|
1879
|
+
constructor(apiBaseUrl: string, provider: string);
|
|
1880
|
+
/**
|
|
1881
|
+
* GET request to the EHR proxy.
|
|
1882
|
+
* @param path — path relative to the provider root (e.g., "/patients/123/")
|
|
1883
|
+
* @param params — optional query parameters
|
|
1884
|
+
*/
|
|
1885
|
+
get<T = unknown>(path: string, params?: Record<string, unknown>): Promise<T>;
|
|
1886
|
+
/**
|
|
1887
|
+
* POST request to the EHR proxy.
|
|
1888
|
+
*/
|
|
1889
|
+
post<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
1890
|
+
/**
|
|
1891
|
+
* PUT request to the EHR proxy.
|
|
1892
|
+
*/
|
|
1893
|
+
put<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
1894
|
+
/**
|
|
1895
|
+
* PATCH request to the EHR proxy.
|
|
1896
|
+
*/
|
|
1897
|
+
patch<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
1898
|
+
/**
|
|
1899
|
+
* DELETE request to the EHR proxy.
|
|
1900
|
+
*/
|
|
1901
|
+
delete<T = unknown>(path: string): Promise<T>;
|
|
1902
|
+
}
|
|
1903
|
+
declare class EhrResource {
|
|
1904
|
+
/** Elation EHR proxy */
|
|
1905
|
+
readonly elation: EhrProviderProxy;
|
|
1906
|
+
/** Hint Health proxy */
|
|
1907
|
+
readonly hint: EhrProviderProxy;
|
|
1908
|
+
constructor(apiBaseUrl: string);
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
/**
|
|
1912
|
+
* NotesResource — push formatted notes to Elation.
|
|
1913
|
+
*
|
|
1914
|
+
* Caller assembles the note body (text + bullets). Truth owns the Elation
|
|
1915
|
+
* OAuth token and the HTTP call so applications can drop Elation
|
|
1916
|
+
* credentials from their own config.
|
|
1917
|
+
*/
|
|
1918
|
+
interface NonVisitNoteBullet {
|
|
1919
|
+
text: string;
|
|
1920
|
+
category?: string;
|
|
1921
|
+
}
|
|
1922
|
+
interface PushNoteToElationInput {
|
|
1923
|
+
patient: number;
|
|
1924
|
+
physician: number;
|
|
1925
|
+
practice: number;
|
|
1926
|
+
note: {
|
|
1927
|
+
text: string;
|
|
1928
|
+
type?: string;
|
|
1929
|
+
};
|
|
1930
|
+
document_date?: string;
|
|
1931
|
+
chart_date?: string;
|
|
1932
|
+
bullets?: NonVisitNoteBullet[];
|
|
1933
|
+
}
|
|
1934
|
+
interface PushNoteToElationResult {
|
|
1935
|
+
success: boolean;
|
|
1936
|
+
elationNoteId: number | null;
|
|
1937
|
+
}
|
|
1938
|
+
interface PushConversationToElationInput {
|
|
1939
|
+
/** One-of: conversationId (Convex) or phonePair. */
|
|
1940
|
+
conversationId?: string;
|
|
1941
|
+
phonePair?: string;
|
|
1942
|
+
/** Actor user id — recorded on the audit row. */
|
|
1943
|
+
initiatedBy: string;
|
|
1944
|
+
/** Pre-assembled note body (transcript-style text). */
|
|
1945
|
+
noteText: string;
|
|
1946
|
+
bullets?: NonVisitNoteBullet[];
|
|
1947
|
+
notesPushed?: number;
|
|
1948
|
+
messagesPushed?: number;
|
|
1949
|
+
tasksPushed?: number;
|
|
1950
|
+
}
|
|
1951
|
+
interface PushConversationToElationResult {
|
|
1952
|
+
success: true;
|
|
1953
|
+
batchId: string;
|
|
1954
|
+
elationNoteId: number | null;
|
|
1955
|
+
notesPushed: number;
|
|
1956
|
+
messagesPushed: number;
|
|
1957
|
+
tasksPushed: number;
|
|
1958
|
+
}
|
|
1959
|
+
declare class NotesResource {
|
|
1960
|
+
private readonly baseUrl;
|
|
1961
|
+
private readonly apiKey;
|
|
1962
|
+
constructor(apiBaseUrl: string, apiKey: string);
|
|
1963
|
+
/** 30s upstream timeout — Elation API has occasional slow hops; we
|
|
1964
|
+
* don't want a pending mutation to hold the UI thread indefinitely. */
|
|
1965
|
+
private static readonly REQUEST_TIMEOUT_MS;
|
|
1966
|
+
private post;
|
|
1967
|
+
/**
|
|
1968
|
+
* Low-level — caller has already resolved Elation patient / physician
|
|
1969
|
+
* / practice. Use `pushConversationToElation` if you only have a
|
|
1970
|
+
* conversation handle.
|
|
1971
|
+
*/
|
|
1972
|
+
pushToElation(input: PushNoteToElationInput): Promise<PushNoteToElationResult>;
|
|
1973
|
+
/**
|
|
1974
|
+
* Orchestrator — pass a conversation handle + pre-assembled note text.
|
|
1975
|
+
* Truth resolves the linked patient via Convex, looks up
|
|
1976
|
+
* physician/practice in Elation, posts the note, and writes an audit
|
|
1977
|
+
* row to `elationSyncEvents`. Replaces CommHub's `pushNotesToElation`
|
|
1978
|
+
* Hasura action.
|
|
1979
|
+
*/
|
|
1980
|
+
pushConversationToElation(input: PushConversationToElationInput): Promise<PushConversationToElationResult>;
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
/**
|
|
1984
|
+
* NotificationsResource — wraps Truth's /api/notifications/* endpoints.
|
|
1985
|
+
*
|
|
1986
|
+
* Server-side use (for example from a CommHub backend job or
|
|
1987
|
+
* another service): `truth.notifications.send({ userId, title, body })`.
|
|
1988
|
+
*
|
|
1989
|
+
* Client-side React usage lives in `@hipnation-truth/sdk/react` via
|
|
1990
|
+
* the `useNotifications` hook which mirrors `expo-notifications`.
|
|
1991
|
+
*/
|
|
1992
|
+
type NotificationPlatform = "ios" | "android" | "web";
|
|
1993
|
+
interface RegisterDeviceInput {
|
|
1994
|
+
userId: string;
|
|
1995
|
+
platform: NotificationPlatform;
|
|
1996
|
+
nativeToken?: string;
|
|
1997
|
+
webPushSubscription?: {
|
|
1998
|
+
endpoint: string;
|
|
1999
|
+
keys: {
|
|
2000
|
+
p256dh: string;
|
|
2001
|
+
auth: string;
|
|
2002
|
+
};
|
|
2003
|
+
};
|
|
2004
|
+
appVersion?: string;
|
|
2005
|
+
osVersion?: string;
|
|
2006
|
+
locale?: string;
|
|
2007
|
+
timezone?: string;
|
|
2008
|
+
/**
|
|
2009
|
+
* iOS only — which APNs endpoint the `nativeToken` was issued
|
|
2010
|
+
* against. The token bytes don't carry this; it's determined by
|
|
2011
|
+
* the build's `aps-environment` entitlement
|
|
2012
|
+
* (`development` ⇒ sandbox, `production` ⇒ production). When the
|
|
2013
|
+
* consumer is an Expo app, detect via
|
|
2014
|
+
* `Application.getIosPushNotificationServiceEnvironmentAsync()`
|
|
2015
|
+
* from `expo-application` and pass the normalised value here.
|
|
2016
|
+
* Omitting this falls back to the application's default
|
|
2017
|
+
* `pushConfig.ios.environment` server-side.
|
|
2018
|
+
*/
|
|
2019
|
+
apnsEnvironment?: "sandbox" | "production";
|
|
2020
|
+
}
|
|
2021
|
+
interface RegisterDeviceResult {
|
|
2022
|
+
deviceId: string;
|
|
2023
|
+
action: "inserted" | "updated";
|
|
2024
|
+
snsEndpointArn?: string;
|
|
2025
|
+
}
|
|
2026
|
+
interface UnregisterDeviceInput {
|
|
2027
|
+
nativeToken?: string;
|
|
2028
|
+
deviceId?: string;
|
|
2029
|
+
}
|
|
2030
|
+
interface SendNotificationInput {
|
|
2031
|
+
userId: string;
|
|
2032
|
+
title: string;
|
|
2033
|
+
body: string;
|
|
2034
|
+
data?: Record<string, unknown>;
|
|
2035
|
+
badge?: number;
|
|
2036
|
+
sound?: string;
|
|
2037
|
+
}
|
|
2038
|
+
interface SendNotificationResult {
|
|
2039
|
+
delivered: number;
|
|
2040
|
+
failed?: number;
|
|
2041
|
+
suppressed?: boolean;
|
|
2042
|
+
suppressionReason?: string;
|
|
2043
|
+
}
|
|
2044
|
+
interface NotificationPreferences {
|
|
2045
|
+
channels: {
|
|
2046
|
+
sms: boolean;
|
|
2047
|
+
push: boolean;
|
|
2048
|
+
email: boolean;
|
|
2049
|
+
inApp: boolean;
|
|
2050
|
+
};
|
|
2051
|
+
quietHours?: {
|
|
2052
|
+
enabled: boolean;
|
|
2053
|
+
start: string;
|
|
2054
|
+
end: string;
|
|
2055
|
+
timezone: string;
|
|
2056
|
+
};
|
|
2057
|
+
doNotDisturbUntil?: string;
|
|
2058
|
+
updatedAt: string;
|
|
2059
|
+
}
|
|
2060
|
+
interface UpdatePreferencesInput {
|
|
2061
|
+
userId: string;
|
|
2062
|
+
channels?: NotificationPreferences["channels"];
|
|
2063
|
+
quietHours?: NotificationPreferences["quietHours"];
|
|
2064
|
+
doNotDisturbUntil?: string | null;
|
|
2065
|
+
}
|
|
2066
|
+
interface ScheduleNotificationInput extends SendNotificationInput {
|
|
2067
|
+
/** ISO 8601 timestamp; must be strictly in the future. */
|
|
2068
|
+
scheduledAt: string;
|
|
2069
|
+
}
|
|
2070
|
+
interface ScheduleNotificationResult {
|
|
2071
|
+
jobId: string;
|
|
2072
|
+
scheduledAt: string;
|
|
2073
|
+
}
|
|
2074
|
+
interface CancelScheduledNotificationResult {
|
|
2075
|
+
cancelled: boolean;
|
|
2076
|
+
reason?: string;
|
|
2077
|
+
status?: string;
|
|
2078
|
+
}
|
|
2079
|
+
type ScheduledJobStatus = "pending" | "executed" | "cancelled" | "failed";
|
|
2080
|
+
interface ScheduledNotification {
|
|
2081
|
+
jobId: string;
|
|
2082
|
+
userId: string;
|
|
2083
|
+
title: string;
|
|
2084
|
+
body: string;
|
|
2085
|
+
data?: unknown;
|
|
2086
|
+
badge?: number;
|
|
2087
|
+
sound?: string;
|
|
2088
|
+
scheduledAt: string;
|
|
2089
|
+
status: ScheduledJobStatus;
|
|
2090
|
+
resultHistoryId?: string;
|
|
2091
|
+
errorMessage?: string;
|
|
2092
|
+
createdAt: string;
|
|
2093
|
+
}
|
|
2094
|
+
interface PushEventPayload {
|
|
2095
|
+
title: string;
|
|
2096
|
+
body: string;
|
|
2097
|
+
data?: unknown;
|
|
2098
|
+
}
|
|
2099
|
+
declare class NotificationsResource {
|
|
2100
|
+
private readonly baseUrl;
|
|
2101
|
+
private readonly apiKey;
|
|
2102
|
+
constructor(apiBaseUrl: string, apiKey: string);
|
|
2103
|
+
private post;
|
|
2104
|
+
private get;
|
|
2105
|
+
private delete;
|
|
2106
|
+
/**
|
|
2107
|
+
* Register a device (or refresh its metadata) for push delivery.
|
|
2108
|
+
* Safe to call repeatedly — the server dedupes by native token.
|
|
2109
|
+
*/
|
|
2110
|
+
registerDevice(input: RegisterDeviceInput): Promise<RegisterDeviceResult>;
|
|
2111
|
+
/** Revoke a device — on sign-out or when the OS reports an invalid token. */
|
|
2112
|
+
unregisterDevice(input: UnregisterDeviceInput): Promise<{
|
|
2113
|
+
revoked: boolean;
|
|
2114
|
+
}>;
|
|
2115
|
+
/**
|
|
2116
|
+
* Send a push notification to every active device belonging to
|
|
2117
|
+
* `userId`. Honors the user's notificationPreferences (quiet hours,
|
|
2118
|
+
* DND, channel off) before publishing.
|
|
2119
|
+
*/
|
|
2120
|
+
send(input: SendNotificationInput): Promise<SendNotificationResult>;
|
|
2121
|
+
/** Read a user's notification preferences. Returns defaults when no row exists. */
|
|
2122
|
+
getPreferences(userId: string): Promise<NotificationPreferences>;
|
|
2123
|
+
updatePreferences(input: UpdatePreferencesInput): Promise<{
|
|
2124
|
+
ok: boolean;
|
|
2125
|
+
}>;
|
|
2126
|
+
/**
|
|
2127
|
+
* Schedule a future push notification. Convex's native scheduler
|
|
2128
|
+
* fires the send at `scheduledAt` and runs the same delivery
|
|
2129
|
+
* pipeline as `send()` (preferences, devices, history audit).
|
|
2130
|
+
*
|
|
2131
|
+
* Throws `NotificationsError` with status 400 if `scheduledAt` is
|
|
2132
|
+
* not strictly in the future.
|
|
2133
|
+
*/
|
|
2134
|
+
schedule(input: ScheduleNotificationInput): Promise<ScheduleNotificationResult>;
|
|
2135
|
+
/**
|
|
2136
|
+
* Cancel a pending scheduled notification. Returns `cancelled: false`
|
|
2137
|
+
* (no error) if the job has already executed, was previously
|
|
2138
|
+
* cancelled, or no longer exists — `reason` describes which case.
|
|
2139
|
+
*/
|
|
2140
|
+
cancelScheduled(jobId: string): Promise<CancelScheduledNotificationResult>;
|
|
2141
|
+
/**
|
|
2142
|
+
* List scheduled notifications for a user — pending, executed,
|
|
2143
|
+
* cancelled, or failed. Most-recent first. Default limit 100.
|
|
2144
|
+
*/
|
|
2145
|
+
listScheduled(userId: string, options?: {
|
|
2146
|
+
limit?: number;
|
|
2147
|
+
}): Promise<ScheduledNotification[]>;
|
|
2148
|
+
getVapidKey(): Promise<string | null>;
|
|
2149
|
+
onPushReceived(callback: (payload: PushEventPayload) => void): () => void;
|
|
2150
|
+
onPushTapped(callback: (payload: PushEventPayload) => void): () => void;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
/**
|
|
2154
|
+
* PatientDetailsResource — merged Hint + Elation patient lookups.
|
|
2155
|
+
*
|
|
2156
|
+
* Backed by the Truth API at /api/patients/details/*, authenticated with
|
|
2157
|
+
* X-API-Key. Replaces CommHub's getPatientDetails / getPatientBasicDetails
|
|
2158
|
+
* / getPatientMedicalDetails actions.
|
|
2159
|
+
*/
|
|
2160
|
+
interface PatientDetailsInput {
|
|
1107
2161
|
hintId?: string;
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
2162
|
+
elationId?: string;
|
|
2163
|
+
}
|
|
2164
|
+
interface PatientDetailsResult {
|
|
2165
|
+
hint: unknown | null;
|
|
2166
|
+
elation: unknown | null;
|
|
2167
|
+
resolvedElationId: string | null;
|
|
2168
|
+
}
|
|
2169
|
+
interface PatientBasicDetailsResult {
|
|
2170
|
+
hint: unknown | null;
|
|
2171
|
+
elationId: string | null;
|
|
2172
|
+
}
|
|
2173
|
+
interface PatientMedicalDetailsResult {
|
|
2174
|
+
problems: unknown | null;
|
|
2175
|
+
medications: unknown | null;
|
|
2176
|
+
allergies: unknown | null;
|
|
2177
|
+
appointments: unknown | null;
|
|
2178
|
+
}
|
|
2179
|
+
declare class PatientDetailsResource {
|
|
2180
|
+
private readonly baseUrl;
|
|
2181
|
+
private readonly apiKey;
|
|
2182
|
+
constructor(apiBaseUrl: string, apiKey: string);
|
|
2183
|
+
private post;
|
|
2184
|
+
get(input: PatientDetailsInput): Promise<PatientDetailsResult>;
|
|
2185
|
+
getBasic(input: PatientDetailsInput): Promise<PatientBasicDetailsResult>;
|
|
2186
|
+
getMedical(elationId: string): Promise<PatientMedicalDetailsResult>;
|
|
2187
|
+
/**
|
|
2188
|
+
* Trigger a server-side refresh of the patient's Elation medical
|
|
2189
|
+
* records (medications, problems, allergies, appointments) into the
|
|
2190
|
+
* Convex cache. Fire-and-forget — the UI should read via the Convex-
|
|
2191
|
+
* reactive `usePatientMedical` hook.
|
|
2192
|
+
*/
|
|
2193
|
+
refreshMedical(elationId: number): Promise<{
|
|
2194
|
+
totals: {
|
|
2195
|
+
medications: number;
|
|
2196
|
+
problems: number;
|
|
2197
|
+
allergies: number;
|
|
2198
|
+
appointments: number;
|
|
2199
|
+
};
|
|
2200
|
+
}>;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
/**
|
|
2204
|
+
* PatientResource provides data access to normalized patient records
|
|
2205
|
+
* backed by Convex.
|
|
2206
|
+
*/
|
|
2207
|
+
|
|
2208
|
+
declare class PatientResource {
|
|
2209
|
+
private readonly convex;
|
|
2210
|
+
constructor(convexClient: ConvexHttpClient);
|
|
2211
|
+
/**
|
|
2212
|
+
* Get a patient by their Truth platform ID.
|
|
2213
|
+
*/
|
|
2214
|
+
get(id: string): Promise<Patient | null>;
|
|
2215
|
+
/**
|
|
2216
|
+
* Get a patient by their Elation EHR ID.
|
|
2217
|
+
*/
|
|
2218
|
+
getByElationId(elationId: string): Promise<Patient | null>;
|
|
2219
|
+
/**
|
|
2220
|
+
* Get a patient by their Hint EHR ID.
|
|
2221
|
+
*/
|
|
2222
|
+
getByHintId(hintId: string): Promise<Patient | null>;
|
|
2223
|
+
/**
|
|
2224
|
+
* List patients with optional search, pagination, and limit.
|
|
2225
|
+
*/
|
|
2226
|
+
list(options?: PatientListOptions): Promise<PaginatedResult<Patient>>;
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
/**
|
|
2230
|
+
* PhysiciansResource — Convex-backed physician lookups.
|
|
2231
|
+
*
|
|
2232
|
+
* Populated from Elation by Truth's daily PhysiciansBackfillCron. Replaces
|
|
2233
|
+
* per-physician Elation HTTP hops with a single Convex batch query.
|
|
2234
|
+
*/
|
|
2235
|
+
|
|
2236
|
+
interface Physician {
|
|
2237
|
+
_id: string;
|
|
2238
|
+
elationId: number;
|
|
2239
|
+
firstName?: string;
|
|
2240
|
+
lastName?: string;
|
|
2241
|
+
npi?: string;
|
|
2242
|
+
credentials?: string;
|
|
2243
|
+
specialties?: string[];
|
|
2244
|
+
practice?: number;
|
|
1117
2245
|
email?: string;
|
|
1118
|
-
/** Primary phone number */
|
|
1119
2246
|
phone?: string;
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
2247
|
+
lastSyncedAt: string;
|
|
2248
|
+
}
|
|
2249
|
+
declare class PhysiciansResource {
|
|
2250
|
+
private readonly convex;
|
|
2251
|
+
constructor(convex: ConvexHttpClient);
|
|
2252
|
+
/**
|
|
2253
|
+
* Resolve a batch of physicians by Elation IDs. Missing ids are dropped.
|
|
2254
|
+
*/
|
|
2255
|
+
getByElationIds(ids: number[]): Promise<Physician[]>;
|
|
2256
|
+
getByElationId(id: number): Promise<Physician | null>;
|
|
2257
|
+
listByPractice(practice: number, limit?: number): Promise<Physician[]>;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
/**
|
|
2261
|
+
* RemindersResource — schedule, cancel, and list conversation reminders.
|
|
2262
|
+
*
|
|
2263
|
+
* Backed by Convex mutations/queries (durable scheduled functions) — replaces
|
|
2264
|
+
* the in-memory setTimeout scheduler that used to live in CommHub's NestJS
|
|
2265
|
+
* backend.
|
|
2266
|
+
*/
|
|
2267
|
+
|
|
2268
|
+
declare class RemindersResource {
|
|
2269
|
+
private readonly convex;
|
|
2270
|
+
constructor(convexClient: ConvexHttpClient);
|
|
2271
|
+
/**
|
|
2272
|
+
* Schedule a reminder to fire at `remindAt`. Returns the reminder id,
|
|
2273
|
+
* which callers should store if they may want to cancel it later.
|
|
2274
|
+
*/
|
|
2275
|
+
schedule(input: ScheduleReminderInput): Promise<ScheduleReminderResult>;
|
|
2276
|
+
/**
|
|
2277
|
+
* Cancel a pending reminder. No-op if the reminder has already fired or
|
|
2278
|
+
* been cancelled.
|
|
2279
|
+
*/
|
|
2280
|
+
cancel(reminderId: string, cancelledBy: string): Promise<{
|
|
2281
|
+
reminderId: string;
|
|
2282
|
+
status: string;
|
|
2283
|
+
}>;
|
|
2284
|
+
/**
|
|
2285
|
+
* List reminders for a conversation (most recent first).
|
|
2286
|
+
*/
|
|
2287
|
+
listByConversation(conversationId: string): Promise<Reminder[]>;
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
type TaskStatus = "open" | "in_progress" | "resolved" | "cancelled";
|
|
2291
|
+
interface Task {
|
|
2292
|
+
_id: string;
|
|
2293
|
+
eventId?: string;
|
|
2294
|
+
assignedTo: string;
|
|
2295
|
+
createdBy: string;
|
|
2296
|
+
title: string;
|
|
2297
|
+
description?: string;
|
|
2298
|
+
data?: unknown;
|
|
2299
|
+
status: TaskStatus;
|
|
2300
|
+
resolvedBy?: string;
|
|
2301
|
+
resolvedAt?: string;
|
|
1125
2302
|
createdAt: string;
|
|
1126
|
-
/** ISO 8601 timestamp of last update */
|
|
1127
2303
|
updatedAt: string;
|
|
1128
2304
|
}
|
|
2305
|
+
interface CreateTaskInput {
|
|
2306
|
+
eventId?: string;
|
|
2307
|
+
assignedTo: string;
|
|
2308
|
+
createdBy: string;
|
|
2309
|
+
title: string;
|
|
2310
|
+
description?: string;
|
|
2311
|
+
data?: unknown;
|
|
2312
|
+
}
|
|
2313
|
+
interface UpdateTaskStatusInput {
|
|
2314
|
+
taskId: string;
|
|
2315
|
+
status: TaskStatus;
|
|
2316
|
+
resolvedBy?: string;
|
|
2317
|
+
data?: unknown;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
1129
2320
|
/**
|
|
1130
|
-
*
|
|
2321
|
+
* TasksResource — create, update status, list, get tasks.
|
|
2322
|
+
*
|
|
2323
|
+
* Backed by Convex. Replaces CommHub's createTaskWithNotification +
|
|
2324
|
+
* updateTaskStatusWithNotification actions. Push notification side-effect
|
|
2325
|
+
* is emitted downstream via Kinesis.
|
|
1131
2326
|
*/
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
2327
|
+
|
|
2328
|
+
declare class TasksResource {
|
|
2329
|
+
private readonly convex;
|
|
2330
|
+
constructor(convexClient: ConvexHttpClient);
|
|
2331
|
+
create(input: CreateTaskInput): Promise<{
|
|
2332
|
+
taskId: string;
|
|
2333
|
+
status: TaskStatus;
|
|
2334
|
+
}>;
|
|
2335
|
+
updateStatus(input: UpdateTaskStatusInput): Promise<{
|
|
2336
|
+
taskId: string;
|
|
2337
|
+
status: TaskStatus;
|
|
2338
|
+
previousStatus: TaskStatus;
|
|
2339
|
+
}>;
|
|
2340
|
+
get(taskId: string): Promise<Task | null>;
|
|
2341
|
+
listByAssignee(assignedTo: string, options?: {
|
|
2342
|
+
status?: TaskStatus;
|
|
2343
|
+
limit?: number;
|
|
2344
|
+
}): Promise<Task[]>;
|
|
2345
|
+
listOpen(limit?: number): Promise<Task[]>;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
interface TranslationResult {
|
|
2349
|
+
translatedText: string;
|
|
2350
|
+
detectedLanguage?: {
|
|
2351
|
+
language: string;
|
|
2352
|
+
score: number;
|
|
2353
|
+
};
|
|
2354
|
+
sourceLanguage: string;
|
|
2355
|
+
targetLanguage: string;
|
|
2356
|
+
}
|
|
2357
|
+
interface DetectionResult {
|
|
2358
|
+
language: string;
|
|
2359
|
+
score: number;
|
|
2360
|
+
isTranslationSupported: boolean;
|
|
2361
|
+
isTransliterationSupported: boolean;
|
|
2362
|
+
}
|
|
2363
|
+
interface TranslateTextInput {
|
|
2364
|
+
text: string;
|
|
2365
|
+
targetLanguage: string;
|
|
2366
|
+
sourceLanguage?: string;
|
|
2367
|
+
}
|
|
2368
|
+
interface TranslateBatchInput {
|
|
2369
|
+
texts: string[];
|
|
2370
|
+
targetLanguage: string;
|
|
2371
|
+
sourceLanguage?: string;
|
|
1139
2372
|
}
|
|
1140
2373
|
|
|
1141
|
-
|
|
2374
|
+
/**
|
|
2375
|
+
* TranslationResource — Azure Translator proxy through Truth API.
|
|
2376
|
+
*
|
|
2377
|
+
* All three operations are HTTP calls to Truth's oRPC endpoints at
|
|
2378
|
+
* `/api/translation/*`, authenticated with the same X-API-Key as the
|
|
2379
|
+
* event tracker.
|
|
2380
|
+
*/
|
|
2381
|
+
|
|
2382
|
+
declare class TranslationResource {
|
|
2383
|
+
private readonly baseUrl;
|
|
2384
|
+
private readonly apiKey;
|
|
2385
|
+
constructor(apiBaseUrl: string, apiKey: string);
|
|
2386
|
+
private post;
|
|
2387
|
+
translate(input: TranslateTextInput): Promise<TranslationResult>;
|
|
2388
|
+
translateBatch(input: TranslateBatchInput): Promise<TranslationResult[]>;
|
|
2389
|
+
detect(text: string): Promise<DetectionResult>;
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2392
|
+
/**
|
|
2393
|
+
* TruthClient -- main entry point for the @hipnation-truth/sdk package.
|
|
2394
|
+
*
|
|
2395
|
+
* Provides:
|
|
2396
|
+
* - `.patients` Resource-based patient data access (Convex-backed)
|
|
2397
|
+
* - `.appointments` Resource-based appointment data access (Convex-backed)
|
|
2398
|
+
* - `.ehr` EHR proxy access (Elation, Hint)
|
|
2399
|
+
* - `.messages` Messaging proxy access (Dialpad)
|
|
2400
|
+
* - `.track()` Fire-and-forget event tracking (batched HTTP -> Truth API)
|
|
2401
|
+
* - `.identify()` Set default actor context for subsequent events
|
|
2402
|
+
* - `.flush()` Force flush of buffered events (for graceful shutdown)
|
|
2403
|
+
*/
|
|
2404
|
+
|
|
2405
|
+
declare class TruthClient {
|
|
2406
|
+
/** Patient data resource (Convex-backed) */
|
|
2407
|
+
readonly patients: PatientResource;
|
|
2408
|
+
/** Appointment data resource (Convex-backed) */
|
|
2409
|
+
readonly appointments: AppointmentResource;
|
|
2410
|
+
/** EHR proxy — typed access to Elation and Hint APIs through Truth */
|
|
2411
|
+
readonly ehr: EhrResource;
|
|
2412
|
+
/** Messaging proxy — typed access to Dialpad APIs through Truth */
|
|
2413
|
+
readonly messages: MessagesResource;
|
|
2414
|
+
/** Conversation reminders (Convex-backed, durable scheduler) */
|
|
2415
|
+
readonly reminders: RemindersResource;
|
|
2416
|
+
/** Translation (Azure Translator proxy) */
|
|
2417
|
+
readonly translation: TranslationResource;
|
|
2418
|
+
/** Tasks (Convex-backed) */
|
|
2419
|
+
readonly tasks: TasksResource;
|
|
2420
|
+
/** Patient details — merged Hint + Elation lookups via Truth API */
|
|
2421
|
+
readonly patientDetails: PatientDetailsResource;
|
|
2422
|
+
/** Attachments — presigned S3 upload/download + Convex metadata */
|
|
2423
|
+
readonly attachments: AttachmentsResource;
|
|
2424
|
+
/** Notes — push formatted notes to Elation */
|
|
2425
|
+
readonly notes: NotesResource;
|
|
2426
|
+
/** Physicians (Convex-backed cache from Elation) */
|
|
2427
|
+
readonly physicians: PhysiciansResource;
|
|
2428
|
+
/** Push / web notifications (AWS End User Messaging) */
|
|
2429
|
+
readonly notifications: NotificationsResource;
|
|
2430
|
+
/** Conversation-tied writes — notes, tasks, outbound messages. */
|
|
2431
|
+
readonly conversations: ConversationsResource;
|
|
2432
|
+
/** User settings — notification preferences (Convex-backed) */
|
|
2433
|
+
readonly userSettings: UserSettingsResource;
|
|
2434
|
+
private readonly convex;
|
|
2435
|
+
private readonly tracker;
|
|
2436
|
+
private _vapidPublicKey;
|
|
2437
|
+
private _webPushReady;
|
|
2438
|
+
private readonly _serviceWorkerPath;
|
|
2439
|
+
constructor(config: TruthClientConfig);
|
|
2440
|
+
get vapidPublicKey(): string | null;
|
|
2441
|
+
get webPushReady(): Promise<void> | null;
|
|
2442
|
+
private initWebPush;
|
|
2443
|
+
/**
|
|
2444
|
+
* The resolved Truth API base URL for this environment.
|
|
2445
|
+
* Use this when making HTTP calls to Truth's proxy endpoints
|
|
2446
|
+
* (e.g., EHR proxy, messages proxy).
|
|
2447
|
+
*
|
|
2448
|
+
* @example
|
|
2449
|
+
* ```ts
|
|
2450
|
+
* const url = `${truth.apiBaseUrl}/api/ehr/elation/patients/123`;
|
|
2451
|
+
* ```
|
|
2452
|
+
*/
|
|
2453
|
+
get apiBaseUrl(): string;
|
|
2454
|
+
/**
|
|
2455
|
+
* Track an event. Fire-and-forget -- the event is buffered internally
|
|
2456
|
+
* and flushed in batches to the Truth API.
|
|
2457
|
+
*
|
|
2458
|
+
* @example
|
|
2459
|
+
* ```ts
|
|
2460
|
+
* truth.track('conversation.message_sent.v1', {
|
|
2461
|
+
* channel: 'sms',
|
|
2462
|
+
* direction: 'outbound',
|
|
2463
|
+
* message_chars: 140,
|
|
2464
|
+
* has_attachment: false,
|
|
2465
|
+
* provider_system: 'dialpad',
|
|
2466
|
+
* });
|
|
2467
|
+
* ```
|
|
2468
|
+
*/
|
|
2469
|
+
track<T extends EventType>(eventType: T, payload: EventPayloadMap[T], options?: TrackOptions): void;
|
|
2470
|
+
/**
|
|
2471
|
+
* Set the default actor context for all subsequent tracked events.
|
|
2472
|
+
* Can be overridden per-event via TrackOptions.
|
|
2473
|
+
*
|
|
2474
|
+
* @example
|
|
2475
|
+
* ```ts
|
|
2476
|
+
* truth.identify('user_123', 'user');
|
|
2477
|
+
* ```
|
|
2478
|
+
*/
|
|
2479
|
+
identify(actorId: string, actorType: ActorContext["actorType"]): void;
|
|
2480
|
+
/**
|
|
2481
|
+
* Flush all buffered events immediately. Returns a Promise that resolves
|
|
2482
|
+
* when the flush completes. Use this for graceful shutdown.
|
|
2483
|
+
*
|
|
2484
|
+
* @example
|
|
2485
|
+
* ```ts
|
|
2486
|
+
* process.on('SIGTERM', async () => {
|
|
2487
|
+
* await truth.flush();
|
|
2488
|
+
* process.exit(0);
|
|
2489
|
+
* });
|
|
2490
|
+
* ```
|
|
2491
|
+
*/
|
|
2492
|
+
flush(): Promise<void>;
|
|
2493
|
+
/**
|
|
2494
|
+
* Gracefully shut down the client. Flushes all pending events and
|
|
2495
|
+
* releases resources.
|
|
2496
|
+
*/
|
|
2497
|
+
destroy(): Promise<void>;
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
/**
|
|
2501
|
+
* React hook for fetching an authenticated Dialpad voicemail URL.
|
|
2502
|
+
*
|
|
2503
|
+
* Provides an imperative `fetchUrl` callback that wraps
|
|
2504
|
+
* `client.messages.getVoicemailUrl()` in React state so CommHub's
|
|
2505
|
+
* `AudioPlayer` can replace its urql `useMutation` with a single hook
|
|
2506
|
+
* call, without adding a query library dependency.
|
|
2507
|
+
*
|
|
2508
|
+
* The TruthClient instance is passed directly so the hook is testable
|
|
2509
|
+
* and doesn't require a global singleton or React context.
|
|
2510
|
+
*
|
|
2511
|
+
* @example
|
|
2512
|
+
* ```tsx
|
|
2513
|
+
* import { useVoicemailUrl } from '@hipnation-truth/sdk/react/voicemail';
|
|
2514
|
+
* import { getTruthClient } from '@/lib/truthClient';
|
|
2515
|
+
*
|
|
2516
|
+
* function AudioPlayer({ uri }: { uri: string }) {
|
|
2517
|
+
* const { fetchUrl, url, isLoading, error } = useVoicemailUrl(getTruthClient());
|
|
2518
|
+
*
|
|
2519
|
+
* const handlePlay = async () => {
|
|
2520
|
+
* const authenticated = await fetchUrl(uri);
|
|
2521
|
+
* if (authenticated) { ... }
|
|
2522
|
+
* };
|
|
2523
|
+
* }
|
|
2524
|
+
* ```
|
|
2525
|
+
*/
|
|
2526
|
+
|
|
2527
|
+
interface UseVoicemailUrlResult {
|
|
2528
|
+
/** Trigger the URL fetch. Resolves with the clean playback URL or null on error. */
|
|
2529
|
+
fetchUrl: (voicemailLink: string) => Promise<string | null>;
|
|
2530
|
+
/** The most recently fetched URL (null until first successful fetch). */
|
|
2531
|
+
url: string | null;
|
|
2532
|
+
/** True while the fetch is in-flight. */
|
|
2533
|
+
isLoading: boolean;
|
|
2534
|
+
/** Error message from the last failed fetch, or null. */
|
|
2535
|
+
error: string | null;
|
|
2536
|
+
}
|
|
2537
|
+
/**
|
|
2538
|
+
* Provides an imperative `fetchUrl` callback that authenticates a Dialpad
|
|
2539
|
+
* voicemail link via the Truth SDK `messages.getVoicemailUrl()` method.
|
|
2540
|
+
*
|
|
2541
|
+
* @param client The TruthClient instance (e.g., from `getTruthClient()`).
|
|
2542
|
+
*/
|
|
2543
|
+
declare function useVoicemailUrl(client: TruthClient): UseVoicemailUrlResult;
|
|
2544
|
+
|
|
2545
|
+
export { ACTIVE_CALL_STATES, type Appointment, type AppointmentListOptions, CONNECTED_CALL_STATES, type ConversationListItem, type ConversationMessage, type ConversationMessageRow, type ConversationNoteRow, type ConversationRow, type ConversationTaskForUserRow, type ConversationTaskRow, type DialpadCallLogRow, type DialpadCallRow, DialpadCallState, type EventPayloadMap, type EventType, type FamilyMemberRow, type Patient, type PatientListOptions, type PatientSearchResult, type PermissionStatus, type Physician$1 as Physician, RINGING_CALL_STATES, TERMINAL_CALL_STATES, type TrackOptions, TruthProvider, type TruthProviderProps, type TruthTrackingContextValue, TruthTrackingProvider, type TruthTrackingProviderProps, type UseActiveCallsOptions, type UseAppointmentListOptions, type UseConversationMessagesOptions, type UseConversationsFilters, type UseMessagesOptions, type UseNotificationsOptions, type UseNotificationsResult, type UsePatientBasicOptions, type UsePatientBasicResult, type UsePatientFamilyMembersInput, type UsePatientListOptions, type UsePatientMedicalOptions, type UsePatientPhotoOptions, type UsePatientSearchOptions, type UseQueryResult, useActiveCalls, useAppointment, useAppointmentByElationId, useAppointments, useConversationByPhonePair, useConversationMessages, useConversationNotes, useConversationNotesByPhonePair, useConversationTasks, useConversationTasksByPhonePair, useConversationTasksForUser, useConversations, useDialpadCallByCallId, useDialpadCallLog, useDialpadCallsForConversation, useMessages, useNotifications, usePatient, usePatientBasic, usePatientByElationId, usePatientByHintId, usePatientFamilyMembers, usePatientMedical, usePatientPhoto, usePatientSearch, usePatients, usePatientsByIds, usePatientsByPhones, usePharmacyByNcpdpId, usePhysicianByElationId, usePhysiciansByElationIds, useRemindersForConversations, useTruth, useUnreadCount, useUserSettings, useVoicemailUrl };
|