@fiado/api-invoker 5.96.0 → 5.97.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 (41) hide show
  1. package/bin/index.d.ts +1 -0
  2. package/bin/index.js +1 -0
  3. package/bin/retailCatalog/api/RetailCatalogBusinessApi.d.ts +2 -1
  4. package/bin/retailCatalog/api/RetailCatalogBusinessApi.js +5 -0
  5. package/bin/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.d.ts +7 -2
  6. package/bin/retailCatalog/index.d.ts +2 -0
  7. package/bin/retailCatalog/index.js +2 -0
  8. package/bin/retailCatalog/queue/RetailInventoryInboundPublisher.d.ts +6 -0
  9. package/bin/retailCatalog/queue/RetailInventoryInboundPublisher.js +31 -0
  10. package/bin/retailCatalog/queue/interfaces/IRetailInventoryInboundPublisher.d.ts +8 -0
  11. package/bin/retailCatalog/queue/interfaces/IRetailInventoryInboundPublisher.js +1 -0
  12. package/bin/retailPromotions/api/RetailPromotionsBusinessApi.d.ts +11 -0
  13. package/bin/retailPromotions/api/RetailPromotionsBusinessApi.js +33 -0
  14. package/bin/retailPromotions/api/interfaces/IRetailPromotionsBusinessApi.d.ts +9 -0
  15. package/bin/retailPromotions/api/interfaces/IRetailPromotionsBusinessApi.js +1 -0
  16. package/bin/retailPromotions/index.d.ts +2 -0
  17. package/bin/retailPromotions/index.js +2 -0
  18. package/bin/retailWizard/api/RetailWizardBusinessApi.d.ts +7 -1
  19. package/bin/retailWizard/api/RetailWizardBusinessApi.js +23 -1
  20. package/bin/retailWizard/api/interfaces/IRetailWizardBusinessApi.d.ts +18 -1
  21. package/bin/retailWizard/index.d.ts +2 -0
  22. package/bin/retailWizard/index.js +2 -0
  23. package/bin/retailWizard/queue/RetailPromotionInboundPublisher.d.ts +6 -0
  24. package/bin/retailWizard/queue/RetailPromotionInboundPublisher.js +31 -0
  25. package/bin/retailWizard/queue/interfaces/IRetailPromotionInboundPublisher.d.ts +8 -0
  26. package/bin/retailWizard/queue/interfaces/IRetailPromotionInboundPublisher.js +1 -0
  27. package/package.json +2 -2
  28. package/src/index.ts +1 -0
  29. package/src/retailCatalog/api/RetailCatalogBusinessApi.ts +12 -1
  30. package/src/retailCatalog/api/interfaces/IRetailCatalogBusinessApi.ts +9 -1
  31. package/src/retailCatalog/index.ts +2 -0
  32. package/src/retailCatalog/queue/RetailInventoryInboundPublisher.ts +25 -0
  33. package/src/retailCatalog/queue/interfaces/IRetailInventoryInboundPublisher.ts +9 -0
  34. package/src/retailPromotions/api/RetailPromotionsBusinessApi.ts +23 -0
  35. package/src/retailPromotions/api/interfaces/IRetailPromotionsBusinessApi.ts +15 -0
  36. package/src/retailPromotions/index.ts +2 -0
  37. package/src/retailWizard/api/RetailWizardBusinessApi.ts +53 -2
  38. package/src/retailWizard/api/interfaces/IRetailWizardBusinessApi.ts +46 -1
  39. package/src/retailWizard/index.ts +2 -0
  40. package/src/retailWizard/queue/RetailPromotionInboundPublisher.ts +25 -0
  41. package/src/retailWizard/queue/interfaces/IRetailPromotionInboundPublisher.ts +9 -0
package/bin/index.d.ts CHANGED
@@ -88,6 +88,7 @@ export * from "./retailCatalog/index.js";
88
88
  export * from "./retailCards/index.js";
89
89
  export * from "./retailNotifications/index.js";
90
90
  export * from "./retailWizard/index.js";
91
+ export * from "./retailPromotions/index.js";
91
92
  export * from "./shortlink/index.js";
92
93
  export * from "./loanConfig/index.js";
93
94
  export * from "./loanOfferings/index.js";
package/bin/index.js CHANGED
@@ -88,6 +88,7 @@ export * from "./retailCatalog/index.js";
88
88
  export * from "./retailCards/index.js";
89
89
  export * from "./retailNotifications/index.js";
90
90
  export * from "./retailWizard/index.js";
91
+ export * from "./retailPromotions/index.js";
91
92
  export * from "./shortlink/index.js";
92
93
  export * from "./loanConfig/index.js";
93
94
  export * from "./loanOfferings/index.js";
@@ -1,6 +1,6 @@
1
1
  import type { IHttpRequest } from "@fiado/http-client";
2
2
  import { StandardResponse } from "@fiado/gateway-adapter";
3
- import type { GetStoreStockCatalogResponse, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, SyncInventoryResponse, ValidateProductResponse } from "@fiado/type-kit/bin/retailCatalog/index.js";
3
+ import type { GetStoreStockCatalogResponse, HoldStockRequest, HoldStockResponse, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, SyncInventoryResponse, ValidateProductResponse } from "@fiado/type-kit/bin/retailCatalog/index.js";
4
4
  import { IRetailCatalogBusinessApi, ProductsByRetailersResponse, ReleaseReservationBody, ReserveInventoryBody, ReserveInventoryResult, SellInventoryBody, StoreCatalogItem } from "./interfaces/IRetailCatalogBusinessApi.js";
