@fiado/type-kit 3.480.0 → 3.482.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 (24) hide show
  1. package/_test_/unit/loanOfferings/segmentCatalog.test.ts +54 -0
  2. package/_test_/unit/retailPromotions/constants.test.ts +2 -1
  3. package/_test_/unit/retailPromotions/salePromotionSegments.test.ts +9 -0
  4. package/bin/loanOfferings/dtos/requests/ListSegmentCatalogQuery.d.ts +6 -0
  5. package/bin/loanOfferings/dtos/requests/ListSegmentCatalogQuery.js +31 -0
  6. package/bin/loanOfferings/dtos/responses/SegmentCatalogResponse.d.ts +15 -0
  7. package/bin/loanOfferings/dtos/responses/SegmentCatalogResponse.js +2 -0
  8. package/bin/loanOfferings/index.d.ts +2 -0
  9. package/bin/loanOfferings/index.js +2 -0
  10. package/bin/retailPromotions/constants/retailPromotionsErrorHttpStatus.js +1 -0
  11. package/bin/retailPromotions/dtos/responses/SalePromotionSegmentsResponse.d.ts +11 -0
  12. package/bin/retailPromotions/dtos/responses/SalePromotionSegmentsResponse.js +2 -0
  13. package/bin/retailPromotions/enums/RetailPromotionsErrorCodeEnum.d.ts +3 -1
  14. package/bin/retailPromotions/enums/RetailPromotionsErrorCodeEnum.js +2 -0
  15. package/bin/retailPromotions/index.d.ts +1 -0
  16. package/bin/retailPromotions/index.js +1 -0
  17. package/package.json +1 -1
  18. package/src/loanOfferings/dtos/requests/ListSegmentCatalogQuery.ts +16 -0
  19. package/src/loanOfferings/dtos/responses/SegmentCatalogResponse.ts +17 -0
  20. package/src/loanOfferings/index.ts +2 -0
  21. package/src/retailPromotions/constants/retailPromotionsErrorHttpStatus.ts +1 -0
  22. package/src/retailPromotions/dtos/responses/SalePromotionSegmentsResponse.ts +12 -0
  23. package/src/retailPromotions/enums/RetailPromotionsErrorCodeEnum.ts +2 -0
  24. package/src/retailPromotions/index.ts +1 -0
@@ -0,0 +1,54 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ ListSegmentCatalogQuery,
6
+ SegmentCatalogItem,
7
+ SegmentCatalogResponse,
8
+ SegmentFilterIdEnum,
9
+ SegmentStatusEnum,
10
+ } from '../../../src/loanOfferings/index';
11
+
12
+ const errorProperties = async (raw: Record<string, unknown>): Promise<string[]> => {
13
+ const instance = plainToInstance(ListSegmentCatalogQuery, raw, { excludeExtraneousValues: true });
14
+ return (await validate(instance as object)).map((error) => error.property);
15
+ };
16
+
17
+ describe('ListSegmentCatalogQuery', () => {
18
+ it('valida con solo el tenantId', async () => {
19
+ expect(await errorProperties({ tenantId: 'tenant-1' })).toEqual([]);
20
+ });
21
+
22
+ it('conserva el filtro de estado', async () => {
23
+ const dto = plainToInstance(
24
+ ListSegmentCatalogQuery,
25
+ { tenantId: 'tenant-1', status: SegmentStatusEnum.ARCHIVED },
26
+ { excludeExtraneousValues: true },
27
+ );
28
+ expect(await validate(dto as object)).toHaveLength(0);
29
+ expect(dto.status).toBe(SegmentStatusEnum.ARCHIVED);
30
+ });
31
+
32
+ it('exige tenantId no vacío', async () => {
33
+ expect(await errorProperties({})).toEqual(['tenantId']);
34
+ expect(await errorProperties({ tenantId: '' })).toEqual(['tenantId']);
35
+ });
36
+
37
+ it('rechaza un estado fuera del enum', async () => {
38
+ expect(await errorProperties({ tenantId: 'tenant-1', status: 'DELETED' })).toEqual(['status']);
39
+ });
40
+ });
41
+
42
+ describe('SegmentCatalogResponse', () => {
43
+ it('tipa cada segmento del catálogo', () => {
44
+ const item: SegmentCatalogItem = {
45
+ segmentId: 'seg-1',
46
+ name: 'Nuevos',
47
+ status: SegmentStatusEnum.ACTIVE,
48
+ filterIds: Object.values(SegmentFilterIdEnum).slice(0, 1),
49
+ isDefault: false,
50
+ };
51
+ const response: SegmentCatalogResponse = { segments: [item] };
52
+ expect(response.segments[0].segmentId).toBe('seg-1');
53
+ });
54
+ });
@@ -43,7 +43,8 @@ describe('catálogo de errores', () => {
43
43
  expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.CODE_NOT_FOUND).toBe(404);
44
44
  expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.DISCOUNT_AFTER_QUOTE).toBe(409);
