@fiado/api-invoker 5.143.0 → 5.144.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 (22) hide show
  1. package/bin/platformRbac/api/PlatformRbacBusinessApi.d.ts +1 -1
  2. package/bin/platformRbac/api/PlatformRbacBusinessApi.js +1 -1
  3. package/bin/platformRbac/api/interfaces/IPlatformRbacBusinessApi.d.ts +1 -1
  4. package/bin/retailCatalog/api/RetailCatalogBusinessApi.d.ts +2 -2
  5. package/bin/retailCatalog/api/RetailCatalogBusinessApi.js +3 -1
  6. package/bin/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.d.ts +8 -7
  7. package/bin/retailIntegration/api/RetailIntegrationConnectorApi.d.ts +5 -1
  8. package/bin/retailIntegration/api/RetailIntegrationConnectorApi.js +33 -7
  9. package/bin/retailIntegration/api/interfaces/IRetailIntegrationConnectorApi.d.ts +5 -1
  10. package/bin/retailOrg/api/RetailOrgBusinessApi.d.ts +5 -3
  11. package/bin/retailOrg/api/RetailOrgBusinessApi.js +13 -6
  12. package/bin/retailOrg/api/interfaces/IRetailOrgBusinessApi.d.ts +17 -3
  13. package/bin/retailOrg/api/interfaces/IRetailOrgBusinessApi.js +4 -1
  14. package/package.json +2 -2
  15. package/src/platformRbac/api/PlatformRbacBusinessApi.ts +1 -1
  16. package/src/platformRbac/api/interfaces/IPlatformRbacBusinessApi.ts +1 -1
  17. package/src/retailCatalog/api/RetailCatalogBusinessApi.ts +5 -3
  18. package/src/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.ts +7 -6
  19. package/src/retailIntegration/api/RetailIntegrationConnectorApi.ts +53 -7
  20. package/src/retailIntegration/api/interfaces/IRetailIntegrationConnectorApi.ts +14 -0
  21. package/src/retailOrg/api/RetailOrgBusinessApi.ts +14 -4
  22. package/src/retailOrg/api/interfaces/IRetailOrgBusinessApi.ts +21 -1
@@ -39,7 +39,7 @@ export default class PlatformRbacBusinessApi implements IPlatformRbacBusinessApi
39
39
  listLevelEntities(tenantId: string, level: PermissionScope, parentId?: string): Promise<APIGatewayProxyResultBody<ListLevelEntitiesResponse>>;
40
40
  /** GET /internal/tenants/{tenantId}/levels/{level}/entities/{id} — detalle de un grupo. */
41
41
  getLevelEntity(tenantId: string, level: PermissionScope, id: string): Promise<APIGatewayProxyResultBody<LevelEntityResponse>>;
42
- /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo. */
42
+ /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo o lo mueve de padre con `parentId`. */
43
43
  updateLevelEntity(tenantId: string, level: PermissionScope, id: string, input: UpdateLevelEntityRequest): Promise<APIGatewayProxyResultBody<LevelEntityResponse>>;
44
44
  /** DELETE /internal/tenants/{tenantId}/levels/{level}/entities/{id} — borra un grupo. El `actedBy` viaja en el cuerpo. */
45
45
  deleteLevelEntity(tenantId: string, level: PermissionScope, id: string, input: DeleteLevelEntityRequest): Promise<APIGatewayProxyResultBody<DeleteLevelEntityResponse>>;
@@ -111,7 +111,7 @@ let PlatformRbacBusinessApi = class PlatformRbacBusinessApi {
111
111
  const url = `${this._levelEntitiesUrl(tenantId, level)}/${encodeURIComponent(id)}`;
112
112
  return await this.httpRequest.get(url);
113
113
  }
