@fiado/type-kit 3.614.0 → 3.616.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_test_/unit/loanCredit/dtos/originateLoanCreditRequest.test.ts +9 -0
- package/_test_/unit/loanOfferings/promotionRetailerScope.test.ts +79 -0
- package/_test_/unit/loanOfferings/segmentCohorts.test.ts +11 -2
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.d.ts +2 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.js +7 -0
- package/bin/loanOfferings/constants/promotionRetailerScope.d.ts +2 -0
- package/bin/loanOfferings/constants/promotionRetailerScope.js +5 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.js +10 -0
- package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.js +7 -0
- package/bin/loanOfferings/dtos/requests/ListPromotedSkusRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/ListPromotedSkusRequest.js +7 -0
- package/bin/loanOfferings/dtos/requests/ListSkuPromotionsRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/ListSkuPromotionsRequest.js +7 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.js +7 -0
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.js +10 -0
- package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.js +7 -0
- package/bin/loanOfferings/dtos/responses/PromotionResponse.d.ts +2 -0
- package/bin/loanOfferings/dtos/responses/SegmentResponse.d.ts +2 -0
- package/bin/loanOfferings/index.d.ts +1 -0
- package/bin/loanOfferings/index.js +1 -0
- package/package.json +1 -1
- package/src/loanCredit/dtos/requests/OriginateLoanCreditRequest.ts +7 -0
- package/src/loanOfferings/constants/promotionRetailerScope.ts +2 -0
- package/src/loanOfferings/dtos/requests/CreatePromotionRequest.ts +12 -0
- package/src/loanOfferings/dtos/requests/CreateSegmentRequest.ts +7 -0
- package/src/loanOfferings/dtos/requests/ListPromotedSkusRequest.ts +7 -0
- package/src/loanOfferings/dtos/requests/ListSkuPromotionsRequest.ts +7 -0
- package/src/loanOfferings/dtos/requests/SimulateCreditPlanRequest.ts +8 -1
- package/src/loanOfferings/dtos/requests/UpdatePromotionRequest.ts +12 -0
- package/src/loanOfferings/dtos/requests/UpdateSegmentRequest.ts +7 -0
- package/src/loanOfferings/dtos/responses/PromotionResponse.ts +2 -0
- package/src/loanOfferings/dtos/responses/SegmentResponse.ts +2 -0
- package/src/loanOfferings/index.ts +1 -0
|
@@ -62,4 +62,13 @@ describe('OriginateLoanCreditRequest', () => {
|
|
|
62
62
|
const bad = await validateWhitelisted({ ...BASE, productCategory: 'CAR', productTier: 'ULTRA' });
|
|
63
63
|
expect(bad.errors.map((error) => error.property).sort()).toEqual(['productCategory', 'productTier']);
|
|
64
64
|
});
|
|
65
|
+
|
|
66
|
+
it('acepta la cadena opcional y rechaza la cadena vacía', async () => {
|
|
67
|
+
const ok = await validateWhitelisted({ ...BASE, retailerId: 'RT-1' });
|
|
68
|
+
expect(ok.errors).toEqual([]);
|
|
69
|
+
expect(ok.dto.retailerId).toBe('RT-1');
|
|
70
|
+
|
|
71
|
+
const bad = await validateWhitelisted({ ...BASE, retailerId: '' });
|
|
72
|
+
expect(bad.errors.map((error) => error.property)).toEqual(['retailerId']);
|
|
73
|
+
});
|
|
65
74
|
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
CreatePromotionRequest,
|
|
6
|
+
ListPromotedSkusRequest,
|
|
7
|
+
ListSkuPromotionsRequest,
|
|
8
|
+
PROMOTION_RETAILER_IDS_MAX_ITEMS,
|
|
9
|
+
SimulateCreditPlanRequest,
|
|
10
|
+
UpdatePromotionRequest,
|
|
11
|
+
} from '../../../src/loanOfferings/index';
|
|
12
|
+
import type { PromotionResponse } from '../../../src/loanOfferings/index';
|
|
13
|
+
|
|
14
|
+
type DtoClass = new () => object;
|
|
15
|
+
|
|
16
|
+
const errorsOf = async (dtoClass: DtoClass, body: object): Promise<string[]> =>
|
|
17
|
+
(await validate(plainToInstance(dtoClass, body, { excludeExtraneousValues: true }) as object)).map((e) => e.property);
|
|
18
|
+
|
|
19
|
+
const createBase = {
|
|
20
|
+
name: 'Tasa preferente cadena',
|
|
21
|
+
description: 'Baja la tasa en una cadena',
|
|
22
|
+
effect: { downPaymentDeltaPct: 0.05 },
|
|
23
|
+
segmentId: 'SEG_SILVER',
|
|
24
|
+
targetLevels: ['SILVER'],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
describe('alcance por cadena en promociones de crédito', () => {
|
|
28
|
+
it('Create acepta cadenas, null y lista vacía como «todas»', async () => {
|
|
29
|
+
const dto = plainToInstance(CreatePromotionRequest, { ...createBase, retailerIds: ['RT-1', 'RT-2'] }, { excludeExtraneousValues: true });
|
|
30
|
+
expect(await validate(dto)).toHaveLength(0);
|
|
31
|
+
expect(dto.retailerIds).toEqual(['RT-1', 'RT-2']);
|
|
32
|
+
expect(await errorsOf(CreatePromotionRequest, { ...createBase, retailerIds: null })).toEqual([]);
|
|
33
|
+
expect(await errorsOf(CreatePromotionRequest, { ...createBase, retailerIds: [] })).toEqual([]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it.each([CreatePromotionRequest, UpdatePromotionRequest])('%p rechaza cadenas mal formadas', async (dtoClass) => {
|
|
37
|
+
const body = dtoClass === CreatePromotionRequest ? createBase : {};
|
|
38
|
+
const tooMany = Array.from({ length: PROMOTION_RETAILER_IDS_MAX_ITEMS + 1 }, (_v, i) => `RT-${i}`);
|
|
39
|
+
expect(await errorsOf(dtoClass, { ...body, retailerIds: 'RT-1' })).toContain('retailerIds');
|
|
40
|
+
expect(await errorsOf(dtoClass, { ...body, retailerIds: [7] })).toContain('retailerIds');
|
|
41
|
+
expect(await errorsOf(dtoClass, { ...body, retailerIds: [''] })).toContain('retailerIds');
|
|
42
|
+
expect(await errorsOf(dtoClass, { ...body, retailerIds: tooMany })).toContain('retailerIds');
|
|
43
|
+
expect(await errorsOf(dtoClass, { ...body, retailerIds: tooMany.slice(1) })).toEqual([]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('Update acepta el parche solo con cadenas', async () => {
|
|
47
|
+
expect(PROMOTION_RETAILER_IDS_MAX_ITEMS).toBe(50);
|
|
48
|
+
expect(await errorsOf(UpdatePromotionRequest, { retailerIds: ['RT-1'] })).toEqual([]);
|
|
49
|
+
expect(await errorsOf(UpdatePromotionRequest, { retailerIds: null })).toEqual([]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('la respuesta expone las cadenas con null como «todas»', () => {
|
|
53
|
+
const scope: Pick<PromotionResponse, 'retailerIds'> = { retailerIds: null };
|
|
54
|
+
expect(scope.retailerIds).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('el simulador recibe la cadena opcional como string', async () => {
|
|
58
|
+
const base = { productPriceCents: 500000, downPaymentPct: 0.2, termWeeks: 26 };
|
|
59
|
+
const dto = plainToInstance(SimulateCreditPlanRequest, { ...base, retailerId: 'RT-1' }, { excludeExtraneousValues: true });
|
|
60
|
+
expect(await validate(dto)).toHaveLength(0);
|
|
61
|
+
expect(dto.retailerId).toBe('RT-1');
|
|
62
|
+
expect(await errorsOf(SimulateCreditPlanRequest, { ...base, retailerId: 7 })).toContain('retailerId');
|
|
63
|
+
expect(await errorsOf(SimulateCreditPlanRequest, { ...base, retailerId: '' })).toContain('retailerId');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe.each([ListPromotedSkusRequest, ListSkuPromotionsRequest])('%p con cadena', (dtoClass) => {
|
|
68
|
+
const valid = { storeId: 'st-1', items: [{ sku: 'SKU-1' }] };
|
|
69
|
+
|
|
70
|
+
it('acepta la cadena opcional junto a la tienda', async () => {
|
|
71
|
+
expect(await errorsOf(dtoClass, valid)).toEqual([]);
|
|
72
|
+
expect(await errorsOf(dtoClass, { ...valid, retailerId: 'RT-1' })).toEqual([]);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('rechaza la cadena vacía o no string', async () => {
|
|
76
|
+
expect(await errorsOf(dtoClass, { ...valid, retailerId: '' })).toContain('retailerId');
|
|
77
|
+
expect(await errorsOf(dtoClass, { ...valid, retailerId: 7 })).toContain('retailerId');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -207,7 +207,7 @@ describe('ChangeCohortStatusRequest, TestCohortRequest y ListCohortsQuery', () =
|
|
|
207
207
|
});
|
|
208
208
|
|
|
209
209
|
describe('Segmento con cohorts', () => {
|
|
210
|
-
it('el alta acepta cohortIds y
|
|
210
|
+
it('el alta acepta cohortIds y conserva filterIds como alias deprecado', async () => {
|
|
211
211
|
const dto = toDto(CreateSegmentRequest, {
|
|
212
212
|
name: 'VIP',
|
|
213
213
|
colorSlot: SegmentColorSlotEnum.SLATE,
|
|
@@ -216,7 +216,15 @@ describe('Segmento con cohorts', () => {
|
|
|
216
216
|
});
|
|
217
217
|
expect(await validate(dto)).toHaveLength(0);
|
|
218
218
|
expect(dto.cohortIds).toEqual(['COH-LEVEL-GOLD']);
|
|
219
|
-
expect(
|
|
219
|
+
expect(dto.filterIds).toEqual(['levelGold']);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('filterIds deprecado es opcional y exige textos en alta y edición', async () => {
|
|
223
|
+
expect(await errorProperties(CreateSegmentRequest, { name: 'X' })).toEqual([]);
|
|
224
|
+
expect(await errorProperties(CreateSegmentRequest, { name: 'X', filterIds: [1] })).toEqual(['filterIds']);
|
|
225
|
+
expect(toDto(UpdateSegmentRequest, { filterIds: ['levelGold'] }).filterIds).toEqual(['levelGold']);
|
|
226
|
+
expect(await errorProperties(UpdateSegmentRequest, { filterIds: [] })).toEqual([]);
|
|
227
|
+
expect(await errorProperties(UpdateSegmentRequest, { filterIds: 'levelGold' })).toEqual(['filterIds']);
|
|
220
228
|
});
|
|
221
229
|
|
|
222
230
|
it('limita los cohorts a 20 y exige textos', async () => {
|
|
@@ -277,6 +285,7 @@ describe('Responses de cohorts y segmentos', () => {
|
|
|
277
285
|
description: null,
|
|
278
286
|
colorSlot: SegmentColorSlotEnum.SLATE,
|
|
279
287
|
cohortIds: [cohort.cohortId],
|
|
288
|
+
filterIds: [],
|
|
280
289
|
memberIds: [],
|
|
281
290
|
isDefault: false,
|
|
282
291
|
status: SegmentStatusEnum.ACTIVE,
|
|
@@ -46,4 +46,6 @@ export declare class OriginateLoanCreditRequest {
|
|
|
46
46
|
productCategory?: ProductCategoryEnum;
|
|
47
47
|
/** Gama del equipo: resuelve promociones acotadas por gama. */
|
|
48
48
|
productTier?: ProductTierEnum;
|
|
49
|
+
/** Cadena de la tienda que vende; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
50
|
+
retailerId?: string;
|
|
49
51
|
}
|
|
@@ -122,3 +122,10 @@ __decorate([
|
|
|
122
122
|
(0, class_validator_1.IsEnum)(ProductTierEnum_1.ProductTierEnum),
|
|
123
123
|
__metadata("design:type", String)
|
|
124
124
|
], OriginateLoanCreditRequest.prototype, "productTier", void 0);
|
|
125
|
+
__decorate([
|
|
126
|
+
(0, class_transformer_1.Expose)(),
|
|
127
|
+
(0, class_validator_1.IsOptional)(),
|
|
128
|
+
(0, class_validator_1.IsString)(),
|
|
129
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
130
|
+
__metadata("design:type", String)
|
|
131
|
+
], OriginateLoanCreditRequest.prototype, "retailerId", void 0);
|
|
@@ -20,6 +20,8 @@ export declare class CreatePromotionRequest {
|
|
|
20
20
|
productCategories?: ProductCategoryEnum[] | null;
|
|
21
21
|
/** Gamas alcanzadas; ausente o `null` = todas las gamas. */
|
|
22
22
|
tiers?: ProductTierEnum[] | null;
|
|
23
|
+
/** Cadenas alcanzadas; ausente, `null` o vacío = todas las cadenas. */
|
|
24
|
+
retailerIds?: string[] | null;
|
|
23
25
|
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
24
26
|
storeIds?: string[] | null;
|
|
25
27
|
validFrom?: string | null;
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.CreatePromotionRequest = void 0;
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
|
+
const promotionRetailerScope_1 = require("../../constants/promotionRetailerScope");
|
|
15
16
|
const CreditPlanLevelEnum_1 = require("../../enums/CreditPlanLevelEnum");
|
|
16
17
|
const ProductCategoryEnum_1 = require("../../../retailCatalog/enums/ProductCategoryEnum");
|
|
17
18
|
const ProductTierEnum_1 = require("../../../retailCatalog/enums/ProductTierEnum");
|
|
@@ -73,6 +74,15 @@ __decorate([
|
|
|
73
74
|
(0, class_validator_1.IsEnum)(ProductTierEnum_1.ProductTierEnum, { each: true }),
|
|
74
75
|
__metadata("design:type", Array)
|
|
75
76
|
], CreatePromotionRequest.prototype, "tiers", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
(0, class_transformer_1.Expose)(),
|
|
79
|
+
(0, class_validator_1.IsOptional)(),
|
|
80
|
+
(0, class_validator_1.IsArray)(),
|
|
81
|
+
(0, class_validator_1.ArrayMaxSize)(promotionRetailerScope_1.PROMOTION_RETAILER_IDS_MAX_ITEMS),
|
|
82
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
83
|
+
(0, class_validator_1.IsNotEmpty)({ each: true }),
|
|
84
|
+
__metadata("design:type", Array)
|
|
85
|
+
], CreatePromotionRequest.prototype, "retailerIds", void 0);
|
|
76
86
|
__decorate([
|
|
77
87
|
(0, class_transformer_1.Expose)(),
|
|
78
88
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -15,6 +15,8 @@ export declare class CreateSegmentRequest {
|
|
|
15
15
|
* dentro de cada cohort las condiciones se unen con Y.
|
|
16
16
|
*/
|
|
17
17
|
cohortIds?: string[];
|
|
18
|
+
/** @deprecated Usar `cohortIds`; se conserva para los consumidores que aún no migran. */
|
|
19
|
+
filterIds?: string[];
|
|
18
20
|
/**
|
|
19
21
|
* Clientes agregados a mano por `retailCustomerId`. Ganan siempre, cumplan o no un cohort.
|
|
20
22
|
* Un segmento puede nacer SOLO con esta lista, sin ningún cohort.
|
|
@@ -50,6 +50,13 @@ __decorate([
|
|
|
50
50
|
(0, class_validator_1.ArrayMaxSize)(20),
|
|
51
51
|
__metadata("design:type", Array)
|
|
52
52
|
], CreateSegmentRequest.prototype, "cohortIds", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, class_transformer_1.Expose)(),
|
|
55
|
+
(0, class_validator_1.IsOptional)(),
|
|
56
|
+
(0, class_validator_1.IsArray)(),
|
|
57
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
58
|
+
__metadata("design:type", Array)
|
|
59
|
+
], CreateSegmentRequest.prototype, "filterIds", void 0);
|
|
53
60
|
__decorate([
|
|
54
61
|
(0, class_transformer_1.Expose)(),
|
|
55
62
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -3,6 +3,8 @@ import { PromotionSkuInput } from './PromotionSkuInput';
|
|
|
3
3
|
/** Body de `POST /private/promotions/promoted-skus` (M2M): SKUs del lote con promoción viva para el badge; hasta 100 SKUs. */
|
|
4
4
|
export declare class ListPromotedSkusRequest {
|
|
5
5
|
storeId: string;
|
|
6
|
+
/** Cadena de la tienda; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
7
|
+
retailerId?: string;
|
|
6
8
|
/** Nivel del cliente si loan-scoring ya corrió. */
|
|
7
9
|
level?: CreditPlanLevelEnum;
|
|
8
10
|
/** Segmento del cliente si ya se resolvió. */
|
|
@@ -25,6 +25,13 @@ __decorate([
|
|
|
25
25
|
(0, class_validator_1.IsNotEmpty)(),
|
|
26
26
|
__metadata("design:type", String)
|
|
27
27
|
], ListPromotedSkusRequest.prototype, "storeId", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_transformer_1.Expose)(),
|
|
30
|
+
(0, class_validator_1.IsOptional)(),
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], ListPromotedSkusRequest.prototype, "retailerId", void 0);
|
|
28
35
|
__decorate([
|
|
29
36
|
(0, class_transformer_1.Expose)(),
|
|
30
37
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -3,6 +3,8 @@ import { PromotionSkuInput } from './PromotionSkuInput';
|
|
|
3
3
|
/** Body de `POST /private/promotions/by-sku` (M2M): promociones vivas de cada SKU del lote; hasta 100 SKUs. */
|
|
4
4
|
export declare class ListSkuPromotionsRequest {
|
|
5
5
|
storeId: string;
|
|
6
|
+
/** Cadena de la tienda; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
7
|
+
retailerId?: string;
|
|
6
8
|
/** Nivel del cliente si loan-scoring ya corrió. */
|
|
7
9
|
level?: CreditPlanLevelEnum;
|
|
8
10
|
/** Segmento del cliente si ya se resolvió. */
|
|
@@ -25,6 +25,13 @@ __decorate([
|
|
|
25
25
|
(0, class_validator_1.IsNotEmpty)(),
|
|
26
26
|
__metadata("design:type", String)
|
|
27
27
|
], ListSkuPromotionsRequest.prototype, "storeId", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_transformer_1.Expose)(),
|
|
30
|
+
(0, class_validator_1.IsOptional)(),
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], ListSkuPromotionsRequest.prototype, "retailerId", void 0);
|
|
28
35
|
__decorate([
|
|
29
36
|
(0, class_transformer_1.Expose)(),
|
|
30
37
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -22,6 +22,8 @@ export declare class SimulateCreditPlanRequest {
|
|
|
22
22
|
productCategory?: ProductCategoryEnum;
|
|
23
23
|
/** Gama del equipo. Sin ella no se resuelven las promociones acotadas por gama. */
|
|
24
24
|
productTier?: ProductTierEnum;
|
|
25
|
+
/** Cadena de la tienda que cotiza; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
26
|
+
retailerId?: string;
|
|
25
27
|
/**
|
|
26
28
|
* Segmentos del cliente, los que devolvió `POST /private/segments/resolve`. Un arreglo vacío
|
|
27
29
|
* declara que el cliente no está en ninguno; ausente declara que el caller no lo consultó.
|
|
@@ -77,6 +77,13 @@ __decorate([
|
|
|
77
77
|
(0, class_validator_1.IsEnum)(ProductTierEnum_1.ProductTierEnum),
|
|
78
78
|
__metadata("design:type", String)
|
|
79
79
|
], SimulateCreditPlanRequest.prototype, "productTier", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, class_transformer_1.Expose)(),
|
|
82
|
+
(0, class_validator_1.IsOptional)(),
|
|
83
|
+
(0, class_validator_1.IsString)(),
|
|
84
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
85
|
+
__metadata("design:type", String)
|
|
86
|
+
], SimulateCreditPlanRequest.prototype, "retailerId", void 0);
|
|
80
87
|
__decorate([
|
|
81
88
|
(0, class_transformer_1.Expose)(),
|
|
82
89
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -18,6 +18,8 @@ export declare class UpdatePromotionRequest {
|
|
|
18
18
|
productCategories?: ProductCategoryEnum[] | null;
|
|
19
19
|
/** Gamas alcanzadas; ausente o `null` = todas las gamas. */
|
|
20
20
|
tiers?: ProductTierEnum[] | null;
|
|
21
|
+
/** Cadenas alcanzadas; ausente, `null` o vacío = todas las cadenas. */
|
|
22
|
+
retailerIds?: string[] | null;
|
|
21
23
|
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
22
24
|
storeIds?: string[] | null;
|
|
23
25
|
validFrom?: string | null;
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.UpdatePromotionRequest = void 0;
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
|
+
const promotionRetailerScope_1 = require("../../constants/promotionRetailerScope");
|
|
15
16
|
const CreditPlanLevelEnum_1 = require("../../enums/CreditPlanLevelEnum");
|
|
16
17
|
const ProductCategoryEnum_1 = require("../../../retailCatalog/enums/ProductCategoryEnum");
|
|
17
18
|
const ProductTierEnum_1 = require("../../../retailCatalog/enums/ProductTierEnum");
|
|
@@ -78,6 +79,15 @@ __decorate([
|
|
|
78
79
|
(0, class_validator_1.IsEnum)(ProductTierEnum_1.ProductTierEnum, { each: true }),
|
|
79
80
|
__metadata("design:type", Array)
|
|
80
81
|
], UpdatePromotionRequest.prototype, "tiers", void 0);
|
|
82
|
+
__decorate([
|
|
83
|
+
(0, class_transformer_1.Expose)(),
|
|
84
|
+
(0, class_validator_1.IsOptional)(),
|
|
85
|
+
(0, class_validator_1.IsArray)(),
|
|
86
|
+
(0, class_validator_1.ArrayMaxSize)(promotionRetailerScope_1.PROMOTION_RETAILER_IDS_MAX_ITEMS),
|
|
87
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
88
|
+
(0, class_validator_1.IsNotEmpty)({ each: true }),
|
|
89
|
+
__metadata("design:type", Array)
|
|
90
|
+
], UpdatePromotionRequest.prototype, "retailerIds", void 0);
|
|
81
91
|
__decorate([
|
|
82
92
|
(0, class_transformer_1.Expose)(),
|
|
83
93
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -12,6 +12,8 @@ export declare class UpdateSegmentRequest {
|
|
|
12
12
|
colorSlot?: SegmentColorSlotEnum;
|
|
13
13
|
/** Reemplaza la lista entera; `[]` deja el segmento sin cohorts. */
|
|
14
14
|
cohortIds?: string[];
|
|
15
|
+
/** @deprecated Usar `cohortIds`; se conserva para los consumidores que aún no migran. */
|
|
16
|
+
filterIds?: string[];
|
|
15
17
|
/** Reemplaza la lista entera; `[]` saca a todos los agregados a mano. */
|
|
16
18
|
memberIds?: string[];
|
|
17
19
|
reason?: string;
|
|
@@ -52,6 +52,13 @@ __decorate([
|
|
|
52
52
|
(0, class_validator_1.ArrayMaxSize)(20),
|
|
53
53
|
__metadata("design:type", Array)
|
|
54
54
|
], UpdateSegmentRequest.prototype, "cohortIds", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, class_transformer_1.Expose)(),
|
|
57
|
+
(0, class_validator_1.IsOptional)(),
|
|
58
|
+
(0, class_validator_1.IsArray)(),
|
|
59
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
60
|
+
__metadata("design:type", Array)
|
|
61
|
+
], UpdateSegmentRequest.prototype, "filterIds", void 0);
|
|
55
62
|
__decorate([
|
|
56
63
|
(0, class_transformer_1.Expose)(),
|
|
57
64
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -27,6 +27,8 @@ export interface PromotionResponse {
|
|
|
27
27
|
productCategories: ProductCategoryEnum[] | null;
|
|
28
28
|
/** `null` = alcanza a todas las gamas. */
|
|
29
29
|
tiers: ProductTierEnum[] | null;
|
|
30
|
+
/** `null` = alcanza a todas las cadenas. */
|
|
31
|
+
retailerIds: string[] | null;
|
|
30
32
|
/** `null` = alcanza a todas las tiendas. Dimensión «Tienda / canal» del alcance. */
|
|
31
33
|
storeIds: string[] | null;
|
|
32
34
|
validFrom: string | null;
|
|
@@ -13,6 +13,8 @@ export interface SegmentResponse {
|
|
|
13
13
|
colorSlot: SegmentColorSlotEnum;
|
|
14
14
|
/** Cohorts del segmento. Vacío = no alcanza a nadie por regla. */
|
|
15
15
|
cohortIds: string[];
|
|
16
|
+
/** @deprecated Mismo contenido que `cohortIds`; usar `cohortIds`. */
|
|
17
|
+
filterIds?: string[];
|
|
16
18
|
/** `retailCustomerId` agregados a mano. Ganan aunque el cliente no cumpla ningún cohort. */
|
|
17
19
|
memberIds: string[];
|
|
18
20
|
/** El catch-all implícito. No acepta cohorts ni individuos, no se archiva y solo se renombra. */
|
|
@@ -27,6 +27,7 @@ export * from './enums/SegmentMembershipReasonEnum';
|
|
|
27
27
|
export * from './enums/SegmentationRecountTriggerEnum';
|
|
28
28
|
export * from './enums/SegmentationRecountStatusEnum';
|
|
29
29
|
export * from './constants/promotionSkuBatch';
|
|
30
|
+
export * from './constants/promotionRetailerScope';
|
|
30
31
|
export * from './dtos/CreditPlan';
|
|
31
32
|
export * from './dtos/PrepaymentMinimum';
|
|
32
33
|
export * from './dtos/Financier';
|
|
@@ -45,6 +45,7 @@ __exportStar(require("./enums/SegmentationRecountTriggerEnum"), exports);
|
|
|
45
45
|
__exportStar(require("./enums/SegmentationRecountStatusEnum"), exports);
|
|
46
46
|
// Constantes
|
|
47
47
|
__exportStar(require("./constants/promotionSkuBatch"), exports);
|
|
48
|
+
__exportStar(require("./constants/promotionRetailerScope"), exports);
|
|
48
49
|
// Entity DTOs
|
|
49
50
|
__exportStar(require("./dtos/CreditPlan"), exports);
|
|
50
51
|
__exportStar(require("./dtos/PrepaymentMinimum"), exports);
|
package/package.json
CHANGED
|
@@ -120,4 +120,11 @@ export class OriginateLoanCreditRequest {
|
|
|
120
120
|
@IsOptional()
|
|
121
121
|
@IsEnum(ProductTierEnum)
|
|
122
122
|
productTier?: ProductTierEnum;
|
|
123
|
+
|
|
124
|
+
/** Cadena de la tienda que vende; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
125
|
+
@Expose()
|
|
126
|
+
@IsOptional()
|
|
127
|
+
@IsString()
|
|
128
|
+
@IsNotEmpty()
|
|
129
|
+
retailerId?: string;
|
|
123
130
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { Expose, Type } from 'class-transformer';
|
|
2
2
|
import {
|
|
3
|
+
ArrayMaxSize,
|
|
3
4
|
ArrayNotEmpty,
|
|
4
5
|
IsArray,
|
|
5
6
|
IsEnum,
|
|
6
7
|
IsInt,
|
|
7
8
|
IsISO8601,
|
|
9
|
+
IsNotEmpty,
|
|
8
10
|
IsOptional,
|
|
9
11
|
IsString,
|
|
10
12
|
ValidateNested,
|
|
11
13
|
} from 'class-validator';
|
|
14
|
+
import { PROMOTION_RETAILER_IDS_MAX_ITEMS } from '../../constants/promotionRetailerScope';
|
|
12
15
|
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
13
16
|
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
14
17
|
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
@@ -65,6 +68,15 @@ export class CreatePromotionRequest {
|
|
|
65
68
|
@IsEnum(ProductTierEnum, { each: true })
|
|
66
69
|
tiers?: ProductTierEnum[] | null;
|
|
67
70
|
|
|
71
|
+
/** Cadenas alcanzadas; ausente, `null` o vacío = todas las cadenas. */
|
|
72
|
+
@Expose()
|
|
73
|
+
@IsOptional()
|
|
74
|
+
@IsArray()
|
|
75
|
+
@ArrayMaxSize(PROMOTION_RETAILER_IDS_MAX_ITEMS)
|
|
76
|
+
@IsString({ each: true })
|
|
77
|
+
@IsNotEmpty({ each: true })
|
|
78
|
+
retailerIds?: string[] | null;
|
|
79
|
+
|
|
68
80
|
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
69
81
|
@Expose()
|
|
70
82
|
@IsOptional()
|
|
@@ -38,6 +38,13 @@ export class CreateSegmentRequest {
|
|
|
38
38
|
@ArrayMaxSize(20)
|
|
39
39
|
cohortIds?: string[];
|
|
40
40
|
|
|
41
|
+
/** @deprecated Usar `cohortIds`; se conserva para los consumidores que aún no migran. */
|
|
42
|
+
@Expose()
|
|
43
|
+
@IsOptional()
|
|
44
|
+
@IsArray()
|
|
45
|
+
@IsString({ each: true })
|
|
46
|
+
filterIds?: string[];
|
|
47
|
+
|
|
41
48
|
/**
|
|
42
49
|
* Clientes agregados a mano por `retailCustomerId`. Ganan siempre, cumplan o no un cohort.
|
|
43
50
|
* Un segmento puede nacer SOLO con esta lista, sin ningún cohort.
|
|
@@ -11,6 +11,13 @@ export class ListPromotedSkusRequest {
|
|
|
11
11
|
@IsNotEmpty()
|
|
12
12
|
storeId!: string;
|
|
13
13
|
|
|
14
|
+
/** Cadena de la tienda; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
15
|
+
@Expose()
|
|
16
|
+
@IsOptional()
|
|
17
|
+
@IsString()
|
|
18
|
+
@IsNotEmpty()
|
|
19
|
+
retailerId?: string;
|
|
20
|
+
|
|
14
21
|
/** Nivel del cliente si loan-scoring ya corrió. */
|
|
15
22
|
@Expose()
|
|
16
23
|
@IsOptional()
|
|
@@ -11,6 +11,13 @@ export class ListSkuPromotionsRequest {
|
|
|
11
11
|
@IsNotEmpty()
|
|
12
12
|
storeId!: string;
|
|
13
13
|
|
|
14
|
+
/** Cadena de la tienda; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
15
|
+
@Expose()
|
|
16
|
+
@IsOptional()
|
|
17
|
+
@IsString()
|
|
18
|
+
@IsNotEmpty()
|
|
19
|
+
retailerId?: string;
|
|
20
|
+
|
|
14
21
|
/** Nivel del cliente si loan-scoring ya corrió. */
|
|
15
22
|
@Expose()
|
|
16
23
|
@IsOptional()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Expose } from 'class-transformer';
|
|
2
|
-
import { IsArray, IsEnum, IsInt, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
|
2
|
+
import { IsArray, IsEnum, IsInt, IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
|
3
3
|
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
4
4
|
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
5
5
|
|
|
@@ -61,6 +61,13 @@ export class SimulateCreditPlanRequest {
|
|
|
61
61
|
@IsEnum(ProductTierEnum)
|
|
62
62
|
productTier?: ProductTierEnum;
|
|
63
63
|
|
|
64
|
+
/** Cadena de la tienda que cotiza; sin ella no se resuelven las promociones acotadas por cadena. */
|
|
65
|
+
@Expose()
|
|
66
|
+
@IsOptional()
|
|
67
|
+
@IsString()
|
|
68
|
+
@IsNotEmpty()
|
|
69
|
+
retailerId?: string;
|
|
70
|
+
|
|
64
71
|
/**
|
|
65
72
|
* Segmentos del cliente, los que devolvió `POST /private/segments/resolve`. Un arreglo vacío
|
|
66
73
|
* declara que el cliente no está en ninguno; ausente declara que el caller no lo consultó.
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { Expose, Type } from 'class-transformer';
|
|
2
2
|
import {
|
|
3
|
+
ArrayMaxSize,
|
|
3
4
|
ArrayNotEmpty,
|
|
4
5
|
IsArray,
|
|
5
6
|
IsEnum,
|
|
6
7
|
IsInt,
|
|
7
8
|
IsISO8601,
|
|
9
|
+
IsNotEmpty,
|
|
8
10
|
IsOptional,
|
|
9
11
|
IsString,
|
|
10
12
|
ValidateNested,
|
|
11
13
|
} from 'class-validator';
|
|
14
|
+
import { PROMOTION_RETAILER_IDS_MAX_ITEMS } from '../../constants/promotionRetailerScope';
|
|
12
15
|
import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
|
|
13
16
|
import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
|
|
14
17
|
import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
|
|
@@ -68,6 +71,15 @@ export class UpdatePromotionRequest {
|
|
|
68
71
|
@IsEnum(ProductTierEnum, { each: true })
|
|
69
72
|
tiers?: ProductTierEnum[] | null;
|
|
70
73
|
|
|
74
|
+
/** Cadenas alcanzadas; ausente, `null` o vacío = todas las cadenas. */
|
|
75
|
+
@Expose()
|
|
76
|
+
@IsOptional()
|
|
77
|
+
@IsArray()
|
|
78
|
+
@ArrayMaxSize(PROMOTION_RETAILER_IDS_MAX_ITEMS)
|
|
79
|
+
@IsString({ each: true })
|
|
80
|
+
@IsNotEmpty({ each: true })
|
|
81
|
+
retailerIds?: string[] | null;
|
|
82
|
+
|
|
71
83
|
/** Tiendas alcanzadas. `null` o ausente = todas. */
|
|
72
84
|
@Expose()
|
|
73
85
|
@IsOptional()
|
|
@@ -36,6 +36,13 @@ export class UpdateSegmentRequest {
|
|
|
36
36
|
@ArrayMaxSize(20)
|
|
37
37
|
cohortIds?: string[];
|
|
38
38
|
|
|
39
|
+
/** @deprecated Usar `cohortIds`; se conserva para los consumidores que aún no migran. */
|
|
40
|
+
@Expose()
|
|
41
|
+
@IsOptional()
|
|
42
|
+
@IsArray()
|
|
43
|
+
@IsString({ each: true })
|
|
44
|
+
filterIds?: string[];
|
|
45
|
+
|
|
39
46
|
/** Reemplaza la lista entera; `[]` saca a todos los agregados a mano. */
|
|
40
47
|
@Expose()
|
|
41
48
|
@IsOptional()
|
|
@@ -28,6 +28,8 @@ export interface PromotionResponse {
|
|
|
28
28
|
productCategories: ProductCategoryEnum[] | null;
|
|
29
29
|
/** `null` = alcanza a todas las gamas. */
|
|
30
30
|
tiers: ProductTierEnum[] | null;
|
|
31
|
+
/** `null` = alcanza a todas las cadenas. */
|
|
32
|
+
retailerIds: string[] | null;
|
|
31
33
|
/** `null` = alcanza a todas las tiendas. Dimensión «Tienda / canal» del alcance. */
|
|
32
34
|
storeIds: string[] | null;
|
|
33
35
|
validFrom: string | null;
|
|
@@ -14,6 +14,8 @@ export interface SegmentResponse {
|
|
|
14
14
|
colorSlot: SegmentColorSlotEnum;
|
|
15
15
|
/** Cohorts del segmento. Vacío = no alcanza a nadie por regla. */
|
|
16
16
|
cohortIds: string[];
|
|
17
|
+
/** @deprecated Mismo contenido que `cohortIds`; usar `cohortIds`. */
|
|
18
|
+
filterIds?: string[];
|
|
17
19
|
/** `retailCustomerId` agregados a mano. Ganan aunque el cliente no cumpla ningún cohort. */
|
|
18
20
|
memberIds: string[];
|
|
19
21
|
/** El catch-all implícito. No acepta cohorts ni individuos, no se archiva y solo se renombra. */
|