5
5
  /**
6
6
  * Publisher HTTP del lambda `retail-catalog-business` (SureKeep Fase 1, pista Retail) para sus
@@ -32,6 +32,7 @@ export default class RetailCatalogBusinessApi implements IRetailCatalogBusinessA
32
32
  reserveStock(storeId: string, body: ReserveStockRequest, tenantId: string): Promise<StandardResponse<ReserveStockResponse>>;
33
33
  renewReservations(storeId: string, body: RenewReservationsRequest, tenantId: string): Promise<StandardResponse<RenewReservationsResponse>>;
34
34
  suggestPieces(storeId: string, query: SuggestPiecesQuery, tenantId: string): Promise<StandardResponse<SuggestPiecesResponse>>;
35
+ holdStock(storeId: string, body: HoldStockRequest, tenantId: string): Promise<StandardResponse<HoldStockResponse>>;
35
36
  sellStock(storeId: string, body: SellStockRequest, tenantId: string): Promise<StandardResponse<SellStockResponse>>;
36
37
  releaseStock(storeId: string, body: ReleaseStockRequest, tenantId: string): Promise<StandardResponse<ReleaseStockResponse>>;
37
38
  returnStock(storeId: string, body: ReturnStockRequest, tenantId: string): Promise<StandardResponse<ReturnStockResponse>>;
@@ -83,8 +83,13 @@ let RetailCatalogBusinessApi = class RetailCatalogBusinessApi {
83
83
  }
84
84
  async suggestPieces(storeId, query, tenantId) {
85
85
  const extra = { sku: query.sku, prefix: query.prefix };
86
+ if (query.sessionId)
87
+ extra.sessionId = query.sessionId;
86
88
  return await this.httpRequest.get(this.storeUrl(storeId, "pieces", tenantId, extra));
87
89
  }
90
+ async holdStock(storeId, body, tenantId) {
91
+ return await this.httpRequest.put(this.storeUrl(storeId, "holds", tenantId), body);
92
+ }
88
93
  async sellStock(storeId, body, tenantId) {
89
94
  return await this.httpRequest.put(this.storeUrl(storeId, "sales", tenantId), body);
90
95
  }
@@ -1,5 +1,5 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
- import type { GetStoreStockCatalogResponse, MdmLockModeEnum, MdmProviderEnum, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, SyncInventoryResponse, ValidateProductResponse } from "@fiado/type-kit/bin/retailCatalog/index.js";
2
+ import type { GetStoreStockCatalogResponse, HoldStockRequest, HoldStockResponse, MdmLockModeEnum, MdmProviderEnum, ReleaseStockRequest, ReleaseStockResponse, RenewReservationsRequest, RenewReservationsResponse, ReserveStockRequest, ReserveStockResponse, ReturnStockRequest, ReturnStockResponse, SellStockRequest, SellStockResponse, SuggestPiecesQuery, SuggestPiecesResponse, SyncInventoryRequest, SyncInventoryResponse, ValidateProductResponse } from "@fiado/type-kit/bin/retailCatalog/index.js";
3
3
  /**
4
4
  * Contrato del publisher HTTP del lambda `retail-catalog-business` (SureKeep Fase 1, pista Retail)
5
5
  * para sus endpoints privados del ciclo de venta del IMEI, consumidos por el wizard F2.
@@ -156,8 +156,13 @@ export interface IRetailCatalogBusinessApi {
156
156
  reserveStock(storeId: string, body: ReserveStockRequest, tenantId: string): Promise<StandardResponse<ReserveStockResponse>>;
157
157
  /** PUT `/private/stores/{storeId}/reservations/renew` — extiende las reservas de las líneas. */
158
158
  renewReservations(storeId: string, body: RenewReservationsRequest, tenantId: string): Promise<StandardResponse<RenewReservationsResponse>>;
159
- /** GET `/private/stores/{storeId}/pieces` — piezas disponibles del SKU que empiezan con `prefix`. */
159
+ /**
160
+ * GET `/private/stores/{storeId}/pieces` — piezas disponibles del SKU que empiezan con `prefix`;
161
+ * con `sessionId` también trae las HELD de esa sesión.
162
+ */
160
163
  suggestPieces(storeId: string, query: SuggestPiecesQuery, tenantId: string): Promise<StandardResponse<SuggestPiecesResponse>>;
164
+ /** PUT `/private/stores/{storeId}/holds` — fija como HELD de la sesión las piezas de una línea (idempotente). */
165
+ holdStock(storeId: string, body: HoldStockRequest, tenantId: string): Promise<StandardResponse<HoldStockResponse>>;
161
166
  /** PUT `/private/stores/{storeId}/sales` — vende las líneas con sus identificadores en una transacción. */
162
167
  sellStock(storeId: string, body: SellStockRequest, tenantId: string): Promise<StandardResponse<SellStockResponse>>;
163
168
  /** PUT `/private/stores/{storeId}/reservations/release` — libera las reservas de las líneas. */
@@ -1,2 +1,4 @@
1
1
  export * from "./api/interfaces/IRetailCatalogBusinessApi.js";
2
2
  export { default as RetailCatalogBusinessApi } from "./api/RetailCatalogBusinessApi.js";
3
+ export * from "./queue/interfaces/IRetailInventoryInboundPublisher.js";
4
+ export * from "./queue/RetailInventoryInboundPublisher.js";
@@ -1,2 +1,4 @@
1
1
  export * from "./api/interfaces/IRetailCatalogBusinessApi.js";
2
2
  export { default as RetailCatalogBusinessApi } from "./api/RetailCatalogBusinessApi.js";