45
45
  expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.CODE_NOT_OWNED).toBe(422);
46
- expect(Object.keys(RetailPromotionsErrorCodeEnum)).toHaveLength(29);
46
+ expect(Object.keys(RetailPromotionsErrorCodeEnum)).toHaveLength(30);
47
+ expect(RETAIL_PROMOTIONS_ERROR_HTTP_STATUS.SPLIT_FINANCING_DISABLED).toBe(409);
47
48
  });
48
49
 
49
50
  it('promo de regalo y de venta mandadas en el campo equivocado son 422', () => {
@@ -0,0 +1,9 @@
1
+ import { SalePromotionSegmentItem, SalePromotionSegmentsResponse } from '../../../src/retailPromotions/index';
2
+
3
+ describe('SalePromotionSegmentsResponse', () => {
4
+ it('tipa cada segmento seleccionable en una promo de venta', () => {
5
+ const item: SalePromotionSegmentItem = { segmentId: 'seg-1', name: 'Nuevos', dependsOnFacts: true, isDefault: false };
6
+ const response: SalePromotionSegmentsResponse = { segments: [item] };
7
+ expect(response.segments).toEqual([item]);
8
+ });
9
+ });
@@ -0,0 +1,6 @@
1
+ import { SegmentStatusEnum } from '../../enums/SegmentStatusEnum';
2
+ /** Query de GET /private/segments: catálogo de segmentos de un tenant, filtrable por estado. */
3
+ export declare class ListSegmentCatalogQuery {
4
+ tenantId: string;
5
+ status?: SegmentStatusEnum;
6
+ }
@@ -0,0 +1,31 @@
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.ListSegmentCatalogQuery = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const SegmentStatusEnum_1 = require("../../enums/SegmentStatusEnum");
16
+ /** Query de GET /private/segments: catálogo de segmentos de un tenant, filtrable por estado. */
17
+ class ListSegmentCatalogQuery {
18
+ }
19
+ exports.ListSegmentCatalogQuery = ListSegmentCatalogQuery;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsString)(),
23
+ (0, class_validator_1.IsNotEmpty)(),
24
+ __metadata("design:type", String)
25
+ ], ListSegmentCatalogQuery.prototype, "tenantId", void 0);
26
+ __decorate([
27
+ (0, class_transformer_1.Expose)(),
28
+ (0, class_validator_1.IsOptional)(),
29
+ (0, class_validator_1.IsEnum)(SegmentStatusEnum_1.SegmentStatusEnum),
30
+ __metadata("design:type", String)
31
+ ], ListSegmentCatalogQuery.prototype, "status", void 0);
@@ -0,0 +1,15 @@
1
+ import { SegmentFilterIdEnum } from '../../enums/SegmentFilterIdEnum';
2
+ import { SegmentStatusEnum } from '../../enums/SegmentStatusEnum';
3
+ /** Un segmento como lo necesita un selector: sin miembros ni metadatos de edición. */
4
+ export interface SegmentCatalogItem {
5
+ segmentId: string;
6
+ name: string;
7
+ status: SegmentStatusEnum;
8
+ filterIds: SegmentFilterIdEnum[];
9
+ /** `true` solo en el catch-all, que el resolve nunca devuelve. */
10
+ isDefault: boolean;
11
+ }
12
+ /** Respuesta de GET /private/segments. */
13
+ export interface SegmentCatalogResponse {
14
+ segments: SegmentCatalogItem[];
15
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -42,6 +42,7 @@ export * from './dtos/requests/UpdateSegmentRequest';
42
42
  export * from './dtos/requests/ChangeSegmentStatusRequest';
43
43
  export * from './dtos/requests/ResolveCustomerSegmentsRequest';
44
44
  export * from './dtos/requests/ComputeAmortizationScheduleRequest';
45
+ export * from './dtos/requests/ListSegmentCatalogQuery';
45
46
  export * from './dtos/responses/CreditPlanResponse';
46
47
  export * from './dtos/responses/FinancierResponse';
47
48
  export * from './dtos/responses/RetailerCreditPlanResponse';
@@ -57,6 +58,7 @@ export * from './dtos/responses/ScopeWidePromotionsResponse';
57
58
  export * from './dtos/responses/StorePolicyResponse';
58
59
  export * from './dtos/responses/SegmentResponse';
59
60
  export * from './dtos/responses/SegmentFilterResponse';
61
+ export * from './dtos/responses/SegmentCatalogResponse';
60
62
  export * from './dtos/responses/ResolveCustomerSegmentsResponse';
61
63
  export * from './dtos/responses/AmortizationScheduleRow';
62
64
  export * from './dtos/responses/AmortizationScheduleResponse';
@@ -61,6 +61,7 @@ __exportStar(require("./dtos/requests/UpdateSegmentRequest"), exports);
61
61
  __exportStar(require("./dtos/requests/ChangeSegmentStatusRequest"), exports);
62
62
  __exportStar(require("./dtos/requests/ResolveCustomerSegmentsRequest"), exports);
63
63
  __exportStar(require("./dtos/requests/ComputeAmortizationScheduleRequest"), exports);
64
+ __exportStar(require("./dtos/requests/ListSegmentCatalogQuery"), exports);
64
65
  // Response DTOs
65
66
  __exportStar(require("./dtos/responses/CreditPlanResponse"), exports);
66
67
  __exportStar(require("./dtos/responses/FinancierResponse"), exports);
@@ -77,6 +78,7 @@ __exportStar(require("./dtos/responses/ScopeWidePromotionsResponse"), exports);
77
78
  __exportStar(require("./dtos/responses/StorePolicyResponse"), exports);
78
79
  __exportStar(require("./dtos/responses/SegmentResponse"), exports);
79
80
  __exportStar(require("./dtos/responses/SegmentFilterResponse"), exports);
81
+ __exportStar(require("./dtos/responses/SegmentCatalogResponse"), exports);
80
82
  __exportStar(require("./dtos/responses/ResolveCustomerSegmentsResponse"), exports);
81
83
  __exportStar(require("./dtos/responses/AmortizationScheduleRow"), exports);
82
84
  __exportStar(require("./dtos/responses/AmortizationScheduleResponse"), exports);
@@ -33,4 +33,5 @@ exports.RETAIL_PROMOTIONS_ERROR_HTTP_STATUS = {
33
33
  [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.SALE_PROMOTION_HOLD_CONFLICT]: 409,
34
34
  [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.INVALID_NEXT_TOKEN]: 400,
35
35
  [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.CATALOG_SKU_NOT_FOUND]: 404,
36
+ [RetailPromotionsErrorCodeEnum_1.RetailPromotionsErrorCodeEnum.SPLIT_FINANCING_DISABLED]: 409,
36
37
  };
@@ -0,0 +1,11 @@
1
+ /** Un segmento seleccionable al configurar una promo de venta. */
2
+ export interface SalePromotionSegmentItem {
3
+ segmentId: string;
4
+ name: string;
5
+ dependsOnFacts: boolean;
6
+ isDefault: boolean;
7
+ }
8
+ /** Respuesta de GET /public/segments. */
9
+ export interface SalePromotionSegmentsResponse {
10
+ segments: SalePromotionSegmentItem[];
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -42,5 +42,7 @@ export declare enum RetailPromotionsErrorCodeEnum {
42
42
  /** El token de paginación no es válido. */
43
43
  INVALID_NEXT_TOKEN = "INVALID_NEXT_TOKEN",
44
44
  /** El SKU no existe en el catálogo. */
45
- CATALOG_SKU_NOT_FOUND = "CATALOG_SKU_NOT_FOUND"
45
+ CATALOG_SKU_NOT_FOUND = "CATALOG_SKU_NOT_FOUND",
46
+ /** Con el reparto apagado no se aplican palancas de precio ni código; los regalos sí. */
47
+ SPLIT_FINANCING_DISABLED = "SPLIT_FINANCING_DISABLED"
46
48
  }
@@ -47,4 +47,6 @@ var RetailPromotionsErrorCodeEnum;
47
47
  RetailPromotionsErrorCodeEnum["INVALID_NEXT_TOKEN"] = "INVALID_NEXT_TOKEN";
48
48
  /** El SKU no existe en el catálogo. */
49
49
  RetailPromotionsErrorCodeEnum["CATALOG_SKU_NOT_FOUND"] = "CATALOG_SKU_NOT_FOUND";
50
+ /** Con el reparto apagado no se aplican palancas de precio ni código; los regalos sí. */
51
+ RetailPromotionsErrorCodeEnum["SPLIT_FINANCING_DISABLED"] = "SPLIT_FINANCING_DISABLED";
50
52
  })(RetailPromotionsErrorCodeEnum || (exports.RetailPromotionsErrorCodeEnum = RetailPromotionsErrorCodeEnum = {}));
