@fiado/type-kit 3.512.0 → 3.514.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 (64) hide show
  1. package/_test_/unit/retailPromotions/activeSalePromotionsBySkus.test.ts +58 -0
  2. package/_test_/unit/rewards/backoffice.test.ts +96 -0
  3. package/bin/retailCatalog/dtos/responses/GetInventorySkuResponse.d.ts +9 -0
  4. package/bin/retailCatalog/dtos/responses/InventoryLensResponse.d.ts +10 -0
  5. package/bin/retailCatalog/enums/CatalogSourceStatusEnum.d.ts +5 -0
  6. package/bin/retailCatalog/enums/CatalogSourceStatusEnum.js +9 -0
  7. package/bin/retailCatalog/index.d.ts +1 -0
  8. package/bin/retailCatalog/index.js +1 -0
  9. package/bin/retailPromotions/constants/activeSalePromotionsBySkus.d.ts +2 -0
  10. package/bin/retailPromotions/constants/activeSalePromotionsBySkus.js +5 -0
  11. package/bin/retailPromotions/dtos/requests/ActiveSalePromotionsBySkusRequest.d.ts +17 -0
  12. package/bin/retailPromotions/dtos/requests/ActiveSalePromotionsBySkusRequest.js +69 -0
  13. package/bin/retailPromotions/dtos/responses/ActiveSalePromotionsBySkusResponse.d.ts +26 -0
  14. package/bin/retailPromotions/dtos/responses/ActiveSalePromotionsBySkusResponse.js +2 -0
  15. package/bin/retailPromotions/enums/SkuSalePromotionLookupStatusEnum.d.ts +9 -0
  16. package/bin/retailPromotions/enums/SkuSalePromotionLookupStatusEnum.js +13 -0
  17. package/bin/retailPromotions/index.d.ts +4 -0
  18. package/bin/retailPromotions/index.js +4 -0
  19. package/bin/rewards/constants/BackofficeLimits.d.ts +6 -0
  20. package/bin/rewards/constants/BackofficeLimits.js +9 -0
  21. package/bin/rewards/dtos/backoffice/CatalogItemListResponse.d.ts +6 -0
  22. package/bin/rewards/dtos/backoffice/CatalogItemListResponse.js +6 -0
  23. package/bin/rewards/dtos/backoffice/CatalogItemRequest.d.ts +19 -0
  24. package/bin/rewards/dtos/backoffice/CatalogItemRequest.js +70 -0
  25. package/bin/rewards/dtos/backoffice/CatalogItemResponse.d.ts +23 -0
  26. package/bin/rewards/dtos/backoffice/CatalogItemResponse.js +6 -0
  27. package/bin/rewards/dtos/backoffice/PackageItemRequest.d.ts +4 -0
  28. package/bin/rewards/dtos/backoffice/PackageItemRequest.js +30 -0
  29. package/bin/rewards/dtos/backoffice/PackageListResponse.d.ts +6 -0
  30. package/bin/rewards/dtos/backoffice/PackageListResponse.js +6 -0
  31. package/bin/rewards/dtos/backoffice/PackageRequest.d.ts +9 -0
  32. package/bin/rewards/dtos/backoffice/PackageRequest.js +47 -0
  33. package/bin/rewards/dtos/backoffice/PackageResponse.d.ts +18 -0
  34. package/bin/rewards/dtos/backoffice/PackageResponse.js +9 -0
  35. package/bin/rewards/dtos/backoffice/RewardChargeToInput.d.ts +4 -0
  36. package/bin/rewards/dtos/backoffice/RewardChargeToInput.js +31 -0
  37. package/bin/rewards/dtos/backoffice/RewardCostInput.d.ts +5 -0
  38. package/bin/rewards/dtos/backoffice/RewardCostInput.js +29 -0
  39. package/bin/rewards/dtos/backoffice/RewardTypeResponse.d.ts +6 -0
  40. package/bin/rewards/dtos/backoffice/RewardTypeResponse.js +7 -0
  41. package/bin/rewards/index.d.ts +11 -0
  42. package/bin/rewards/index.js +13 -0
  43. package/package.json +1 -1
  44. package/src/retailCatalog/dtos/responses/GetInventorySkuResponse.ts +10 -0
  45. package/src/retailCatalog/dtos/responses/InventoryLensResponse.ts +12 -0
  46. package/src/retailCatalog/enums/CatalogSourceStatusEnum.ts +5 -0
  47. package/src/retailCatalog/index.ts +1 -0
  48. package/src/retailPromotions/constants/activeSalePromotionsBySkus.ts +2 -0
  49. package/src/retailPromotions/dtos/requests/ActiveSalePromotionsBySkusRequest.ts +50 -0
  50. package/src/retailPromotions/dtos/responses/ActiveSalePromotionsBySkusResponse.ts +29 -0
  51. package/src/retailPromotions/enums/SkuSalePromotionLookupStatusEnum.ts +9 -0
  52. package/src/retailPromotions/index.ts +4 -0
  53. package/src/rewards/constants/BackofficeLimits.ts +6 -0
  54. package/src/rewards/dtos/backoffice/CatalogItemListResponse.ts +7 -0
  55. package/src/rewards/dtos/backoffice/CatalogItemRequest.ts +52 -0
  56. package/src/rewards/dtos/backoffice/CatalogItemResponse.ts +22 -0
  57. package/src/rewards/dtos/backoffice/PackageItemRequest.ts +15 -0
  58. package/src/rewards/dtos/backoffice/PackageListResponse.ts +7 -0
  59. package/src/rewards/dtos/backoffice/PackageRequest.ts +31 -0
  60. package/src/rewards/dtos/backoffice/PackageResponse.ts +20 -0
  61. package/src/rewards/dtos/backoffice/RewardChargeToInput.ts +16 -0
  62. package/src/rewards/dtos/backoffice/RewardCostInput.ts +14 -0
  63. package/src/rewards/dtos/backoffice/RewardTypeResponse.ts +7 -0
  64. package/src/rewards/index.ts +15 -0