114
- /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo. */
114
+ /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo o lo mueve de padre con `parentId`. */
115
115
  async updateLevelEntity(tenantId, level, id, input) {
116
116
  const url = `${this._levelEntitiesUrl(tenantId, level)}/${encodeURIComponent(id)}`;
117
117
  return await this.httpRequest.put(url, input);
@@ -82,7 +82,7 @@ export interface IPlatformRbacBusinessApi {
82
82
  listLevelEntities(tenantId: string, level: PermissionScope, parentId?: string): Promise<APIGatewayProxyResultBody<ListLevelEntitiesResponse>>;
83
83
  /** GET /internal/tenants/{tenantId}/levels/{level}/entities/{id} — detalle de un grupo. */
84
84
  getLevelEntity(tenantId: string, level: PermissionScope, id: string): Promise<APIGatewayProxyResultBody<LevelEntityResponse>>;
85
- /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo. */
85
+ /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo o lo mueve de padre con `parentId`. */
86
86
  updateLevelEntity(tenantId: string, level: PermissionScope, id: string, input: UpdateLevelEntityRequest): Promise<APIGatewayProxyResultBody<LevelEntityResponse>>;
87
87
  /** DELETE /internal/tenants/{tenantId}/levels/{level}/entities/{id} — borra un grupo. El `actedBy` viaja en el cuerpo. */
88
88
  deleteLevelEntity(tenantId: string, level: PermissionScope, id: string, input: DeleteLevelEntityRequest): Promise<APIGatewayProxyResultBody<DeleteLevelEntityResponse>>;
@@ -3,7 +3,7 @@ import { StandardResponse } from "@fiado/gateway-adapter";
3
3
  import type { GetStoreStockCatalogResponse, HoldStockRequest, HoldStockResponse, InventoryLensQuery, InventoryLensResponse, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, SyncInventoryResponse, ValidateProductResponse, StoreCatalogItem as StockCatalogItem } from "@fiado/type-kit/bin/retailCatalog/index.js";
4
4
  import type { PaginatedResult } from "@fiado/type-kit/bin/retailOrg/index.js";
5
5
  import type { ApplyInventoryEventRequest, ApplyInventoryEventResponse, ApplyProductEventRequest, ApplyProductEventResponse } from "@fiado/type-kit/bin/retailIntegration/index.js";
6
- import { IRetailCatalogBusinessApi, ProductsByRetailersResponse, ReleaseReservationBody, ReserveInventoryBody, ReserveInventoryResult, SellInventoryBody, StoreCatalogItem } from "./interfaces/IRetailCatalogBusinessApi.js";
6
+ import { IRetailCatalogBusinessApi, ProductsByRetailersResponse, ReleaseReservationBody, ReserveInventoryBody, ReserveInventoryResult, SellInventoryInput, StoreCatalogItem } from "./interfaces/IRetailCatalogBusinessApi.js";
7
7
  /**
8
8
  * Publisher HTTP del lambda `retail-catalog-business` (SureKeep Fase 1, pista Retail) para sus
9
9
  * endpoints privados del ciclo de venta del IMEI. Contrato y semántica completos →
@@ -26,7 +26,7 @@ export default class RetailCatalogBusinessApi implements IRetailCatalogBusinessA
26
26
  validateProduct(retailerId: string, sku: string, issuer: string): Promise<StandardResponse<ValidateProductResponse>>;
27
27
  getProductsByRetailers(retailerIds: string[], tenantId: string): Promise<StandardResponse<ProductsByRetailersResponse>>;
28
28
  reserveInventory(imei: string, body: ReserveInventoryBody, issuer: string): Promise<StandardResponse<ReserveInventoryResult>>;
29
- sellInventory(imei: string, body: SellInventoryBody, issuer: string): Promise<StandardResponse<void>>;
29
+ sellInventory(imei: string, body: SellInventoryInput, issuer: string): Promise<StandardResponse<void>>;
30
30
  releaseInventory(imei: string, body: ReleaseReservationBody, issuer: string): Promise<StandardResponse<void>>;
31
31
  returnInventory(imei: string, issuer: string): Promise<StandardResponse<void>>;
32
32
  /** URL de una ruta de tienda con `tenantId` y los parámetros extra en query. */
@@ -60,7 +60,9 @@ let RetailCatalogBusinessApi = class RetailCatalogBusinessApi {
60
60
  }
61
61
  async sellInventory(imei, body, issuer) {
62
62
  const url = `${this.baseUrl}/private/inventory/${encodeURIComponent(imei)}/sell`;
63
- return await this.httpRequest.put(url, body, this.tenantHeader(issuer));
63
+ const { saleId, ...rest } = body;
64
+ const payload = saleId === undefined ? rest : { ...rest, saleId };
65
+ return await this.httpRequest.put(url, payload, this.tenantHeader(issuer));
64
66
  }
65
67
  async releaseInventory(imei, body, issuer) {
66
68
  const url = `${this.baseUrl}/private/inventory/${encodeURIComponent(imei)}/release`;
@@ -1,5 +1,5 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
- import type { GetStoreStockCatalogResponse, HoldStockRequest, HoldStockResponse, InventoryLensQuery, InventoryLensResponse, MdmLockModeEnum, MdmProviderEnum, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, StoreCatalogItem as StockCatalogItem, SyncInventoryResponse, ValidateProductResponse } from "@fiado/type-kit/bin/retailCatalog/index.js";
2
+ import type { GetStoreStockCatalogResponse, HoldStockRequest, HoldStockResponse, InventoryLensQuery, InventoryLensResponse, MdmLockModeEnum, MdmProviderEnum, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SellInventoryRequest, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, StoreCatalogItem as StockCatalogItem, SyncInventoryResponse, ValidateProductResponse } from "@fiado/type-kit/bin/retailCatalog/index.js";
3
3
  import type { PaginatedResult } from "@fiado/type-kit/bin/retailOrg/index.js";
4
4
  import type { ApplyInventoryEventRequest, ApplyInventoryEventResponse, ApplyProductEventRequest, ApplyProductEventResponse } from "@fiado/type-kit/bin/retailIntegration/index.js";
5
5
  /**
@@ -93,11 +93,12 @@ export interface ReserveInventoryBody {
93
93
  sku: string;
94
94
  sessionId: string;
95
95
  }
96
- /** Body de PUT `/private/inventory/{imei}/sell` (DEC-020 del destino: `customerId` puebla `soldToCustomerId`). */
97
- export interface SellInventoryBody {
98
- sessionId: string;
99
- customerId: string;
100
- }
96
+ /** Body de PUT `/private/inventory/{imei}/sell`; `saleId` opcional mientras el wizard de main no lo mande (catalog lo exige en runtime). */
97
+ export type SellInventoryInput = Omit<SellInventoryRequest, 'saleId'> & {
98
+ saleId?: string;
99
+ };
100
+ /** Alias de `SellInventoryInput`; se conserva por compatibilidad con consumidores. */
101
+ export type SellInventoryBody = SellInventoryInput;
101
102
  /** Body de PUT `/private/inventory/{imei}/release` (DEC-018 del destino: verifica titularidad de la sesión). */
102
103
  export interface ReleaseReservationBody {
103
104
  sessionId: string;
@@ -149,7 +150,7 @@ export interface IRetailCatalogBusinessApi {
149
150
  /** PUT `/private/inventory/{imei}/reserve` — reserva atómica del IMEI para una sesión (AVAILABLE → RESERVED). */
150
151
  reserveInventory(imei: string, body: ReserveInventoryBody, issuer: string): Promise<StandardResponse<ReserveInventoryResult>>;
151
152
  /** PUT `/private/inventory/{imei}/sell` — vende el IMEI (RESERVED → SOLD). */
152
- sellInventory(imei: string, body: SellInventoryBody, issuer: string): Promise<StandardResponse<void>>;
153
+ sellInventory(imei: string, body: SellInventoryInput, issuer: string): Promise<StandardResponse<void>>;
153
154
  /** PUT `/private/inventory/{imei}/release` — libera la reserva (RESERVED → AVAILABLE, titularidad de la sesión). */
154
155
  releaseInventory(imei: string, body: ReleaseReservationBody, issuer: string): Promise<StandardResponse<void>>;
155
156
  /** PUT `/private/inventory/{imei}/return` — devuelve el IMEI vendido al stock (SOLD → AVAILABLE, sin body). */
@@ -1,6 +1,6 @@
1
1
  import type { IHttpRequest } from "@fiado/http-client";
2
2
  import { StandardResponse } from "@fiado/gateway-adapter";
3
- import type { GetRetailInventoryRequest, GetRetailInventoryResponse, ListRetailCatalogRequest, ListRetailCatalogResponse, ListRetailStoresRequest, ListRetailStoresResponse, ListRetailUsersRequest, ListRetailUsersResponse, RegisterRetailSaleRequest, RegisterRetailSaleResponse, RetailSystemSale } from "@fiado/type-kit/bin/retailIntegration/index.js";
3
+ import type { CancelRetailSaleRequest, CancelRetailSaleResponse, CheckRetailInventoryRequest, CheckRetailInventoryResponse, GetRetailInventoryRequest, GetRetailInventoryResponse, ListRetailCatalogRequest, ListRetailCatalogResponse, ListRetailStoresRequest, ListRetailStoresResponse, ListRetailUsersRequest, ListRetailUsersResponse, RegisterRetailSaleRequest, RegisterRetailSaleResponse, RetailSystemSale, RetailTenantQuery } from "@fiado/type-kit/bin/retailIntegration/index.js";
4
4
  import { IRetailIntegrationConnectorApi } from "./interfaces/IRetailIntegrationConnectorApi.js";
5
5
  /** Publisher de la salida privada de `retail-integration-connector`. */
6
6
  export default class RetailIntegrationConnectorApi implements IRetailIntegrationConnectorApi {
@@ -12,6 +12,10 @@ export default class RetailIntegrationConnectorApi implements IRetailIntegration
12
12
  getRetailInventory(request: GetRetailInventoryRequest): Promise<StandardResponse<GetRetailInventoryResponse>>;
13
13
  listRetailUsers(request: ListRetailUsersRequest): Promise<StandardResponse<ListRetailUsersResponse>>;
14
14
  registerRetailSale(request: RegisterRetailSaleRequest, sale: RetailSystemSale): Promise<StandardResponse<RegisterRetailSaleResponse>>;
15
+ cancelRetailSale(query: RetailTenantQuery, cancellation: CancelRetailSaleRequest): Promise<StandardResponse<CancelRetailSaleResponse>>;
16
+ checkRetailInventory(request: CheckRetailInventoryRequest): Promise<StandardResponse<CheckRetailInventoryResponse>>;
15
17
  private getWithTimeout;
18
+ private tenantQuery;
19
+ private listQuery;
16
20
  private toQuery;
17
21
  }
@@ -13,6 +13,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
13
13
  import { inject, injectable } from "inversify";
14
14
  /** Mayor que el Timeout de 10 s del connector, para no cortar una venta en vuelo. */
15
15
  const RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS = 12000;
16
+ /** Mayor que los 2.5 s del connector hacia el retailer; la consulta en vivo no debe frenar la venta. */
17
+ const RETAIL_LIVE_CHECK_TIMEOUT_MS = 3000;
16
18
  /** Publisher de la salida privada de `retail-integration-connector`. */
17
19
  let RetailIntegrationConnectorApi = class RetailIntegrationConnectorApi {
18
20
  httpRequest;
@@ -22,42 +24,66 @@ let RetailIntegrationConnectorApi = class RetailIntegrationConnectorApi {
22
24
  }
23
25
  async listRetailStores(request) {
24
26
  return await this.getWithTimeout("/private/retail/stores", {
25
- tenantId: request.tenantId,
27
+ ...this.listQuery(request),
26
28
  limit: request.limit,
27
29
  nextToken: request.nextToken,
28
30
  });
29
31
  }
30
32
  async listRetailCatalog(request) {
31
33
  return await this.getWithTimeout("/private/retail/catalog", {
32
- tenantId: request.tenantId,
34
+ ...this.listQuery(request),
33
35
  limit: request.limit,
34
36
  nextToken: request.nextToken,
35
37
  });
36
38
  }
37
39
  async getRetailInventory(request) {
38
40
  return await this.getWithTimeout("/private/retail/inventory", {
39
- tenantId: request.tenantId,
41
+ ...this.tenantQuery(request),
40
42
  storeId: request.storeId,
43
+ runId: request.runId,
41
44
  });
42
45
  }
43
46
  async listRetailUsers(request) {
44
47
  return await this.getWithTimeout("/private/retail/users", {
45
- tenantId: request.tenantId,
48
+ ...this.tenantQuery(request),
46
49
  storeId: request.storeId,
50
+ runId: request.runId,
47
51
  limit: request.limit,
48
52
  nextToken: request.nextToken,
49
53
  });
50
54
  }
51
55
  async registerRetailSale(request, sale) {
52
- const url = `${this.baseUrl}/private/retail/sales?${this.toQuery({ tenantId: request.tenantId })}`;
56
+ const url = `${this.baseUrl}/private/retail/sales?${this.toQuery(this.tenantQuery(request))}`;
53
57
  return await this.httpRequest.post(url, sale, {}, undefined, false, {
54
58
  timeout: RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS,
55
59
  });
56
60
  }
61
+ async cancelRetailSale(query, cancellation) {
62
+ const url = `${this.baseUrl}/private/retail/sales/cancel?${this.toQuery(this.tenantQuery(query))}`;
63
+ return await this.httpRequest.post(url, cancellation, {}, undefined, false, {
64
+ timeout: RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS,
65
+ });
66
+ }
67
+ async checkRetailInventory(request) {
68
+ const fields = {
69
+ ...this.tenantQuery(request),
70
+ storeId: request.storeId,
71
+ identifiers: request.identifiers.join(","),
72
+ sessionId: request.sessionId,
73
+ };
74
+ return await this.getWithTimeout("/private/retail/inventory/live-check", fields, RETAIL_LIVE_CHECK_TIMEOUT_MS);
75
+ }
57
76
  // GET con timeout propio; nunca `enableTimeout`, que tomaría el timeout corto del consumidor.
58
- async getWithTimeout(path, fields) {
77
+ async getWithTimeout(path, fields, timeout = RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS) {
59
78
  const url = `${this.baseUrl}${path}?${this.toQuery(fields)}`;
60
- return await this.httpRequest.get(url, {}, {}, undefined, { timeout: RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS }, false);
79
+ return await this.httpRequest.get(url, {}, {}, undefined, { timeout }, false);
80
+ }
81
+ // El connector coteja tenantId y retailerId contra el secreto del tenant.
82
+ tenantQuery(query) {
83
+ return { tenantId: query.tenantId, retailerId: query.retailerId };
84
+ }
85
+ listQuery(query) {
86
+ return { ...this.tenantQuery(query), runId: query.runId };
61
87
  }
62
88
  toQuery(fields) {
63
89
  const params = new URLSearchParams();
@@ -1,5 +1,5 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
- import type { GetRetailInventoryRequest, GetRetailInventoryResponse, ListRetailCatalogRequest, ListRetailCatalogResponse, ListRetailStoresRequest, ListRetailStoresResponse, ListRetailUsersRequest, ListRetailUsersResponse, RegisterRetailSaleRequest, RegisterRetailSaleResponse, RetailSystemSale } from "@fiado/type-kit/bin/retailIntegration/index.js";
2
+ import type { CancelRetailSaleRequest, CancelRetailSaleResponse, CheckRetailInventoryRequest, CheckRetailInventoryResponse, GetRetailInventoryRequest, GetRetailInventoryResponse, ListRetailCatalogRequest, ListRetailCatalogResponse, ListRetailStoresRequest, ListRetailStoresResponse, ListRetailUsersRequest, ListRetailUsersResponse, RegisterRetailSaleRequest, RegisterRetailSaleResponse, RetailSystemSale, RetailTenantQuery } from "@fiado/type-kit/bin/retailIntegration/index.js";
3
3
  /**
4
4
  * Salida privada de `retail-integration-connector` hacia el sistema del retailer del tenant.
5
5
  * Env var del consumidor: `RETAIL_INTEGRATION_CONNECTOR_URL: '{{resolve:ssm:retail-integration-connector}}'`.
@@ -15,4 +15,8 @@ export interface IRetailIntegrationConnectorApi {
15
15
  listRetailUsers(request: ListRetailUsersRequest): Promise<StandardResponse<ListRetailUsersResponse>>;
16
16
  /** `POST /private/retail/sales` — registra la venta; ante timeout o 502, reintenta con el mismo `saleId`. */
17
17
  registerRetailSale(request: RegisterRetailSaleRequest, sale: RetailSystemSale): Promise<StandardResponse<RegisterRetailSaleResponse>>;
18
+ /** `POST /private/retail/sales/cancel` — cancela la venta con el mismo `saleId` del registro; 12 s. */
19
+ cancelRetailSale(query: RetailTenantQuery, cancellation: CancelRetailSaleRequest): Promise<StandardResponse<CancelRetailSaleResponse>>;
20
+ /** `GET /private/retail/inventory/live-check` — qué identificadores lista hoy la tienda; 3 s. */
21
+ checkRetailInventory(request: CheckRetailInventoryRequest): Promise<StandardResponse<CheckRetailInventoryResponse>>;
18
22
  }
@@ -2,7 +2,7 @@ import type { IHttpRequest } from "@fiado/http-client";
2
2
  import { StandardResponse } from "@fiado/gateway-adapter";
3
3
  import { RetailerValidationDto, StoreValidationDto, RetailUserValidationDto, CollectorValidationDto, PrivateSellerListResponse, PrivateGoalListResponse, GoalTargetTypeEnum, RetailUserStatusEnum, PrivateRetailUserWalletResponse } from "@fiado/type-kit/bin/retailOrg/index.js";
4
4
  import type { ApplyRetailUserEventRequest, ApplyRetailUserEventResponse, ApplyStoreEventRequest, ApplyStoreEventResponse } from "@fiado/type-kit/bin/retailIntegration/index.js";
5
- import { IRetailOrgBusinessApi, RetailerRosterStatusFilter, StoreRosterStatusFilter } from "./interfaces/IRetailOrgBusinessApi.js";
5
+ import { IRetailOrgBusinessApi, RetailOrgRequestOptions, RetailerRosterStatusFilter, StoreRosterStatusFilter } from "./interfaces/IRetailOrgBusinessApi.js";
6
6
  /**
7
7
  * Publisher HTTP del lambda `retail-org-business` (componente 04 SureKeep Fase 1) para sus 9
8
8
  * endpoints privados de validación. Contrato y semántica completos → `IRetailOrgBusinessApi`.
@@ -27,8 +27,10 @@ export default class RetailOrgBusinessApi implements IRetailOrgBusinessApi {
27
27
  * qué `status` SÍ tiene default y por qué acá el estado es el CRUDO, sin cascada del padre)
28
28
  * → `IRetailOrgBusinessApi.listRetailers`.
29
29
  */
30
- listRetailers(tenantId: string, status?: RetailerRosterStatusFilter): Promise<StandardResponse<RetailerValidationDto[]>>;
31
- getRetailer(retailerId: string, tenantId: string): Promise<StandardResponse<RetailerValidationDto>>;
30
+ listRetailers(tenantId: string, status?: RetailerRosterStatusFilter, integrated?: boolean, options?: RetailOrgRequestOptions): Promise<StandardResponse<RetailerValidationDto[]>>;
31
+ getRetailer(retailerId: string, tenantId: string, options?: RetailOrgRequestOptions): Promise<StandardResponse<RetailerValidationDto>>;
32
+ /** Aplica el timeout solo si el caller lo pide; sin él, el GET queda igual que siempre. */
33
+ private getWithOptionalTimeout;
32
34
  getRetailerByStore(storeId: string, tenantId: string): Promise<StandardResponse<RetailerValidationDto>>;
33
35
  getStore(retailerId: string, storeId: string, tenantId: string): Promise<StandardResponse<StoreValidationDto>>;
34
36
  /**
@@ -37,17 +37,24 @@ let RetailOrgBusinessApi = class RetailOrgBusinessApi {
37
37
  * qué `status` SÍ tiene default y por qué acá el estado es el CRUDO, sin cascada del padre)
38
38
  * → `IRetailOrgBusinessApi.listRetailers`.
39
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.
40
+ async listRetailers(tenantId, status, integrated, options) {
43
41
  const query = new URLSearchParams({ tenantId });
44
42
  if (status)
45
43
  query.set("status", status);
46
- return await this.httpRequest.get(`${this.baseUrl}/private/retailers?${query.toString()}`);
44
+ if (integrated !== undefined)
45
+ query.set("integrated", String(integrated));
46
+ const url = `${this.baseUrl}/private/retailers?${query.toString()}`;
47
+ return await this.getWithOptionalTimeout(url, options);
47
48
  }
48
- async getRetailer(retailerId, tenantId) {
49
+ async getRetailer(retailerId, tenantId, options) {
49
50
  const url = `${this.baseUrl}/private/retailers/${encodeURIComponent(retailerId)}?tenantId=${encodeURIComponent(tenantId)}`;
50
- return await this.httpRequest.get(url);
51
+ return await this.getWithOptionalTimeout(url, options);
52
+ }
53
+ /** Aplica el timeout solo si el caller lo pide; sin él, el GET queda igual que siempre. */
54
+ async getWithOptionalTimeout(url, options) {
55
+ if (options?.timeoutMs === undefined)
56
+ return await this.httpRequest.get(url);
57
+ return await this.httpRequest.get(url, undefined, undefined, undefined, { timeout: options.timeoutMs });
51
58
  }
52
59
  async getRetailerByStore(storeId, tenantId) {
53
60
  const url = `${this.baseUrl}/private/retailers/by-store/${encodeURIComponent(storeId)}?tenantId=${encodeURIComponent(tenantId)}`;
@@ -1,6 +1,14 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
2
  import { RetailerValidationDto, StoreValidationDto, RetailUserValidationDto, CollectorValidationDto, PrivateSellerListResponse, PrivateGoalListResponse, GoalTargetTypeEnum, RetailUserStatusEnum, RetailerStatusEnum, StoreStatusEnum, PrivateRetailUserWalletResponse } from "@fiado/type-kit/bin/retailOrg/index.js";
3
3
  import type { ApplyRetailUserEventRequest, ApplyRetailUserEventResponse, ApplyStoreEventRequest, ApplyStoreEventResponse } from "@fiado/type-kit/bin/retailIntegration/index.js";
4
+ /** Timeout que el connector y el wizard pasan a `getRetailer`: cabe en los 3 s por evento del connector. */
5
+ export declare const RETAIL_ORG_GET_RETAILER_TIMEOUT_MS = 1500;
6
+ /** Timeout que el connector pasa a `listRetailers`: el padrón trae el árbol completo del silo. */
7
+ export declare const RETAIL_ORG_LIST_RETAILERS_TIMEOUT_MS = 5000;
8
+ /** Opciones por llamada. Sin `timeoutMs` no se aplica timeout propio. */
9
+ export interface RetailOrgRequestOptions {
10
+ timeoutMs?: number;
11
+ }
4
12
  /**
5
13
  * Filtro de `listStoresByRetailer`. `"ALL"` no es un estado de tienda: es la ausencia de filtro, y
6
14
  * va en el MISMO parámetro que los estados porque los dos hablan del mismo eje — un segundo flag
@@ -87,17 +95,23 @@ export interface IRetailOrgBusinessApi {
87
95
  * Devuelve `[]` si ningún retailer pasa el filtro. **No hay 404**: el silo siempre existe — lo
88
96
  * garantiza el `tenantId`, que es lo que resolvió el contexto del tenant.
89
97
  *
98
+ * `integrated = true` deja solo los retailers con la bandera de integración prendida; cada
99
+ * retailer trae `integrationSystem` e `integrationActivatedAt` cuando la tiene. Timeout opt-in vía
100
+ * `options.timeoutMs` (ver `RETAIL_ORG_LIST_RETAILERS_TIMEOUT_MS`).
101
+ *
90
102
  * @throws `400 RETAILER_STATUS_FILTER_INVALID` si `status` no es del catálogo ·
91
103
  * `400 UNKNOWN_TENANT` sin `tenantId`.
92
104
  */
93
- listRetailers(tenantId: string, status?: RetailerRosterStatusFilter): Promise<StandardResponse<RetailerValidationDto[]>>;
105
+ listRetailers(tenantId: string, status?: RetailerRosterStatusFilter, integrated?: boolean, options?: RetailOrgRequestOptions): Promise<StandardResponse<RetailerValidationDto[]>>;
94
106
  /**
95
107
  * GET /private/retailers/{retailerId} — valida que el retailer exista y devuelve su shape mínimo
96
- * (id, name, type, status, parentId). `status` ya viene con la cascada aplicada (estado efectivo).
108
+ * (id, name, type, status, parentId) y la bandera de integración. `status` ya viene con la cascada
109
+ * aplicada (estado efectivo). Timeout opt-in vía `options.timeoutMs` (ver
110
+ * `RETAIL_ORG_GET_RETAILER_TIMEOUT_MS`).
97
111
  *
98
112
  * @throws si el retailer no existe (`404 RETAILER_NOT_FOUND`).
99
113
  */
100
- getRetailer(retailerId: string, tenantId: string): Promise<StandardResponse<RetailerValidationDto>>;
114
+ getRetailer(retailerId: string, tenantId: string, options?: RetailOrgRequestOptions): Promise<StandardResponse<RetailerValidationDto>>;
101
115
  /**
102
116
  * GET /private/retailers/by-store/{storeId} — resuelve el retailer DUEÑO de una tienda teniendo
103
117
  * SOLO el `storeId`, sin conocer el retailer. Es el único privado que no va anidado, porque es el
@@ -1 +1,4 @@
1
- export {};
1
+ /** Timeout que el connector y el wizard pasan a `getRetailer`: cabe en los 3 s por evento del connector. */
2
+ export const RETAIL_ORG_GET_RETAILER_TIMEOUT_MS = 1500;
3
+ /** Timeout que el connector pasa a `listRetailers`: el padrón trae el árbol completo del silo. */
4
+ export const RETAIL_ORG_LIST_RETAILERS_TIMEOUT_MS = 5000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/api-invoker",
3
- "version": "5.143.0",
3
+ "version": "5.144.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.14.0",
35
35
  "@fiado/http-client": "^2.0.1",
36
36
  "@fiado/logger": "^1.1.3",
37
- "@fiado/type-kit": "^3.575.0",
37
+ "@fiado/type-kit": "^3.579.0",
38
38
  "dotenv": "^16.4.7"
39
39
  },
40
40
  "peerDependencies": {
@@ -204,7 +204,7 @@ export default class PlatformRbacBusinessApi implements IPlatformRbacBusinessApi
204
204
  return await this.httpRequest.get(url);
205
205
  }
206
206
 
207
- /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo. */
207
+ /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo o lo mueve de padre con `parentId`. */
208
208
  async updateLevelEntity(
209
209
  tenantId: string,
210
210
  level: PermissionScope,
@@ -174,7 +174,7 @@ export interface IPlatformRbacBusinessApi {
174
174
  id: string,
175
175
  ): Promise<APIGatewayProxyResultBody<LevelEntityResponse>>;
176
176
 
177
- /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo. */
177
+ /** PUT /internal/tenants/{tenantId}/levels/{level}/entities/{id} — renombra un grupo o lo mueve de padre con `parentId`. */
178
178
  updateLevelEntity(
179
179
  tenantId: string,
180
180
  level: PermissionScope,
@@ -41,7 +41,7 @@ import {
41
41
  ReserveInventoryBody,
42
42
  ReserveInventoryResult,
43
43
  RETAILER_PRODUCTS_BATCH_MAX,
44
- SellInventoryBody,
44
+ SellInventoryInput,
45
45
  StoreCatalogItem,
46
46
  } from "./interfaces/IRetailCatalogBusinessApi.js";
47
47
 
@@ -114,9 +114,11 @@ export default class RetailCatalogBusinessApi implements IRetailCatalogBusinessA
114
114
  return await this.httpRequest.put(url, body, this.tenantHeader(issuer));
115
115
  }
116
116
 
117
- async sellInventory(imei: string, body: SellInventoryBody, issuer: string): Promise<StandardResponse<void>> {
117
+ async sellInventory(imei: string, body: SellInventoryInput, issuer: string): Promise<StandardResponse<void>> {
118
118
  const url = `${this.baseUrl}/private/inventory/${encodeURIComponent(imei)}/sell`;
119
- return await this.httpRequest.put(url, body, this.tenantHeader(issuer));
119
+ const { saleId, ...rest } = body;
120
+ const payload = saleId === undefined ? rest : { ...rest, saleId };
121
+ return await this.httpRequest.put(url, payload, this.tenantHeader(issuer));
120
122
  }
121
123
 
122
124
  async releaseInventory(imei: string, body: ReleaseReservationBody, issuer: string): Promise<StandardResponse<void>> {
@@ -17,6 +17,7 @@ import type {
17
17
  ReturnStockResponse,
18
18
  SellStockRequest,
19
19
  SellStockResponse,
20
+ SellInventoryRequest,
20
21
  SuggestPiecesQuery,
21
22
  SuggestPiecesResponse,
22
23
  SyncInventoryRequest,
@@ -137,11 +138,11 @@ export interface ReserveInventoryBody {
137
138
  sessionId: string;
138
139
  }
139
140
 
140
- /** Body de PUT `/private/inventory/{imei}/sell` (DEC-020 del destino: `customerId` puebla `soldToCustomerId`). */
141
- export interface SellInventoryBody {
142
- sessionId: string;
143
- customerId: string;
144
- }
141
+ /** Body de PUT `/private/inventory/{imei}/sell`; `saleId` opcional mientras el wizard de main no lo mande (catalog lo exige en runtime). */
142
+ export type SellInventoryInput = Omit<SellInventoryRequest, 'saleId'> & { saleId?: string };
143
+
144
+ /** Alias de `SellInventoryInput`; se conserva por compatibilidad con consumidores. */
145
+ export type SellInventoryBody = SellInventoryInput;
145
146
 
146
147
  /** Body de PUT `/private/inventory/{imei}/release` (DEC-018 del destino: verifica titularidad de la sesión). */
147
148
  export interface ReleaseReservationBody {
@@ -206,7 +207,7 @@ export interface IRetailCatalogBusinessApi {
206
207
  reserveInventory(imei: string, body: ReserveInventoryBody, issuer: string): Promise<StandardResponse<ReserveInventoryResult>>;
207
208
 
208
209
  /** PUT `/private/inventory/{imei}/sell` — vende el IMEI (RESERVED → SOLD). */
209
- sellInventory(imei: string, body: SellInventoryBody, issuer: string): Promise<StandardResponse<void>>;
210
+ sellInventory(imei: string, body: SellInventoryInput, issuer: string): Promise<StandardResponse<void>>;
210
211
 
211
212
  /** PUT `/private/inventory/{imei}/release` — libera la reserva (RESERVED → AVAILABLE, titularidad de la sesión). */
212
213
  releaseInventory(imei: string, body: ReleaseReservationBody, issuer: string): Promise<StandardResponse<void>>;
@@ -2,6 +2,10 @@ import { inject, injectable } from "inversify";
2
2
  import type { IHttpRequest } from "@fiado/http-client";
3
3
  import { StandardResponse } from "@fiado/gateway-adapter";
4
4
  import type {
5
+ CancelRetailSaleRequest,
6
+ CancelRetailSaleResponse,
7
+ CheckRetailInventoryRequest,
8
+ CheckRetailInventoryResponse,
5
9
  GetRetailInventoryRequest,
6
10
  GetRetailInventoryResponse,
7
11
  ListRetailCatalogRequest,
@@ -12,13 +16,18 @@ import type {
12
16
  ListRetailUsersResponse,
13
17
  RegisterRetailSaleRequest,
14
18
  RegisterRetailSaleResponse,
19
+ RetailListQuery,
15
20
  RetailSystemSale,
21
+ RetailTenantQuery,
16
22
  } from "@fiado/type-kit/bin/retailIntegration/index.js";
17
23
  import { IRetailIntegrationConnectorApi } from "./interfaces/IRetailIntegrationConnectorApi.js";
18
24
 
19
25
  /** Mayor que el Timeout de 10 s del connector, para no cortar una venta en vuelo. */
20
26
  const RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS = 12000;
21
27
 
28
+ /** Mayor que los 2.5 s del connector hacia el retailer; la consulta en vivo no debe frenar la venta. */
29
+ const RETAIL_LIVE_CHECK_TIMEOUT_MS = 3000;
30
+
22
31
  type QueryFields = Record<string, string | number | undefined>;
23
32
 
24
33
  /** Publisher de la salida privada de `retail-integration-connector`. */
@@ -30,7 +39,7 @@ export default class RetailIntegrationConnectorApi implements IRetailIntegration
30
39
 
31
40
  async listRetailStores(request: ListRetailStoresRequest): Promise<StandardResponse<ListRetailStoresResponse>> {
32
41
  return await this.getWithTimeout("/private/retail/stores", {
33
- tenantId: request.tenantId,
42
+ ...this.listQuery(request),
34
43
  limit: request.limit,
35
44
  nextToken: request.nextToken,
36
45
  });
@@ -38,7 +47,7 @@ export default class RetailIntegrationConnectorApi implements IRetailIntegration
38
47
 
39
48
  async listRetailCatalog(request: ListRetailCatalogRequest): Promise<StandardResponse<ListRetailCatalogResponse>> {
40
49
  return await this.getWithTimeout("/private/retail/catalog", {
41
- tenantId: request.tenantId,
50
+ ...this.listQuery(request),
42
51
  limit: request.limit,
43
52
  nextToken: request.nextToken,
44
53
  });
@@ -46,15 +55,17 @@ export default class RetailIntegrationConnectorApi implements IRetailIntegration
46
55
 
47
56
  async getRetailInventory(request: GetRetailInventoryRequest): Promise<StandardResponse<GetRetailInventoryResponse>> {
48
57
  return await this.getWithTimeout("/private/retail/inventory", {
49
- tenantId: request.tenantId,
58
+ ...this.tenantQuery(request),
50
59
  storeId: request.storeId,
60
+ runId: request.runId,
51
61
  });
52
62
  }
53
63
 
54
64
  async listRetailUsers(request: ListRetailUsersRequest): Promise<StandardResponse<ListRetailUsersResponse>> {
55
65
  return await this.getWithTimeout("/private/retail/users", {
56
- tenantId: request.tenantId,
66
+ ...this.tenantQuery(request),
57
67
  storeId: request.storeId,
68
+ runId: request.runId,
58
69
  limit: request.limit,
59
70
  nextToken: request.nextToken,
60
71
  });
@@ -64,16 +75,51 @@ export default class RetailIntegrationConnectorApi implements IRetailIntegration
64
75
  request: RegisterRetailSaleRequest,
65
76
  sale: RetailSystemSale,
66
77
  ): Promise<StandardResponse<RegisterRetailSaleResponse>> {
67
- const url = `${this.baseUrl}/private/retail/sales?${this.toQuery({ tenantId: request.tenantId })}`;
78
+ const url = `${this.baseUrl}/private/retail/sales?${this.toQuery(this.tenantQuery(request))}`;
68
79
  return await this.httpRequest.post(url, sale, {}, undefined, false, {
69
80
  timeout: RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS,
70
81
  });
71
82
  }
72
83
 
84
+ async cancelRetailSale(
85
+ query: RetailTenantQuery,
86
+ cancellation: CancelRetailSaleRequest,
87
+ ): Promise<StandardResponse<CancelRetailSaleResponse>> {
88
+ const url = `${this.baseUrl}/private/retail/sales/cancel?${this.toQuery(this.tenantQuery(query))}`;
89
+ return await this.httpRequest.post(url, cancellation, {}, undefined, false, {
90
+ timeout: RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS,
91
+ });
92
+ }
93
+
94
+ async checkRetailInventory(
95
+ request: CheckRetailInventoryRequest,
96
+ ): Promise<StandardResponse<CheckRetailInventoryResponse>> {
97
+ const fields = {
98
+ ...this.tenantQuery(request),
99
+ storeId: request.storeId,
100
+ identifiers: request.identifiers.join(","),
101
+ sessionId: request.sessionId,
102
+ };
103
+ return await this.getWithTimeout("/private/retail/inventory/live-check", fields, RETAIL_LIVE_CHECK_TIMEOUT_MS);
104
+ }
105
+
73
106
  // GET con timeout propio; nunca `enableTimeout`, que tomaría el timeout corto del consumidor.
74
- private async getWithTimeout<T>(path: string, fields: QueryFields): Promise<StandardResponse<T>> {
107
+ private async getWithTimeout<T>(
108
+ path: string,
109
+ fields: QueryFields,
110
+ timeout = RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS,
111
+ ): Promise<StandardResponse<T>> {
75
112
  const url = `${this.baseUrl}${path}?${this.toQuery(fields)}`;
76
- return await this.httpRequest.get(url, {}, {}, undefined, { timeout: RETAIL_INTEGRATION_CONNECTOR_TIMEOUT_MS }, false);
113
+ return await this.httpRequest.get(url, {}, {}, undefined, { timeout }, false);
114
+ }
115
+
116
+ // El connector coteja tenantId y retailerId contra el secreto del tenant.
117
+ private tenantQuery(query: RetailTenantQuery): QueryFields {
118
+ return { tenantId: query.tenantId, retailerId: query.retailerId };
119
+ }
120
+
121
+ private listQuery(query: RetailListQuery): QueryFields {
122
+ return { ...this.tenantQuery(query), runId: query.runId };
77
123
  }
78
124
 
79
125
  private toQuery(fields: QueryFields): string {
@@ -1,5 +1,9 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
2
  import type {
3
+ CancelRetailSaleRequest,
4
+ CancelRetailSaleResponse,
5
+ CheckRetailInventoryRequest,
6
+ CheckRetailInventoryResponse,
3
7
  GetRetailInventoryRequest,
4
8
  GetRetailInventoryResponse,
5
9
  ListRetailCatalogRequest,
@@ -11,6 +15,7 @@ import type {
11
15
  RegisterRetailSaleRequest,
12
16
  RegisterRetailSaleResponse,
13
17
  RetailSystemSale,
18
+ RetailTenantQuery,
14
19
  } from "@fiado/type-kit/bin/retailIntegration/index.js";
15
20
 
16
21
  /**
@@ -35,4 +40,13 @@ export interface IRetailIntegrationConnectorApi {
35
40
  request: RegisterRetailSaleRequest,
36
41
  sale: RetailSystemSale,
37
42
  ): Promise<StandardResponse<RegisterRetailSaleResponse>>;
43
+
44
+ /** `POST /private/retail/sales/cancel` — cancela la venta con el mismo `saleId` del registro; 12 s. */
45
+ cancelRetailSale(
46
+ query: RetailTenantQuery,
47
+ cancellation: CancelRetailSaleRequest,
48
+ ): Promise<StandardResponse<CancelRetailSaleResponse>>;
49
+
50
+ /** `GET /private/retail/inventory/live-check` — qué identificadores lista hoy la tienda; 3 s. */
51
+ checkRetailInventory(request: CheckRetailInventoryRequest): Promise<StandardResponse<CheckRetailInventoryResponse>>;
38
52
  }
@@ -22,6 +22,7 @@ import type {
22
22
  } from "@fiado/type-kit/bin/retailIntegration/index.js";
23
23
  import {
24
24
  IRetailOrgBusinessApi,
25
+ RetailOrgRequestOptions,
25
26
  RetailerRosterStatusFilter,
26
27
  StoreRosterStatusFilter,
27
28
  } from "./interfaces/IRetailOrgBusinessApi.js";
@@ -55,20 +56,29 @@ export default class RetailOrgBusinessApi implements IRetailOrgBusinessApi {
55
56
  async listRetailers(
56
57
  tenantId: string,
57
58
  status?: RetailerRosterStatusFilter,
59
+ integrated?: boolean,
60
+ options?: RetailOrgRequestOptions,
58
61
  ): Promise<StandardResponse<RetailerValidationDto[]>> {
59
- // `URLSearchParams` en vez de concatenar: `status` es opcional y armar el `&status=` a mano
60
- // deja un `&status=undefined` en cuanto alguien se distrae.
61
62
  const query = new URLSearchParams({ tenantId });
62
63
  if (status) query.set("status", status);
63
- return await this.httpRequest.get(`${this.baseUrl}/private/retailers?${query.toString()}`);
64
+ if (integrated !== undefined) query.set("integrated", String(integrated));
65
+ const url = `${this.baseUrl}/private/retailers?${query.toString()}`;
66
+ return await this.getWithOptionalTimeout(url, options);
64
67
  }
65
68
 
66
69
  async getRetailer(
67
70
  retailerId: string,
68
71
  tenantId: string,
72
+ options?: RetailOrgRequestOptions,
69
73
  ): Promise<StandardResponse<RetailerValidationDto>> {
70
74
  const url = `${this.baseUrl}/private/retailers/${encodeURIComponent(retailerId)}?tenantId=${encodeURIComponent(tenantId)}`;
71
- return await this.httpRequest.get(url);
75
+ return await this.getWithOptionalTimeout(url, options);
76
+ }
77
+
78
+ /** Aplica el timeout solo si el caller lo pide; sin él, el GET queda igual que siempre. */
79
+ private async getWithOptionalTimeout<T>(url: string, options?: RetailOrgRequestOptions): Promise<StandardResponse<T>> {
80
+ if (options?.timeoutMs === undefined) return await this.httpRequest.get(url);
81
+ return await this.httpRequest.get(url, undefined, undefined, undefined, { timeout: options.timeoutMs });
72
82
  }
73
83
 
74
84
  async getRetailerByStore(
@@ -19,6 +19,17 @@ import type {
19
19
  ApplyStoreEventResponse,
20
20
  } from "@fiado/type-kit/bin/retailIntegration/index.js";
21
21
 
22
+ /** Timeout que el connector y el wizard pasan a `getRetailer`: cabe en los 3 s por evento del connector. */
23
+ export const RETAIL_ORG_GET_RETAILER_TIMEOUT_MS = 1500;
24
+
25
+ /** Timeout que el connector pasa a `listRetailers`: el padrón trae el árbol completo del silo. */
26
+ export const RETAIL_ORG_LIST_RETAILERS_TIMEOUT_MS = 5000;
27
+
28
+ /** Opciones por llamada. Sin `timeoutMs` no se aplica timeout propio. */
29
+ export interface RetailOrgRequestOptions {
30
+ timeoutMs?: number;
31
+ }
32
+
22
33
  /**
23
34
  * Filtro de `listStoresByRetailer`. `"ALL"` no es un estado de tienda: es la ausencia de filtro, y
24
35
  * va en el MISMO parámetro que los estados porque los dos hablan del mismo eje — un segundo flag
@@ -107,23 +118,32 @@ export interface IRetailOrgBusinessApi {
107
118
  * Devuelve `[]` si ningún retailer pasa el filtro. **No hay 404**: el silo siempre existe — lo
108
119
  * garantiza el `tenantId`, que es lo que resolvió el contexto del tenant.
109
120
  *
121
+ * `integrated = true` deja solo los retailers con la bandera de integración prendida; cada
122
+ * retailer trae `integrationSystem` e `integrationActivatedAt` cuando la tiene. Timeout opt-in vía
123
+ * `options.timeoutMs` (ver `RETAIL_ORG_LIST_RETAILERS_TIMEOUT_MS`).
124
+ *
110
125
  * @throws `400 RETAILER_STATUS_FILTER_INVALID` si `status` no es del catálogo ·
111
126
  * `400 UNKNOWN_TENANT` sin `tenantId`.
112
127
  */
113
128
  listRetailers(
114
129
  tenantId: string,
115
130
  status?: RetailerRosterStatusFilter,
131
+ integrated?: boolean,
132
+ options?: RetailOrgRequestOptions,
116
133
  ): Promise<StandardResponse<RetailerValidationDto[]>>;
117
134
 
118
135
  /**
119
136
  * GET /private/retailers/{retailerId} — valida que el retailer exista y devuelve su shape mínimo
120
- * (id, name, type, status, parentId). `status` ya viene con la cascada aplicada (estado efectivo).
137
+ * (id, name, type, status, parentId) y la bandera de integración. `status` ya viene con la cascada
138
+ * aplicada (estado efectivo). Timeout opt-in vía `options.timeoutMs` (ver
139
+ * `RETAIL_ORG_GET_RETAILER_TIMEOUT_MS`).
121
140
  *
122
141
  * @throws si el retailer no existe (`404 RETAILER_NOT_FOUND`).
123
142
  */
124
143
  getRetailer(
125
144
  retailerId: string,
126
145
  tenantId: string,
146
+ options?: RetailOrgRequestOptions,
127
147
  ): Promise<StandardResponse<RetailerValidationDto>>;
128
148
 
129
149
  /**