3
+ export * from "./queue/interfaces/IRetailInventoryInboundPublisher.js";
4
+ export * from "./queue/RetailInventoryInboundPublisher.js";
@@ -0,0 +1,6 @@
1
+ import type { InventoryInboundMessage } from "@fiado/type-kit/bin/retailCatalog/index.js";
2
+ import { IRetailInventoryInboundPublisher } from "./interfaces/IRetailInventoryInboundPublisher.js";
3
+ export declare class RetailInventoryInboundPublisher implements IRetailInventoryInboundPublisher {
4
+ private readonly RETAIL_INVENTORY_INBOUND_QUEUE_URL;
5
+ publish(message: InventoryInboundMessage): Promise<void>;
6
+ }
@@ -0,0 +1,31 @@
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
+ import { SendMessageCommand, SQSClient } from "@aws-sdk/client-sqs";
8
+ import { injectable } from "inversify";
9
+ let RetailInventoryInboundPublisher = class RetailInventoryInboundPublisher {
10
+ RETAIL_INVENTORY_INBOUND_QUEUE_URL = process.env.RETAIL_INVENTORY_INBOUND_QUEUE_URL;
11
+ async publish(message) {
12
+ try {
13
+ const client = new SQSClient();
14
+ // Cola estándar: sin MessageGroupId; el consumidor deduplica por sesión y venta.
15
+ const sendMessageRequest = {
16
+ QueueUrl: this.RETAIL_INVENTORY_INBOUND_QUEUE_URL,
17
+ MessageBody: JSON.stringify(message),
18
+ };
19
+ const command = new SendMessageCommand(sendMessageRequest);
20
+ await client.send(command);
21
+ }
22
+ catch (error) {
23
+ const errorMessage = error instanceof Error ? error.message : String(error);
24
+ throw new Error(`Error publishing message to RetailInventoryInboundQueue: ${errorMessage}`);
25
+ }
26
+ }
27
+ };
28
+ RetailInventoryInboundPublisher = __decorate([
29
+ injectable()
30
+ ], RetailInventoryInboundPublisher);
31
+ export { RetailInventoryInboundPublisher };
@@ -0,0 +1,8 @@
1
+ import type { InventoryInboundMessage } from "@fiado/type-kit/bin/retailCatalog/index.js";
2
+ /**
3
+ * Publisher hacia `RetailInventoryInboundQueue` (SALE_APPLIED | RETURN), que consume `retail-catalog-business`.
4
+ * Env var requerida en el productor: `RETAIL_INVENTORY_INBOUND_QUEUE_URL`.
5
+ */
6
+ export interface IRetailInventoryInboundPublisher {
7
+ publish(message: InventoryInboundMessage): Promise<void>;
8
+ }
@@ -0,0 +1,11 @@
1
+ import type { IHttpRequest } from "@fiado/http-client";
2
+ import { StandardResponse } from "@fiado/gateway-adapter";
3
+ import type { PrivateReleaseSalePromotionResponse } from "@fiado/type-kit/bin/retailPromotions/index.js";
4
+ import { IRetailPromotionsBusinessApi } from "./interfaces/IRetailPromotionsBusinessApi.js";
5
+ /** Publisher HTTP de los privados de `retail-promotions-business`. Contrato -> `IRetailPromotionsBusinessApi`. */
6
+ export default class RetailPromotionsBusinessApi implements IRetailPromotionsBusinessApi {
7
+ private httpRequest;
8
+ private readonly baseUrl;
9
+ constructor(httpRequest: IHttpRequest);
10
+ releaseSalePromotion(tenantId: string, sessionId: string): Promise<StandardResponse<PrivateReleaseSalePromotionResponse>>;
11
+ }
@@ -0,0 +1,33 @@
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
+ /** Publisher HTTP de los privados de `retail-promotions-business`. Contrato -> `IRetailPromotionsBusinessApi`. */
15
+ let RetailPromotionsBusinessApi = class RetailPromotionsBusinessApi {
16
+ httpRequest;
17
+ // El buildspec publica la URL en SSM con "/" final; se normaliza para no armar "//private".
18
+ baseUrl = (process.env.RETAIL_PROMOTIONS_BUSINESS_URL || "").replace(/\/+$/, "");
19
+ constructor(httpRequest) {
20
+ this.httpRequest = httpRequest;
21
+ }
22
+ async releaseSalePromotion(tenantId, sessionId) {
23
+ const query = new URLSearchParams({ tenantId });
24
+ const url = `${this.baseUrl}/private/sessions/${encodeURIComponent(sessionId)}/sale-promotion?${query.toString()}`;
25
+ return await this.httpRequest.delete(url);
26
+ }
27
+ };
28
+ RetailPromotionsBusinessApi = __decorate([
29
+ injectable(),
30
+ __param(0, inject("IHttpRequest")),
31
+ __metadata("design:paramtypes", [Object])
32
+ ], RetailPromotionsBusinessApi);
33
+ export default RetailPromotionsBusinessApi;
@@ -0,0 +1,9 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import type { PrivateReleaseSalePromotionResponse } from "@fiado/type-kit/bin/retailPromotions/index.js";
3
+ export interface IRetailPromotionsBusinessApi {
4
+ /**
5
+ * `DELETE /private/sessions/{sessionId}/sale-promotion`: suelta el apartado de la promo de venta.
6
+ * Lo llama el wizard al cancelar. Es idempotente: `released: false` si no había apartado.
7
+ */
8
+ releaseSalePromotion(tenantId: string, sessionId: string): Promise<StandardResponse<PrivateReleaseSalePromotionResponse>>;
9
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/IRetailPromotionsBusinessApi.js";
2
+ export { default as RetailPromotionsBusinessApi } from "./api/RetailPromotionsBusinessApi.js";
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/IRetailPromotionsBusinessApi.js";
2
+ export { default as RetailPromotionsBusinessApi } from "./api/RetailPromotionsBusinessApi.js";
@@ -1,6 +1,6 @@
1
1
  import type { IHttpRequest } from "@fiado/http-client";
2
2
  import { StandardResponse } from "@fiado/gateway-adapter";
3
- import { WizardSessionLookupResponse } from "@fiado/type-kit/bin/retailWizard/index.js";
3
+ import type { ApplyLinePromotionRequest, ApplySalePromotionRequest, PrivateWizardSessionResponse, SetAnchorGiftsRequest, SetAnchorGiftsResponse, WizardSessionLookupResponse } from "@fiado/type-kit/bin/retailWizard/index.js";
4
4
  import { IRetailWizardBusinessApi } from "./interfaces/IRetailWizardBusinessApi.js";
5
5
  /**
6
6
  * Publisher HTTP del lambda `retail-wizard-business` (componente 05 SureKeep Fase 2) para sus
@@ -20,4 +20,10 @@ export default class RetailWizardBusinessApi implements IRetailWizardBusinessApi
20
20
  * estados, el techo de 100 y lo que NO devuelve) -> `IRetailWizardBusinessApi`.
21
21
  */
22
22
  getWizardSessionsByIds(wizardSessionIds: string[], tenantId: string): Promise<StandardResponse<WizardSessionLookupResponse>>;
23
+ applyLinePromotion(sessionId: string, lineId: string, body: ApplyLinePromotionRequest, tenantId: string): Promise<void>;
24
+ setAnchorGifts(sessionId: string, anchorLineId: string, body: SetAnchorGiftsRequest, tenantId: string): Promise<StandardResponse<SetAnchorGiftsResponse>>;
25
+ applySalePromotion(sessionId: string, body: ApplySalePromotionRequest, tenantId: string): Promise<void>;
26
+ getPrivateWizardSession(sessionId: string, tenantId: string): Promise<StandardResponse<PrivateWizardSessionResponse>>;
27
+ /** URL de `/private/wizard/sessions/{id}[/subPath]` con `tenantId` en query. */
28
+ private sessionUrl;
23
29
  }
