@fiado/api-invoker 5.66.0 → 5.68.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.
Files changed (30) hide show
  1. package/bin/datacultrConnector/api/interfaces/IDatacultrConnectorApi.d.ts +2 -16
  2. package/bin/datacultrConnector/api/interfaces/IDatacultrConnectorApi.js +49 -1
  3. package/bin/index.d.ts +1 -0
  4. package/bin/index.js +1 -0
  5. package/bin/loanCredit/api/LoanCreditDeviceApi.d.ts +4 -1
  6. package/bin/loanCredit/api/LoanCreditDeviceApi.js +17 -0
  7. package/bin/loanCredit/api/interfaces/ILoanCreditDeviceApi.d.ts +35 -7
  8. package/bin/retailCatalog/api/RetailCatalogBusinessApi.d.ts +3 -2
  9. package/bin/retailCatalog/api/RetailCatalogBusinessApi.js +4 -10
  10. package/bin/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.d.ts +17 -48
  11. package/bin/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.js +0 -2
  12. package/bin/trustonicConnector/api/TrustonicConnectorApi.d.ts +34 -0
  13. package/bin/trustonicConnector/api/TrustonicConnectorApi.js +73 -0
  14. package/bin/trustonicConnector/api/interfaces/ITrustonicConnectorApi.d.ts +158 -0
  15. package/bin/trustonicConnector/api/interfaces/ITrustonicConnectorApi.js +1 -0
  16. package/bin/trustonicConnector/index.d.ts +2 -0
  17. package/bin/trustonicConnector/index.js +2 -0
  18. package/bin/utils/MdmEnvelopes.d.ts +17 -0
  19. package/bin/utils/MdmEnvelopes.js +6 -0
  20. package/package.json +2 -2
  21. package/src/datacultrConnector/api/interfaces/IDatacultrConnectorApi.ts +4 -18
  22. package/src/index.ts +1 -0
  23. package/src/loanCredit/api/LoanCreditDeviceApi.ts +30 -0
  24. package/src/loanCredit/api/interfaces/ILoanCreditDeviceApi.ts +46 -6
  25. package/src/retailCatalog/api/RetailCatalogBusinessApi.ts +12 -14
  26. package/src/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.ts +25 -52
  27. package/src/trustonicConnector/api/TrustonicConnectorApi.ts +118 -0
  28. package/src/trustonicConnector/api/interfaces/ITrustonicConnectorApi.ts +216 -0
  29. package/src/trustonicConnector/index.ts +2 -0
  30. package/src/utils/MdmEnvelopes.ts +20 -0
