@healthcloudai/hc-login-connector 0.2.1 → 0.3.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/README.md +141 -81
- package/dist/index.cjs +185 -256
- package/dist/index.d.cts +18 -170
- package/dist/index.d.ts +18 -170
- package/dist/index.js +188 -264
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ below follow the current behavior implemented in `src/client.ts`.
|
|
|
19
19
|
6. Password reset initiation and password reset confirmation
|
|
20
20
|
7. Access token, ID token, tenant, and base URL helper methods
|
|
21
21
|
8. Token refresh using the stored refresh token
|
|
22
|
-
9. Authenticated patient header retrieval through `
|
|
22
|
+
9. Authenticated patient header retrieval through `getPatientHeader()`
|
|
23
23
|
10. Built on the shared Healthcheck HttpClient layer
|
|
24
24
|
|
|
25
25
|
---
|
|
@@ -242,14 +242,14 @@ strings. If a field needs to contain multiple values, serialize those values int
|
|
|
242
242
|
one string value, such as a comma separated list or another separator-separated
|
|
243
243
|
list expected by the integration.
|
|
244
244
|
|
|
245
|
-
`
|
|
245
|
+
`isOTP` is a dedicated boolean option that controls whether `User.Attributes.VERIFY_EMAIL_CODE` is included in the registration payload, depending on whether email verification should be handled through an OTP code.
|
|
246
246
|
|
|
247
|
-
- If `
|
|
248
|
-
- If `
|
|
247
|
+
- If `isOTP` is `true`, the client sends `VERIFY_EMAIL_CODE: "true"`.
|
|
248
|
+
- If `isOTP` is `false` or omitted, `VERIFY_EMAIL_CODE` is not sent.
|
|
249
249
|
|
|
250
250
|
#### OTP-based registration
|
|
251
251
|
|
|
252
|
-
Use this when email verification should be handled through an OTP code. In this case, `
|
|
252
|
+
Use this when email verification should be handled through an OTP code. In this case, `isOTP` should be `true`.
|
|
253
253
|
|
|
254
254
|
```ts
|
|
255
255
|
await loginClient.register(
|
|
@@ -258,7 +258,7 @@ await loginClient.register(
|
|
|
258
258
|
"John",
|
|
259
259
|
"Smith",
|
|
260
260
|
{
|
|
261
|
-
|
|
261
|
+
isOTP: true,
|
|
262
262
|
attributes: {
|
|
263
263
|
Specialty: "Cardiology",
|
|
264
264
|
NPINumber: "1234567890",
|
|
@@ -301,7 +301,7 @@ Request sent for the OTP example above:
|
|
|
301
301
|
|
|
302
302
|
#### Link-based registration
|
|
303
303
|
|
|
304
|
-
Use this when email verification should be handled through an email link. In this case, `
|
|
304
|
+
Use this when email verification should be handled through an email link. In this case, `isOTP` should be omitted or `false`.
|
|
305
305
|
|
|
306
306
|
```ts
|
|
307
307
|
await loginClient.register(
|
|
@@ -354,7 +354,7 @@ Notes:
|
|
|
354
354
|
- `attributes` is the extension point for arbitrary additional registration fields.
|
|
355
355
|
- The module does not need to know custom attribute names in advance.
|
|
356
356
|
- All `attributes` values should be strings. Multi-value attributes should be serialized into one string value, such as a comma separated list or another integration-specific separator-separated list.
|
|
357
|
-
- `
|
|
357
|
+
- `isOTP` takes precedence over any manually provided `VERIFY_EMAIL_CODE` inside `attributes`.
|
|
358
358
|
|
|
359
359
|
---
|
|
360
360
|
|
|
@@ -366,12 +366,12 @@ Registers a patient for the configured tenant using the richer registration payl
|
|
|
366
366
|
|
|
367
367
|
`TenantID` is injected internally from `configure(...)`.
|
|
368
368
|
|
|
369
|
-
`
|
|
369
|
+
`isOTP` behaves the same way as in `register(...)`:
|
|
370
370
|
when enabled, the client injects `VERIFY_EMAIL_CODE: "true"` into `User.Attributes`.
|
|
371
371
|
|
|
372
372
|
#### OTP-based registration
|
|
373
373
|
|
|
374
|
-
Use this when email verification should be handled through an OTP code. In this case, `
|
|
374
|
+
Use this when email verification should be handled through an OTP code. In this case, `isOTP` should be `true`.
|
|
375
375
|
|
|
376
376
|
```ts
|
|
377
377
|
await loginClient.registerFull({
|
|
@@ -389,7 +389,7 @@ await loginClient.registerFull({
|
|
|
389
389
|
genderIdentity: "Male",
|
|
390
390
|
status: 0,
|
|
391
391
|
language: "en",
|
|
392
|
-
|
|
392
|
+
isOTP: true,
|
|
393
393
|
attributes: {
|
|
394
394
|
source: "sdk-test"
|
|
395
395
|
},
|
|
@@ -449,7 +449,7 @@ Request sent for the usage example above:
|
|
|
449
449
|
|
|
450
450
|
#### Link-based registration
|
|
451
451
|
|
|
452
|
-
Use this when email verification should be handled through an email link. In this case, `
|
|
452
|
+
Use this when email verification should be handled through an email link. In this case, `isOTP` should be omitted or `false`.
|
|
453
453
|
|
|
454
454
|
```ts
|
|
455
455
|
await loginClient.registerFull({
|
|
@@ -510,14 +510,14 @@ verification settings.
|
|
|
510
510
|
when email verification should be handled through an OTP code, the client sends
|
|
511
511
|
`VERIFY_EMAIL_CODE: "true"` inside `User.Attributes`.
|
|
512
512
|
|
|
513
|
-
- If `options.
|
|
514
|
-
- The value is sent as a string inside `User.Attributes`, matching the `register(...)` method behavior when `
|
|
515
|
-
- If `options.
|
|
513
|
+
- If `options.isOTP` is `true`, the client sends `VERIFY_EMAIL_CODE: "true"`.
|
|
514
|
+
- The value is sent as a string inside `User.Attributes`, matching the `register(...)` method behavior when `isOTP` is `true`.
|
|
515
|
+
- If `options.isOTP` is `false` or omitted, `VERIFY_EMAIL_CODE` is not sent.
|
|
516
516
|
- Calling `verifyEmail(...)` without `options` keeps OTP email verification disabled by default.
|
|
517
517
|
|
|
518
518
|
#### OTP-based email verification
|
|
519
519
|
|
|
520
|
-
Use this when email verification should be handled through an OTP code. In this case, `options.
|
|
520
|
+
Use this when email verification should be handled through an OTP code. In this case, `options.isOTP` should be `true`.
|
|
521
521
|
|
|
522
522
|
```ts
|
|
523
523
|
await loginClient.verifyEmail(
|
|
@@ -525,7 +525,7 @@ await loginClient.verifyEmail(
|
|
|
525
525
|
"123456",
|
|
526
526
|
"en",
|
|
527
527
|
{
|
|
528
|
-
|
|
528
|
+
isOTP: true
|
|
529
529
|
}
|
|
530
530
|
);
|
|
531
531
|
```
|
|
@@ -552,7 +552,7 @@ Request sent for the OTP example above:
|
|
|
552
552
|
|
|
553
553
|
#### Link-based email verification
|
|
554
554
|
|
|
555
|
-
Use this when email verification should be handled through an email link. In this case, `options.
|
|
555
|
+
Use this when email verification should be handled through an email link. In this case, `options.isOTP` should be omitted or `false`.
|
|
556
556
|
|
|
557
557
|
```ts
|
|
558
558
|
await loginClient.verifyEmail(
|
|
@@ -607,21 +607,21 @@ settings.
|
|
|
607
607
|
when email verification should be handled through an OTP code, the client sends
|
|
608
608
|
`VERIFY_EMAIL_CODE: "true"` inside `User.Attributes`.
|
|
609
609
|
|
|
610
|
-
- If `options.
|
|
611
|
-
- The value is sent as a string inside `User.Attributes`, matching the `register(...)` method behavior when `
|
|
612
|
-
- If `options.
|
|
610
|
+
- If `options.isOTP` is `true`, the client sends `VERIFY_EMAIL_CODE: "true"`.
|
|
611
|
+
- The value is sent as a string inside `User.Attributes`, matching the `register(...)` method behavior when `isOTP` is `true`.
|
|
612
|
+
- If `options.isOTP` is `false` or omitted, `VERIFY_EMAIL_CODE` is not sent.
|
|
613
613
|
- Calling `resendEmailVerify(...)` without `options` keeps OTP email verification disabled by default.
|
|
614
614
|
|
|
615
615
|
#### OTP-based resend
|
|
616
616
|
|
|
617
|
-
Use this when email verification should be handled through an OTP code. In this case, `options.
|
|
617
|
+
Use this when email verification should be handled through an OTP code. In this case, `options.isOTP` should be `true`.
|
|
618
618
|
|
|
619
619
|
```ts
|
|
620
620
|
await loginClient.resendEmailVerify(
|
|
621
621
|
"john.smith@example.com",
|
|
622
622
|
"en",
|
|
623
623
|
{
|
|
624
|
-
|
|
624
|
+
isOTP: true
|
|
625
625
|
}
|
|
626
626
|
);
|
|
627
627
|
```
|
|
@@ -648,7 +648,7 @@ Request sent for the OTP example above:
|
|
|
648
648
|
|
|
649
649
|
#### Link-based resend
|
|
650
650
|
|
|
651
|
-
Use this when email verification should be handled through an email link. In this case, `options.
|
|
651
|
+
Use this when email verification should be handled through an email link. In this case, `options.isOTP` should be omitted or `false`.
|
|
652
652
|
|
|
653
653
|
```ts
|
|
654
654
|
await loginClient.resendEmailVerify(
|
|
@@ -989,20 +989,20 @@ Status:
|
|
|
989
989
|
|
|
990
990
|
### Reset Password
|
|
991
991
|
|
|
992
|
-
`
|
|
992
|
+
`requestPasswordReset` supports both OTP-based and link-based reset initiation
|
|
993
993
|
flows.
|
|
994
994
|
|
|
995
|
-
`
|
|
996
|
-
|
|
997
|
-
|
|
995
|
+
`isOTP` is optional. When it is `true`, the client includes
|
|
996
|
+
`IsPasswordResetWithOTP: true` in the API request. When `false` or omitted, the
|
|
997
|
+
backend field is not sent at all.
|
|
998
998
|
|
|
999
999
|
#### OTP-based password reset initiation
|
|
1000
1000
|
|
|
1001
1001
|
Use this when the password reset flow should be handled through an OTP code.
|
|
1002
|
-
In this case, `
|
|
1002
|
+
In this case, `isOTP` should be `true`.
|
|
1003
1003
|
|
|
1004
1004
|
```ts
|
|
1005
|
-
await loginClient.
|
|
1005
|
+
await loginClient.requestPasswordReset("john.smith@example.com", true);
|
|
1006
1006
|
```
|
|
1007
1007
|
|
|
1008
1008
|
#### Full API request
|
|
@@ -1020,11 +1020,11 @@ await loginClient.resetPassword("john.smith@example.com", true);
|
|
|
1020
1020
|
#### Link-based password reset initiation
|
|
1021
1021
|
|
|
1022
1022
|
Use this when the password reset flow should be handled from an email link.
|
|
1023
|
-
In this case, `
|
|
1023
|
+
In this case, `isOTP` should be omitted by passing `false` or
|
|
1024
1024
|
leaving the second argument out.
|
|
1025
1025
|
|
|
1026
1026
|
```ts
|
|
1027
|
-
await loginClient.
|
|
1027
|
+
await loginClient.requestPasswordReset("john.smith@example.com", false);
|
|
1028
1028
|
```
|
|
1029
1029
|
|
|
1030
1030
|
Effective request body:
|
|
@@ -1061,28 +1061,27 @@ Status:
|
|
|
1061
1061
|
|
|
1062
1062
|
### Reset Password Confirm
|
|
1063
1063
|
|
|
1064
|
-
`
|
|
1064
|
+
`confirmPasswordReset` supports both OTP-based and link-based confirmation
|
|
1065
1065
|
flows.
|
|
1066
1066
|
|
|
1067
|
-
If `
|
|
1068
|
-
|
|
1069
|
-
link-based flow, the frontend is responsible for taking
|
|
1070
|
-
password reset email link and passing that token in the
|
|
1067
|
+
If `isOTP` is `true`, `Code` is required. If `isOTP` is not `true`, `Token` is
|
|
1068
|
+
required. The client maps `isOTP: true` to `IsPasswordResetWithOTP: true` in the
|
|
1069
|
+
API request. For the link-based flow, the frontend is responsible for taking
|
|
1070
|
+
the token from the password reset email link and passing that token in the
|
|
1071
|
+
payload.
|
|
1071
1072
|
|
|
1072
1073
|
#### OTP-based password reset confirmation
|
|
1073
1074
|
|
|
1074
1075
|
Use this when the password reset flow was started with OTP. In this case,
|
|
1075
|
-
`
|
|
1076
|
+
`isOTP` should be `true` and `Code` should contain the final
|
|
1076
1077
|
reset code.
|
|
1077
1078
|
|
|
1078
1079
|
```ts
|
|
1079
|
-
await loginClient.
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
Code: "123456"
|
|
1085
|
-
}
|
|
1080
|
+
await loginClient.confirmPasswordReset({
|
|
1081
|
+
Email: "john.smith@example.com",
|
|
1082
|
+
Password: "ExamplePassword123!",
|
|
1083
|
+
isOTP: true,
|
|
1084
|
+
Code: "123456"
|
|
1086
1085
|
});
|
|
1087
1086
|
```
|
|
1088
1087
|
|
|
@@ -1105,15 +1104,13 @@ Request body:
|
|
|
1105
1104
|
Use this when the password reset flow was started from an email link. In this
|
|
1106
1105
|
case, `Token` should be included in the payload, the frontend should read the
|
|
1107
1106
|
token value from the password reset email link and send that token in the
|
|
1108
|
-
request payload, and `
|
|
1107
|
+
request payload, and `isOTP` should be omitted or `false`.
|
|
1109
1108
|
|
|
1110
1109
|
```ts
|
|
1111
|
-
await loginClient.
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
Token: "token-from-email-link"
|
|
1116
|
-
}
|
|
1110
|
+
await loginClient.confirmPasswordReset({
|
|
1111
|
+
Email: "john.smith@example.com",
|
|
1112
|
+
Password: "ExamplePassword123!",
|
|
1113
|
+
Token: "token-from-email-link"
|
|
1117
1114
|
});
|
|
1118
1115
|
```
|
|
1119
1116
|
|
|
@@ -1240,19 +1237,19 @@ If an API key has been configured through setApiKey(...), the returned header ob
|
|
|
1240
1237
|
|
|
1241
1238
|
---
|
|
1242
1239
|
|
|
1243
|
-
### Get
|
|
1240
|
+
### Get Patient Header
|
|
1244
1241
|
|
|
1245
|
-
Public signature: `loginClient.
|
|
1242
|
+
Public signature: `loginClient.getPatientHeader()`
|
|
1246
1243
|
|
|
1247
1244
|
Calls the patient header endpoint and returns the raw server response.
|
|
1248
1245
|
It requires a stored ID token.
|
|
1249
1246
|
|
|
1250
1247
|
```ts
|
|
1251
|
-
const
|
|
1248
|
+
const header = await loginClient.getPatientHeader();
|
|
1252
1249
|
```
|
|
1253
1250
|
|
|
1254
1251
|
#### Full API request
|
|
1255
|
-
`
|
|
1252
|
+
`getPatientHeader()` does not send a request body.
|
|
1256
1253
|
|
|
1257
1254
|
#### API response
|
|
1258
1255
|
|
|
@@ -1266,42 +1263,60 @@ Status:
|
|
|
1266
1263
|
{
|
|
1267
1264
|
"Data": {
|
|
1268
1265
|
"Record": {
|
|
1269
|
-
"
|
|
1270
|
-
"
|
|
1266
|
+
"Status": 1,
|
|
1267
|
+
"Sex": "Male",
|
|
1268
|
+
"GenderIdentity": "Male",
|
|
1269
|
+
"HasInsurance": true,
|
|
1270
|
+
"HasIDCard": true,
|
|
1271
|
+
"HasSelfie": true,
|
|
1272
|
+
"Flags": null,
|
|
1271
1273
|
"FirstName": "John",
|
|
1272
1274
|
"LastName": "Smith",
|
|
1275
|
+
"MiddleName": null,
|
|
1276
|
+
"BirthDate": "1990-01-01T00:00:00",
|
|
1273
1277
|
"Email": "john.smith@example.com",
|
|
1274
1278
|
"Phone": "+15555550123",
|
|
1275
|
-
"
|
|
1276
|
-
"Gender": "male",
|
|
1277
|
-
"Sex": "Male",
|
|
1279
|
+
"Gender": "Male",
|
|
1278
1280
|
"Race": "White",
|
|
1279
|
-
"Ethnicity": "
|
|
1280
|
-
"
|
|
1281
|
-
"
|
|
1282
|
-
"HasSelfie": false,
|
|
1281
|
+
"Ethnicity": "",
|
|
1282
|
+
"CRMID": null,
|
|
1283
|
+
"AppleUserId": null,
|
|
1283
1284
|
"Address": {
|
|
1284
|
-
"StreetAndNumber": "
|
|
1285
|
+
"StreetAndNumber": "1 Main St",
|
|
1285
1286
|
"Extension": null,
|
|
1286
1287
|
"City": "Springfield",
|
|
1287
|
-
"State": "
|
|
1288
|
-
"PostalCode": "
|
|
1288
|
+
"State": "IL",
|
|
1289
|
+
"PostalCode": "62701",
|
|
1289
1290
|
"Country": "US"
|
|
1290
1291
|
},
|
|
1291
1292
|
"Attributes": {
|
|
1292
|
-
"
|
|
1293
|
-
"
|
|
1294
|
-
"
|
|
1293
|
+
"AthenaPatientID": "patient-id-example",
|
|
1294
|
+
"AthenaGuarantorFirstName": "John",
|
|
1295
|
+
"AthenaGuarantorLastName": "Smith",
|
|
1296
|
+
"AthenaGuarantorEmail": "john.smith@example.com",
|
|
1297
|
+
"AthenaCountryCode": "USA",
|
|
1298
|
+
"AthenaDepartmentId": "1",
|
|
1299
|
+
"AthenaEmailExists": "True",
|
|
1300
|
+
"AthenaTestPatient": "False",
|
|
1301
|
+
"PatientImageURL": "https://storage.example.com/selfie_example.jpg",
|
|
1302
|
+
"CompositeID": "tenant-id/john.smith@example.com",
|
|
1303
|
+
"Insurance": "EXAMPLE INSURANCE"
|
|
1295
1304
|
},
|
|
1296
|
-
"CompositeID": "
|
|
1297
|
-
"FHIRID": "fhir-id-example"
|
|
1305
|
+
"CompositeID": "tenant-id/john.smith@example.com",
|
|
1306
|
+
"FHIRID": "fhir-id-example",
|
|
1307
|
+
"AthenaID": "patient-id-example",
|
|
1308
|
+
"Created": "0001-01-01T00:00:00",
|
|
1309
|
+
"Modified": "0001-01-01T00:00:00",
|
|
1310
|
+
"CreatedByID": null,
|
|
1311
|
+
"ModifiedByID": null,
|
|
1312
|
+
"IsDeactivated": false,
|
|
1313
|
+
"TenantID": "test-tenant",
|
|
1314
|
+
"ID": "record-uuid-example"
|
|
1298
1315
|
},
|
|
1299
1316
|
"Encounters": null,
|
|
1300
|
-
"EHR": "
|
|
1317
|
+
"EHR": "athena",
|
|
1301
1318
|
"PendingActions": [
|
|
1302
|
-
"
|
|
1303
|
-
"ADD_ID",
|
|
1304
|
-
"IMPORT_VITALS"
|
|
1319
|
+
"TAKE_TEST"
|
|
1305
1320
|
]
|
|
1306
1321
|
},
|
|
1307
1322
|
"ErrorMessage": null,
|
|
@@ -1369,10 +1384,47 @@ eyJ_id_token_example
|
|
|
1369
1384
|
- Use `submitOnboardingStep(...)` or the onboarding helper methods to complete required onboarding steps.
|
|
1370
1385
|
- Call `login(...)` to authenticate and store the returned access, refresh, and ID tokens in memory.
|
|
1371
1386
|
- Use `refreshToken()` to replace the current token set when a stored refresh token is available.
|
|
1372
|
-
- Use `getAuthHeader()`, `getAccessToken()`, `getIDToken()`, and `
|
|
1387
|
+
- Use `getAuthHeader()`, `getAccessToken()`, `getIDToken()`, and `getPatientHeader()` for authenticated flows after login.
|
|
1373
1388
|
- Other Healthcheck connectors can consume `getAuthHeader()` instead of managing auth tokens directly.
|
|
1374
1389
|
|
|
1375
1390
|
|
|
1391
|
+
## Token Expiry and Refresh
|
|
1392
|
+
|
|
1393
|
+
The SDK does **not** auto-refresh tokens. Call `refreshToken()` proactively when the token is about to expire.
|
|
1394
|
+
|
|
1395
|
+
`getTokens()` returns the current in-memory token set, including `expiresAt` — an absolute Unix millisecond timestamp parsed from the `Expiration` field the backend returns.
|
|
1396
|
+
|
|
1397
|
+
`isTokenExpired()` is a helper that returns `true` when there is no stored token or when `Date.now() >= expiresAt`.
|
|
1398
|
+
|
|
1399
|
+
Recommended pattern:
|
|
1400
|
+
|
|
1401
|
+
```ts
|
|
1402
|
+
async function ensureFreshToken(loginClient: HCLoginClient): Promise<void> {
|
|
1403
|
+
if (loginClient.isTokenExpired()) {
|
|
1404
|
+
await loginClient.refreshToken();
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// Call before any authenticated connector operation
|
|
1409
|
+
await ensureFreshToken(loginClient);
|
|
1410
|
+
const result = await otherConnector.someMethod();
|
|
1411
|
+
```
|
|
1412
|
+
|
|
1413
|
+
`getTokens()` shape:
|
|
1414
|
+
|
|
1415
|
+
```ts
|
|
1416
|
+
interface AuthTokens {
|
|
1417
|
+
accessToken: string;
|
|
1418
|
+
refreshToken: string;
|
|
1419
|
+
idToken: string | null;
|
|
1420
|
+
expiresAt: number; // absolute milliseconds since Unix epoch
|
|
1421
|
+
}
|
|
1422
|
+
```
|
|
1423
|
+
|
|
1424
|
+
`refreshToken()` does not require a current ID token. It uses the stored refresh token from the previous successful `login()` call.
|
|
1425
|
+
|
|
1426
|
+
---
|
|
1427
|
+
|
|
1376
1428
|
## Notes
|
|
1377
1429
|
|
|
1378
1430
|
- `configure()` stores tenant configuration locally and does not send an HTTP request.
|
|
@@ -1380,7 +1432,15 @@ eyJ_id_token_example
|
|
|
1380
1432
|
- `register()`, `verifyEmail()`, and `resendEmailVerify()` all follow the same string-based `User.Attributes.VERIFY_EMAIL_CODE` pattern for OTP email verification flows.
|
|
1381
1433
|
- `saveAddress()` accepts an `Address`.
|
|
1382
1434
|
- `login()` stores the initial token set internally, and `refreshToken()` updates that stored token set when a refresh token is available.
|
|
1383
|
-
- `
|
|
1384
|
-
- `
|
|
1385
|
-
- `getAuthHeader()`, `getAccessToken()`, `getIDToken()`, `getBaseUrl()`, and `
|
|
1435
|
+
- `getPatientHeader()` calls the patient header endpoint.
|
|
1436
|
+
- `getAuthHeader()` returns `Authorization: Bearer <idToken>` + `X-Tenant-ID`. It does **not** carry an API key — each connector adds its own key independently.
|
|
1437
|
+
- `getAuthHeader()`, `getAccessToken()`, `getIDToken()`, `getBaseUrl()`, `getTenantId()`, `getTokens()`, and `isTokenExpired()` return or evaluate local values and do not perform HTTP requests.
|
|
1386
1438
|
- This connector is intended to be reused by other Healthcheck SDK connectors built on the same HTTP layer.
|
|
1439
|
+
|
|
1440
|
+
---
|
|
1441
|
+
|
|
1442
|
+
## getPatientHeader vs getDashboard
|
|
1443
|
+
|
|
1444
|
+
`HCLoginClient.getPatientHeader()` calls `/api/patient/header` and returns a lightweight patient record plus pending actions. Typically called once after login to check patient state.
|
|
1445
|
+
|
|
1446
|
+
`HCSettingsClient.getDashboard()` (in `hc-settings-connector`) calls `/api/patient/dashboard` and returns a richer dashboard including encounters. These are different endpoints with different response shapes — not duplicates.
|