@@ -0,0 +1,58 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ ACTIVE_SALE_PROMOTIONS_MAX_SKUS,
6
+ ActiveSalePromotionsBySkusRequest,
7
+ SkuSalePromotionLookupStatusEnum,
8
+ } from '../../../src/retailPromotions/index';
9
+ import type { ActiveSalePromotionsBySkusResponse } from '../../../src/retailPromotions/index';
10
+ import { CatalogSourceStatusEnum } from '../../../src/retailCatalog/index';
11
+ import type { GetInventorySkuResponse, InventoryLensListItem, InventoryLensResponse } from '../../../src/retailCatalog/index';
12
+
13
+ const errorsOf = async (body: object) =>
14
+ (await validate(plainToInstance(ActiveSalePromotionsBySkusRequest, body, { excludeExtraneousValues: true }))).map((e) => e.property);
15
+
16
+ const valid = { tenantId: 'SUREKEEP', retailerId: 'ret-1', items: [{ sku: 'SKU-1', category: 'PHONE', tier: 'MID' }] };
17
+
18
+ describe('ActiveSalePromotionsBySkusRequest', () => {
19
+ it('acepta tenant, cadena, tienda opcional y SKUs con tipo y gama opcionales', async () => {
20
+ expect(await errorsOf(valid)).toEqual([]);
21
+ expect(await errorsOf({ ...valid, storeId: 'st-1', items: [{ sku: 'SKU-2' }] })).toEqual([]);
22
+ });
23
+
24
+ it('un SKU vacío no tumba el lote: se resuelve como INVALID_ID por entrada', async () => {
25
+ expect(await errorsOf({ ...valid, items: [{ sku: '' }] })).toEqual([]);
26
+ });
27
+
28
+ it.each([
29
+ ['sin tenantId', { ...valid, tenantId: undefined }, 'tenantId'],
30
+ ['sin retailerId', { ...valid, retailerId: '' }, 'retailerId'],
31
+ ['sin items', { ...valid, items: undefined }, 'items'],
32
+ ['tipo fuera del enum', { ...valid, items: [{ sku: 'A', category: 'CAR' }] }, 'items'],
33
+ ])('rechaza %s', async (_l, body, property) => {
34
+ expect(await errorsOf(body)).toContain(property);
35
+ });
36
+
37
+ it(`rechaza más de ${ACTIVE_SALE_PROMOTIONS_MAX_SKUS} SKUs`, async () => {
38
+ const items = Array.from({ length: ACTIVE_SALE_PROMOTIONS_MAX_SKUS + 1 }, (_v, i) => ({ sku: `S${i}` }));
39
+ expect(await errorsOf({ ...valid, items })).toContain('items');
40
+ });
41
+ });
42
+
43
+ describe('contratos de promos vigentes por SKU', () => {
44
+ it('una entrada por SKU con su estado y sus promos', () => {
45
+ const response: ActiveSalePromotionsBySkusResponse = {
46
+ items: [{ sku: 'SKU-1', status: SkuSalePromotionLookupStatusEnum.OK, promotions: [] }],
47
+ };
48
+ expect(Object.values(SkuSalePromotionLookupStatusEnum)).toEqual(['OK', 'UNAVAILABLE', 'INVALID_ID']);
49
+ expect(response.items[0]?.status).toBe('OK');
50
+ });
51
+
52
+ it('la ficha y el lente del catálogo llevan las promos y el estado de su fuente', () => {
53
+ const sku: Pick<GetInventorySkuResponse, 'promotions' | 'sources'> = { promotions: null, sources: { promotions: CatalogSourceStatusEnum.UNAVAILABLE } };
54
+ const row: Pick<InventoryLensListItem, 'hasPromotion' | 'promotionNames'> = { hasPromotion: true, promotionNames: ['Hot Sale'] };
55
+ const lens: Pick<InventoryLensResponse, 'sources'> = { sources: { promotions: CatalogSourceStatusEnum.OK } };
56
+ expect([sku.sources?.promotions, row.promotionNames, lens.sources?.promotions]).toEqual(['UNAVAILABLE', ['Hot Sale'], 'OK']);
57
+ });
58
+ });
@@ -0,0 +1,96 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { JsonValue } from '../../../src/common';
5
+ import { CatalogItemRequest, PackageRequest, REWARD_ITEM_KEY_MAX_LENGTH, REWARD_PACKAGE_MAX_ITEMS } from '../../../src/rewards';
6
+
7
+ const catalog = {
8
+ id: 'example-reward-a',
9
+ name: 'Recompensa A',
10
+ description: 'Recompensa de ejemplo',
11
+ type: 'ExampleType',
12
+ config: { amount: 50, nested: { list: [1, 2] } },
13
+ cost: { amount: 50, currency: 'MXN' },
14
+ chargeTo: { partnerId: 'ALIADO-001', partnerName: 'Aliado de ejemplo' },
15
+ status: 'ACTIVE',
16
+ };
17
+ const pkg = { id: 'paquete-1', name: 'Paquete 1', status: 'ACTIVE', items: [{ itemKey: 'itemA', catalogItemId: 'example-reward-a' }] };
18
+
19
+ const asCatalog = (o: Record<string, JsonValue> = {}): CatalogItemRequest =>
20
+ plainToInstance(CatalogItemRequest, { ...catalog, ...o }, { excludeExtraneousValues: true });
21
+ const asPackage = (o: Record<string, JsonValue> = {}): PackageRequest =>
22
+ plainToInstance(PackageRequest, { ...pkg, ...o }, { excludeExtraneousValues: true });
23
+ const props = async (dto: object): Promise<string[]> => (await validate(dto)).map((e) => e.property);
24
+
25
+ describe('CatalogItemRequest', () => {
26
+ it('valida una recompensa correcta y conserva el config anidado completo', async () => {
27
+ const dto = asCatalog();
28
+ expect(await validate(dto)).toHaveLength(0);
29
+ expect(dto.config).toEqual({ amount: 50, nested: { list: [1, 2] } });
30
+ });
31
+
32
+ it.each<[string, Record<string, JsonValue>, string]>([
33
+ ['id con espacios', { id: 'con espacio' }, 'id'],
34
+ ['id vacío', { id: '' }, 'id'],
35
+ ['name vacío', { name: '' }, 'name'],
36
+ ['name > 120', { name: 'x'.repeat(121) }, 'name'],
37
+ ['type vacío', { type: '' }, 'type'],
38
+ ['config que no es objeto', { config: 'texto' }, 'config'],
39
+ ['status desconocido', { status: 'BORRADO' }, 'status'],
40
+ ['costo negativo', { cost: { amount: -1, currency: 'MXN' } }, 'cost'],
41
+ ['costo con 3 decimales', { cost: { amount: 1.234, currency: 'MXN' } }, 'cost'],
42
+ ['moneda desconocida', { cost: { amount: 5, currency: 'XXX' } }, 'cost'],
43
+ ['chargeTo sin partnerId', { chargeTo: { partnerId: '', partnerName: 'A' } }, 'chargeTo'],
44
+ ])('rechaza %s', async (_nombre, override, property) => {
45
+ expect(await props(asCatalog(override))).toContain(property);
46
+ });
47
+
48
+ it('acepta costo 0 (recompensa gratuita para el aliado)', async () => {
49
+ expect(await validate(asCatalog({ cost: { amount: 0, currency: 'MXN' } }))).toHaveLength(0);
50
+ });
51
+
52
+ it('descarta campos extra (version, dependencies, updatedBy no se aceptan del cliente)', () => {
53
+ const dto = asCatalog({ version: 99, dependencies: [], updatedBy: 'hacker' });
54
+ expect('version' in dto).toBe(false);
55
+ expect('dependencies' in dto).toBe(false);
56
+ expect('updatedBy' in dto).toBe(false);
57
+ });
58
+ });
59
+
60
+ describe('PackageRequest', () => {
61
+ it('valida un paquete correcto', async () => {
62
+ expect(await validate(asPackage())).toHaveLength(0);
63
+ });
64
+
65
+ it('exige al menos un ítem', async () => {
66
+ expect(await props(asPackage({ items: [] }))).toContain('items');
67
+ });
68
+
69
+ it(`itemKey de ${REWARD_ITEM_KEY_MAX_LENGTH} caracteres entra; de ${REWARD_ITEM_KEY_MAX_LENGTH + 1} no (RW-{grantId}-{itemKey} ≤ 64)`, async () => {
70
+ const ok = asPackage({ items: [{ itemKey: 'k'.repeat(REWARD_ITEM_KEY_MAX_LENGTH), catalogItemId: 'r1' }] });
71
+ const tooLong = asPackage({ items: [{ itemKey: 'k'.repeat(REWARD_ITEM_KEY_MAX_LENGTH + 1), catalogItemId: 'r1' }] });
72
+ expect(await validate(ok)).toHaveLength(0);
73
+ expect(await props(tooLong)).toContain('items');
74
+ });
75
+
76
+ it.each(['con espacio', 'con#almohadilla', 'acentó'])('rechaza el itemKey %s (caracteres fuera de [A-Za-z0-9_-])', async (itemKey) => {
77
+ expect(await props(asPackage({ items: [{ itemKey, catalogItemId: 'r1' }] }))).toContain('items');
78
+ });
79
+
80
+ it('REWARD_ITEM_KEY_MAX_LENGTH es 28 (igual que REWARDS_MAX_ITEM_KEY_LENGTH de api-invoker)', () => {
81
+ expect(REWARD_ITEM_KEY_MAX_LENGTH).toBe(28);
82
+ });
83
+
84
+ it('REWARD_PACKAGE_MAX_ITEMS es 4 (igual que MAX_ITEMS_PER_PACKAGE del worker, B-12): 4 ítems entran, 5 no', async () => {
85
+ expect(REWARD_PACKAGE_MAX_ITEMS).toBe(4);
86
+ const itemsOf = (n: number): JsonValue[] =>
87
+ Array.from({ length: n }, (_, i) => ({ itemKey: `item${i}`, catalogItemId: 'example-reward-a' }));
88
+ expect(await validate(asPackage({ items: itemsOf(REWARD_PACKAGE_MAX_ITEMS) }))).toHaveLength(0);
89
+ expect(await props(asPackage({ items: itemsOf(REWARD_PACKAGE_MAX_ITEMS + 1) }))).toContain('items');
90
+ });
91
+
92
+ it('acepta el MISMO catalogItemId en dos itemKey distintos (decisión de la Parte 2: cada ítem tiene su transactionNumber)', async () => {
93
+ const items = [{ itemKey: 'itemA', catalogItemId: 'example-reward-a' }, { itemKey: 'itemB', catalogItemId: 'example-reward-a' }];
94
+ expect(await validate(asPackage({ items }))).toHaveLength(0);
95
+ });
96
+ });
@@ -2,6 +2,8 @@ import type { InventoryItemStatusEnum } from '../../enums/InventoryItemStatusEnu
2
2
  import type { InventoryMovementTypeEnum } from '../../enums/InventoryMovementTypeEnum';
