@fiado/api-invoker 5.11.0 → 5.13.0
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/bin/biometrics-business/BiometricsBusinessApi.d.ts +27 -0
- package/bin/biometrics-business/BiometricsBusinessApi.js +55 -0
- package/bin/biometrics-business/index.d.ts +2 -0
- package/bin/biometrics-business/index.js +2 -0
- package/bin/biometrics-business/interfaces/IBiometricsBusinessApi.d.ts +55 -0
- package/bin/biometrics-business/interfaces/IBiometricsBusinessApi.js +1 -0
- package/bin/container.config.js +2 -0
- package/bin/index.d.ts +1 -0
- package/bin/index.js +1 -0
- package/bin/zendesk/ZendeskApi.d.ts +2 -0
- package/bin/zendesk/ZendeskApi.js +4 -0
- package/bin/zendesk/interfaces/IZendeskApi.d.ts +7 -0
- package/package.json +2 -2
- package/src/biometrics-business/BiometricsBusinessApi.ts +59 -0
- package/src/biometrics-business/index.ts +2 -0
- package/src/biometrics-business/interfaces/IBiometricsBusinessApi.ts +69 -0
- package/src/container.config.ts +3 -0
- package/src/index.ts +1 -0
- package/src/zendesk/ZendeskApi.ts +6 -0
- package/src/zendesk/interfaces/IZendeskApi.ts +8 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IBiometricsBusinessApi } from "./interfaces/IBiometricsBusinessApi.js";
|
|
2
|
+
import type { BiometricVerificationChangedV1, BiometricVerificationResponse, CreateBiometricVerificationRequest } from "@fiado/type-kit/bin/biometrics/index.js";
|
|
3
|
+
import type { ApiGatewayResponse } from "@fiado/gateway-adapter";
|
|
4
|
+
import type { IHttpRequest } from "@fiado/http-client";
|
|
5
|
+
/**
|
|
6
|
+
* Implementación del cliente de `biometrics-business`. Ver `IBiometricsBusinessApi` para el
|
|
7
|
+
* contrato y el manejo de respuestas.
|
|
8
|
+
*
|
|
9
|
+
* El `/private` NO va en el path: lo aporta el `baseUrl` que se resuelve del SSM.
|
|
10
|
+
*/
|
|
11
|
+
export default class BiometricsBusinessApi implements IBiometricsBusinessApi {
|
|
12
|
+
private httpRequest;
|
|
13
|
+
/**
|
|
14
|
+
* ⚠️ Se le quita el slash final y los paths lo ponen explícito.
|
|
15
|
+
*
|
|
16
|
+
* No es cosmético: hay dos convenciones conviviendo en esta lib. `MetamapConnectorApi` hace
|
|
17
|
+
* `${baseUrl}facematch/signature` — o sea que **depende** de que el SSM devuelva la URL
|
|
18
|
+
* terminada en `/`, y si algún día no la devuelve así arma `...v1/privatefacematch/signature`
|
|
19
|
+
* y el 404 no dice por qué. `KycVerificationsBusinessApi` normaliza. Acá se sigue el segundo,
|
|
20
|
+
* que funciona con las dos formas.
|
|
21
|
+
*/
|
|
22
|
+
private readonly baseUrl;
|
|
23
|
+
constructor(httpRequest: IHttpRequest);
|
|
24
|
+
createBiometricVerification(data: CreateBiometricVerificationRequest): Promise<ApiGatewayResponse<BiometricVerificationResponse>>;
|
|
25
|
+
getBiometricVerification(biometricVerificationId: string): Promise<ApiGatewayResponse<BiometricVerificationResponse>>;
|
|
26
|
+
applyBiometricEvent(biometricVerificationId: string, data: BiometricVerificationChangedV1): Promise<ApiGatewayResponse<void>>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { inject, injectable } from "inversify";
|
|
14
|
+
/**
|
|
15
|
+
* Implementación del cliente de `biometrics-business`. Ver `IBiometricsBusinessApi` para el
|
|
16
|
+
* contrato y el manejo de respuestas.
|
|
17
|
+
*
|
|
18
|
+
* El `/private` NO va en el path: lo aporta el `baseUrl` que se resuelve del SSM.
|
|
19
|
+
*/
|
|
20
|
+
let BiometricsBusinessApi = class BiometricsBusinessApi {
|
|
21
|
+
httpRequest;
|
|
22
|
+
/**
|
|
23
|
+
* ⚠️ Se le quita el slash final y los paths lo ponen explícito.
|
|
24
|
+
*
|
|
25
|
+
* No es cosmético: hay dos convenciones conviviendo en esta lib. `MetamapConnectorApi` hace
|
|
26
|
+
* `${baseUrl}facematch/signature` — o sea que **depende** de que el SSM devuelva la URL
|
|
27
|
+
* terminada en `/`, y si algún día no la devuelve así arma `...v1/privatefacematch/signature`
|
|
28
|
+
* y el 404 no dice por qué. `KycVerificationsBusinessApi` normaliza. Acá se sigue el segundo,
|
|
29
|
+
* que funciona con las dos formas.
|
|
30
|
+
*/
|
|
31
|
+
baseUrl = (process.env.BIOMETRICS_BUSINESS_LAMBDA_URL || "").replace(/\/+$/, "");
|
|
32
|
+
constructor(httpRequest) {
|
|
33
|
+
this.httpRequest = httpRequest;
|
|
34
|
+
}
|
|
35
|
+
async createBiometricVerification(data) {
|
|
36
|
+
const url = `${this.baseUrl}/biometric-verifications`;
|
|
37
|
+
return await this.httpRequest.post(url, data);
|
|
38
|
+
}
|
|
39
|
+
async getBiometricVerification(biometricVerificationId) {
|
|
40
|
+
// encodeURIComponent y no interpolación pelada: el id va en el path, y aunque hoy lo genera
|
|
41
|
+
// biometrics-business, el día que un caller pase basura preferimos un 404 a una URL rota.
|
|
42
|
+
const url = `${this.baseUrl}/biometric-verifications/${encodeURIComponent(biometricVerificationId)}`;
|
|
43
|
+
return await this.httpRequest.get(url);
|
|
44
|
+
}
|
|
45
|
+
async applyBiometricEvent(biometricVerificationId, data) {
|
|
46
|
+
const url = `${this.baseUrl}/biometric-verifications/${encodeURIComponent(biometricVerificationId)}/events`;
|
|
47
|
+
return await this.httpRequest.post(url, data);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
BiometricsBusinessApi = __decorate([
|
|
51
|
+
injectable(),
|
|
52
|
+
__param(0, inject("IHttpRequest")),
|
|
53
|
+
__metadata("design:paramtypes", [Object])
|
|
54
|
+
], BiometricsBusinessApi);
|
|
55
|
+
export default BiometricsBusinessApi;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BiometricVerificationChangedV1, BiometricVerificationResponse, CreateBiometricVerificationRequest } from "@fiado/type-kit/bin/biometrics/index.js";
|
|
2
|
+
import type { ApiGatewayResponse } from "@fiado/gateway-adapter";
|
|
3
|
+
/**
|
|
4
|
+
* Cliente de `biometrics-business`, el master de la lógica biométrica de Fiado.
|
|
5
|
+
*
|
|
6
|
+
* Tres endpoints privados (VPC-only) con DOS audiencias distintas:
|
|
7
|
+
*
|
|
8
|
+
* - **Cualquier producto que necesite un biométrico** usa `createBiometricVerification` +
|
|
9
|
+
* `getBiometricVerification` (polling).
|
|
10
|
+
* - **`kyc-metamap-webhook` y solo él** usa `applyBiometricEvent`, para avisar que llegó un
|
|
11
|
+
* resultado del proveedor.
|
|
12
|
+
*
|
|
13
|
+
* `baseUrl` = `process.env.BIOMETRICS_BUSINESS_LAMBDA_URL` (SSM key = nombre del repo, que lo
|
|
14
|
+
* publica su propio buildspec).
|
|
15
|
+
*/
|
|
16
|
+
export interface IBiometricsBusinessApi {
|
|
17
|
+
/**
|
|
18
|
+
* Pide una verificación biométrica. Devuelve lo que haga falta para ejecutarla, según el
|
|
19
|
+
* `deliveryMode`: con Metamap es un link hospedado ya acortado.
|
|
20
|
+
*
|
|
21
|
+
* **Idempotente por persona**: si ya hay una verificación viva del mismo `directoryId` + `type`
|
|
22
|
+
* + `provider`, devuelve ESA — mismo id, mismo link. Reintentar no publica otra selfie ni deja
|
|
23
|
+
* links huérfanos.
|
|
24
|
+
*
|
|
25
|
+
* ⚠️ Lanza tipado si no se puede armar (sin foto de referencia, proveedor caído, combinación no
|
|
26
|
+
* soportada). **`biometrics-business` NO degrada**: no sabe qué debe pasar en tu flujo si falla.
|
|
27
|
+
* Esa política es tuya — el wizard, por ejemplo, degrada a KYC completo.
|
|
28
|
+
*/
|
|
29
|
+
createBiometricVerification(data: CreateBiometricVerificationRequest): Promise<ApiGatewayResponse<BiometricVerificationResponse>>;
|
|
30
|
+
/**
|
|
31
|
+
* El estado actual de una verificación. Es el endpoint de polling.
|
|
32
|
+
*
|
|
33
|
+
* Leer `status` (dónde va el proceso) y `result` (qué dijo el biométrico) **por separado**: el
|
|
34
|
+
* veredicto del facematch llega antes del cierre, así que `result` puede venir en `MATCH` con
|
|
35
|
+
* `status` todavía en `IN_PROGRESS`. No es una inconsistencia.
|
|
36
|
+
*
|
|
37
|
+
* La expiración no depende de que llegue ningún evento: este `GET` la calcula y la persiste.
|
|
38
|
+
*/
|
|
39
|
+
getBiometricVerification(biometricVerificationId: string): Promise<ApiGatewayResponse<BiometricVerificationResponse>>;
|
|
40
|
+
/**
|
|
41
|
+
* Avisa que el proveedor reportó algo sobre una verificación. **Su único caller legítimo es
|
|
42
|
+
* `kyc-metamap-webhook`** — un producto normal no llama acá.
|
|
43
|
+
*
|
|
44
|
+
* 🔴 **Idempotente por `eventId`, y eso NO es un detalle.** Este canal reemplaza a una cola, así
|
|
45
|
+
* que la durabilidad la da el reintento del proveedor: recibir el mismo evento dos veces es el
|
|
46
|
+
* camino NORMAL, no la excepción. Un `eventId` repetido devuelve 200 y no aplica nada.
|
|
47
|
+
*
|
|
48
|
+
* Cómo tratar la respuesta desde el webhook:
|
|
49
|
+
* - `200` → aplicado o descartado por duplicado. Los dos son éxito.
|
|
50
|
+
* - `404` / `409` → **no reintentar**: no existe, o ya está en un estado terminal.
|
|
51
|
+
* - `5xx` → devolver no-200 al proveedor **para que reintente**. Esto es seguro SOLO en la rama
|
|
52
|
+
* biométrica, que corta antes de escribir nada y no tiene efectos que duplicar.
|
|
53
|
+
*/
|
|
54
|
+
applyBiometricEvent(biometricVerificationId: string, data: BiometricVerificationChangedV1): Promise<ApiGatewayResponse<void>>;
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/bin/container.config.js
CHANGED
|
@@ -9,6 +9,7 @@ import { Publisher } from "./account-fiadoinc/index.js";
|
|
|
9
9
|
import AccountFiadoIncApi from "./account-fiadoinc/AccountFiadoIncApi.js";
|
|
10
10
|
import AccountPagoConfiadoApi from "./account-pagoconfiado/AccountPagoConfiadoApi.js";
|
|
11
11
|
import MetamapConnectorApi from "./metamap-connector/MetamapConnectorApi.js";
|
|
12
|
+
import BiometricsBusinessApi from "./biometrics-business/BiometricsBusinessApi.js";
|
|
12
13
|
import AccountFiadoSAApi from "./account-fiadosa/AccountFiadoSAApi.js";
|
|
13
14
|
import STPAccountApi from "./stpAccount/api/STPAccountApi.js";
|
|
14
15
|
import { SessionActivityPublisher } from "./sessionActivity/index.js";
|
|
@@ -140,6 +141,7 @@ export const apiInvokerBindings = new ContainerModule(({ bind }) => {
|
|
|
140
141
|
bind("IAccountFiadoIncApi").to(AccountFiadoIncApi);
|
|
141
142
|
bind("IAccountPagoConfiadoApi").to(AccountPagoConfiadoApi);
|
|
142
143
|
bind("IMetamapConnectorApi").to(MetamapConnectorApi);
|
|
144
|
+
bind("IBiometricsBusinessApi").to(BiometricsBusinessApi);
|
|
143
145
|
bind("IAccountFiadoSAApi").to(AccountFiadoSAApi);
|
|
144
146
|
bind("INotificationMessagesPublisher").to(NotificationMessagePublisher);
|
|
145
147
|
bind("INotificationWSMessagesPublisher").to(NotificationWSMessagePublisher);
|
package/bin/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from "./account-fiadoinc/index.js";
|
|
|
11
11
|
export * from "./account-fiadosa/index.js";
|
|
12
12
|
export * from "./account-pagoconfiado/index.js";
|
|
13
13
|
export * from "./metamap-connector/index.js";
|
|
14
|
+
export * from "./biometrics-business/index.js";
|
|
14
15
|
export * from "./account-beneficiary/index.js";
|
|
15
16
|
export * from "./exchangeRates/index.js";
|
|
16
17
|
export * from "./authentication/index.js";
|
package/bin/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export * from "./account-fiadoinc/index.js";
|
|
|
11
11
|
export * from "./account-fiadosa/index.js";
|
|
12
12
|
export * from "./account-pagoconfiado/index.js";
|
|
13
13
|
export * from "./metamap-connector/index.js";
|
|
14
|
+
export * from "./biometrics-business/index.js";
|
|
14
15
|
export * from "./account-beneficiary/index.js";
|
|
15
16
|
export * from "./exchangeRates/index.js";
|
|
16
17
|
export * from "./authentication/index.js";
|
|
@@ -2,6 +2,7 @@ import { IHttpRequest } from "@fiado/http-client";
|
|
|
2
2
|
import { IZendeskApi } from "./interfaces/IZendeskApi.js";
|
|
3
3
|
type FiadoApiResponse<T> = import('@fiado/type-kit/bin/apiResponse/dtos/FiadoApiResponse.js').default<T>;
|
|
4
4
|
import { HelpdeskCreateUserRequest, HelpdeskCreateTicketRequest } from '@fiado/type-kit/bin/helpdesk/index.js';
|
|
5
|
+
import { SendProactiveMessageRequest, ISendProactiveMessageResponse } from '@fiado/type-kit/bin/zendeskMessaging/index.js';
|
|
5
6
|
export declare class ZendeskApi implements IZendeskApi {
|
|
6
7
|
private httpRequest;
|
|
7
8
|
private readonly baseUrl;
|
|
@@ -11,5 +12,6 @@ export declare class ZendeskApi implements IZendeskApi {
|
|
|
11
12
|
deleteByDirectoryId(directoryId: string): Promise<FiadoApiResponse<{
|
|
12
13
|
deletedCount: number;
|
|
13
14
|
}>>;
|
|
15
|
+
sendProactiveMessage(data: SendProactiveMessageRequest): Promise<FiadoApiResponse<ISendProactiveMessageResponse>>;
|
|
14
16
|
}
|
|
15
17
|
export {};
|
|
@@ -31,6 +31,10 @@ let ZendeskApi = class ZendeskApi {
|
|
|
31
31
|
const url = `${this.baseUrl}private/directory/${directoryId}`;
|
|
32
32
|
return await this.httpRequest.delete(url);
|
|
33
33
|
}
|
|
34
|
+
async sendProactiveMessage(data) {
|
|
35
|
+
const url = `${this.baseUrl}messaging/send-proactive`;
|
|
36
|
+
return await this.httpRequest.post(url, data);
|
|
37
|
+
}
|
|
34
38
|
};
|
|
35
39
|
ZendeskApi = __decorate([
|
|
36
40
|
injectable(),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
type FiadoApiResponse<T> = import('@fiado/type-kit/bin/apiResponse/dtos/FiadoApiResponse.js').default<T>;
|
|
2
2
|
import { HelpdeskCreateTicketRequest, HelpdeskCreateUserRequest } from '@fiado/type-kit/bin/helpdesk/index.js';
|
|
3
|
+
import { SendProactiveMessageRequest, ISendProactiveMessageResponse } from '@fiado/type-kit/bin/zendeskMessaging/index.js';
|
|
3
4
|
/**
|
|
4
5
|
* Interfaz para el servicio de Zendesk
|
|
5
6
|
*/
|
|
@@ -14,5 +15,11 @@ export interface IZendeskApi {
|
|
|
14
15
|
deleteByDirectoryId(directoryId: string): Promise<FiadoApiResponse<{
|
|
15
16
|
deletedCount: number;
|
|
16
17
|
}>>;
|
|
18
|
+
/**
|
|
19
|
+
* Envia un mensaje proactivo a un usuario via Zendesk Messaging (Sunshine Conversations).
|
|
20
|
+
* Crea (o reutiliza) el usuario y la conversacion en Sunshine a partir del directoryId.
|
|
21
|
+
* @param data directoryId + message (displayName opcional).
|
|
22
|
+
*/
|
|
23
|
+
sendProactiveMessage(data: SendProactiveMessageRequest): Promise<FiadoApiResponse<ISendProactiveMessageResponse>>;
|
|
17
24
|
}
|
|
18
25
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fiado/api-invoker",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.13.0",
|
|
4
4
|
"description": "Sirve como un puente entre diferentes funciones lambda, facilitando la comunicación entre ellas a través de invocaciones http",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@fiado/gateway-adapter": "^3.9.0",
|
|
35
35
|
"@fiado/http-client": "^2.0.1",
|
|
36
36
|
"@fiado/logger": "^1.1.3",
|
|
37
|
-
"@fiado/type-kit": "^3.
|
|
37
|
+
"@fiado/type-kit": "^3.253.0",
|
|
38
38
|
"dotenv": "^16.4.7"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { inject, injectable } from "inversify";
|
|
2
|
+
import type { IBiometricsBusinessApi } from "./interfaces/IBiometricsBusinessApi.js";
|
|
3
|
+
import type {
|
|
4
|
+
BiometricVerificationChangedV1,
|
|
5
|
+
BiometricVerificationResponse,
|
|
6
|
+
CreateBiometricVerificationRequest,
|
|
7
|
+
} from "@fiado/type-kit/bin/biometrics/index.js";
|
|
8
|
+
import type { ApiGatewayResponse } from "@fiado/gateway-adapter";
|
|
9
|
+
// ⚠️ `import type` y NO un import de valor. `@fiado/http-client` se publica como CJS; importar
|
|
10
|
+
// `IHttpRequest` como valor hace que jest falle al cargar el módulo bajo ESM
|
|
11
|
+
// ("does not provide an export named 'IHttpRequest'"). Con `import type` se borra al compilar.
|
|
12
|
+
// `MetamapConnectorApi` lo hace como valor y no lo nota porque no tiene tests.
|
|
13
|
+
import type { IHttpRequest } from "@fiado/http-client";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Implementación del cliente de `biometrics-business`. Ver `IBiometricsBusinessApi` para el
|
|
17
|
+
* contrato y el manejo de respuestas.
|
|
18
|
+
*
|
|
19
|
+
* El `/private` NO va en el path: lo aporta el `baseUrl` que se resuelve del SSM.
|
|
20
|
+
*/
|
|
21
|
+
@injectable()
|
|
22
|
+
export default class BiometricsBusinessApi implements IBiometricsBusinessApi {
|
|
23
|
+
/**
|
|
24
|
+
* ⚠️ Se le quita el slash final y los paths lo ponen explícito.
|
|
25
|
+
*
|
|
26
|
+
* No es cosmético: hay dos convenciones conviviendo en esta lib. `MetamapConnectorApi` hace
|
|
27
|
+
* `${baseUrl}facematch/signature` — o sea que **depende** de que el SSM devuelva la URL
|
|
28
|
+
* terminada en `/`, y si algún día no la devuelve así arma `...v1/privatefacematch/signature`
|
|
29
|
+
* y el 404 no dice por qué. `KycVerificationsBusinessApi` normaliza. Acá se sigue el segundo,
|
|
30
|
+
* que funciona con las dos formas.
|
|
31
|
+
*/
|
|
32
|
+
private readonly baseUrl = (process.env.BIOMETRICS_BUSINESS_LAMBDA_URL || "").replace(/\/+$/, "");
|
|
33
|
+
|
|
34
|
+
constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
|
|
35
|
+
|
|
36
|
+
async createBiometricVerification(
|
|
37
|
+
data: CreateBiometricVerificationRequest,
|
|
38
|
+
): Promise<ApiGatewayResponse<BiometricVerificationResponse>> {
|
|
39
|
+
const url = `${this.baseUrl}/biometric-verifications`;
|
|
40
|
+
return await this.httpRequest.post(url, data);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getBiometricVerification(
|
|
44
|
+
biometricVerificationId: string,
|
|
45
|
+
): Promise<ApiGatewayResponse<BiometricVerificationResponse>> {
|
|
46
|
+
// encodeURIComponent y no interpolación pelada: el id va en el path, y aunque hoy lo genera
|
|
47
|
+
// biometrics-business, el día que un caller pase basura preferimos un 404 a una URL rota.
|
|
48
|
+
const url = `${this.baseUrl}/biometric-verifications/${encodeURIComponent(biometricVerificationId)}`;
|
|
49
|
+
return await this.httpRequest.get(url);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async applyBiometricEvent(
|
|
53
|
+
biometricVerificationId: string,
|
|
54
|
+
data: BiometricVerificationChangedV1,
|
|
55
|
+
): Promise<ApiGatewayResponse<void>> {
|
|
56
|
+
const url = `${this.baseUrl}/biometric-verifications/${encodeURIComponent(biometricVerificationId)}/events`;
|
|
57
|
+
return await this.httpRequest.post(url, data);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BiometricVerificationChangedV1,
|
|
3
|
+
BiometricVerificationResponse,
|
|
4
|
+
CreateBiometricVerificationRequest,
|
|
5
|
+
} from "@fiado/type-kit/bin/biometrics/index.js";
|
|
6
|
+
import type { ApiGatewayResponse } from "@fiado/gateway-adapter";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cliente de `biometrics-business`, el master de la lógica biométrica de Fiado.
|
|
10
|
+
*
|
|
11
|
+
* Tres endpoints privados (VPC-only) con DOS audiencias distintas:
|
|
12
|
+
*
|
|
13
|
+
* - **Cualquier producto que necesite un biométrico** usa `createBiometricVerification` +
|
|
14
|
+
* `getBiometricVerification` (polling).
|
|
15
|
+
* - **`kyc-metamap-webhook` y solo él** usa `applyBiometricEvent`, para avisar que llegó un
|
|
16
|
+
* resultado del proveedor.
|
|
17
|
+
*
|
|
18
|
+
* `baseUrl` = `process.env.BIOMETRICS_BUSINESS_LAMBDA_URL` (SSM key = nombre del repo, que lo
|
|
19
|
+
* publica su propio buildspec).
|
|
20
|
+
*/
|
|
21
|
+
export interface IBiometricsBusinessApi {
|
|
22
|
+
/**
|
|
23
|
+
* Pide una verificación biométrica. Devuelve lo que haga falta para ejecutarla, según el
|
|
24
|
+
* `deliveryMode`: con Metamap es un link hospedado ya acortado.
|
|
25
|
+
*
|
|
26
|
+
* **Idempotente por persona**: si ya hay una verificación viva del mismo `directoryId` + `type`
|
|
27
|
+
* + `provider`, devuelve ESA — mismo id, mismo link. Reintentar no publica otra selfie ni deja
|
|
28
|
+
* links huérfanos.
|
|
29
|
+
*
|
|
30
|
+
* ⚠️ Lanza tipado si no se puede armar (sin foto de referencia, proveedor caído, combinación no
|
|
31
|
+
* soportada). **`biometrics-business` NO degrada**: no sabe qué debe pasar en tu flujo si falla.
|
|
32
|
+
* Esa política es tuya — el wizard, por ejemplo, degrada a KYC completo.
|
|
33
|
+
*/
|
|
34
|
+
createBiometricVerification(
|
|
35
|
+
data: CreateBiometricVerificationRequest,
|
|
36
|
+
): Promise<ApiGatewayResponse<BiometricVerificationResponse>>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* El estado actual de una verificación. Es el endpoint de polling.
|
|
40
|
+
*
|
|
41
|
+
* Leer `status` (dónde va el proceso) y `result` (qué dijo el biométrico) **por separado**: el
|
|
42
|
+
* veredicto del facematch llega antes del cierre, así que `result` puede venir en `MATCH` con
|
|
43
|
+
* `status` todavía en `IN_PROGRESS`. No es una inconsistencia.
|
|
44
|
+
*
|
|
45
|
+
* La expiración no depende de que llegue ningún evento: este `GET` la calcula y la persiste.
|
|
46
|
+
*/
|
|
47
|
+
getBiometricVerification(
|
|
48
|
+
biometricVerificationId: string,
|
|
49
|
+
): Promise<ApiGatewayResponse<BiometricVerificationResponse>>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Avisa que el proveedor reportó algo sobre una verificación. **Su único caller legítimo es
|
|
53
|
+
* `kyc-metamap-webhook`** — un producto normal no llama acá.
|
|
54
|
+
*
|
|
55
|
+
* 🔴 **Idempotente por `eventId`, y eso NO es un detalle.** Este canal reemplaza a una cola, así
|
|
56
|
+
* que la durabilidad la da el reintento del proveedor: recibir el mismo evento dos veces es el
|
|
57
|
+
* camino NORMAL, no la excepción. Un `eventId` repetido devuelve 200 y no aplica nada.
|
|
58
|
+
*
|
|
59
|
+
* Cómo tratar la respuesta desde el webhook:
|
|
60
|
+
* - `200` → aplicado o descartado por duplicado. Los dos son éxito.
|
|
61
|
+
* - `404` / `409` → **no reintentar**: no existe, o ya está en un estado terminal.
|
|
62
|
+
* - `5xx` → devolver no-200 al proveedor **para que reintente**. Esto es seguro SOLO en la rama
|
|
63
|
+
* biométrica, que corta antes de escribir nada y no tiene efectos que duplicar.
|
|
64
|
+
*/
|
|
65
|
+
applyBiometricEvent(
|
|
66
|
+
biometricVerificationId: string,
|
|
67
|
+
data: BiometricVerificationChangedV1,
|
|
68
|
+
): Promise<ApiGatewayResponse<void>>;
|
|
69
|
+
}
|
package/src/container.config.ts
CHANGED
|
@@ -14,6 +14,8 @@ import { IAccountPagoConfiadoApi } from "./account-pagoconfiado/index.js";
|
|
|
14
14
|
import AccountPagoConfiadoApi from "./account-pagoconfiado/AccountPagoConfiadoApi.js";
|
|
15
15
|
import { IMetamapConnectorApi } from "./metamap-connector/index.js";
|
|
16
16
|
import MetamapConnectorApi from "./metamap-connector/MetamapConnectorApi.js";
|
|
17
|
+
import { IBiometricsBusinessApi } from "./biometrics-business/index.js";
|
|
18
|
+
import BiometricsBusinessApi from "./biometrics-business/BiometricsBusinessApi.js";
|
|
17
19
|
import { IAccountFiadoSAApi } from "./account-fiadosa/index.js";
|
|
18
20
|
import AccountFiadoSAApi from "./account-fiadosa/AccountFiadoSAApi.js";
|
|
19
21
|
import { ISTPAccountApi } from "./stpAccount/index.js";
|
|
@@ -204,6 +206,7 @@ export const apiInvokerBindings = new ContainerModule(({ bind }) => {
|
|
|
204
206
|
bind<IAccountFiadoIncApi>("IAccountFiadoIncApi").to(AccountFiadoIncApi);
|
|
205
207
|
bind<IAccountPagoConfiadoApi>("IAccountPagoConfiadoApi").to(AccountPagoConfiadoApi);
|
|
206
208
|
bind<IMetamapConnectorApi>("IMetamapConnectorApi").to(MetamapConnectorApi);
|
|
209
|
+
bind<IBiometricsBusinessApi>("IBiometricsBusinessApi").to(BiometricsBusinessApi);
|
|
207
210
|
bind<IAccountFiadoSAApi>("IAccountFiadoSAApi").to(AccountFiadoSAApi);
|
|
208
211
|
bind<INotificationMessagesPublisher>("INotificationMessagesPublisher").to(NotificationMessagePublisher);
|
|
209
212
|
bind<INotificationWSMessagesPublisher>("INotificationWSMessagesPublisher").to(NotificationWSMessagePublisher);
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from "./account-fiadoinc/index.js";
|
|
|
11
11
|
export * from "./account-fiadosa/index.js";
|
|
12
12
|
export * from "./account-pagoconfiado/index.js";
|
|
13
13
|
export * from "./metamap-connector/index.js";
|
|
14
|
+
export * from "./biometrics-business/index.js";
|
|
14
15
|
export * from "./account-beneficiary/index.js";
|
|
15
16
|
export * from "./exchangeRates/index.js";
|
|
16
17
|
export * from "./authentication/index.js";
|
|
@@ -4,6 +4,7 @@ import { IHttpRequest } from "@fiado/http-client";
|
|
|
4
4
|
import { IZendeskApi } from "./interfaces/IZendeskApi.js";
|
|
5
5
|
type FiadoApiResponse<T> = import('@fiado/type-kit/bin/apiResponse/dtos/FiadoApiResponse.js').default<T>;
|
|
6
6
|
import { HelpdeskCreateUserRequest, HelpdeskCreateTicketRequest } from '@fiado/type-kit/bin/helpdesk/index.js';
|
|
7
|
+
import { SendProactiveMessageRequest, ISendProactiveMessageResponse } from '@fiado/type-kit/bin/zendeskMessaging/index.js';
|
|
7
8
|
dotenv.config();
|
|
8
9
|
|
|
9
10
|
@injectable()
|
|
@@ -26,4 +27,9 @@ export class ZendeskApi implements IZendeskApi {
|
|
|
26
27
|
const url = `${this.baseUrl}private/directory/${directoryId}`;
|
|
27
28
|
return await this.httpRequest.delete<FiadoApiResponse<{ deletedCount: number }>>(url);
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
async sendProactiveMessage(data: SendProactiveMessageRequest): Promise<FiadoApiResponse<ISendProactiveMessageResponse>> {
|
|
32
|
+
const url: string = `${this.baseUrl}messaging/send-proactive`;
|
|
33
|
+
return await this.httpRequest.post<FiadoApiResponse<ISendProactiveMessageResponse>>(url, data);
|
|
34
|
+
}
|
|
29
35
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
type FiadoApiResponse<T> = import('@fiado/type-kit/bin/apiResponse/dtos/FiadoApiResponse.js').default<T>;
|
|
2
2
|
import { HelpdeskCreateTicketRequest, HelpdeskCreateUserRequest } from '@fiado/type-kit/bin/helpdesk/index.js';
|
|
3
|
+
import { SendProactiveMessageRequest, ISendProactiveMessageResponse } from '@fiado/type-kit/bin/zendeskMessaging/index.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Interfaz para el servicio de Zendesk
|
|
@@ -15,4 +16,11 @@ export interface IZendeskApi {
|
|
|
15
16
|
*/
|
|
16
17
|
// TODO(type-kit): swap a Directory.DeleteByDirectoryResponse cuando se publique
|
|
17
18
|
deleteByDirectoryId(directoryId: string): Promise<FiadoApiResponse<{ deletedCount: number }>>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Envia un mensaje proactivo a un usuario via Zendesk Messaging (Sunshine Conversations).
|
|
22
|
+
* Crea (o reutiliza) el usuario y la conversacion en Sunshine a partir del directoryId.
|
|
23
|
+
* @param data directoryId + message (displayName opcional).
|
|
24
|
+
*/
|
|
25
|
+
sendProactiveMessage(data: SendProactiveMessageRequest): Promise<FiadoApiResponse<ISendProactiveMessageResponse>>;
|
|
18
26
|
}
|