@fiado/api-invoker 5.39.0 → 5.41.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/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.d.ts +7 -0
- package/bin/retailOrg/api/RetailOrgBusinessApi.d.ts +9 -2
- package/bin/retailOrg/api/RetailOrgBusinessApi.js +15 -1
- package/bin/retailOrg/api/interfaces/IRetailOrgBusinessApi.d.ts +41 -2
- package/package.json +1 -1
- package/src/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.ts +10 -0
- package/src/retailOrg/api/RetailOrgBusinessApi.ts +19 -1
- package/src/retailOrg/api/interfaces/IRetailOrgBusinessApi.ts +46 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StandardResponse } from "@fiado/gateway-adapter";
|
|
2
|
+
import type { MdmLockModeEnum, MdmProviderEnum } from "@fiado/type-kit/bin/retailCatalog/index.js";
|
|
2
3
|
/**
|
|
3
4
|
* Contrato del publisher HTTP del lambda `retail-catalog-business` (SureKeep Fase 1, pista Retail)
|
|
4
5
|
* para sus endpoints privados del ciclo de venta del IMEI, consumidos por el wizard F2.
|
|
@@ -45,6 +46,12 @@ export interface StoreCatalogItem {
|
|
|
45
46
|
tier: string;
|
|
46
47
|
/** Financieras alternativas habilitadas (derivación externa, paso 04 del wizard). */
|
|
47
48
|
eligibleFinanciers: string[];
|
|
49
|
+
/** `true` si el producto se vende con MDM. */
|
|
50
|
+
mdmEnabled: boolean;
|
|
51
|
+
/** Proveedor MDM; `null` si el producto no lleva MDM. */
|
|
52
|
+
mdmProvider: MdmProviderEnum | null;
|
|
53
|
+
/** Modo de bloqueo pactado; `null` si el producto no lleva MDM. */
|
|
54
|
+
mdmLockMode: MdmLockModeEnum | null;
|
|
48
55
|
}
|
|
49
56
|
/** Resultado de la reserva (espeja `ReserveInventoryResponse` del destino). */
|
|
50
57
|
export interface ReserveInventoryResult {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { IHttpRequest } from "@fiado/http-client";
|
|
2
2
|
import { StandardResponse } from "@fiado/gateway-adapter";
|
|
3
3
|
import { RetailerValidationDto, StoreValidationDto, RetailUserValidationDto, CollectorValidationDto, PrivateSellerListResponse, RetailUserStatusEnum } from "@fiado/type-kit/bin/retailOrg/index.js";
|
|
4
|
-
import { IRetailOrgBusinessApi, StoreRosterStatusFilter } from "./interfaces/IRetailOrgBusinessApi.js";
|
|
4
|
+
import { IRetailOrgBusinessApi, RetailerRosterStatusFilter, StoreRosterStatusFilter } from "./interfaces/IRetailOrgBusinessApi.js";
|
|
5
5
|
/**
|
|
6
|
-
* Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus
|
|
6
|
+
* Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus 9
|
|
7
7
|
* endpoints privados de validación. Contrato y semántica completos → `IRetailOrgBusinessApi`.
|
|
8
8
|
*
|
|
9
9
|
* Los paths y el `?tenantId=` fueron verificados contra dev (200 + negativos 400/404) el
|
|
@@ -20,6 +20,13 @@ export default class RetailOrgBusinessApi implements IRetailOrgBusinessApi {
|
|
|
20
20
|
private httpRequest;
|
|
21
21
|
private readonly baseUrl;
|
|
22
22
|
constructor(httpRequest: IHttpRequest);
|
|
23
|
+
/**
|
|
24
|
+
* El padrón de retailers del SILO — lo consume la pantalla de analítica del Portal Admin, que
|
|
25
|
+
* agrega ventas de todo el silo y no de una cadena. Contrato y semántica completos (incluido por
|
|
26
|
+
* qué `status` SÍ tiene default y por qué acá el estado es el CRUDO, sin cascada del padre)
|
|
27
|
+
* → `IRetailOrgBusinessApi.listRetailers`.
|
|
28
|
+
*/
|
|
29
|
+
listRetailers(tenantId: string, status?: RetailerRosterStatusFilter): Promise<StandardResponse<RetailerValidationDto[]>>;
|
|
23
30
|
getRetailer(retailerId: string, tenantId: string): Promise<StandardResponse<RetailerValidationDto>>;
|
|
24
31
|
getRetailerByStore(storeId: string, tenantId: string): Promise<StandardResponse<RetailerValidationDto>>;
|
|
25
32
|
getStore(retailerId: string, storeId: string, tenantId: string): Promise<StandardResponse<StoreValidationDto>>;
|
|
@@ -12,7 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { inject, injectable } from "inversify";
|
|
14
14
|
/**
|
|
15
|
-
* Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus
|
|
15
|
+
* Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus 9
|
|
16
16
|
* endpoints privados de validación. Contrato y semántica completos → `IRetailOrgBusinessApi`.
|
|
17
17
|
*
|
|
18
18
|
* Los paths y el `?tenantId=` fueron verificados contra dev (200 + negativos 400/404) el
|
|
@@ -31,6 +31,20 @@ let RetailOrgBusinessApi = class RetailOrgBusinessApi {
|
|
|
31
31
|
constructor(httpRequest) {
|
|
32
32
|
this.httpRequest = httpRequest;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* El padrón de retailers del SILO — lo consume la pantalla de analítica del Portal Admin, que
|
|
36
|
+
* agrega ventas de todo el silo y no de una cadena. Contrato y semántica completos (incluido por
|
|
37
|
+
* qué `status` SÍ tiene default y por qué acá el estado es el CRUDO, sin cascada del padre)
|
|
38
|
+
* → `IRetailOrgBusinessApi.listRetailers`.
|
|
39
|
+
*/
|
|
40
|
+
async listRetailers(tenantId, status) {
|
|
41
|
+
// `URLSearchParams` en vez de concatenar: `status` es opcional y armar el `&status=` a mano
|
|
42
|
+
// deja un `&status=undefined` en cuanto alguien se distrae.
|
|
43
|
+
const query = new URLSearchParams({ tenantId });
|
|
44
|
+
if (status)
|
|
45
|
+
query.set("status", status);
|
|
46
|
+
return await this.httpRequest.get(`${this.baseUrl}/private/retailers?${query.toString()}`);
|
|
47
|
+
}
|
|
34
48
|
async getRetailer(retailerId, tenantId) {
|
|
35
49
|
const url = `${this.baseUrl}/private/retailers/${encodeURIComponent(retailerId)}?tenantId=${encodeURIComponent(tenantId)}`;
|
|
36
50
|
return await this.httpRequest.get(url);
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { StandardResponse } from "@fiado/gateway-adapter";
|
|
2
|
-
import { RetailerValidationDto, StoreValidationDto, RetailUserValidationDto, CollectorValidationDto, PrivateSellerListResponse, RetailUserStatusEnum, StoreStatusEnum } from "@fiado/type-kit/bin/retailOrg/index.js";
|
|
2
|
+
import { RetailerValidationDto, StoreValidationDto, RetailUserValidationDto, CollectorValidationDto, PrivateSellerListResponse, RetailUserStatusEnum, RetailerStatusEnum, StoreStatusEnum } from "@fiado/type-kit/bin/retailOrg/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Filtro de `listStoresByRetailer`. `"ALL"` no es un estado de tienda: es la ausencia de filtro, y
|
|
5
5
|
* va en el MISMO parámetro que los estados porque los dos hablan del mismo eje — un segundo flag
|
|
6
6
|
* tipo `includeInactive` admitiría combinaciones sin sentido que alguien tendría que resolver.
|
|
7
7
|
*/
|
|
8
8
|
export type StoreRosterStatusFilter = StoreStatusEnum | "ALL";
|
|
9
|
+
/** Filtro de `listRetailers`. Mismo criterio que `StoreRosterStatusFilter`, un nivel más arriba. */
|
|
10
|
+
export type RetailerRosterStatusFilter = RetailerStatusEnum | "ALL";
|
|
9
11
|
/**
|
|
10
12
|
* Contrato del publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1)
|
|
11
|
-
* para sus
|
|
13
|
+
* para sus 9 endpoints privados de VALIDACIÓN (service-to-service, VPC-only).
|
|
12
14
|
*
|
|
13
15
|
* Consumidores previstos (regla R5 — cruces entre lambdas son SOLO lecturas de validación;
|
|
14
16
|
* ningún lambda escribe en tabla ajena):
|
|
@@ -51,6 +53,43 @@ export type StoreRosterStatusFilter = StoreStatusEnum | "ALL";
|
|
|
51
53
|
* Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
|
|
52
54
|
*/
|
|
53
55
|
export interface IRetailOrgBusinessApi {
|
|
56
|
+
/**
|
|
57
|
+
* `GET /private/retailers` — el **padrón de retailers del SILO**.
|
|
58
|
+
*
|
|
59
|
+
* ── 🔴 Por qué este método existe ────────────────────────────────────────────────────────────
|
|
60
|
+
* Lo consume la pantalla de analítica del Portal Admin, que agrega ventas de TODO el silo y no
|
|
61
|
+
* de una cadena. Para eso necesita saber **qué retailers existen**, y ningún otro privado lo
|
|
62
|
+
* dice: `getRetailer` resuelve UNO por id, `getRetailerByStore` el dueño de una tienda, y el
|
|
63
|
+
* resto baja un nivel. El único que lista cadenas, `publicListRetailers`, va detrás del
|
|
64
|
+
* `W4Authorizer` (token de usuario, no invocable entre lambdas), pagina, y devuelve el registro
|
|
65
|
+
* completo con RFC y datos de contacto.
|
|
66
|
+
*
|
|
67
|
+
* Es el hermano de `listStoresByRetailer` un nivel más arriba: aquel da las tiendas de UNA
|
|
68
|
+
* cadena, este da las cadenas. Sin `retailerId` en la firma: el recurso es el silo entero, que
|
|
69
|
+
* ya lo determina el `tenantId`.
|
|
70
|
+
*
|
|
71
|
+
* Devuelve el mismo `RetailerValidationDto` que `getRetailer` — `retailerId`, `name`, `type`,
|
|
72
|
+
* `status`, `parentId` — **sin ningún campo PII**. Trae el árbol COMPLETO (cadenas raíz +
|
|
73
|
+
* subdistribuidores + franquicias, a cualquier profundidad): una venta cuelga de una tienda que
|
|
74
|
+
* pertenece a un retailer de cualquier nivel, así que quedarse en las raíces perdería ventas.
|
|
75
|
+
*
|
|
76
|
+
* ⚠️ El `status` es el CRUDO de la fila, NO uno efectivo — a diferencia de `getStore` y
|
|
77
|
+
* `listStoresByRetailer`, donde sí viene la cascada del padre aplicada. En retail-org un
|
|
78
|
+
* retailer no hereda el estado de su padre en ninguna lectura: un subdistribuidor `ACTIVE` de
|
|
79
|
+
* una cadena `SUSPENDED` sale como `ACTIVE`. Si eso importa, cruza el `parentId`.
|
|
80
|
+
*
|
|
81
|
+
* ── ⚠️ `status` SÍ tiene default, igual que `listStoresByRetailer` ───────────────────────────
|
|
82
|
+
* Omitirlo devuelve **solo los `ACTIVE`**. Pasa `"ALL"` para el padrón completo. El default vive
|
|
83
|
+
* en el lambda, no acá: mandarlo implícito desde el publisher partiría la decisión en dos
|
|
84
|
+
* lugares que alguien tendría que mantener sincronizados.
|
|
85
|
+
*
|
|
86
|
+
* Devuelve `[]` si ningún retailer pasa el filtro. **No hay 404**: el silo siempre existe — lo
|
|
87
|
+
* garantiza el `tenantId`, que es lo que resolvió el contexto del tenant.
|
|
88
|
+
*
|
|
89
|
+
* @throws `400 RETAILER_STATUS_FILTER_INVALID` si `status` no es del catálogo ·
|
|
90
|
+
* `400 UNKNOWN_TENANT` sin `tenantId`.
|
|
91
|
+
*/
|
|
92
|
+
listRetailers(tenantId: string, status?: RetailerRosterStatusFilter): Promise<StandardResponse<RetailerValidationDto[]>>;
|
|
54
93
|
/**
|
|
55
94
|
* GET /private/retailers/{retailerId} — valida que el retailer exista y devuelve su shape mínimo
|
|
56
95
|
* (id, name, type, status, parentId). `status` ya viene con la cascada aplicada (estado efectivo).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fiado/api-invoker",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.41.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",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StandardResponse } from "@fiado/gateway-adapter";
|
|
2
|
+
import type { MdmLockModeEnum, MdmProviderEnum } from "@fiado/type-kit/bin/retailCatalog/index.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Contrato del publisher HTTP del lambda `retail-catalog-business` (SureKeep Fase 1, pista Retail)
|
|
@@ -50,6 +51,15 @@ export interface StoreCatalogItem {
|
|
|
50
51
|
tier: string;
|
|
51
52
|
/** Financieras alternativas habilitadas (derivación externa, paso 04 del wizard). */
|
|
52
53
|
eligibleFinanciers: string[];
|
|
54
|
+
// Política MDM del producto (2026-08-25, MINOR aditivo). El detalle de la venta la muestra y el
|
|
55
|
+
// destino ya trae el producto cargado. Es la POLÍTICA del producto, no el estado del candado del
|
|
56
|
+
// dispositivo (ese vive en `loan-credit`).
|
|
57
|
+
/** `true` si el producto se vende con MDM. */
|
|
58
|
+
mdmEnabled: boolean;
|
|
59
|
+
/** Proveedor MDM; `null` si el producto no lleva MDM. */
|
|
60
|
+
mdmProvider: MdmProviderEnum | null;
|
|
61
|
+
/** Modo de bloqueo pactado; `null` si el producto no lleva MDM. */
|
|
62
|
+
mdmLockMode: MdmLockModeEnum | null;
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
/** Resultado de la reserva (espeja `ReserveInventoryResponse` del destino). */
|
|
@@ -11,11 +11,12 @@ import {
|
|
|
11
11
|
} from "@fiado/type-kit/bin/retailOrg/index.js";
|
|
12
12
|
import {
|
|
13
13
|
IRetailOrgBusinessApi,
|
|
14
|
+
RetailerRosterStatusFilter,
|
|
14
15
|
StoreRosterStatusFilter,
|
|
15
16
|
} from "./interfaces/IRetailOrgBusinessApi.js";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
|
-
* Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus
|
|
19
|
+
* Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus 9
|
|
19
20
|
* endpoints privados de validación. Contrato y semántica completos → `IRetailOrgBusinessApi`.
|
|
20
21
|
*
|
|
21
22
|
* Los paths y el `?tenantId=` fueron verificados contra dev (200 + negativos 400/404) el
|
|
@@ -34,6 +35,23 @@ export default class RetailOrgBusinessApi implements IRetailOrgBusinessApi {
|
|
|
34
35
|
|
|
35
36
|
constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
|
|
36
37
|
|
|
38
|
+
/**
|
|
39
|
+
* El padrón de retailers del SILO — lo consume la pantalla de analítica del Portal Admin, que
|
|
40
|
+
* agrega ventas de todo el silo y no de una cadena. Contrato y semántica completos (incluido por
|
|
41
|
+
* qué `status` SÍ tiene default y por qué acá el estado es el CRUDO, sin cascada del padre)
|
|
42
|
+
* → `IRetailOrgBusinessApi.listRetailers`.
|
|
43
|
+
*/
|
|
44
|
+
async listRetailers(
|
|
45
|
+
tenantId: string,
|
|
46
|
+
status?: RetailerRosterStatusFilter,
|
|
47
|
+
): Promise<StandardResponse<RetailerValidationDto[]>> {
|
|
48
|
+
// `URLSearchParams` en vez de concatenar: `status` es opcional y armar el `&status=` a mano
|
|
49
|
+
// deja un `&status=undefined` en cuanto alguien se distrae.
|
|
50
|
+
const query = new URLSearchParams({ tenantId });
|
|
51
|
+
if (status) query.set("status", status);
|
|
52
|
+
return await this.httpRequest.get(`${this.baseUrl}/private/retailers?${query.toString()}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
async getRetailer(
|
|
38
56
|
retailerId: string,
|
|
39
57
|
tenantId: string,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
CollectorValidationDto,
|
|
7
7
|
PrivateSellerListResponse,
|
|
8
8
|
RetailUserStatusEnum,
|
|
9
|
+
RetailerStatusEnum,
|
|
9
10
|
StoreStatusEnum,
|
|
10
11
|
} from "@fiado/type-kit/bin/retailOrg/index.js";
|
|
11
12
|
|
|
@@ -16,9 +17,12 @@ import {
|
|
|
16
17
|
*/
|
|
17
18
|
export type StoreRosterStatusFilter = StoreStatusEnum | "ALL";
|
|
18
19
|
|
|
20
|
+
/** Filtro de `listRetailers`. Mismo criterio que `StoreRosterStatusFilter`, un nivel más arriba. */
|
|
21
|
+
export type RetailerRosterStatusFilter = RetailerStatusEnum | "ALL";
|
|
22
|
+
|
|
19
23
|
/**
|
|
20
24
|
* Contrato del publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1)
|
|
21
|
-
* para sus
|
|
25
|
+
* para sus 9 endpoints privados de VALIDACIÓN (service-to-service, VPC-only).
|
|
22
26
|
*
|
|
23
27
|
* Consumidores previstos (regla R5 — cruces entre lambdas son SOLO lecturas de validación;
|
|
24
28
|
* ningún lambda escribe en tabla ajena):
|
|
@@ -61,6 +65,47 @@ export type StoreRosterStatusFilter = StoreStatusEnum | "ALL";
|
|
|
61
65
|
* Convención CLAUDE.md global: SSM key = nombre del lambda owner de la URL.
|
|
62
66
|
*/
|
|
63
67
|
export interface IRetailOrgBusinessApi {
|
|
68
|
+
/**
|
|
69
|
+
* `GET /private/retailers` — el **padrón de retailers del SILO**.
|
|
70
|
+
*
|
|
71
|
+
* ── 🔴 Por qué este método existe ────────────────────────────────────────────────────────────
|
|
72
|
+
* Lo consume la pantalla de analítica del Portal Admin, que agrega ventas de TODO el silo y no
|
|
73
|
+
* de una cadena. Para eso necesita saber **qué retailers existen**, y ningún otro privado lo
|
|
74
|
+
* dice: `getRetailer` resuelve UNO por id, `getRetailerByStore` el dueño de una tienda, y el
|
|
75
|
+
* resto baja un nivel. El único que lista cadenas, `publicListRetailers`, va detrás del
|
|
76
|
+
* `W4Authorizer` (token de usuario, no invocable entre lambdas), pagina, y devuelve el registro
|
|
77
|
+
* completo con RFC y datos de contacto.
|
|
78
|
+
*
|
|
79
|
+
* Es el hermano de `listStoresByRetailer` un nivel más arriba: aquel da las tiendas de UNA
|
|
80
|
+
* cadena, este da las cadenas. Sin `retailerId` en la firma: el recurso es el silo entero, que
|
|
81
|
+
* ya lo determina el `tenantId`.
|
|
82
|
+
*
|
|
83
|
+
* Devuelve el mismo `RetailerValidationDto` que `getRetailer` — `retailerId`, `name`, `type`,
|
|
84
|
+
* `status`, `parentId` — **sin ningún campo PII**. Trae el árbol COMPLETO (cadenas raíz +
|
|
85
|
+
* subdistribuidores + franquicias, a cualquier profundidad): una venta cuelga de una tienda que
|
|
86
|
+
* pertenece a un retailer de cualquier nivel, así que quedarse en las raíces perdería ventas.
|
|
87
|
+
*
|
|
88
|
+
* ⚠️ El `status` es el CRUDO de la fila, NO uno efectivo — a diferencia de `getStore` y
|
|
89
|
+
* `listStoresByRetailer`, donde sí viene la cascada del padre aplicada. En retail-org un
|
|
90
|
+
* retailer no hereda el estado de su padre en ninguna lectura: un subdistribuidor `ACTIVE` de
|
|
91
|
+
* una cadena `SUSPENDED` sale como `ACTIVE`. Si eso importa, cruza el `parentId`.
|
|
92
|
+
*
|
|
93
|
+
* ── ⚠️ `status` SÍ tiene default, igual que `listStoresByRetailer` ───────────────────────────
|
|
94
|
+
* Omitirlo devuelve **solo los `ACTIVE`**. Pasa `"ALL"` para el padrón completo. El default vive
|
|
95
|
+
* en el lambda, no acá: mandarlo implícito desde el publisher partiría la decisión en dos
|
|
96
|
+
* lugares que alguien tendría que mantener sincronizados.
|
|
97
|
+
*
|
|
98
|
+
* Devuelve `[]` si ningún retailer pasa el filtro. **No hay 404**: el silo siempre existe — lo
|
|
99
|
+
* garantiza el `tenantId`, que es lo que resolvió el contexto del tenant.
|
|
100
|
+
*
|
|
101
|
+
* @throws `400 RETAILER_STATUS_FILTER_INVALID` si `status` no es del catálogo ·
|
|
102
|
+
* `400 UNKNOWN_TENANT` sin `tenantId`.
|
|
103
|
+
*/
|
|
104
|
+
listRetailers(
|
|
105
|
+
tenantId: string,
|
|
106
|
+
status?: RetailerRosterStatusFilter,
|
|
107
|
+
): Promise<StandardResponse<RetailerValidationDto[]>>;
|
|
108
|
+
|
|
64
109
|
/**
|
|
65
110
|
* GET /private/retailers/{retailerId} — valida que el retailer exista y devuelve su shape mínimo
|
|
66
111
|
* (id, name, type, status, parentId). `status` ya viene con la cascada aplicada (estado efectivo).
|