3
3
  import type { InventoryMovementReasonEnum } from '../../enums/InventoryMovementReasonEnum';
4
4
  import type { SkuPriceEntry } from './SkuPriceEntry';
5
+ import type { CatalogSourceStatusEnum } from '../../enums/CatalogSourceStatusEnum';
6
+ import type { ActiveSalePromotionSummary } from '../../../retailPromotions/dtos/responses/ActiveSalePromotionsBySkusResponse';
5
7
  /** Un movimiento del libro de inventario. */
6
8
  export interface InventoryMovementEntry {
7
9
  storeId: string;
@@ -36,4 +38,11 @@ export interface GetInventorySkuResponse {
36
38
  /** Vacío si el SKU se rastrea por cantidad. */
37
39
  piecesByStore: InventoryStorePieces[];
38
40
  currentPrice: SkuPriceEntry | null;
41
+ /** Promos de venta vigentes del SKU; `null` si retail-promotions no respondió. */
42
+ promotions?: ActiveSalePromotionSummary[] | null;
43
+ sources?: InventorySkuSources;
44
+ }
45
+ /** Estado de las fuentes externas de la ficha. */
46
+ export interface InventorySkuSources {
47
+ promotions: CatalogSourceStatusEnum;
39
48
  }
@@ -5,6 +5,7 @@ import type { ProductTierEnum } from '../../enums/ProductTierEnum';
5
5
  import type { InventoryLensUnavailableReasonEnum } from '../../enums/InventoryLensUnavailableReasonEnum';
6
6
  import type { InventoryTransferReasonEnum } from '../../enums/InventoryTransferReasonEnum';
7
7
  import type { ItemTypeEnum } from '../../enums/ItemTypeEnum';
8
+ import type { CatalogSourceStatusEnum } from '../../enums/CatalogSourceStatusEnum';
8
9
  /**
9
10
  * Los contadores que la pantalla «Inventario» del Admin VL pinta arriba, siempre — los cuatro viajan
10
11
  * con cualquier `filter`, porque las tarjetas no cambian al cambiar de tab.
@@ -115,6 +116,10 @@ export interface InventoryLensListItem {
115
116
  sold30d: number;
116
117
  /** Producto físico o servicio. Ausente = PRODUCT. */
117
118
  itemType?: ItemTypeEnum;
119
+ /** Tiene al menos una promo de venta vigente; `null` si retail-promotions no respondió. */
120
+ hasPromotion?: boolean | null;
121
+ /** Nombres de sus promos de venta vigentes; `null` si retail-promotions no respondió. */
122
+ promotionNames?: string[] | null;
118
123
  }
