@fiado/api-invoker 5.12.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.
@@ -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,2 @@
1
+ export * from './interfaces/IBiometricsBusinessApi.js';
2
+ export * from './BiometricsBusinessApi.js';
@@ -0,0 +1,2 @@
1
+ export * from './interfaces/IBiometricsBusinessApi.js';
2
+ export * from './BiometricsBusinessApi.js';
@@ -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
+ }
@@ -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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/api-invoker",
3
- "version": "5.12.0",
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.235.0",
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,2 @@
1
+ export * from './interfaces/IBiometricsBusinessApi.js';
2
+ export * from './BiometricsBusinessApi.js';
@@ -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
+ }
@@ -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";