vet-sdk-core-ts 0.4.3 → 0.4.5

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 CHANGED
@@ -6,6 +6,31 @@ UHC SDK packages and must not import them.
6
6
  The SDK consumes governed browser-safe values from `vet-data-utils-ts` and
7
7
  owns gateway request construction. GW VET remains the policy authority.
8
8
 
9
+ ## Professional break-glass authorization
10
+
11
+ Node BFFs call `buildVeterinaryBreakGlassSmartAuthorization` with only the
12
+ animal DID, governed sections, incident id and clinical justification. The
13
+ result can be passed directly to
14
+ `ServerProfileSessionManager.openProfessional().requestSmartToken(...)`.
15
+ It contains the veterinary purpose, scope, 15-minute cap and audited emergency
16
+ claims, but never a `client_id`, SMART audience, private-key assertion or VP.
17
+ Those OpenID proofs are reconstructed and signed by the registered server
18
+ wallet in `gdc-sdk-node-ts`.
19
+
20
+ ```ts
21
+ const authorization = buildVeterinaryBreakGlassSmartAuthorization({
22
+ subjectDid,
23
+ requestedSections,
24
+ incidentId,
25
+ justification,
26
+ })
27
+
28
+ await openedProfessional.requestSmartToken(authorization)
29
+ ```
30
+
31
+ `buildVeterinaryBreakGlassSmartRequest` remains only as a low-level
32
+ compatibility envelope for integrations that already own the OpenID fields.
33
+
9
34
  The numeric animal identity and external evidence contract is documented in
10
35
  [`docs/ANIMAL_IDENTITY.md`](docs/ANIMAL_IDENTITY.md).
11
36
 
@@ -41,7 +66,10 @@ findVetChainSpeciesByTaxonomyId("9685")?.key; // "Cat"
41
66
  `buildVeterinaryDigitalTwinSearchRequest` accepts only one governed section,
42
67
  selected resource families, display text and dates. It returns both the FHIR
43
68
  `Parameters` body and the `filters` map for `DigitalTwinSdk.search`; callers do
44
- not author `Composition.section` or resource claim names.
69
+ not author `Composition.section` or resource claim names. The returned public
70
+ resource is `ResearchSubject`, so the Node SDK sends
71
+ `POST digitaltwin/.../ResearchSubject/_search`; the `Composition.*` fields
72
+ filter the canonical Composition embedded in that ResearchSubject.
45
73
 