119
124
  /** Fila del lente — el tipo depende del tab pedido. */
120
125
  export type InventoryLensItem = InventoryLensSkuItem | InventoryLensTransferSuggestion | InventoryLensListItem;
@@ -147,4 +152,9 @@ export interface InventoryLensResponse {
147
152
  unavailable?: boolean;
148
153
  /** Por qué no se pudo. Presente solo junto a `unavailable: true`. */
149
154
  reason?: InventoryLensUnavailableReasonEnum;
155
+ /** Estado de las fuentes externas; solo en el modo `list`. */
156
+ sources?: InventoryLensSources;
157
+ }
158
+ export interface InventoryLensSources {
159
+ promotions: CatalogSourceStatusEnum;
150
160
  }
@@ -0,0 +1,5 @@
1
+ /** Si una fuente externa de una respuesta del catálogo contestó (`OK`) o falló (`UNAVAILABLE`). */
2
+ export declare enum CatalogSourceStatusEnum {
3
+ OK = "OK",
4
+ UNAVAILABLE = "UNAVAILABLE"
5
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CatalogSourceStatusEnum = void 0;
4
+ /** Si una fuente externa de una respuesta del catálogo contestó (`OK`) o falló (`UNAVAILABLE`). */
5
+ var CatalogSourceStatusEnum;
6
+ (function (CatalogSourceStatusEnum) {
7
+ CatalogSourceStatusEnum["OK"] = "OK";
8
+ CatalogSourceStatusEnum["UNAVAILABLE"] = "UNAVAILABLE";
9
+ })(CatalogSourceStatusEnum || (exports.CatalogSourceStatusEnum = CatalogSourceStatusEnum = {}));
@@ -36,6 +36,7 @@ export * from './enums/InventorySyncResultStatusEnum';
36
36
  export * from './enums/InventorySyncRejectionCodeEnum';
37
37
  export * from './enums/PriceSourceEnum';
38
38
  export * from './enums/InventoryLensPeriodEnum';
39
+ export * from './enums/CatalogSourceStatusEnum';
39
40
  export * from './dtos/ProductComponent';
40
41
  export * from './dtos/requests/ReservationLineRef';
41
42
  export * from './dtos/requests/StockLine';
@@ -60,6 +60,7 @@ __exportStar(require("./enums/InventorySyncResultStatusEnum"), exports);
60
60
  __exportStar(require("./enums/InventorySyncRejectionCodeEnum"), exports);
61
61
  __exportStar(require("./enums/PriceSourceEnum"), exports);
62
62
  __exportStar(require("./enums/InventoryLensPeriodEnum"), exports);
63
+ __exportStar(require("./enums/CatalogSourceStatusEnum"), exports);
63
64
  __exportStar(require("./dtos/ProductComponent"), exports);
64
65
  __exportStar(require("./dtos/requests/ReservationLineRef"), exports);
65
66
  __exportStar(require("./dtos/requests/StockLine"), exports);
@@ -0,0 +1,2 @@
1
+ /** Tope de SKUs por llamada a `POST /private/sale-promotions/active-by-skus`; el caller parte en bloques. */
2
+ export declare const ACTIVE_SALE_PROMOTIONS_MAX_SKUS = 100;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ACTIVE_SALE_PROMOTIONS_MAX_SKUS = void 0;
4
+ /** Tope de SKUs por llamada a `POST /private/sale-promotions/active-by-skus`; el caller parte en bloques. */
5
+ exports.ACTIVE_SALE_PROMOTIONS_MAX_SKUS = 100;
@@ -0,0 +1,17 @@
1
+ import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
2
+ import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
3
+ /** Un SKU con su tipo y gama; sin ellos no cumple un alcance por tipo o por gama. */
4
+ export declare class ActiveSalePromotionsSkuInput {
5
+ /** Un SKU vacío no invalida el lote: sale como `INVALID_ID`. */
6
+ sku: string;
7
+ category?: ProductCategoryEnum | null;
8
+ tier?: ProductTierEnum | null;
9
+ }
10
+ /** Body de `POST /private/sale-promotions/active-by-skus` (M2M): hasta 100 SKUs; los repetidos se cuentan una vez. */
11
+ export declare class ActiveSalePromotionsBySkusRequest {
12
+ tenantId: string;
13
+ retailerId: string;
14
+ /** Con tienda, solo las promos cuyo alcance la incluye; sin ella, las de cualquier tienda. */
15
+ storeId?: string;
16
+ items: ActiveSalePromotionsSkuInput[];
17
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ActiveSalePromotionsBySkusRequest = exports.ActiveSalePromotionsSkuInput = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const ProductCategoryEnum_1 = require("../../../retailCatalog/enums/ProductCategoryEnum");
16
+ const ProductTierEnum_1 = require("../../../retailCatalog/enums/ProductTierEnum");
17
+ const activeSalePromotionsBySkus_1 = require("../../constants/activeSalePromotionsBySkus");
18
+ /** Un SKU con su tipo y gama; sin ellos no cumple un alcance por tipo o por gama. */
19
+ class ActiveSalePromotionsSkuInput {
20
+ }
21
+ exports.ActiveSalePromotionsSkuInput = ActiveSalePromotionsSkuInput;
22
+ __decorate([
23
+ (0, class_transformer_1.Expose)(),
24
+ (0, class_validator_1.IsString)(),
25
+ __metadata("design:type", String)
26
+ ], ActiveSalePromotionsSkuInput.prototype, "sku", void 0);
27
+ __decorate([
28
+ (0, class_transformer_1.Expose)(),
29
+ (0, class_validator_1.IsOptional)(),
30
+ (0, class_validator_1.IsEnum)(ProductCategoryEnum_1.ProductCategoryEnum),
31
+ __metadata("design:type", String)
32
+ ], ActiveSalePromotionsSkuInput.prototype, "category", void 0);
33
+ __decorate([
34
+ (0, class_transformer_1.Expose)(),
35
+ (0, class_validator_1.IsOptional)(),
36
+ (0, class_validator_1.IsEnum)(ProductTierEnum_1.ProductTierEnum),
37
+ __metadata("design:type", String)
38
+ ], ActiveSalePromotionsSkuInput.prototype, "tier", void 0);
39
+ /** Body de `POST /private/sale-promotions/active-by-skus` (M2M): hasta 100 SKUs; los repetidos se cuentan una vez. */
40
+ class ActiveSalePromotionsBySkusRequest {
41
+ }
42
+ exports.ActiveSalePromotionsBySkusRequest = ActiveSalePromotionsBySkusRequest;
43
+ __decorate([
44
+ (0, class_transformer_1.Expose)(),
45
+ (0, class_validator_1.IsString)(),
46
+ (0, class_validator_1.IsNotEmpty)(),
47
+ __metadata("design:type", String)
48
+ ], ActiveSalePromotionsBySkusRequest.prototype, "tenantId", void 0);
49
+ __decorate([
50
+ (0, class_transformer_1.Expose)(),
51
+ (0, class_validator_1.IsString)(),
52
+ (0, class_validator_1.IsNotEmpty)(),
53
+ __metadata("design:type", String)
54
+ ], ActiveSalePromotionsBySkusRequest.prototype, "retailerId", void 0);
55
+ __decorate([
56
+ (0, class_transformer_1.Expose)(),
57
+ (0, class_validator_1.IsOptional)(),
58
+ (0, class_validator_1.IsString)(),
59
+ (0, class_validator_1.IsNotEmpty)(),
60
+ __metadata("design:type", String)
61
+ ], ActiveSalePromotionsBySkusRequest.prototype, "storeId", void 0);
62
+ __decorate([
63
+ (0, class_transformer_1.Expose)(),
64
+ (0, class_validator_1.IsArray)(),
65
+ (0, class_validator_1.ArrayMaxSize)(activeSalePromotionsBySkus_1.ACTIVE_SALE_PROMOTIONS_MAX_SKUS),
66
+ (0, class_validator_1.ValidateNested)({ each: true }),
67
+ (0, class_transformer_1.Type)(() => ActiveSalePromotionsSkuInput),
68
+ __metadata("design:type", Array)
69
+ ], ActiveSalePromotionsBySkusRequest.prototype, "items", void 0);
@@ -0,0 +1,26 @@
1
+ import type { SalePromotionLevers, SalePromotionScope, SalePromotionSegmentation } from '../SalePromotionLevers';
2
+ import type { SkuSalePromotionLookupStatusEnum } from '../../enums/SkuSalePromotionLookupStatusEnum';
3
+ /** Promo de venta vigente hoy que alcanza al SKU, con su contenido de la versión actual. */
4
+ export interface ActiveSalePromotionSummary {
5
+ promotionId: string;
6
+ name: string;
7
+ /** Palancas en español: «$500 de descuento + 3× $50 de tiempo aire + $300 al Wallet Fiado». */
8
+ benefitSummary: string;
9
+ levers: SalePromotionLevers;
10
+ /** `null` = arrancó al publicarse. */
11
+ validFrom: string | null;
12
+ /** `null` = permanente. */
13
+ validUntil: string | null;
14
+ segmentation: SalePromotionSegmentation;
15
+ scope: SalePromotionScope;
16
+ }
17
+ export interface SkuActiveSalePromotions {
18
+ sku: string;
19
+ status: SkuSalePromotionLookupStatusEnum;
20
+ /** Vacío si no tiene ninguna o si el estado no es `OK`. */
21
+ promotions: ActiveSalePromotionSummary[];
22
+ }
23
+ /** Response de `POST /private/sale-promotions/active-by-skus`: una entrada por SKU, en el orden pedido. */
24
+ export interface ActiveSalePromotionsBySkusResponse {
25
+ items: SkuActiveSalePromotions[];
26
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ /** Cómo se resolvió cada SKU del lote de promos vigentes; hay una entrada por SKU pedido. */
2
+ export declare enum SkuSalePromotionLookupStatusEnum {
3
+ /** Se leyeron las promos; `promotions` vacío es un dato: no tiene ninguna vigente. */
4
+ OK = "OK",
5
+ /** No se pudieron leer las promos; el caller lo pinta como fuente caída y reintenta. */
6
+ UNAVAILABLE = "UNAVAILABLE",
7
+ /** El SKU no tiene forma de SKU; reintentarlo igual nunca sirve. */
8
+ INVALID_ID = "INVALID_ID"
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SkuSalePromotionLookupStatusEnum = void 0;
4
+ /** Cómo se resolvió cada SKU del lote de promos vigentes; hay una entrada por SKU pedido. */
5
+ var SkuSalePromotionLookupStatusEnum;
6
+ (function (SkuSalePromotionLookupStatusEnum) {
7
+ /** Se leyeron las promos; `promotions` vacío es un dato: no tiene ninguna vigente. */
8
+ SkuSalePromotionLookupStatusEnum["OK"] = "OK";
9
+ /** No se pudieron leer las promos; el caller lo pinta como fuente caída y reintenta. */
10
+ SkuSalePromotionLookupStatusEnum["UNAVAILABLE"] = "UNAVAILABLE";
11
+ /** El SKU no tiene forma de SKU; reintentarlo igual nunca sirve. */
12
+ SkuSalePromotionLookupStatusEnum["INVALID_ID"] = "INVALID_ID";
13
+ })(SkuSalePromotionLookupStatusEnum || (exports.SkuSalePromotionLookupStatusEnum = SkuSalePromotionLookupStatusEnum = {}));
@@ -17,9 +17,11 @@ export * from './enums/EntitlementKindEnum';
17
17
  export * from './enums/SaleCouponAvailabilityEnum';
18
18
  export * from './enums/RetailPromotionsErrorCodeEnum';
19
19
  export * from './enums/SalePromotionKindEnum';
20
+ export * from './enums/SkuSalePromotionLookupStatusEnum';
20
21
  export * from './constants/retailPromotionsErrorHttpStatus';
21
22
  export * from './constants/salePromotionTransitions';
22
23
  export * from './constants/bonusPreMoney';
24
+ export * from './constants/activeSalePromotionsBySkus';
23
25
  export * from './helpers/resolveSalePromotionTransition';
24
26
  export * from './helpers/computeBudgetUsedBps';
25
27
  export * from './helpers/resolveSalePromotionKind';
@@ -50,8 +52,10 @@ export * from './dtos/requests/HoldPromotionInput';
50
52
  export * from './dtos/requests/HoldSalePromotionRequest';
51
53
  export * from './dtos/requests/GetSaleCouponQuery';
52
54
  export * from './dtos/requests/SkuSalePromotionsQuery';
55
+ export * from './dtos/requests/ActiveSalePromotionsBySkusRequest';
53
56
  export * from './dtos/responses/SalePromotionCrudResponses';
54
57
  export * from './dtos/responses/DiscountCodeResponses';
55
58
  export * from './dtos/responses/WizardSalePromotionResponses';
56
59
  export * from './dtos/responses/SkuSalePromotionsResponse';
57
60
  export * from './dtos/responses/SalePromotionSegmentsResponse';
61
+ export * from './dtos/responses/ActiveSalePromotionsBySkusResponse';
@@ -34,10 +34,12 @@ __exportStar(require("./enums/EntitlementKindEnum"), exports);
34
34
  __exportStar(require("./enums/SaleCouponAvailabilityEnum"), exports);
35
35
  __exportStar(require("./enums/RetailPromotionsErrorCodeEnum"), exports);
36
36
  __exportStar(require("./enums/SalePromotionKindEnum"), exports);
37
+ __exportStar(require("./enums/SkuSalePromotionLookupStatusEnum"), exports);
37
38
  // Constantes y helpers puros
38
39
  __exportStar(require("./constants/retailPromotionsErrorHttpStatus"), exports);
39
40
  __exportStar(require("./constants/salePromotionTransitions"), exports);
40
41
  __exportStar(require("./constants/bonusPreMoney"), exports);
42
+ __exportStar(require("./constants/activeSalePromotionsBySkus"), exports);
41
43
  __exportStar(require("./helpers/resolveSalePromotionTransition"), exports);
42
44
  __exportStar(require("./helpers/computeBudgetUsedBps"), exports);
43
45
  __exportStar(require("./helpers/resolveSalePromotionKind"), exports);
@@ -71,9 +73,11 @@ __exportStar(require("./dtos/requests/HoldPromotionInput"), exports);
71
73
  __exportStar(require("./dtos/requests/HoldSalePromotionRequest"), exports);
72
74
  __exportStar(require("./dtos/requests/GetSaleCouponQuery"), exports);
73
75
  __exportStar(require("./dtos/requests/SkuSalePromotionsQuery"), exports);
76
+ __exportStar(require("./dtos/requests/ActiveSalePromotionsBySkusRequest"), exports);
74
77
  // Response DTOs
75
78
  __exportStar(require("./dtos/responses/SalePromotionCrudResponses"), exports);
76
79
  __exportStar(require("./dtos/responses/DiscountCodeResponses"), exports);
77
80
  __exportStar(require("./dtos/responses/WizardSalePromotionResponses"), exports);
78
81
  __exportStar(require("./dtos/responses/SkuSalePromotionsResponse"), exports);
79
82
  __exportStar(require("./dtos/responses/SalePromotionSegmentsResponse"), exports);
83
+ __exportStar(require("./dtos/responses/ActiveSalePromotionsBySkusResponse"), exports);
@@ -0,0 +1,6 @@
1
+ /** Máximo del `itemKey` de un paquete: `RW-{grantId(32)}-{itemKey}` ≤ 64 (igual que REWARDS_MAX_ITEM_KEY_LENGTH de api-invoker). */
2
+ export declare const REWARD_ITEM_KEY_MAX_LENGTH = 28;
3
+ export declare const REWARD_ITEM_KEY_PATTERN: RegExp;
4
+ export declare const REWARD_ID_PATTERN: RegExp;
5
+ /** Máximo de ítems de un paquete (B-12 de rewards-business: presupuesto de tiempo del worker). Igual a `MAX_ITEMS_PER_PACKAGE` del lambda. */
6
+ export declare const REWARD_PACKAGE_MAX_ITEMS = 4;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REWARD_PACKAGE_MAX_ITEMS = exports.REWARD_ID_PATTERN = exports.REWARD_ITEM_KEY_PATTERN = exports.REWARD_ITEM_KEY_MAX_LENGTH = void 0;
4
+ /** Máximo del `itemKey` de un paquete: `RW-{grantId(32)}-{itemKey}` ≤ 64 (igual que REWARDS_MAX_ITEM_KEY_LENGTH de api-invoker). */
5
+ exports.REWARD_ITEM_KEY_MAX_LENGTH = 28;
6
+ exports.REWARD_ITEM_KEY_PATTERN = new RegExp(`^[A-Za-z0-9_-]{1,${exports.REWARD_ITEM_KEY_MAX_LENGTH}}$`);
7
+ exports.REWARD_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
8
+ /** Máximo de ítems de un paquete (B-12 de rewards-business: presupuesto de tiempo del worker). Igual a `MAX_ITEMS_PER_PACKAGE` del lambda. */
9
+ exports.REWARD_PACKAGE_MAX_ITEMS = 4;
@@ -0,0 +1,6 @@
1
+ import { CatalogItemResponse } from './CatalogItemResponse';
2
+ export declare class CatalogItemListResponse {
3
+ items: CatalogItemResponse[];
4
+ /** Cursor opaco de la página siguiente; ausente en la última página. */
5
+ nextCursor?: string;
6
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CatalogItemListResponse = void 0;
4
+ class CatalogItemListResponse {
5
+ }
6
+ exports.CatalogItemListResponse = CatalogItemListResponse;
@@ -0,0 +1,19 @@
1
+ import { JsonValue } from '../../../common';
2
+ import { RewardStatusEnum } from '../../enums/RewardStatusEnum';
3
+ import { RewardChargeToInput } from './RewardChargeToInput';
4
+ import { RewardCostInput } from './RewardCostInput';
5
+ /** Crear (POST) o reemplazar (PUT) una recompensa del catálogo. `version`, `dependencies` y `updatedBy` los pone el servidor. */
6
+ export declare class CatalogItemRequest {
7
+ id: string;
8
+ name: string;
9
+ description: string;
10
+ /** `type` del adaptador (IRewardType.type). Inmutable una vez creada la recompensa. */
11
+ type: string;
12
+ /** Forma definida por cada tipo; el lambda la valida con `IRewardType.validateConfig`. */
13
+ config: {
14
+ [key: string]: JsonValue;
15
+ };
16
+ cost: RewardCostInput;
17
+ chargeTo: RewardChargeToInput;
18
+ status: RewardStatusEnum;
19
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CatalogItemRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const BackofficeLimits_1 = require("../../constants/BackofficeLimits");
16
+ const RewardStatusEnum_1 = require("../../enums/RewardStatusEnum");
17
+ const RewardChargeToInput_1 = require("./RewardChargeToInput");
18
+ const RewardCostInput_1 = require("./RewardCostInput");
19
+ /** Crear (POST) o reemplazar (PUT) una recompensa del catálogo. `version`, `dependencies` y `updatedBy` los pone el servidor. */
20
+ class CatalogItemRequest {
21
+ }
22
+ exports.CatalogItemRequest = CatalogItemRequest;
23
+ __decorate([
24
+ (0, class_transformer_1.Expose)(),
25
+ (0, class_validator_1.IsString)(),
26
+ (0, class_validator_1.Matches)(BackofficeLimits_1.REWARD_ID_PATTERN),
27
+ __metadata("design:type", String)
28
+ ], CatalogItemRequest.prototype, "id", void 0);
29
+ __decorate([
30
+ (0, class_transformer_1.Expose)(),
31
+ (0, class_validator_1.IsString)(),
32
+ (0, class_validator_1.IsNotEmpty)(),
33
+ (0, class_validator_1.MaxLength)(120),
34
+ __metadata("design:type", String)
35
+ ], CatalogItemRequest.prototype, "name", void 0);
36
+ __decorate([
37
+ (0, class_transformer_1.Expose)(),
38
+ (0, class_validator_1.IsString)(),
39
+ (0, class_validator_1.MaxLength)(500),
40
+ __metadata("design:type", String)
41
+ ], CatalogItemRequest.prototype, "description", void 0);
42
+ __decorate([
43
+ (0, class_transformer_1.Expose)(),
44
+ (0, class_validator_1.IsString)(),
45
+ (0, class_validator_1.IsNotEmpty)(),
46
+ (0, class_validator_1.MaxLength)(60),
47
+ __metadata("design:type", String)
48
+ ], CatalogItemRequest.prototype, "type", void 0);
49
+ __decorate([
50
+ (0, class_transformer_1.Expose)(),
51
+ (0, class_validator_1.IsObject)(),
52
+ __metadata("design:type", Object)
53
+ ], CatalogItemRequest.prototype, "config", void 0);
54
+ __decorate([
55
+ (0, class_transformer_1.Expose)(),
56
+ (0, class_validator_1.ValidateNested)(),
57
+ (0, class_transformer_1.Type)(() => RewardCostInput_1.RewardCostInput),
58
+ __metadata("design:type", RewardCostInput_1.RewardCostInput)
59
+ ], CatalogItemRequest.prototype, "cost", void 0);
60
+ __decorate([
61
+ (0, class_transformer_1.Expose)(),
62
+ (0, class_validator_1.ValidateNested)(),
63
+ (0, class_transformer_1.Type)(() => RewardChargeToInput_1.RewardChargeToInput),
64
+ __metadata("design:type", RewardChargeToInput_1.RewardChargeToInput)
65
+ ], CatalogItemRequest.prototype, "chargeTo", void 0);
66
+ __decorate([
67
+ (0, class_transformer_1.Expose)(),
68
+ (0, class_validator_1.IsEnum)(RewardStatusEnum_1.RewardStatusEnum),
69
+ __metadata("design:type", String)
70
+ ], CatalogItemRequest.prototype, "status", void 0);
@@ -0,0 +1,23 @@
1
+ import { JsonValue } from '../../../common';
2
+ import { RewardStatusEnum } from '../../enums/RewardStatusEnum';
3
+ import { RewardChargeTo } from '../RewardChargeTo';
4
+ import { RewardCost } from '../RewardCost';
5
+ import { RewardDependency } from '../RewardDependency';
6
+ export declare class CatalogItemResponse {
7
+ id: string;
8
+ name: string;
9
+ description: string;
10
+ type: string;
11
+ config: {
12
+ [key: string]: JsonValue;
13
+ };
14
+ cost: RewardCost;
15
+ chargeTo: RewardChargeTo;
16
+ /** Solo lectura: las calcula el tipo a partir de `config`. */
17
+ dependencies: RewardDependency[];
18
+ status: RewardStatusEnum;
19
+ version: number;
20
+ updatedBy: string;
21
+ createdAt: number;
22
+ updatedAt: number;
23
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CatalogItemResponse = void 0;
4
+ class CatalogItemResponse {
5
+ }
6
+ exports.CatalogItemResponse = CatalogItemResponse;
@@ -0,0 +1,4 @@
1
+ export declare class PackageItemRequest {
2
+ itemKey: string;
3
+ catalogItemId: string;
4
+ }