@@ -0,0 +1,118 @@
1
+ import { inject, injectable } from "inversify";
2
+ import type { IHttpRequest } from "@fiado/http-client";
3
+ import { StandardResponse } from "@fiado/gateway-adapter";
4
+ import {
5
+ DeviceAutoLockScheduleRequest,
6
+ DeviceAutoLockScheduleResponse,
7
+ DeviceEnrollInitiateResponse,
8
+ DeviceEnrollRequest,
9
+ DeviceEnrollStatusRequest,
10
+ DeviceEnrollStatusResponse,
11
+ DeviceLastSeenRequest,
12
+ DeviceLastSeenResponse,
13
+ DeviceLockRequest,
14
+ DeviceLockResponse,
15
+ DeviceNotifyRequest,
16
+ DeviceNotifyResponse,
17
+ DevicePinUnlockRequest,
18
+ DevicePinUnlockResponse,
19
+ DeviceReleaseInitiateResponse,
20
+ DeviceReleaseRequest,
21
+ DeviceReleaseStatusRequest,
22
+ DeviceReleaseStatusResponse,
23
+ DeviceStatusRequest,
24
+ DeviceStatusResponse,
25
+ DeviceUnlockRequest,
26
+ DeviceUnlockResponse,
27
+ } from "@fiado/type-kit/bin/mdm/index.js";
28
+ import { DeviceBatchRequest, DeviceBatchResult } from "../../utils/MdmEnvelopes.js";
29
+ import {
30
+ DeviceInitiateBatchResult,
31
+ DevicePollingBatchRequest,
32
+ ITrustonicConnectorApi,
33
+ } from "./interfaces/ITrustonicConnectorApi.js";
34
+
35
+ /**
36
+ * Publisher HTTP del lambda `trustonic-connector` (segundo provider MDM de SureKeep). Contrato y
37
+ * semántica completos → `ITrustonicConnectorApi` (paths sin prefijo `/private`, sin tenant,
38
+ * `StandardResponse` → leer `result.data`, granularidad por ítem, y las cinco diferencias reales
39
+ * contra el connector de Datacultr).
40
+ *
41
+ * Env var requerida en el consumer: `TRUSTONIC_CONNECTOR_URL`.
42
+ * El template.yml del consumer la setea con:
43
+ *
44
+ * TRUSTONIC_CONNECTOR_URL: '{{resolve:ssm:trustonic-connector}}'
45
+ *
46
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
47
+ */
48
+ @injectable()
49
+ export default class TrustonicConnectorApi implements ITrustonicConnectorApi {
50
+ // El buildspec publica la URL en SSM con "/" final — se normaliza para no armar "//devices".
51
+ private readonly baseUrl = (process.env.TRUSTONIC_CONNECTOR_URL || "").replace(/\/+$/, "");
52
+
53
+ constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
54
+
55
+ async enrollDevices(
56
+ input: DeviceBatchRequest<DeviceEnrollRequest>,
57
+ ): Promise<StandardResponse<DeviceInitiateBatchResult<DeviceEnrollInitiateResponse>>> {
58
+ return await this.httpRequest.post(`${this.baseUrl}/devices/enroll`, input);
59
+ }
60
+
61
+ async enrollStatus(
62
+ input: DevicePollingBatchRequest<DeviceEnrollStatusRequest>,
63
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceEnrollStatusResponse>>> {
64
+ return await this.httpRequest.post(`${this.baseUrl}/devices/enroll/status`, input);
65
+ }
66
+
67
+ async getStatus(
68
+ input: DeviceBatchRequest<DeviceStatusRequest>,
69
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceStatusResponse>>> {
70
+ return await this.httpRequest.post(`${this.baseUrl}/devices/status`, input);
71
+ }
72
+
73
+ async getLastSeen(
74
+ input: DeviceBatchRequest<DeviceLastSeenRequest>,
75
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceLastSeenResponse>>> {
76
+ return await this.httpRequest.post(`${this.baseUrl}/devices/last-seen`, input);
77
+ }
78
+
79
+ async lockDevices(
80
+ input: DeviceBatchRequest<DeviceLockRequest>,
81
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceLockResponse>>> {
82
+ return await this.httpRequest.post(`${this.baseUrl}/devices/lock`, input);
83
+ }
84
+
85
+ async unlockDevices(
86
+ input: DeviceBatchRequest<DeviceUnlockRequest>,
87
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceUnlockResponse>>> {
88
+ return await this.httpRequest.post(`${this.baseUrl}/devices/unlock`, input);
89
+ }
90
+
91
+ async autoLockSchedule(
92
+ input: DeviceBatchRequest<DeviceAutoLockScheduleRequest>,
93
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceAutoLockScheduleResponse>>> {
94
+ return await this.httpRequest.post(`${this.baseUrl}/devices/auto-lock-schedule`, input);
95
+ }
96
+
97
+ async pinUnlock(input: DevicePinUnlockRequest): Promise<StandardResponse<DevicePinUnlockResponse>> {
98
+ return await this.httpRequest.post(`${this.baseUrl}/devices/pin-unlock`, input);
99
+ }
100
+
101
+ async notifyDevices(
102
+ input: DeviceBatchRequest<DeviceNotifyRequest>,
103
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceNotifyResponse>>> {
104
+ return await this.httpRequest.post(`${this.baseUrl}/devices/notify`, input);
105
+ }
106
+
107
+ async releaseDevices(
108
+ input: DeviceBatchRequest<DeviceReleaseRequest>,
109
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceReleaseInitiateResponse>>> {
110
+ return await this.httpRequest.post(`${this.baseUrl}/devices/release`, input);
111
+ }
112
+
113
+ async releaseStatus(
114
+ input: DevicePollingBatchRequest<DeviceReleaseStatusRequest>,
115
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceReleaseStatusResponse>>> {
116
+ return await this.httpRequest.post(`${this.baseUrl}/devices/release/status`, input);
117
+ }
118
+ }
@@ -0,0 +1,216 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import {
3
+ DeviceAutoLockScheduleRequest,
4
+ DeviceAutoLockScheduleResponse,
5
+ DeviceEnrollInitiateResponse,
6
+ DeviceEnrollRequest,
7
+ DeviceEnrollStatusRequest,
8
+ DeviceEnrollStatusResponse,
9
+ DeviceLastSeenRequest,
10
+ DeviceLastSeenResponse,
11
+ DeviceLockRequest,
12
+ DeviceLockResponse,
13
+ DeviceNotifyRequest,
14
+ DeviceNotifyResponse,
15
+ DevicePinUnlockRequest,
16
+ DevicePinUnlockResponse,
17
+ DeviceReleaseInitiateResponse,
18
+ DeviceReleaseRequest,
19
+ DeviceReleaseStatusRequest,
20
+ DeviceReleaseStatusResponse,
21
+ DeviceStatusRequest,
22
+ DeviceStatusResponse,
23
+ DeviceUnlockRequest,
24
+ DeviceUnlockResponse,
25
+ MdmProviderEnum,
26
+ } from "@fiado/type-kit/bin/mdm/index.js";
27
+ import { DeviceBatchRequest, DeviceBatchResult } from "../../../utils/MdmEnvelopes.js";
28
+
29
+ /**
30
+ * Contrato del publisher HTTP del lambda `trustonic-connector` — el segundo provider MDM de
31
+ * SureKeep, que traduce el contrato agnóstico de dispositivo (`@fiado/type-kit/bin/mdm`) a la API
32
+ * de Trustonic. Su consumidor es el módulo `device/` de `loan-credit-business`, que NUNCA le pega
33
+ * por `http-client` directo: entre lambdas Fiado se habla siempre por `@fiado/api-invoker`.
34
+ *
35
+ * ─────────────────────────────────────────────────────────────────────────────
36
+ * SUPERFICIE — 11 operaciones, las mismas que `IDatacultrConnectorApi`.
37
+ * ─────────────────────────────────────────────────────────────────────────────
38
+ * El connector expone 16 endpoints. Quedan afuera `restrictApps`, `archive`, `deactivate`,
39
+ * `deactivateStatus` y `deviceLog`: `IMdmProviderAdapter` de `loan-credit-business` no los pide y
40
+ * el adapter tiene un solo contrato para los dos providers. Sumar operaciones que solo soporta
41
+ * Trustonic es un cambio aparte, con su propia decisión.
42
+ *
43
+ * ─────────────────────────────────────────────────────────────────────────────
44
+ * PATHS — `/devices/...`, SIN prefijo `/private`. Igual que Datacultr.
45
+ * ─────────────────────────────────────────────────────────────────────────────
46
+ * El aislamiento no lo da el prefijo sino la red: la API privada es `EndpointConfiguration:
47
+ * PRIVATE` con ResourcePolicy que deniega todo lo que no venga de los VPC Endpoints de Fiado.
48
+ *
49
+ * ─────────────────────────────────────────────────────────────────────────────
50
+ * SIN TENANT y `Feature.ANONIMUS`.
51
+ * ─────────────────────────────────────────────────────────────────────────────
52
+ * Ningún método lleva `tenantId`: el `PrivateController` del destino no lee `X-Tenant-Id` ni
53
+ * `x-tenant-issuer`, y las credenciales de Trustonic salen de un único secret del lambda. Los
54
+ * privados son `Feature.ANONIMUS` — sin RBAC y sin claims, así que el caller no manda
55
+ * `Authorization`. Misma deuda que Datacultr: cuando el MDM sea multi-tenant, este contrato suma
56
+ * el tenant y pasa a ser un cambio MAJOR.
57
+ *
58
+ * ⚠️ Retorno `StandardResponse<T>` — el consumer lee `result.data`, NO `result.body`.
59
+ * Errores de transporte (falla el lambda entero, no un ítem): el publisher RECHAZA con el
60
+ * `DomainError` tipado del destino. Nunca fallback: el caller jamás recibe un batch vacío
61
+ * disfrazado de éxito.
62
+ *
63
+ * Granularidad POR ÍTEM — el batch NUNCA falla entero:
64
+ * - Cada `results[i]` trae su propio `status` (`SUCCESS` | `PENDING` | `ERROR`) y un `error`
65
+ * opcional. Un 200 puede traer ítems en `ERROR`: el caller TIENE que recorrer `results`.
66
+ * - El `error.code` del ítem es un `MdmErrorCodeEnum`. El `status` no lleva el motivo.
67
+ *
68
+ * ─────────────────────────────────────────────────────────────────────────────
69
+ * DIFERENCIAS DE CONTRATO CONTRA DATACULTR — no son intercambiables.
70
+ * ─────────────────────────────────────────────────────────────────────────────
71
+ * 1. `enrollDevices` devuelve `pollingHandle` + `provider` además de `results`; en Datacultr solo
72
+ * devuelve `results`. Acá el enroll es async de verdad y el handle es obligatorio para polear.
73
+ * 2. `enrollStatus` y `releaseStatus` EXIGEN `pollingHandle` en el body. En Datacultr el sobre de
74
+ * entrada es solo `{ items }`.
75
+ * 3. `lockDevices` soporta `TEMPORARY` de verdad; Datacultr lo degrada por ítem.
76
+ * 4. `autoLockSchedule` está degradado en Trustonic; en Datacultr es la vía real del bloqueo.
77
+ * 5. `notifyDevices` usa `title` + `content` (texto crudo) e ignora `notificationCode`; en
78
+ * Datacultr es al revés.
79
+ *
80
+ * Env var requerida en el consumer: `TRUSTONIC_CONNECTOR_URL`.
81
+ * El template.yml del consumer la setea con:
82
+ *
83
+ * TRUSTONIC_CONNECTOR_URL: '{{resolve:ssm:trustonic-connector}}'
84
+ *
85
+ * Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
86
+ */
87
+
88
+ /**
89
+ * Sobre de entrada de los endpoints `/status` de Trustonic: además de los ítems exige el
90
+ * `pollingHandle` que devolvió el initiate. Es un string opaco — no lo inspecciones.
91
+ */
92
+ export interface DevicePollingBatchRequest<TItem> {
93
+ pollingHandle: string;
94
+ items: TItem[];
95
+ }
96
+
97
+ /**
98
+ * Sobre de salida de un initiate async de Trustonic. `pollingHandle` es lo que el caller manda
99
+ * después a `/status`; `provider` identifica qué MDM atendió la operación.
100
+ */
101
+ export interface DeviceInitiateBatchResult<TItem> {
102
+ pollingHandle: string;
103
+ provider: MdmProviderEnum;
104
+ results: TItem[];
105
+ }
106
+
107
+ export interface ITrustonicConnectorApi {
108
+ /**
109
+ * POST `/devices/enroll` — inicia el enrolamiento de cada IMEI en Trustonic (upload de
110
+ * inventario + activación del servicio `DeviceFinancing` en una call atómica).
111
+ *
112
+ * ASYNC de verdad, a diferencia de Datacultr: el destino devuelve `pollingHandle` y el caller
113
+ * DEBE polear `enrollStatus` con ese handle hasta que todos los ítems sean terminales. El caso
114
+ * típico es que todos vuelvan en `PENDING`.
115
+ *
116
+ * `DeviceEnrollRequest.lockMode` (`ONDEMAND` pospago / `SCHEDULED` prepago) es opcional; si se
117
+ * omite el destino asume `ONDEMAND`.
118
+ */
119
+ enrollDevices(
120
+ input: DeviceBatchRequest<DeviceEnrollRequest>,
121
+ ): Promise<StandardResponse<DeviceInitiateBatchResult<DeviceEnrollInitiateResponse>>>;
122
+
123
+ /**
124
+ * POST `/devices/enroll/status` — estado del enrolamiento iniciado con `enrollDevices`.
125
+ *
126
+ * ⚠️ EXIGE `pollingHandle`: sin él el destino responde 400 `MISSING_POLLING_HANDLE`.
127
+ *
128
+ * Los campos `enrolledAt`, `enrollmentMode`, `enrollmentId`, `brand` y `model` siempre vienen
129
+ * `undefined` — el endpoint de Trustonic no los expone; existen para Datacultr.
130
+ */
131
+ enrollStatus(
132
+ input: DevicePollingBatchRequest<DeviceEnrollStatusRequest>,
133
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceEnrollStatusResponse>>>;
134
+
135
+ /** POST `/devices/status` — estado actual de cada IMEI, con `brand`, `model` y `lastSeenAt`. */
136
+ getStatus(
137
+ input: DeviceBatchRequest<DeviceStatusRequest>,
138
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceStatusResponse>>>;
139
+
140
+ /** POST `/devices/last-seen` — último contacto reportado por cada IMEI (heartbeat). */
141
+ getLastSeen(
142
+ input: DeviceBatchRequest<DeviceLastSeenRequest>,
143
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceLastSeenResponse>>>;
144
+
145
+ /**
146
+ * POST `/devices/lock` — bloquea cada IMEI, con mensaje opcional en pantalla.
147
+ * Acepta `mode: TEMPORARY` de verdad (con `durationSeconds`), que Datacultr degrada por ítem.
148
+ */
149
+ lockDevices(
150
+ input: DeviceBatchRequest<DeviceLockRequest>,
151
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceLockResponse>>>;
152
+
153
+ /**
154
+ * POST `/devices/unlock` — desbloquea cada IMEI.
155
+ * `unlockUntil` (ISO-8601) acota hasta cuándo vale el desbloqueo y solo aplica en modo
156
+ * `SCHEDULED`; si el modo lo exige y falta, el ítem vuelve en `ERROR` con
157
+ * `MdmErrorCodeEnum.UNLOCK_UNTIL_REQUIRED`.
158
+ */
159
+ unlockDevices(
160
+ input: DeviceBatchRequest<DeviceUnlockRequest>,
161
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceUnlockResponse>>>;
162
+
163
+ /**
164
+ * POST `/devices/auto-lock-schedule` — programa el bloqueo de cada IMEI en una fecha futura.
165
+ *
166
+ * ⚠️ DEGRADADO en Trustonic: el destino no llama al proveedor y devuelve cada ítem en `ERROR`
167
+ * con `PROVIDER_NOT_SUPPORTED`. Es el espejo exacto de Datacultr, donde ésta es la vía real del
168
+ * bloqueo. El caller no debe asumir la misma semántica entre providers.
169
+ */
170
+ autoLockSchedule(
171
+ input: DeviceBatchRequest<DeviceAutoLockScheduleRequest>,
172
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceAutoLockScheduleResponse>>>;
173
+
174
+ /**
175
+ * POST `/devices/pin-unlock` — pide a Trustonic el PIN offline de un equipo sin conectividad.
176
+ *
177
+ * ⚠️ NO ES BATCH y NO LLEVA SOBRE, a diferencia del resto del contrato: el body es el
178
+ * `DevicePinUnlockRequest` pelado y la respuesta es el `DevicePinUnlockResponse` directo en
179
+ * `data`, sin `{ result }` — ahí difiere del `pinUnlock` de Datacultr.
180
+ *
181
+ * Operación sensible: `pin`, `validitySeconds` y `generatedAt` solo vienen con `status`
182
+ * `SUCCESS`. El PIN viaja únicamente en esta respuesta — nunca loggearlo.
183
+ */
184
+ pinUnlock(input: DevicePinUnlockRequest): Promise<StandardResponse<DevicePinUnlockResponse>>;
185
+
186
+ /**
187
+ * POST `/devices/notify` — manda una notificación (`BANNER` o `FULLSCREEN`) a cada IMEI.
188
+ * Trustonic usa `title` y `content` como texto crudo e ignora `notificationCode`, al revés que
189
+ * Datacultr, que resuelve el texto por catálogo.
190
+ */
191
+ notifyDevices(
192
+ input: DeviceBatchRequest<DeviceNotifyRequest>,
193
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceNotifyResponse>>>;
194
+
195
+ /**
196
+ * POST `/devices/release` — libera definitivamente cada IMEI del MDM (fin de tenure).
197
+ *
198
+ * ⚠️ IRREVERSIBLE: un equipo liberado no se puede re-enrolar en Trustonic.
199
+ * Es sync y terminal — cada ítem vuelve `SUCCESS` o `ERROR`, nunca `PENDING`, y la respuesta NO
200
+ * trae `pollingHandle` (asimetría con `enrollDevices`).
201
+ */
202
+ releaseDevices(
203
+ input: DeviceBatchRequest<DeviceReleaseRequest>,
204
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceReleaseInitiateResponse>>>;
205
+
206
+ /**
207
+ * POST `/devices/release/status` — consulta el estado de una liberación.
208
+ *
209
+ * ⚠️ EXIGE `pollingHandle` aunque `releaseDevices` no devuelva ninguno: el caller tiene que
210
+ * inventar o reusar un identificador de tracing. Existe solo por simetría con Datacultr, donde
211
+ * el release sí es async; contra Trustonic normalmente no hace falta llamarlo.
212
+ */
213
+ releaseStatus(
214
+ input: DevicePollingBatchRequest<DeviceReleaseStatusRequest>,
215
+ ): Promise<StandardResponse<DeviceBatchResult<DeviceReleaseStatusResponse>>>;
216
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/ITrustonicConnectorApi.js";
2
+ export { default as TrustonicConnectorApi } from "./api/TrustonicConnectorApi.js";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Sobres de request/response compartidos por los connectors MDM (`datacultr-connector`,
3
+ * `trustonic-connector`). No viven en `@fiado/type-kit/bin/mdm` porque los DTOs publicados
4
+ * son de UN imei; el sobre es dominio del líder (gap E8), migrar a type-kit cuando lo publique.
5
+ */
6
+
7
+ /** Sobre de entrada de los endpoints batch de un connector MDM. */
8
+ export interface DeviceBatchRequest<TItem> {
9
+ items: TItem[];
10
+ }
11
+
12
+ /** Sobre de salida de los endpoints batch: viaja dentro de `StandardResponse.data`. */
13
+ export interface DeviceBatchResult<TItem> {
14
+ results: TItem[];
15
+ }
16
+
17
+ /** Sobre de salida de los endpoints de UN solo IMEI. Hoy solo `pinUnlock` no es batch. */
18
+ export interface DeviceSingleResult<TItem> {
19
+ result: TItem;
20
+ }