@@ -22,7 +22,8 @@ import { inject, injectable } from "inversify";
22
22
  */
23
23
  let RetailWizardBusinessApi = class RetailWizardBusinessApi {
24
24
  httpRequest;
25
- baseUrl = process.env.RETAIL_WIZARD_BUSINESS_URL || "";
25
+ // El buildspec publica la URL en SSM con "/" final; se normaliza para no armar "//private".
26
+ baseUrl = (process.env.RETAIL_WIZARD_BUSINESS_URL || "").replace(/\/+$/, "");
26
27
  constructor(httpRequest) {
27
28
  this.httpRequest = httpRequest;
28
29
  }
@@ -36,6 +37,27 @@ let RetailWizardBusinessApi = class RetailWizardBusinessApi {
36
37
  const query = new URLSearchParams({ ids: wizardSessionIds.join(","), tenantId });
37
38
  return await this.httpRequest.get(`${this.baseUrl}/private/wizard-sessions/batch?${query.toString()}`);
38
39
  }
40
+ async applyLinePromotion(sessionId, lineId, body, tenantId) {
41
+ // El 204 no trae cuerpo (http-client devuelve ""); los errores se propagan tal cual.
42
+ const path = `lines/${encodeURIComponent(lineId)}/promotion`;
43
+ await this.httpRequest.put(this.sessionUrl(sessionId, tenantId, path), body);
44
+ }
45
+ async setAnchorGifts(sessionId, anchorLineId, body, tenantId) {
46
+ const path = `lines/${encodeURIComponent(anchorLineId)}/gifts`;
47
+ return await this.httpRequest.put(this.sessionUrl(sessionId, tenantId, path), body);
48
+ }
49
+ async applySalePromotion(sessionId, body, tenantId) {
50
+ await this.httpRequest.put(this.sessionUrl(sessionId, tenantId, "sale-promotion"), body);
51
+ }
52
+ async getPrivateWizardSession(sessionId, tenantId) {
53
+ return await this.httpRequest.get(this.sessionUrl(sessionId, tenantId));
54
+ }
55
+ /** URL de `/private/wizard/sessions/{id}[/subPath]` con `tenantId` en query. */
56
+ sessionUrl(sessionId, tenantId, subPath) {
57
+ const base = `${this.baseUrl}/private/wizard/sessions/${encodeURIComponent(sessionId)}`;
58
+ const query = new URLSearchParams({ tenantId });
59
+ return `${subPath ? `${base}/${subPath}` : base}?${query.toString()}`;
60
+ }
39
61
  };
