@benup/bensdk 1.11.12 → 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 = {
|
|
@@ -17,7 +19,28 @@ export type AuthHandlerResult = {
|
|
|
17
19
|
outcome: 'SUCCEEDED';
|
|
18
20
|
instance?: AxiosInstance;
|
|
19
21
|
};
|
|
22
|
+
export type CredentialsHealthCheckResult = {
|
|
23
|
+
outcome: 'FAILED';
|
|
24
|
+
reason?: string;
|
|
25
|
+
} | {
|
|
26
|
+
outcome: 'SUCCEEDED';
|
|
27
|
+
} | {
|
|
28
|
+
outcome: 'RETRY';
|
|
29
|
+
reason?: string;
|
|
30
|
+
};
|
|
20
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
|
+
};
|
|
21
44
|
stateMachine: Base['stateMachine'] & {
|
|
22
45
|
DEDUCTION_FILE_INGESTION?: {
|
|
23
46
|
REQUESTED_DEDUCTION_FILE_INGESTION: {
|
|
@@ -35,6 +58,7 @@ export type BenefitDefinition = Omit<Base, 'stateMachine'> & {
|
|
|
35
58
|
};
|
|
36
59
|
auth?: {
|
|
37
60
|
handler: (credentials: any, ctx: any) => Promise<AuthHandlerResult>;
|
|
61
|
+
credentialsHealthCheckHandler?: (credentials: any) => Promise<CredentialsHealthCheckResult>;
|
|
38
62
|
};
|
|
39
63
|
};
|
|
40
64
|
export {};
|
|
@@ -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
|
+
};
|