46
74
  ```ts
47
75
  const request = buildVeterinaryDigitalTwinSearchRequest({
@@ -26,9 +26,29 @@ export type VeterinaryBreakGlassSmartRequest = Readonly<{
26
26
  }>;
27
27
  }>;
28
28
  }>;
29
+ /**
30
+ * Business-only SMART authorization consumed by a high-level professional
31
+ * runtime. Wallet keys, client identifiers, audiences, JWT assertions and VPs
32
+ * deliberately do not belong to this browser-safe contract.
33
+ */
34
+ export type VeterinaryBreakGlassSmartAuthorization = Readonly<{
35
+ subjectDid: string;
36
+ purpose: 'EMERGENCY';
37
+ scopes: readonly [string];
38
+ acrValues: 'urn:antifraud:acr:openid4vp:employee';
39
+ requestBodyClaims: Readonly<{
40
+ expires_in: number;
41
+ break_glass: Readonly<{
42
+ incidentId: string;
43
+ subjectKind: 'animal';
44
+ reasonCode: 'animal-emergency';
45
+ justification: string;
46
+ }>;
47
+ }>;
48
+ }>;
29
49
  export type VeterinaryDigitalTwinSearchRequest = Readonly<{
30
50
  format: VeterinaryDigitalTwinFormat;
31
- resourceType: 'Composition';
51
+ resourceType: 'ResearchSubject';
32
52
  filters: Readonly<Record<string, string | readonly string[]>>;
33
53
  payload: Readonly<{
34
54
  thid: string;
@@ -36,6 +56,23 @@ export type VeterinaryDigitalTwinSearchRequest = Readonly<{
36
56
  }>;
37
57
  }>;
38
58
  export declare function buildVetGatewayRoutePrefix(context: VetGatewayRouteContext): string;
59
+ /**
60
+ * Converts the portal's governed emergency form into the business fields for
61
+ * `ServerProfileSessionManager.openProfessional().requestSmartToken(...)`.
62
+ * The Node SDK derives and signs every OpenID/VP field from the registered
63
+ * wallet; the portal never supplies or persists that plumbing.
64
+ */
65
+ export declare function buildVeterinaryBreakGlassSmartAuthorization(input: Readonly<{
66
+ subjectDid: string;
67
+ requestedSections: readonly string[];
68
+ incidentId: string;
69
+ justification: string;
70
+ }>): VeterinaryBreakGlassSmartAuthorization;
71
+ /**
72
+ * Low-level compatibility envelope for callers that already own OpenID
73
+ * plumbing. New Node BFFs should use
74
+ * `buildVeterinaryBreakGlassSmartAuthorization` with `openProfessional`.
75
+ */
39
76
  export declare function buildVeterinaryBreakGlassSmartRequest(input: Readonly<{
40
77
  thid: string;
41
78
  actorDid: string;
@@ -50,8 +87,9 @@ export declare function buildVeterinaryBreakGlassSmartRequest(input: Readonly<{
50
87
  }>): VeterinaryBreakGlassSmartRequest;
51
88
  /**
52
89
  * Converts browser-safe search values into both FHIR Parameters and the exact
53
- * filter map accepted by the Node DigitalTwin SDK. Callers never choose flat
54
- * claim names.
90
+ * filter map accepted by the Node DigitalTwin SDK. The public twin resource is
91
+ * ResearchSubject; Composition.* filters address its embedded canonical
92
+ * Composition index. Callers never choose flat claim names.
55
93
  */
56
94
  export declare function buildVeterinaryDigitalTwinSearchRequest(input: Readonly<{
57
95
  thid: string;
@@ -6,11 +6,41 @@ export function buildVetGatewayRoutePrefix(context) {
6
6
  throw new TypeError('vet_gateway_jurisdiction_invalid');
7
7
  return `/${tenantId}/cds-${jurisdiction}/v1/${context.sector}`;
8
8
  }
9
- export function buildVeterinaryBreakGlassSmartRequest(input) {
9
+ /**
10
+ * Converts the portal's governed emergency form into the business fields for
11
+ * `ServerProfileSessionManager.openProfessional().requestSmartToken(...)`.
12
+ * The Node SDK derives and signs every OpenID/VP field from the registered
13
+ * wallet; the portal never supplies or persists that plumbing.
14
+ */
15
+ export function buildVeterinaryBreakGlassSmartAuthorization(input) {
10
16
  const emergency = parseVeterinaryBreakGlassRequestData(input);
11
- const actorDid = did(input.actorDid, 'vet_break_glass_actor_invalid');
12
17
  const section = emergency.requestedSections.join(',');
13
18
  const scope = `organization/Composition.rs?subject=${encodeURIComponent(emergency.subjectDid)}&section=${encodeURIComponent(section)}`;
19
+ return Object.freeze({
20
+ subjectDid: emergency.subjectDid,
21
+ purpose: 'EMERGENCY',
22
+ scopes: Object.freeze([scope]),
23
+ acrValues: 'urn:antifraud:acr:openid4vp:employee',
24
+ requestBodyClaims: Object.freeze({
25
+ expires_in: VeterinaryBreakGlassMaxLifetimeSeconds,
26
+ break_glass: Object.freeze({
27
+ incidentId: emergency.incidentId,
28
+ subjectKind: emergency.subjectKind,
29
+ reasonCode: emergency.reasonCode,
30
+ justification: emergency.justification,
31
+ }),
32
+ }),
33
+ });
34
+ }
35
+ /**
36
+ * Low-level compatibility envelope for callers that already own OpenID
37
+ * plumbing. New Node BFFs should use
38
+ * `buildVeterinaryBreakGlassSmartAuthorization` with `openProfessional`.
39
+ */
40
+ export function buildVeterinaryBreakGlassSmartRequest(input) {
41
+ const emergency = parseVeterinaryBreakGlassRequestData(input);
42
+ const actorDid = did(input.actorDid, 'vet_break_glass_actor_invalid');
43
+ const authorization = buildVeterinaryBreakGlassSmartAuthorization(emergency);
14
44
  return Object.freeze({
15
45
  thid: bounded(input.thid, 'thid'),
16
46
  iss: actorDid,
@@ -21,23 +51,19 @@ export function buildVeterinaryBreakGlassSmartRequest(input) {
21
51
  client_assertion: bounded(input.clientAssertion, 'clientAssertion'),
22
52
  client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
23
53
  vp_token: bounded(input.vpToken, 'vpToken'),
24
- acr_values: 'urn:antifraud:acr:openid4vp:employee',
25
- purpose: 'EMERGENCY',
26
- scope,
27
- expires_in: VeterinaryBreakGlassMaxLifetimeSeconds,
28
- break_glass: {
29
- incidentId: emergency.incidentId,
30
- subjectKind: emergency.subjectKind,
31
- reasonCode: emergency.reasonCode,
32
- justification: emergency.justification,
33
- },
54
+ acr_values: authorization.acrValues,
55
+ purpose: authorization.purpose,
56
+ scope: authorization.scopes[0],
57
+ expires_in: authorization.requestBodyClaims.expires_in,
58
+ break_glass: authorization.requestBodyClaims.break_glass,
34
59
  },
35
60
  });
36
61
  }
37
62
  /**
38
63
  * Converts browser-safe search values into both FHIR Parameters and the exact
39
- * filter map accepted by the Node DigitalTwin SDK. Callers never choose flat
40
- * claim names.
64
+ * filter map accepted by the Node DigitalTwin SDK. The public twin resource is
65
+ * ResearchSubject; Composition.* filters address its embedded canonical
66
+ * Composition index. Callers never choose flat claim names.
41
67
  */
42
68
  export function buildVeterinaryDigitalTwinSearchRequest(input) {
43
69
  const search = parseVeterinaryDigitalTwinSearch(input.search);
@@ -67,14 +93,14 @@ export function buildVeterinaryDigitalTwinSearchRequest(input) {
67
93
  return Object.freeze({
68
94
  format,
69
95
  filters: Object.freeze(filters),
70
- // GW stores the pseudonymous twin as a Composition. The selected nested
71
- // resource families become repeated Parameters entries; they never change
72
- // the asynchronous route resource type.
73
- resourceType: 'Composition',
96
+ // ResearchSubject is the public twin. Its embedded canonical Composition
97
+ // indexes the selected nested resource families as repeated Parameters;
98
+ // those filters never change the asynchronous route resource type.
99
+ resourceType: 'ResearchSubject',
74
100
  payload: {
75
101
  thid: bounded(input.thid, 'thid'),
76
102
  body: format === VeterinaryDigitalTwinFormats.Api
77
- ? { data: [{ type: 'Composition-search-request-v1.0', resource: { resourceType: 'Parameters', parameter } }] }
103
+ ? { data: [{ type: 'ResearchSubject-search-request-v1.0', resource: { resourceType: 'Parameters', parameter } }] }
78
104
  : { resourceType: 'Parameters', parameter },
79
105
  },
80
106
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vet-sdk-core-ts",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Browser-safe VetChain core contracts and governed animal species identifiers",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Connecting Solution & Applications Ltd",