40
62
  RetailWizardBusinessApi = __decorate([
41
63
  injectable(),
@@ -1,5 +1,5 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
- import { WizardSessionLookupResponse } from "@fiado/type-kit/bin/retailWizard/index.js";
2
+ import type { ApplyLinePromotionRequest, ApplySalePromotionRequest, PrivateWizardSessionResponse, SetAnchorGiftsRequest, SetAnchorGiftsResponse, WizardSessionLookupResponse } from "@fiado/type-kit/bin/retailWizard/index.js";
3
3
  /**
4
4
  * Contrato del publisher HTTP del lambda `retail-wizard-business` (componente 05 SureKeep Fase 2)
5
5
  * para sus endpoints privados (service-to-service, VPC-only).
@@ -55,4 +55,21 @@ export interface IRetailWizardBusinessApi {
55
55
  * `400 UNKNOWN_TENANT` sin `tenantId`.
56
56
  */
57
57
  getWizardSessionsByIds(wizardSessionIds: string[], tenantId: string): Promise<StandardResponse<WizardSessionLookupResponse>>;
58
+ /**
59
+ * `PUT /private/wizard/sessions/{id}/lines/{lineId}/promotion` (M2M de Promociones). Reemplaza la
60
+ * promo de la línea por valor. Responde 204 sin body.
61
+ */
62
+ applyLinePromotion(sessionId: string, lineId: string, body: ApplyLinePromotionRequest, tenantId: string): Promise<void>;
63
+ /**
64
+ * `PUT /private/wizard/sessions/{id}/lines/{anchorLineId}/gifts` (M2M de Promociones). Deja
65
+ * exactamente esos regalos en el ancla; `items: []` suelta todos.
66
+ */
67
+ setAnchorGifts(sessionId: string, anchorLineId: string, body: SetAnchorGiftsRequest, tenantId: string): Promise<StandardResponse<SetAnchorGiftsResponse>>;
68
+ /**
69
+ * `PUT /private/wizard/sessions/{id}/sale-promotion` (M2M de Promociones). Ambos campos en `null`
70
+ * es «Ninguna». Responde 204 sin body.
71
+ */
72
+ applySalePromotion(sessionId: string, body: ApplySalePromotionRequest, tenantId: string): Promise<void>;
73
+ /** `GET /private/wizard/sessions/{id}`: la sesión como la lee Promociones (líneas, ancla, promo de venta). */
74
+ getPrivateWizardSession(sessionId: string, tenantId: string): Promise<StandardResponse<PrivateWizardSessionResponse>>;
58
75
  }
@@ -1,2 +1,4 @@
1
1
  export * from "./api/interfaces/IRetailWizardBusinessApi.js";
2
2
  export { default as RetailWizardBusinessApi } from "./api/RetailWizardBusinessApi.js";
3
+ export * from "./queue/interfaces/IRetailPromotionInboundPublisher.js";
4
+ export * from "./queue/RetailPromotionInboundPublisher.js";
@@ -1,2 +1,4 @@
1
1
  export * from "./api/interfaces/IRetailWizardBusinessApi.js";
2
2
  export { default as RetailWizardBusinessApi } from "./api/RetailWizardBusinessApi.js";
3
+ export * from "./queue/interfaces/IRetailPromotionInboundPublisher.js";
4
+ export * from "./queue/RetailPromotionInboundPublisher.js";
@@ -0,0 +1,6 @@
1
+ import type { RetailPromotionInboundMessage } from "@fiado/type-kit/bin/retailWizard/index.js";
2
+ import { IRetailPromotionInboundPublisher } from "./interfaces/IRetailPromotionInboundPublisher.js";
3
+ export declare class RetailPromotionInboundPublisher implements IRetailPromotionInboundPublisher {
4
+ private readonly RETAIL_PROMOTION_INBOUND_QUEUE_URL;
5
+ publish(message: RetailPromotionInboundMessage): Promise<void>;
6
+ }
@@ -0,0 +1,31 @@
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
+ import { SendMessageCommand, SQSClient } from "@aws-sdk/client-sqs";
8
+ import { injectable } from "inversify";
9
+ let RetailPromotionInboundPublisher = class RetailPromotionInboundPublisher {
10
+ RETAIL_PROMOTION_INBOUND_QUEUE_URL = process.env.RETAIL_PROMOTION_INBOUND_QUEUE_URL;
11
+ async publish(message) {
12
+ try {
13
+ const client = new SQSClient();
14
+ // Cola estándar: sin MessageGroupId; el consumidor deduplica por venta.
15
+ const sendMessageRequest = {
16
+ QueueUrl: this.RETAIL_PROMOTION_INBOUND_QUEUE_URL,
17
+ MessageBody: JSON.stringify(message),
18
+ };
19
+ const command = new SendMessageCommand(sendMessageRequest);
20
+ await client.send(command);
21
+ }
22
+ catch (error) {
23
+ const errorMessage = error instanceof Error ? error.message : String(error);
24
+ throw new Error(`Error publishing message to RetailPromotionInboundQueue: ${errorMessage}`);
25
+ }
26
+ }
27
+ };
28
+ RetailPromotionInboundPublisher = __decorate([
29
+ injectable()
30
+ ], RetailPromotionInboundPublisher);
31
+ export { RetailPromotionInboundPublisher };
@@ -0,0 +1,8 @@
1
+ import type { RetailPromotionInboundMessage } from "@fiado/type-kit/bin/retailWizard/index.js";
2
+ /**
3
+ * Publisher hacia `RetailPromotionInboundQueue` (SALE_CONFIRMED | SALE_CANCELLED), que consume `retail-promotions`.
4
+ * Env var requerida en el productor: `RETAIL_PROMOTION_INBOUND_QUEUE_URL`.
5
+ */
6
+ export interface IRetailPromotionInboundPublisher {
7
+ publish(message: RetailPromotionInboundMessage): Promise<void>;
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/api-invoker",
3
- "version": "5.96.0",
3
+ "version": "5.97.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.468.0",
37
+ "@fiado/type-kit": "3.473.0",
38
38
  "dotenv": "^16.4.7"
39
39
  },
40
40
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -88,6 +88,7 @@ export * from "./retailCatalog/index.js";
88
88
  export * from "./retailCards/index.js";
89
89
  export * from "./retailNotifications/index.js";
90
90
  export * from "./retailWizard/index.js";
91
+ export * from "./retailPromotions/index.js";
91
92
  export * from "./shortlink/index.js";
92
93
  export * from "./loanConfig/index.js";
93
94
  export * from "./loanOfferings/index.js";
@@ -3,6 +3,8 @@ import type { IHttpRequest } from "@fiado/http-client";
3
3
  import { StandardResponse } from "@fiado/gateway-adapter";
4
4
  import type {
5
5
  GetStoreStockCatalogResponse,
6
+ HoldStockRequest,
7
+ HoldStockResponse,
6
8
  ReleaseStockRequest,
7
9
  ReleaseStockResponse,
8
10
  RenewReservationsRequest,
@@ -142,10 +144,19 @@ export default class RetailCatalogBusinessApi implements IRetailCatalogBusinessA
142
144
  query: SuggestPiecesQuery,
143
145
  tenantId: string,
144
146
  ): Promise<StandardResponse<SuggestPiecesResponse>> {
145
- const extra = { sku: query.sku, prefix: query.prefix };
147
+ const extra: Record<string, string> = { sku: query.sku, prefix: query.prefix };
148
+ if (query.sessionId) extra.sessionId = query.sessionId;
146
149
  return await this.httpRequest.get(this.storeUrl(storeId, "pieces", tenantId, extra));
147
150
  }
148
151
 
152
+ async holdStock(
153
+ storeId: string,
154
+ body: HoldStockRequest,
155
+ tenantId: string,
156
+ ): Promise<StandardResponse<HoldStockResponse>> {
157
+ return await this.httpRequest.put(this.storeUrl(storeId, "holds", tenantId), body);
158
+ }
159
+
149
160
  async sellStock(
150
161
  storeId: string,
151
162
  body: SellStockRequest,
@@ -1,6 +1,8 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
2
  import type {
3
3
  GetStoreStockCatalogResponse,
4
+ HoldStockRequest,
5
+ HoldStockResponse,
4
6
  MdmLockModeEnum,
5
7
  MdmProviderEnum,
6
8
  ReleaseStockRequest,
@@ -218,13 +220,19 @@ export interface IRetailCatalogBusinessApi {
218
220
  tenantId: string,
219
221
  ): Promise<StandardResponse<RenewReservationsResponse>>;
220
222
 
221
- /** GET `/private/stores/{storeId}/pieces` — piezas disponibles del SKU que empiezan con `prefix`. */
223
+ /**
224
+ * GET `/private/stores/{storeId}/pieces` — piezas disponibles del SKU que empiezan con `prefix`;
225
+ * con `sessionId` también trae las HELD de esa sesión.
226
+ */
222
227
  suggestPieces(
223
228
  storeId: string,
224
229
  query: SuggestPiecesQuery,
225
230
  tenantId: string,
226
231
  ): Promise<StandardResponse<SuggestPiecesResponse>>;
227
232
 
233
+ /** PUT `/private/stores/{storeId}/holds` — fija como HELD de la sesión las piezas de una línea (idempotente). */
234
+ holdStock(storeId: string, body: HoldStockRequest, tenantId: string): Promise<StandardResponse<HoldStockResponse>>;
235
+
228
236
  /** PUT `/private/stores/{storeId}/sales` — vende las líneas con sus identificadores en una transacción. */
229
237
  sellStock(storeId: string, body: SellStockRequest, tenantId: string): Promise<StandardResponse<SellStockResponse>>;
230
238
 
@@ -1,2 +1,4 @@
1
1
  export * from "./api/interfaces/IRetailCatalogBusinessApi.js";
2
2
  export { default as RetailCatalogBusinessApi } from "./api/RetailCatalogBusinessApi.js";
3
+ export * from "./queue/interfaces/IRetailInventoryInboundPublisher.js";
4
+ export * from "./queue/RetailInventoryInboundPublisher.js";
@@ -0,0 +1,25 @@
1
+ import { SendMessageCommand, SendMessageRequest, SQSClient } from "@aws-sdk/client-sqs";
2
+ import { injectable } from "inversify";
3
+ import type { InventoryInboundMessage } from "@fiado/type-kit/bin/retailCatalog/index.js";
4
+ import { IRetailInventoryInboundPublisher } from "./interfaces/IRetailInventoryInboundPublisher.js";
5
+
6
+ @injectable()
7
+ export class RetailInventoryInboundPublisher implements IRetailInventoryInboundPublisher {
8
+ private readonly RETAIL_INVENTORY_INBOUND_QUEUE_URL = process.env.RETAIL_INVENTORY_INBOUND_QUEUE_URL;
9
+
10
+ async publish(message: InventoryInboundMessage): Promise<void> {
11
+ try {
12
+ const client: SQSClient = new SQSClient();
13
+ // Cola estándar: sin MessageGroupId; el consumidor deduplica por sesión y venta.
14
+ const sendMessageRequest: SendMessageRequest = {
15
+ QueueUrl: this.RETAIL_INVENTORY_INBOUND_QUEUE_URL,
16
+ MessageBody: JSON.stringify(message),
17
+ };
18
+ const command: SendMessageCommand = new SendMessageCommand(sendMessageRequest);
19
+ await client.send(command);
20
+ } catch (error) {
21
+ const errorMessage = error instanceof Error ? error.message : String(error);
22
+ throw new Error(`Error publishing message to RetailInventoryInboundQueue: ${errorMessage}`);
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,9 @@
1
+ import type { InventoryInboundMessage } from "@fiado/type-kit/bin/retailCatalog/index.js";
2
+
3
+ /**
4
+ * Publisher hacia `RetailInventoryInboundQueue` (SALE_APPLIED | RETURN), que consume `retail-catalog-business`.
5
+ * Env var requerida en el productor: `RETAIL_INVENTORY_INBOUND_QUEUE_URL`.
6
+ */
7
+ export interface IRetailInventoryInboundPublisher {
8
+ publish(message: InventoryInboundMessage): Promise<void>;
9
+ }
@@ -0,0 +1,23 @@
1
+ import { inject, injectable } from "inversify";
2
+ import type { IHttpRequest } from "@fiado/http-client";
3
+ import { StandardResponse } from "@fiado/gateway-adapter";
4
+ import type { PrivateReleaseSalePromotionResponse } from "@fiado/type-kit/bin/retailPromotions/index.js";
5
+ import { IRetailPromotionsBusinessApi } from "./interfaces/IRetailPromotionsBusinessApi.js";
6
+
7
+ /** Publisher HTTP de los privados de `retail-promotions-business`. Contrato -> `IRetailPromotionsBusinessApi`. */
8
+ @injectable()
9
+ export default class RetailPromotionsBusinessApi implements IRetailPromotionsBusinessApi {
10
+ // El buildspec publica la URL en SSM con "/" final; se normaliza para no armar "//private".
11
+ private readonly baseUrl = (process.env.RETAIL_PROMOTIONS_BUSINESS_URL || "").replace(/\/+$/, "");
12
+
13
+ constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
14
+
15
+ async releaseSalePromotion(
16
+ tenantId: string,
17
+ sessionId: string,
18
+ ): Promise<StandardResponse<PrivateReleaseSalePromotionResponse>> {
19
+ const query = new URLSearchParams({ tenantId });
20
+ const url = `${this.baseUrl}/private/sessions/${encodeURIComponent(sessionId)}/sale-promotion?${query.toString()}`;
21
+ return await this.httpRequest.delete(url);
22
+ }
23
+ }
@@ -0,0 +1,15 @@
1
+ import { StandardResponse } from "@fiado/gateway-adapter";
2
+ import type { PrivateReleaseSalePromotionResponse } from "@fiado/type-kit/bin/retailPromotions/index.js";
3
+
4
+ // Contrato de los privados de `retail-promotions-business`; el caller manda `tenantId` por query.
5
+ // El consumer necesita `RETAIL_PROMOTIONS_BUSINESS_URL` = `{{resolve:ssm:retail-promotions-business}}`.
6
+ export interface IRetailPromotionsBusinessApi {
7
+ /**
8
+ * `DELETE /private/sessions/{sessionId}/sale-promotion`: suelta el apartado de la promo de venta.
9
+ * Lo llama el wizard al cancelar. Es idempotente: `released: false` si no había apartado.
10
+ */
11
+ releaseSalePromotion(
12
+ tenantId: string,
13
+ sessionId: string,
14
+ ): Promise<StandardResponse<PrivateReleaseSalePromotionResponse>>;
15
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api/interfaces/IRetailPromotionsBusinessApi.js";
2
+ export { default as RetailPromotionsBusinessApi } from "./api/RetailPromotionsBusinessApi.js";
@@ -1,7 +1,14 @@
1
1
  import { inject, injectable } from "inversify";
2
2
  import type { IHttpRequest } from "@fiado/http-client";
3
3
  import { StandardResponse } from "@fiado/gateway-adapter";
4
- import { WizardSessionLookupResponse } from "@fiado/type-kit/bin/retailWizard/index.js";
4
+ import type {
5
+ ApplyLinePromotionRequest,
6
+ ApplySalePromotionRequest,
7
+ PrivateWizardSessionResponse,
8
+ SetAnchorGiftsRequest,
9
+ SetAnchorGiftsResponse,
10
+ WizardSessionLookupResponse,
11
+ } from "@fiado/type-kit/bin/retailWizard/index.js";
5
12
  import { IRetailWizardBusinessApi } from "./interfaces/IRetailWizardBusinessApi.js";
6
13
 
7
14
  /**
@@ -15,7 +22,8 @@ import { IRetailWizardBusinessApi } from "./interfaces/IRetailWizardBusinessApi.
15
22
  */
16
23
  @injectable()
17
24
  export default class RetailWizardBusinessApi implements IRetailWizardBusinessApi {
18
- private readonly baseUrl = process.env.RETAIL_WIZARD_BUSINESS_URL || "";
25
+ // El buildspec publica la URL en SSM con "/" final; se normaliza para no armar "//private".
26
+ private readonly baseUrl = (process.env.RETAIL_WIZARD_BUSINESS_URL || "").replace(/\/+$/, "");
19
27
 
20
28
  constructor(@inject("IHttpRequest") private httpRequest: IHttpRequest) {}
21
29
 
@@ -32,4 +40,47 @@ export default class RetailWizardBusinessApi implements IRetailWizardBusinessApi
32
40
  const query = new URLSearchParams({ ids: wizardSessionIds.join(","), tenantId });
33
41
  return await this.httpRequest.get(`${this.baseUrl}/private/wizard-sessions/batch?${query.toString()}`);
34
42
  }
43
+
44
+ async applyLinePromotion(
45
+ sessionId: string,
46
+ lineId: string,
47
+ body: ApplyLinePromotionRequest,
48
+ tenantId: string,
49
+ ): Promise<void> {
50
+ // El 204 no trae cuerpo (http-client devuelve ""); los errores se propagan tal cual.
51
+ const path = `lines/${encodeURIComponent(lineId)}/promotion`;
52
+ await this.httpRequest.put(this.sessionUrl(sessionId, tenantId, path), body);
53
+ }
54
+
55
+ async setAnchorGifts(
56
+ sessionId: string,
57
+ anchorLineId: string,
58
+ body: SetAnchorGiftsRequest,
59
+ tenantId: string,
60
+ ): Promise<StandardResponse<SetAnchorGiftsResponse>> {
61
+ const path = `lines/${encodeURIComponent(anchorLineId)}/gifts`;
62
+ return await this.httpRequest.put(this.sessionUrl(sessionId, tenantId, path), body);
63
+ }
64
+
65
+ async applySalePromotion(
66
+ sessionId: string,
67
+ body: ApplySalePromotionRequest,
68
+ tenantId: string,
69
+ ): Promise<void> {
70
+ await this.httpRequest.put(this.sessionUrl(sessionId, tenantId, "sale-promotion"), body);
71
+ }
72
+
73
+ async getPrivateWizardSession(
74
+ sessionId: string,
75
+ tenantId: string,
76
+ ): Promise<StandardResponse<PrivateWizardSessionResponse>> {
77
+ return await this.httpRequest.get(this.sessionUrl(sessionId, tenantId));
78
+ }
79
+
80
+ /** URL de `/private/wizard/sessions/{id}[/subPath]` con `tenantId` en query. */
81
+ private sessionUrl(sessionId: string, tenantId: string, subPath?: string): string {
82
+ const base = `${this.baseUrl}/private/wizard/sessions/${encodeURIComponent(sessionId)}`;
83
+ const query = new URLSearchParams({ tenantId });
84
+ return `${subPath ? `${base}/${subPath}` : base}?${query.toString()}`;
85
+ }
35
86
  }
@@ -1,5 +1,12 @@
1
1
  import { StandardResponse } from "@fiado/gateway-adapter";
2
- import { WizardSessionLookupResponse } from "@fiado/type-kit/bin/retailWizard/index.js";
2
+ import type {
3
+ ApplyLinePromotionRequest,
4
+ ApplySalePromotionRequest,
5
+ PrivateWizardSessionResponse,
6
+ SetAnchorGiftsRequest,
7
+ SetAnchorGiftsResponse,
8
+ WizardSessionLookupResponse,
9
+ } from "@fiado/type-kit/bin/retailWizard/index.js";
3
10
 
4
11
  /**
5
12
  * Contrato del publisher HTTP del lambda `retail-wizard-business` (componente 05 SureKeep Fase 2)
@@ -59,4 +66,42 @@ export interface IRetailWizardBusinessApi {
59
66
  wizardSessionIds: string[],
60
67
  tenantId: string,
61
68
  ): Promise<StandardResponse<WizardSessionLookupResponse>>;
69
+
70
+ /**
71
+ * `PUT /private/wizard/sessions/{id}/lines/{lineId}/promotion` (M2M de Promociones). Reemplaza la
72
+ * promo de la línea por valor. Responde 204 sin body.
73
+ */
74
+ applyLinePromotion(
75
+ sessionId: string,
76
+ lineId: string,
77
+ body: ApplyLinePromotionRequest,
78
+ tenantId: string,
79
+ ): Promise<void>;
80
+
81
+ /**
82
+ * `PUT /private/wizard/sessions/{id}/lines/{anchorLineId}/gifts` (M2M de Promociones). Deja
83
+ * exactamente esos regalos en el ancla; `items: []` suelta todos.
84
+ */
85
+ setAnchorGifts(
86
+ sessionId: string,
87
+ anchorLineId: string,
88
+ body: SetAnchorGiftsRequest,
89
+ tenantId: string,
90
+ ): Promise<StandardResponse<SetAnchorGiftsResponse>>;
91
+
92
+ /**
93
+ * `PUT /private/wizard/sessions/{id}/sale-promotion` (M2M de Promociones). Ambos campos en `null`
94
+ * es «Ninguna». Responde 204 sin body.
95
+ */
96
+ applySalePromotion(
97
+ sessionId: string,
98
+ body: ApplySalePromotionRequest,
99
+ tenantId: string,
100
+ ): Promise<void>;
101
+
102
+ /** `GET /private/wizard/sessions/{id}`: la sesión como la lee Promociones (líneas, ancla, promo de venta). */
103
+ getPrivateWizardSession(
104
+ sessionId: string,
105
+ tenantId: string,
106
+ ): Promise<StandardResponse<PrivateWizardSessionResponse>>;
62
107
  }
@@ -1,2 +1,4 @@
1
1
  export * from "./api/interfaces/IRetailWizardBusinessApi.js";
2
2
  export { default as RetailWizardBusinessApi } from "./api/RetailWizardBusinessApi.js";
3
+ export * from "./queue/interfaces/IRetailPromotionInboundPublisher.js";
4
+ export * from "./queue/RetailPromotionInboundPublisher.js";
@@ -0,0 +1,25 @@
1
+ import { SendMessageCommand, SendMessageRequest, SQSClient } from "@aws-sdk/client-sqs";
2
+ import { injectable } from "inversify";
3
+ import type { RetailPromotionInboundMessage } from "@fiado/type-kit/bin/retailWizard/index.js";
4
+ import { IRetailPromotionInboundPublisher } from "./interfaces/IRetailPromotionInboundPublisher.js";
5
+
6
+ @injectable()
7
+ export class RetailPromotionInboundPublisher implements IRetailPromotionInboundPublisher {
8
+ private readonly RETAIL_PROMOTION_INBOUND_QUEUE_URL = process.env.RETAIL_PROMOTION_INBOUND_QUEUE_URL;
9
+
10
+ async publish(message: RetailPromotionInboundMessage): Promise<void> {
11
+ try {
12
+ const client: SQSClient = new SQSClient();
13
+ // Cola estándar: sin MessageGroupId; el consumidor deduplica por venta.
14
+ const sendMessageRequest: SendMessageRequest = {
15
+ QueueUrl: this.RETAIL_PROMOTION_INBOUND_QUEUE_URL,
16
+ MessageBody: JSON.stringify(message),
17
+ };
18
+ const command: SendMessageCommand = new SendMessageCommand(sendMessageRequest);
19
+ await client.send(command);
20
+ } catch (error) {
21
+ const errorMessage = error instanceof Error ? error.message : String(error);
22
+ throw new Error(`Error publishing message to RetailPromotionInboundQueue: ${errorMessage}`);
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,9 @@
1
+ import type { RetailPromotionInboundMessage } from "@fiado/type-kit/bin/retailWizard/index.js";
2
+
3
+ /**
4
+ * Publisher hacia `RetailPromotionInboundQueue` (SALE_CONFIRMED | SALE_CANCELLED), que consume `retail-promotions`.
5
+ * Env var requerida en el productor: `RETAIL_PROMOTION_INBOUND_QUEUE_URL`.
6
+ */
7
+ export interface IRetailPromotionInboundPublisher {
8
+ publish(message: RetailPromotionInboundMessage): Promise<void>;
9
+ }