@@ -50,3 +50,4 @@ export * from './dtos/responses/SalePromotionCrudResponses';
50
50
  export * from './dtos/responses/DiscountCodeResponses';
51
51
  export * from './dtos/responses/WizardSalePromotionResponses';
52
52
  export * from './dtos/responses/SkuSalePromotionsResponse';
53
+ export * from './dtos/responses/SalePromotionSegmentsResponse';
@@ -71,3 +71,4 @@ __exportStar(require("./dtos/responses/SalePromotionCrudResponses"), exports);
71
71
  __exportStar(require("./dtos/responses/DiscountCodeResponses"), exports);
72
72
  __exportStar(require("./dtos/responses/WizardSalePromotionResponses"), exports);
73
73
  __exportStar(require("./dtos/responses/SkuSalePromotionsResponse"), exports);
74
+ __exportStar(require("./dtos/responses/SalePromotionSegmentsResponse"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.480.0",
3
+ "version": "3.482.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,16 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator';
3
+ import { SegmentStatusEnum } from '../../enums/SegmentStatusEnum';
4
+
5
+ /** Query de GET /private/segments: catálogo de segmentos de un tenant, filtrable por estado. */
6
+ export class ListSegmentCatalogQuery {
7
+ @Expose()
8
+ @IsString()
9
+ @IsNotEmpty()
10
+ tenantId!: string;
11
+
12
+ @Expose()
13
+ @IsOptional()
14
+ @IsEnum(SegmentStatusEnum)
15
+ status?: SegmentStatusEnum;
16
+ }
@@ -0,0 +1,17 @@
1
+ import { SegmentFilterIdEnum } from '../../enums/SegmentFilterIdEnum';
2
+ import { SegmentStatusEnum } from '../../enums/SegmentStatusEnum';
3
+
4
+ /** Un segmento como lo necesita un selector: sin miembros ni metadatos de edición. */
5
+ export interface SegmentCatalogItem {
6
+ segmentId: string;
7
+ name: string;
8
+ status: SegmentStatusEnum;
9
+ filterIds: SegmentFilterIdEnum[];
10
+ /** `true` solo en el catch-all, que el resolve nunca devuelve. */
11
+ isDefault: boolean;
12
+ }
13
+
14
+ /** Respuesta de GET /private/segments. */
15
+ export interface SegmentCatalogResponse {
16
+ segments: SegmentCatalogItem[];
17
+ }
@@ -47,6 +47,7 @@ export * from './dtos/requests/UpdateSegmentRequest';
47
47
  export * from './dtos/requests/ChangeSegmentStatusRequest';
48
48
  export * from './dtos/requests/ResolveCustomerSegmentsRequest';
49
49
  export * from './dtos/requests/ComputeAmortizationScheduleRequest';
50
+ export * from './dtos/requests/ListSegmentCatalogQuery';
50
51
 
51
52
  // Response DTOs
52
53
  export * from './dtos/responses/CreditPlanResponse';
@@ -64,6 +65,7 @@ export * from './dtos/responses/ScopeWidePromotionsResponse';
64
65
  export * from './dtos/responses/StorePolicyResponse';
65
66
  export * from './dtos/responses/SegmentResponse';
66
67
  export * from './dtos/responses/SegmentFilterResponse';
68
+ export * from './dtos/responses/SegmentCatalogResponse';
67
69
  export * from './dtos/responses/ResolveCustomerSegmentsResponse';
68
70
  export * from './dtos/responses/AmortizationScheduleRow';
69
71
  export * from './dtos/responses/AmortizationScheduleResponse';
@@ -31,4 +31,5 @@ export const RETAIL_PROMOTIONS_ERROR_HTTP_STATUS: Readonly<Record<C, 400 | 403 |
31
31
  [C.SALE_PROMOTION_HOLD_CONFLICT]: 409,
32
32
  [C.INVALID_NEXT_TOKEN]: 400,
33
33
  [C.CATALOG_SKU_NOT_FOUND]: 404,
34
+ [C.SPLIT_FINANCING_DISABLED]: 409,
34
35
  };
@@ -0,0 +1,12 @@
1
+ /** Un segmento seleccionable al configurar una promo de venta. */
2
+ export interface SalePromotionSegmentItem {
3
+ segmentId: string;
4
+ name: string;
5
+ dependsOnFacts: boolean;
6
+ isDefault: boolean;
7
+ }
8
+
9
+ /** Respuesta de GET /public/segments. */
10
+ export interface SalePromotionSegmentsResponse {
11
+ segments: SalePromotionSegmentItem[];
12
+ }
@@ -43,4 +43,6 @@ export enum RetailPromotionsErrorCodeEnum {
43
43
  INVALID_NEXT_TOKEN = 'INVALID_NEXT_TOKEN',
44
44
  /** El SKU no existe en el catálogo. */
45
45
  CATALOG_SKU_NOT_FOUND = 'CATALOG_SKU_NOT_FOUND',
46
+ /** Con el reparto apagado no se aplican palancas de precio ni código; los regalos sí. */
47
+ SPLIT_FINANCING_DISABLED = 'SPLIT_FINANCING_DISABLED',
46
48
  }
@@ -59,3 +59,4 @@ export * from './dtos/responses/SalePromotionCrudResponses';
59
59
  export * from './dtos/responses/DiscountCodeResponses';
60
60
  export * from './dtos/responses/WizardSalePromotionResponses';
61
61
  export * from './dtos/responses/SkuSalePromotionsResponse';
62
+ export * from './dtos/responses/SalePromotionSegmentsResponse';