@benup/bensdk 1.11.13 → 1.11.14

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.
@@ -2,11 +2,13 @@ import z from 'zod';
2
2
  import { EmploymentContracts } from '@benup-dev/benup-api';
3
3
  import { AxiosInstance } from 'axios';
4
4
  import { BenefitDefinitionSchema } from '../schemas/benefit-definition.schema';
5
+ import { LockHelper } from './lib/lock-helper.lib.type';
5
6
  import { TokenHelper } from './lib/token-helper.lib.type';
6
7
  import { StateHandlerCtx, WebhookRequest, WebhookResponse } from './state-handler.types';
7
8
  type Base = z.infer<typeof BenefitDefinitionSchema>;
8
9
  export type AuthHandlerCtx = {
9
10
  tokenHelper: TokenHelper;
11
+ lockHelper: LockHelper;
10
12
  employmentContract: z.infer<typeof EmploymentContracts.default.collection.default>;
11
13
  };
12
14
  export type AuthHandlerResult = {
@@ -22,8 +24,23 @@ export type CredentialsHealthCheckResult = {
22
24
  reason?: string;
23
25
  } | {
24
26
  outcome: 'SUCCEEDED';
27
+ } | {
28
+ outcome: 'RETRY';
29
+ reason?: string;
25
30
  };
26
31
  export type BenefitDefinition = Omit<Base, 'stateMachine'> & {
32
+ /**
33
+ * Defines if the benefit integrates via file-exchange
34
+ * if so it should define which engine-type use via type
35
+ * which mime-type of file generated a csv? so 'text/csv'
36
+ * and template field defines other name for template used file, the default is
37
+ * looking for #shared/definitions/benefitID/template.handlebars so it will become -> #shared/definitions/benefitID/{{template}}
38
+ */
39
+ fileIntegration?: {
40
+ type: 'handlebars';
41
+ mime: 'text/csv' | 'text/plain';
42
+ template?: string;
43
+ };
27
44
  stateMachine: Base['stateMachine'] & {
28
45
  DEDUCTION_FILE_INGESTION?: {
29
46
  REQUESTED_DEDUCTION_FILE_INGESTION: {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Type definition for distributed lock helper
3
+ *
4
+ * Problem: Multiple action-consumer instances process messages in "parallel" and call
5
+ * auth handlers concurrently. When tokens are not cached, this causes simultaneous
6
+ * API calls to vendor's auth endpoint, resulting in:
7
+ * - Rate limiting issues
8
+ * - Redundant credential exchanges
9
+ * - Potential auth failures
10
+ *
11
+ * Solution: Use a distributed lock (Redis-based) to ensure only one instance authenticates
12
+ * at a time. This is a "partial" solution that fails open gracefully: if Redis is unavailable,
13
+ * locks cannot be acquired and the message will be retried.
14
+ *
15
+ * Implementation: See auth-lock.ts for the Redis-based implementation
16
+ */
17
+ export type LockHelper = {
18
+ /**
19
+ * Executes a function while holding a lock
20
+ * If lock cannot be acquired, throws an error
21
+ * @param key - Lock key
22
+ * @param fn - Function to execute
23
+ * @returns Result of function
24
+ */
25
+ executeWithLock: <T>(key: string, fn: () => Promise<T>) => Promise<T>;
26
+ };
@@ -68,6 +68,10 @@ export interface StateHandlerCtx {
68
68
  * benefitPartnerAPI Axios instance
69
69
  */
70
70
  benefitPartnerAPI?: AxiosInstance;
71
+ /**
72
+ * dataGatewayAPI Axios instance
73
+ */
74
+ dataGatewayAPI: AxiosInstance;
71
75
  /**
72
76
  * deductionFileIngestionHelper
73
77
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benup/bensdk",
3
- "version": "1.11.13",
3
+ "version": "1.11.14",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {