@fiado/type-kit 3.373.0 → 3.375.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 (34) hide show
  1. package/_test_/unit/loanOfferings/storePolicyRequests.test.ts +117 -0
  2. package/bin/collection/dtos/RegisterCollectibleResponse.d.ts +9 -0
  3. package/bin/collection/dtos/RegisterCollectibleResponse.js +29 -0
  4. package/bin/collection/enums/RegisterCollectibleStatus.d.ts +6 -0
  5. package/bin/collection/enums/RegisterCollectibleStatus.js +10 -0
  6. package/bin/collection/index.d.ts +2 -0
  7. package/bin/collection/index.js +2 -0
  8. package/bin/loanOfferings/dtos/requests/ChangeStorePolicyStatusRequest.d.ts +10 -0
  9. package/bin/loanOfferings/dtos/requests/ChangeStorePolicyStatusRequest.js +35 -0
  10. package/bin/loanOfferings/dtos/requests/CreateStorePolicyRequest.d.ts +40 -0
  11. package/bin/loanOfferings/dtos/requests/CreateStorePolicyRequest.js +169 -0
  12. package/bin/loanOfferings/dtos/requests/UpdateStorePolicyRequest.d.ts +21 -0
  13. package/bin/loanOfferings/dtos/requests/UpdateStorePolicyRequest.js +109 -0
  14. package/bin/loanOfferings/dtos/responses/SimulationResultResponse.d.ts +6 -0
  15. package/bin/loanOfferings/dtos/responses/StorePolicyResponse.d.ts +58 -0
  16. package/bin/loanOfferings/dtos/responses/StorePolicyResponse.js +2 -0
  17. package/bin/loanOfferings/enums/StorePolicyPhaseEnum.d.ts +11 -0
  18. package/bin/loanOfferings/enums/StorePolicyPhaseEnum.js +15 -0
  19. package/bin/loanOfferings/enums/StorePolicyStatusEnum.d.ts +11 -0
  20. package/bin/loanOfferings/enums/StorePolicyStatusEnum.js +15 -0
  21. package/bin/loanOfferings/index.d.ts +6 -0
  22. package/bin/loanOfferings/index.js +6 -0
  23. package/package.json +1 -1
  24. package/src/collection/dtos/RegisterCollectibleResponse.ts +12 -0
  25. package/src/collection/enums/RegisterCollectibleStatus.ts +6 -0
  26. package/src/collection/index.ts +2 -0
  27. package/src/loanOfferings/dtos/requests/ChangeStorePolicyStatusRequest.ts +20 -0
  28. package/src/loanOfferings/dtos/requests/CreateStorePolicyRequest.ts +156 -0
  29. package/src/loanOfferings/dtos/requests/UpdateStorePolicyRequest.ts +94 -0
  30. package/src/loanOfferings/dtos/responses/SimulationResultResponse.ts +6 -0
  31. package/src/loanOfferings/dtos/responses/StorePolicyResponse.ts +63 -0
  32. package/src/loanOfferings/enums/StorePolicyPhaseEnum.ts +11 -0
  33. package/src/loanOfferings/enums/StorePolicyStatusEnum.ts +11 -0
  34. package/src/loanOfferings/index.ts +6 -0
@@ -0,0 +1,117 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ ChangeStorePolicyStatusRequest,
6
+ CreateStorePolicyRequest,
7
+ CreditPlanLevelEnum,
8
+ StorePolicyHardeningDto,
9
+ StorePolicyStatusEnum,
10
+ UpdateStorePolicyRequest,
11
+ } from '../../../src/loanOfferings/index';
12
+
13
+ /** El alta mínima válida: una política que endurece el piso de SCI. */
14
+ const base = {
15
+ name: 'Freno de riesgo Norte',
16
+ hardening: { minSciScore: 70 },
17
+ };
18
+
19
+ type StorePolicyRequestClass =
20
+ | typeof CreateStorePolicyRequest
21
+ | typeof UpdateStorePolicyRequest
22
+ | typeof ChangeStorePolicyStatusRequest;
23
+
24
+ const errorProperties = async (
25
+ raw: Record<string, unknown>,
26
+ dtoClass: StorePolicyRequestClass = CreateStorePolicyRequest,
27
+ ): Promise<string[]> => {
28
+ const instance = plainToInstance(dtoClass, raw, { excludeExtraneousValues: true });
29
+ return (await validate(instance as object)).map((error) => error.property);
30
+ };
31
+
32
+ describe('CreateStorePolicyRequest', () => {
33
+ it('valida con los obligatorios y tipa el grupo de endurecimiento', async () => {
34
+ const dto = plainToInstance(CreateStorePolicyRequest, base, { excludeExtraneousValues: true });
35
+ expect(await validate(dto as object)).toHaveLength(0);
36
+ expect(dto.hardening).toBeInstanceOf(StorePolicyHardeningDto);
37
+ expect(dto.hardening?.minSciScore).toBe(70);
38
+ });
39
+
40
+ it('conserva cada campo del alcance: sin @Expose() la exclusión los borraría', async () => {
41
+ const dto = plainToInstance(
42
+ CreateStorePolicyRequest,
43
+ {
44
+ ...base,
45
+ description: 'Sube el piso de score en las tiendas del norte',
46
+ easing: { tnaAnnual: 1.9 },
47
+ suspended: false,
48
+ allowedSkus: ['SKU-1'],
49
+ storeIds: ['ST-04'],
50
+ targetLevels: ['SILVER'],
51
+ targetSkus: ['SKU-1'],
52
+ validFrom: '2026-09-01',
53
+ validUntil: '2026-12-31',
54
+ reason: 'Cartera vencida por arriba del objetivo',
55
+ },
56
+ { excludeExtraneousValues: true },
57
+ );
58
+ expect(await validate(dto as object)).toHaveLength(0);
59
+ expect(dto.targetLevels).toEqual([CreditPlanLevelEnum.SILVER]);
60
+ expect(dto.easing?.tnaAnnual).toBe(1.9);
61
+ expect(dto.storeIds).toEqual(['ST-04']);
62
+ expect(dto.reason).toBe('Cartera vencida por arriba del objetivo');
63
+ });
64
+
65
+ it('exige el nombre', async () => {
66
+ expect(await errorProperties({ hardening: { minSciScore: 70 } })).toContain('name');
67
+ });
68
+
69
+ it('rechaza una palanca fuera de su cota', async () => {
70
+ expect(await errorProperties({ ...base, hardening: { minSciScore: 140 } })).toContain(
71
+ 'hardening',
72
+ );
73
+ expect(await errorProperties({ ...base, easing: { minDownPaymentPct: 1.4 } })).toContain(
74
+ 'easing',
75
+ );
76
+ });
77
+
78
+ it('rechaza una fecha que no es ISO 8601', async () => {
79
+ expect(await errorProperties({ ...base, validFrom: 'mañana' })).toContain('validFrom');
80
+ });
81
+
82
+ it('exige al menos un elemento en cada lista de alcance', async () => {
83
+ expect(await errorProperties({ ...base, storeIds: [] })).toContain('storeIds');
84
+ expect(await errorProperties({ ...base, targetLevels: [] })).toContain('targetLevels');
85
+ });
86
+ });
87
+
88
+ describe('UpdateStorePolicyRequest', () => {
89
+ it('el parche vacío es válido: no exige el nombre', async () => {
90
+ expect(await errorProperties({}, UpdateStorePolicyRequest)).toHaveLength(0);
91
+ });
92
+
93
+ it('sigue validando las palancas que sí vienen', async () => {
94
+ expect(
95
+ await errorProperties({ hardening: { tnaAnnualFloor: 9 } }, UpdateStorePolicyRequest),
96
+ ).toContain('hardening');
97
+ });
98
+ });
99
+
100
+ describe('ChangeStorePolicyStatusRequest', () => {
101
+ it('acepta un estado del enum con su motivo', async () => {
102
+ const dto = plainToInstance(
103
+ ChangeStorePolicyStatusRequest,
104
+ { status: 'PAUSED', reason: 'Revisión de riesgo' },
105
+ { excludeExtraneousValues: true },
106
+ );
107
+ expect(await validate(dto as object)).toHaveLength(0);
108
+ expect(dto.status).toBe(StorePolicyStatusEnum.PAUSED);
109
+ expect(dto.reason).toBe('Revisión de riesgo');
110
+ });
111
+
112
+ it('rechaza un estado que no existe', async () => {
113
+ expect(await errorProperties({ status: 'ARCHIVED' }, ChangeStorePolicyStatusRequest)).toContain(
114
+ 'status',
115
+ );
116
+ });
117
+ });
@@ -0,0 +1,9 @@
1
+ import { RegisterCollectibleStatus } from '../enums/RegisterCollectibleStatus';
2
+ /**
3
+ * Resultado de dar de alta un cargo cobrable. El `intentId` es la referencia con la que el motor
4
+ * sigue ese cargo, y es la misma tanto si el alta es nueva como si el cargo ya estaba registrado.
5
+ */
6
+ export declare class RegisterCollectibleResponse {
7
+ status: RegisterCollectibleStatus;
8
+ intentId: string;
9
+ }
@@ -0,0 +1,29 @@
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.RegisterCollectibleResponse = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const RegisterCollectibleStatus_1 = require("../enums/RegisterCollectibleStatus");
15
+ /**
16
+ * Resultado de dar de alta un cargo cobrable. El `intentId` es la referencia con la que el motor
17
+ * sigue ese cargo, y es la misma tanto si el alta es nueva como si el cargo ya estaba registrado.
18
+ */
19
+ class RegisterCollectibleResponse {
20
+ }
21
+ exports.RegisterCollectibleResponse = RegisterCollectibleResponse;
22
+ __decorate([
23
+ (0, class_validator_1.IsEnum)(RegisterCollectibleStatus_1.RegisterCollectibleStatus),
24
+ __metadata("design:type", String)
25
+ ], RegisterCollectibleResponse.prototype, "status", void 0);
26
+ __decorate([
27
+ (0, class_validator_1.IsString)(),
28
+ __metadata("design:type", String)
29
+ ], RegisterCollectibleResponse.prototype, "intentId", void 0);
@@ -0,0 +1,6 @@
1
+ export declare enum RegisterCollectibleStatus {
2
+ /** El cargo se indexó por primera vez y ya entra en los reintentos del motor. */
3
+ REGISTERED = "REGISTERED",
4
+ /** Ese cargo ya estaba dado de alta. Volver a registrarlo es un no-op. */
5
+ ALREADY_REGISTERED = "ALREADY_REGISTERED"
6
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RegisterCollectibleStatus = void 0;
4
+ var RegisterCollectibleStatus;
5
+ (function (RegisterCollectibleStatus) {
6
+ /** El cargo se indexó por primera vez y ya entra en los reintentos del motor. */
7
+ RegisterCollectibleStatus["REGISTERED"] = "REGISTERED";
8
+ /** Ese cargo ya estaba dado de alta. Volver a registrarlo es un no-op. */
9
+ RegisterCollectibleStatus["ALREADY_REGISTERED"] = "ALREADY_REGISTERED";
10
+ })(RegisterCollectibleStatus || (exports.RegisterCollectibleStatus = RegisterCollectibleStatus = {}));
@@ -3,6 +3,7 @@ export * from './enums/CollectionState';
3
3
  export * from './enums/SagaStep';
4
4
  export * from './enums/CollectionResultStatus';
5
5
  export * from './enums/DeregisterChargeStatus';
6
+ export * from './enums/RegisterCollectibleStatus';
6
7
  export * from './dtos/PendingChargeDto';
7
8
  export * from './dtos/CollectRequest';
8
9
  export * from './dtos/CollectResponse';
@@ -16,6 +17,7 @@ export * from './dtos/CollectionProductConfigDto';
16
17
  export * from './dtos/UpsertProductConfigRequest';
17
18
  export * from './dtos/ApplyCollectionResultRequest';
18
19
  export * from './dtos/DeregisterChargeResponse';
20
+ export * from './dtos/RegisterCollectibleResponse';
19
21
  export * from './dtos/ResolvePendingChargesRequest';
20
22
  export * from './dtos/MoneyInEvent';
21
23
  export * from './dtos/CollectionIntentSummaryDto';
@@ -20,6 +20,7 @@ __exportStar(require("./enums/CollectionState"), exports);
20
20
  __exportStar(require("./enums/SagaStep"), exports);
21
21
  __exportStar(require("./enums/CollectionResultStatus"), exports);
22
22
  __exportStar(require("./enums/DeregisterChargeStatus"), exports);
23
+ __exportStar(require("./enums/RegisterCollectibleStatus"), exports);
23
24
  // DTOs
24
25
  __exportStar(require("./dtos/PendingChargeDto"), exports);
25
26
  __exportStar(require("./dtos/CollectRequest"), exports);
@@ -34,6 +35,7 @@ __exportStar(require("./dtos/CollectionProductConfigDto"), exports);
34
35
  __exportStar(require("./dtos/UpsertProductConfigRequest"), exports);
35
36
  __exportStar(require("./dtos/ApplyCollectionResultRequest"), exports);
36
37
  __exportStar(require("./dtos/DeregisterChargeResponse"), exports);
38
+ __exportStar(require("./dtos/RegisterCollectibleResponse"), exports);
37
39
  __exportStar(require("./dtos/ResolvePendingChargesRequest"), exports);
38
40
  __exportStar(require("./dtos/MoneyInEvent"), exports);
39
41
  // DTOs — backoffice de monitoreo
@@ -0,0 +1,10 @@
1
+ import { StorePolicyStatusEnum } from '../../enums/StorePolicyStatusEnum';
2
+ /**
3
+ * Body de PUT /store-policies/:policyId/status — publicar, pausar, reanudar o vencer.
4
+ * Transiciones válidas: `DRAFT→PUBLISHED`, `PUBLISHED⇄PAUSED`, `PUBLISHED|PAUSED→EXPIRED`.
5
+ * `reason` acompaña el cambio y queda en la bitácora.
6
+ */
7
+ export declare class ChangeStorePolicyStatusRequest {
8
+ status: StorePolicyStatusEnum;
9
+ reason?: string;
10
+ }
@@ -0,0 +1,35 @@
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.ChangeStorePolicyStatusRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const StorePolicyStatusEnum_1 = require("../../enums/StorePolicyStatusEnum");
16
+ /**
17
+ * Body de PUT /store-policies/:policyId/status — publicar, pausar, reanudar o vencer.
18
+ * Transiciones válidas: `DRAFT→PUBLISHED`, `PUBLISHED⇄PAUSED`, `PUBLISHED|PAUSED→EXPIRED`.
19
+ * `reason` acompaña el cambio y queda en la bitácora.
20
+ */
21
+ class ChangeStorePolicyStatusRequest {
22
+ }
23
+ exports.ChangeStorePolicyStatusRequest = ChangeStorePolicyStatusRequest;
24
+ __decorate([
25
+ (0, class_transformer_1.Expose)(),
26
+ (0, class_validator_1.IsEnum)(StorePolicyStatusEnum_1.StorePolicyStatusEnum),
27
+ __metadata("design:type", String)
28
+ ], ChangeStorePolicyStatusRequest.prototype, "status", void 0);
29
+ __decorate([
30
+ (0, class_transformer_1.Expose)(),
31
+ (0, class_validator_1.IsOptional)(),
32
+ (0, class_validator_1.IsString)(),
33
+ (0, class_validator_1.MaxLength)(280),
34
+ __metadata("design:type", String)
35
+ ], ChangeStorePolicyStatusRequest.prototype, "reason", void 0);
@@ -0,0 +1,40 @@
1
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
2
+ /** Grupo de palancas que ENDURECEN las condiciones del plan. */
3
+ export declare class StorePolicyHardeningDto {
4
+ /** Piso de SCI; es compuerta de elegibilidad, no término del crédito. */
5
+ minSciScore?: number;
6
+ minDownPaymentPct?: number;
7
+ /** Piso de TNA en decimal: la tasa no puede bajar de ahí. */
8
+ tnaAnnualFloor?: number;
9
+ maxFinancedAmountCents?: number;
10
+ }
11
+ /** Grupo de palancas que AFLOJAN las condiciones del plan. */
12
+ export declare class StorePolicyEasingDto {
13
+ minDownPaymentPct?: number;
14
+ tnaAnnual?: number;
15
+ maxFinancedAmountCents?: number;
16
+ }
17
+ /**
18
+ * Body de POST /store-policies — alta de una política especial de tienda.
19
+ * Nace en `DRAFT`: el estado, `policyId`, `version` y la auditoría los asigna el lambda y NO viajan
20
+ * en el request. Que haya al menos una palanca o compuerta lo valida el lambda.
21
+ */
22
+ export declare class CreateStorePolicyRequest {
23
+ name: string;
24
+ description?: string;
25
+ hardening?: StorePolicyHardeningDto;
26
+ easing?: StorePolicyEasingDto;
27
+ /** Compuerta que niega la venta en las tiendas alcanzadas. */
28
+ suspended?: boolean;
29
+ /** Compuerta: SKUs habilitados. Ausente = sin restricción. */
30
+ allowedSkus?: string[];
31
+ /** Alcance: tiendas alcanzadas. Ausente = toda la red. */
32
+ storeIds?: string[];
33
+ /** Alcance: niveles alcanzados. Ausente = todos los niveles. */
34
+ targetLevels?: CreditPlanLevelEnum[];
35
+ /** Alcance: SKUs alcanzados. Ausente = todos los productos. */
36
+ targetSkus?: string[];
37
+ validFrom?: string;
38
+ validUntil?: string;
39
+ reason?: string;
40
+ }
@@ -0,0 +1,169 @@
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.CreateStorePolicyRequest = exports.StorePolicyEasingDto = exports.StorePolicyHardeningDto = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const CreditPlanLevelEnum_1 = require("../../enums/CreditPlanLevelEnum");
16
+ /** Grupo de palancas que ENDURECEN las condiciones del plan. */
17
+ class StorePolicyHardeningDto {
18
+ }
19
+ exports.StorePolicyHardeningDto = StorePolicyHardeningDto;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsOptional)(),
23
+ (0, class_validator_1.IsInt)(),
24
+ (0, class_validator_1.Min)(0),
25
+ (0, class_validator_1.Max)(100),
26
+ __metadata("design:type", Number)
27
+ ], StorePolicyHardeningDto.prototype, "minSciScore", void 0);
28
+ __decorate([
29
+ (0, class_transformer_1.Expose)(),
30
+ (0, class_validator_1.IsOptional)(),
31
+ (0, class_validator_1.IsNumber)(),
32
+ (0, class_validator_1.Min)(0),
33
+ (0, class_validator_1.Max)(1),
34
+ __metadata("design:type", Number)
35
+ ], StorePolicyHardeningDto.prototype, "minDownPaymentPct", void 0);
36
+ __decorate([
37
+ (0, class_transformer_1.Expose)(),
38
+ (0, class_validator_1.IsOptional)(),
39
+ (0, class_validator_1.IsNumber)(),
40
+ (0, class_validator_1.Min)(0),
41
+ (0, class_validator_1.Max)(5),
42
+ __metadata("design:type", Number)
43
+ ], StorePolicyHardeningDto.prototype, "tnaAnnualFloor", void 0);
44
+ __decorate([
45
+ (0, class_transformer_1.Expose)(),
46
+ (0, class_validator_1.IsOptional)(),
47
+ (0, class_validator_1.IsInt)(),
48
+ (0, class_validator_1.Min)(0),
49
+ __metadata("design:type", Number)
50
+ ], StorePolicyHardeningDto.prototype, "maxFinancedAmountCents", void 0);
51
+ /** Grupo de palancas que AFLOJAN las condiciones del plan. */
52
+ class StorePolicyEasingDto {
53
+ }
54
+ exports.StorePolicyEasingDto = StorePolicyEasingDto;
55
+ __decorate([
56
+ (0, class_transformer_1.Expose)(),
57
+ (0, class_validator_1.IsOptional)(),
58
+ (0, class_validator_1.IsNumber)(),
59
+ (0, class_validator_1.Min)(0),
60
+ (0, class_validator_1.Max)(1),
61
+ __metadata("design:type", Number)
62
+ ], StorePolicyEasingDto.prototype, "minDownPaymentPct", void 0);
63
+ __decorate([
64
+ (0, class_transformer_1.Expose)(),
65
+ (0, class_validator_1.IsOptional)(),
66
+ (0, class_validator_1.IsNumber)(),
67
+ (0, class_validator_1.Min)(0),
68
+ (0, class_validator_1.Max)(5),
69
+ __metadata("design:type", Number)
70
+ ], StorePolicyEasingDto.prototype, "tnaAnnual", void 0);
71
+ __decorate([
72
+ (0, class_transformer_1.Expose)(),
73
+ (0, class_validator_1.IsOptional)(),
74
+ (0, class_validator_1.IsInt)(),
75
+ (0, class_validator_1.Min)(0),
76
+ __metadata("design:type", Number)
77
+ ], StorePolicyEasingDto.prototype, "maxFinancedAmountCents", void 0);
78
+ /**
79
+ * Body de POST /store-policies — alta de una política especial de tienda.
80
+ * Nace en `DRAFT`: el estado, `policyId`, `version` y la auditoría los asigna el lambda y NO viajan
81
+ * en el request. Que haya al menos una palanca o compuerta lo valida el lambda.
82
+ */
83
+ class CreateStorePolicyRequest {
84
+ }
85
+ exports.CreateStorePolicyRequest = CreateStorePolicyRequest;
86
+ __decorate([
87
+ (0, class_transformer_1.Expose)(),
88
+ (0, class_validator_1.IsString)(),
89
+ (0, class_validator_1.MaxLength)(120),
90
+ __metadata("design:type", String)
91
+ ], CreateStorePolicyRequest.prototype, "name", void 0);
92
+ __decorate([
93
+ (0, class_transformer_1.Expose)(),
94
+ (0, class_validator_1.IsOptional)(),
95
+ (0, class_validator_1.IsString)(),
96
+ (0, class_validator_1.MaxLength)(500),
97
+ __metadata("design:type", String)
98
+ ], CreateStorePolicyRequest.prototype, "description", void 0);
99
+ __decorate([
100
+ (0, class_transformer_1.Expose)(),
101
+ (0, class_validator_1.IsOptional)(),
102
+ (0, class_validator_1.ValidateNested)(),
103
+ (0, class_transformer_1.Type)(() => StorePolicyHardeningDto),
104
+ __metadata("design:type", StorePolicyHardeningDto)
105
+ ], CreateStorePolicyRequest.prototype, "hardening", void 0);
106
+ __decorate([
107
+ (0, class_transformer_1.Expose)(),
108
+ (0, class_validator_1.IsOptional)(),
109
+ (0, class_validator_1.ValidateNested)(),
110
+ (0, class_transformer_1.Type)(() => StorePolicyEasingDto),
111
+ __metadata("design:type", StorePolicyEasingDto)
112
+ ], CreateStorePolicyRequest.prototype, "easing", void 0);
113
+ __decorate([
114
+ (0, class_transformer_1.Expose)(),
115
+ (0, class_validator_1.IsOptional)(),
116
+ (0, class_validator_1.IsBoolean)(),
117
+ __metadata("design:type", Boolean)
118
+ ], CreateStorePolicyRequest.prototype, "suspended", void 0);
119
+ __decorate([
120
+ (0, class_transformer_1.Expose)(),
121
+ (0, class_validator_1.IsOptional)(),
122
+ (0, class_validator_1.IsArray)(),
123
+ (0, class_validator_1.ArrayNotEmpty)(),
124
+ (0, class_validator_1.IsString)({ each: true }),
125
+ __metadata("design:type", Array)
126
+ ], CreateStorePolicyRequest.prototype, "allowedSkus", void 0);
127
+ __decorate([
128
+ (0, class_transformer_1.Expose)(),
129
+ (0, class_validator_1.IsOptional)(),
130
+ (0, class_validator_1.IsArray)(),
131
+ (0, class_validator_1.ArrayNotEmpty)(),
132
+ (0, class_validator_1.IsString)({ each: true }),
133
+ __metadata("design:type", Array)
134
+ ], CreateStorePolicyRequest.prototype, "storeIds", void 0);
135
+ __decorate([
136
+ (0, class_transformer_1.Expose)(),
137
+ (0, class_validator_1.IsOptional)(),
138
+ (0, class_validator_1.IsArray)(),
139
+ (0, class_validator_1.ArrayNotEmpty)(),
140
+ (0, class_validator_1.IsEnum)(CreditPlanLevelEnum_1.CreditPlanLevelEnum, { each: true }),
141
+ __metadata("design:type", Array)
142
+ ], CreateStorePolicyRequest.prototype, "targetLevels", void 0);
143
+ __decorate([
144
+ (0, class_transformer_1.Expose)(),
145
+ (0, class_validator_1.IsOptional)(),
146
+ (0, class_validator_1.IsArray)(),
147
+ (0, class_validator_1.ArrayNotEmpty)(),
148
+ (0, class_validator_1.IsString)({ each: true }),
149
+ __metadata("design:type", Array)
150
+ ], CreateStorePolicyRequest.prototype, "targetSkus", void 0);
151
+ __decorate([
152
+ (0, class_transformer_1.Expose)(),
153
+ (0, class_validator_1.IsOptional)(),
154
+ (0, class_validator_1.IsISO8601)(),
155
+ __metadata("design:type", String)
156
+ ], CreateStorePolicyRequest.prototype, "validFrom", void 0);
157
+ __decorate([
158
+ (0, class_transformer_1.Expose)(),
159
+ (0, class_validator_1.IsOptional)(),
160
+ (0, class_validator_1.IsISO8601)(),
161
+ __metadata("design:type", String)
162
+ ], CreateStorePolicyRequest.prototype, "validUntil", void 0);
163
+ __decorate([
164
+ (0, class_transformer_1.Expose)(),
165
+ (0, class_validator_1.IsOptional)(),
166
+ (0, class_validator_1.IsString)(),
167
+ (0, class_validator_1.MaxLength)(280),
168
+ __metadata("design:type", String)
169
+ ], CreateStorePolicyRequest.prototype, "reason", void 0);
@@ -0,0 +1,21 @@
1
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
2
+ import { StorePolicyEasingDto, StorePolicyHardeningDto } from './CreateStorePolicyRequest';
3
+ /**
4
+ * Body de PUT /store-policies/:policyId — edición parcial (todos los campos opcionales).
5
+ * Sube `version`. El cambio de estado va por su endpoint dedicado. Cada grupo de palancas se
6
+ * reemplaza entero cuando viene, no se mergea clave a clave.
7
+ */
8
+ export declare class UpdateStorePolicyRequest {
9
+ name?: string;
10
+ description?: string;
11
+ hardening?: StorePolicyHardeningDto;
12
+ easing?: StorePolicyEasingDto;
13
+ suspended?: boolean;
14
+ allowedSkus?: string[];
15
+ storeIds?: string[];
16
+ targetLevels?: CreditPlanLevelEnum[];
17
+ targetSkus?: string[];
18
+ validFrom?: string;
19
+ validUntil?: string;
20
+ reason?: string;
21
+ }
@@ -0,0 +1,109 @@
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.UpdateStorePolicyRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const CreditPlanLevelEnum_1 = require("../../enums/CreditPlanLevelEnum");
16
+ const CreateStorePolicyRequest_1 = require("./CreateStorePolicyRequest");
17
+ /**
18
+ * Body de PUT /store-policies/:policyId — edición parcial (todos los campos opcionales).
19
+ * Sube `version`. El cambio de estado va por su endpoint dedicado. Cada grupo de palancas se
20
+ * reemplaza entero cuando viene, no se mergea clave a clave.
21
+ */
22
+ class UpdateStorePolicyRequest {
23
+ }
24
+ exports.UpdateStorePolicyRequest = UpdateStorePolicyRequest;
25
+ __decorate([
26
+ (0, class_transformer_1.Expose)(),
27
+ (0, class_validator_1.IsOptional)(),
28
+ (0, class_validator_1.IsString)(),
29
+ (0, class_validator_1.MaxLength)(120),
30
+ __metadata("design:type", String)
31
+ ], UpdateStorePolicyRequest.prototype, "name", void 0);
32
+ __decorate([
33
+ (0, class_transformer_1.Expose)(),
34
+ (0, class_validator_1.IsOptional)(),
35
+ (0, class_validator_1.IsString)(),
36
+ (0, class_validator_1.MaxLength)(500),
37
+ __metadata("design:type", String)
38
+ ], UpdateStorePolicyRequest.prototype, "description", void 0);
39
+ __decorate([
40
+ (0, class_transformer_1.Expose)(),
41
+ (0, class_validator_1.IsOptional)(),
42
+ (0, class_validator_1.ValidateNested)(),
43
+ (0, class_transformer_1.Type)(() => CreateStorePolicyRequest_1.StorePolicyHardeningDto),
44
+ __metadata("design:type", CreateStorePolicyRequest_1.StorePolicyHardeningDto)
45
+ ], UpdateStorePolicyRequest.prototype, "hardening", void 0);
46
+ __decorate([
47
+ (0, class_transformer_1.Expose)(),
48
+ (0, class_validator_1.IsOptional)(),
49
+ (0, class_validator_1.ValidateNested)(),
50
+ (0, class_transformer_1.Type)(() => CreateStorePolicyRequest_1.StorePolicyEasingDto),
51
+ __metadata("design:type", CreateStorePolicyRequest_1.StorePolicyEasingDto)
52
+ ], UpdateStorePolicyRequest.prototype, "easing", void 0);
53
+ __decorate([
54
+ (0, class_transformer_1.Expose)(),
55
+ (0, class_validator_1.IsOptional)(),
56
+ (0, class_validator_1.IsBoolean)(),
57
+ __metadata("design:type", Boolean)
58
+ ], UpdateStorePolicyRequest.prototype, "suspended", void 0);
59
+ __decorate([
60
+ (0, class_transformer_1.Expose)(),
61
+ (0, class_validator_1.IsOptional)(),
62
+ (0, class_validator_1.IsArray)(),
63
+ (0, class_validator_1.ArrayNotEmpty)(),
64
+ (0, class_validator_1.IsString)({ each: true }),
65
+ __metadata("design:type", Array)
66
+ ], UpdateStorePolicyRequest.prototype, "allowedSkus", void 0);
67
+ __decorate([
68
+ (0, class_transformer_1.Expose)(),
69
+ (0, class_validator_1.IsOptional)(),
70
+ (0, class_validator_1.IsArray)(),
71
+ (0, class_validator_1.ArrayNotEmpty)(),
72
+ (0, class_validator_1.IsString)({ each: true }),
73
+ __metadata("design:type", Array)
74
+ ], UpdateStorePolicyRequest.prototype, "storeIds", void 0);
75
+ __decorate([
76
+ (0, class_transformer_1.Expose)(),
77
+ (0, class_validator_1.IsOptional)(),
78
+ (0, class_validator_1.IsArray)(),
79
+ (0, class_validator_1.ArrayNotEmpty)(),
80
+ (0, class_validator_1.IsEnum)(CreditPlanLevelEnum_1.CreditPlanLevelEnum, { each: true }),
81
+ __metadata("design:type", Array)
82
+ ], UpdateStorePolicyRequest.prototype, "targetLevels", void 0);
83
+ __decorate([
84
+ (0, class_transformer_1.Expose)(),
85
+ (0, class_validator_1.IsOptional)(),
86
+ (0, class_validator_1.IsArray)(),
87
+ (0, class_validator_1.ArrayNotEmpty)(),
88
+ (0, class_validator_1.IsString)({ each: true }),
89
+ __metadata("design:type", Array)
90
+ ], UpdateStorePolicyRequest.prototype, "targetSkus", void 0);
91
+ __decorate([
92
+ (0, class_transformer_1.Expose)(),
93
+ (0, class_validator_1.IsOptional)(),
94
+ (0, class_validator_1.IsISO8601)(),
95
+ __metadata("design:type", String)
96
+ ], UpdateStorePolicyRequest.prototype, "validFrom", void 0);
97
+ __decorate([
98
+ (0, class_transformer_1.Expose)(),
99
+ (0, class_validator_1.IsOptional)(),
100
+ (0, class_validator_1.IsISO8601)(),
101
+ __metadata("design:type", String)
102
+ ], UpdateStorePolicyRequest.prototype, "validUntil", void 0);
103
+ __decorate([
104
+ (0, class_transformer_1.Expose)(),
105
+ (0, class_validator_1.IsOptional)(),
106
+ (0, class_validator_1.IsString)(),
107
+ (0, class_validator_1.MaxLength)(280),
108
+ __metadata("design:type", String)
109
+ ], UpdateStorePolicyRequest.prototype, "reason", void 0);
@@ -1,4 +1,5 @@
1
1
  import { PromotionEffectKindEnum } from '../../enums/PromotionEffectKindEnum';
2
+ import { PlanTermProvenance } from './StorePolicyResponse';
2
3
  /**
3
4
  * Un renglón de la tabla de amortización (M2 §3.3). Todos los montos en cents.
4
5
  */
@@ -59,4 +60,9 @@ export interface SimulationResultResponse {
59
60
  * incluyen: es el porqué de la cuota, no un extra a sumar.
60
61
  */
61
62
  appliedPromotion: AppliedPromotionResponse | null;
63
+ /**
64
+ * Qué capas tocaron cada término y en qué orden. Va vacío (`{}`) si ninguna política especial
65
+ * alcanzó la venta, y ausente si el lambda todavía no lo emite.
66
+ */
67
+ provenance?: PlanTermProvenance;
62
68
  }
@@ -0,0 +1,58 @@
1
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
2
+ import { StorePolicyPhaseEnum } from '../../enums/StorePolicyPhaseEnum';
3
+ import { StorePolicyStatusEnum } from '../../enums/StorePolicyStatusEnum';
4
+ /** Capas que pueden tocar un término del plan, en el orden en que se pliegan. */
5
+ export type PlanTermLayer = 'PLAN' | 'EASING' | 'PROMOTION' | 'HARDENING';
6
+ /**
7
+ * Cadena de capas que tocaron cada término, no una capa única: una palanca puede registrarse como
8
+ * aplicada y quedar pisada después. Va vacío (`{}`) si ninguna política alcanzó la venta.
9
+ */
10
+ export type PlanTermProvenance = Record<string, PlanTermLayer[]>;
11
+ /** Palancas que ENDURECEN. Se pliegan con `max` sobre pisos y `min` sobre techos. */
12
+ export interface StorePolicyHardening {
13
+ /** Piso de SCI. Es COMPUERTA de elegibilidad, no término del crédito. */
14
+ minSciScore?: number;
15
+ minDownPaymentPct?: number;
16
+ /** Piso de TNA: la tasa no puede bajar de ahí. */
17
+ tnaAnnualFloor?: number;
18
+ maxFinancedAmountCents?: number;
19
+ }
20
+ /** Palancas que AFLOJAN. Solo aplican si mejoran contra el PLAN CRUDO. */
21
+ export interface StorePolicyEasing {
22
+ minDownPaymentPct?: number;
23
+ tnaAnnual?: number;
24
+ maxFinancedAmountCents?: number;
25
+ }
26
+ /**
27
+ * Shape de salida de una política especial (GET / POST / PUT de /store-policies).
28
+ * Montos en cents; porcentajes y TNA en decimal. `phase` es DERIVADO y no vive en la tabla.
29
+ */
30
+ export interface StorePolicyResponse {
31
+ policyId: string;
32
+ name: string;
33
+ description: string | null;
34
+ status: StorePolicyStatusEnum;
35
+ /** Derivada de las fechas contra hoy; `null` cuando el estado no es `PUBLISHED`. */
36
+ phase: StorePolicyPhaseEnum | null;
37
+ hardening: StorePolicyHardening;
38
+ easing: StorePolicyEasing;
39
+ /** COMPUERTA: niega la venta. */
40
+ suspended: boolean;
41
+ /** COMPUERTA: `null` = sin restricción. Distinto de `targetSkus`, que es ALCANCE. */
42
+ allowedSkus: string[] | null;
43
+ /** ALCANCE. `null` = toda la red. */
44
+ storeIds: string[] | null;
45
+ /** ALCANCE. `null` = todos los niveles. */
46
+ targetLevels: CreditPlanLevelEnum[] | null;
47
+ /** ALCANCE. `null` = todos los SKUs. */
48
+ targetSkus: string[] | null;
49
+ validFrom: string | null;
50
+ validUntil: string | null;
51
+ reason: string | null;
52
+ version: number;
53
+ createdAt: string;
54
+ updatedAt: string;
55
+ createdBy: string;
56
+ updatedBy: string;
57
+ publishedAt: string | null;
58
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Fase de vigencia de una política especial PUBLICADA, derivada de `validFrom`/`validUntil` contra
3
+ * hoy. No se persiste — así no hace falta un cron que mueva estados a medianoche. `null` cuando el
4
+ * estado persistido no es `PUBLISHED`.
5
+ * @enum {string}
6
+ */
7
+ export declare enum StorePolicyPhaseEnum {
8
+ SCHEDULED = "SCHEDULED",
9
+ ACTIVE = "ACTIVE",
10
+ EXPIRED = "EXPIRED"
11
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorePolicyPhaseEnum = void 0;
4
+ /**
5
+ * Fase de vigencia de una política especial PUBLICADA, derivada de `validFrom`/`validUntil` contra
6
+ * hoy. No se persiste — así no hace falta un cron que mueva estados a medianoche. `null` cuando el
7
+ * estado persistido no es `PUBLISHED`.
8
+ * @enum {string}
9
+ */
10
+ var StorePolicyPhaseEnum;
11
+ (function (StorePolicyPhaseEnum) {
12
+ StorePolicyPhaseEnum["SCHEDULED"] = "SCHEDULED";
13
+ StorePolicyPhaseEnum["ACTIVE"] = "ACTIVE";
14
+ StorePolicyPhaseEnum["EXPIRED"] = "EXPIRED";
15
+ })(StorePolicyPhaseEnum || (exports.StorePolicyPhaseEnum = StorePolicyPhaseEnum = {}));
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Estado PERSISTIDO de una política especial de tienda. `EXPIRED` es terminal. La fase que ve el
3
+ * operador NO se guarda: se deriva de las fechas — ver `StorePolicyPhaseEnum`.
4
+ * @enum {string}
5
+ */
6
+ export declare enum StorePolicyStatusEnum {
7
+ DRAFT = "DRAFT",
8
+ PUBLISHED = "PUBLISHED",
9
+ PAUSED = "PAUSED",
10
+ EXPIRED = "EXPIRED"
11
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorePolicyStatusEnum = void 0;
4
+ /**
5
+ * Estado PERSISTIDO de una política especial de tienda. `EXPIRED` es terminal. La fase que ve el
6
+ * operador NO se guarda: se deriva de las fechas — ver `StorePolicyPhaseEnum`.
7
+ * @enum {string}
8
+ */
9
+ var StorePolicyStatusEnum;
10
+ (function (StorePolicyStatusEnum) {
11
+ StorePolicyStatusEnum["DRAFT"] = "DRAFT";
12
+ StorePolicyStatusEnum["PUBLISHED"] = "PUBLISHED";
13
+ StorePolicyStatusEnum["PAUSED"] = "PAUSED";
14
+ StorePolicyStatusEnum["EXPIRED"] = "EXPIRED";
15
+ })(StorePolicyStatusEnum || (exports.StorePolicyStatusEnum = StorePolicyStatusEnum = {}));
@@ -8,6 +8,8 @@ export * from './enums/PromotionStatusEnum';
8
8
  export * from './enums/PromotionEffectKindEnum';
9
9
  export * from './enums/PromotionPhaseEnum';
10
10
  export * from './enums/PromotionLogEventEnum';
11
+ export * from './enums/StorePolicyStatusEnum';
12
+ export * from './enums/StorePolicyPhaseEnum';
11
13
  export * from './dtos/CreditPlan';
12
14
  export * from './dtos/Financier';
13
15
  export * from './dtos/RetailerCreditPlan';
@@ -25,6 +27,9 @@ export * from './dtos/requests/CreatePromotionRequest';
25
27
  export * from './dtos/requests/UpdatePromotionRequest';
26
28
  export * from './dtos/requests/ChangePromotionStatusRequest';
27
29
  export * from './dtos/requests/ConsumePromotionRequest';
30
+ export * from './dtos/requests/CreateStorePolicyRequest';
31
+ export * from './dtos/requests/UpdateStorePolicyRequest';
32
+ export * from './dtos/requests/ChangeStorePolicyStatusRequest';
28
33
  export * from './dtos/responses/CreditPlanResponse';
29
34
  export * from './dtos/responses/FinancierResponse';
30
35
  export * from './dtos/responses/RetailerCreditPlanResponse';
@@ -32,3 +37,4 @@ export * from './dtos/responses/SimulationResultResponse';
32
37
  export * from './dtos/responses/PromotionResponse';
33
38
  export * from './dtos/responses/PromotionLogEntryResponse';
34
39
  export * from './dtos/responses/ConsumePromotionResponse';
40
+ export * from './dtos/responses/StorePolicyResponse';
@@ -25,6 +25,8 @@ __exportStar(require("./enums/PromotionStatusEnum"), exports);
25
25
  __exportStar(require("./enums/PromotionEffectKindEnum"), exports);
26
26
  __exportStar(require("./enums/PromotionPhaseEnum"), exports);
27
27
  __exportStar(require("./enums/PromotionLogEventEnum"), exports);
28
+ __exportStar(require("./enums/StorePolicyStatusEnum"), exports);
29
+ __exportStar(require("./enums/StorePolicyPhaseEnum"), exports);
28
30
  // Entity DTOs
29
31
  __exportStar(require("./dtos/CreditPlan"), exports);
30
32
  __exportStar(require("./dtos/Financier"), exports);
@@ -44,6 +46,9 @@ __exportStar(require("./dtos/requests/CreatePromotionRequest"), exports);
44
46
  __exportStar(require("./dtos/requests/UpdatePromotionRequest"), exports);
45
47
  __exportStar(require("./dtos/requests/ChangePromotionStatusRequest"), exports);
46
48
  __exportStar(require("./dtos/requests/ConsumePromotionRequest"), exports);
49
+ __exportStar(require("./dtos/requests/CreateStorePolicyRequest"), exports);
50
+ __exportStar(require("./dtos/requests/UpdateStorePolicyRequest"), exports);
51
+ __exportStar(require("./dtos/requests/ChangeStorePolicyStatusRequest"), exports);
47
52
  // Response DTOs
48
53
  __exportStar(require("./dtos/responses/CreditPlanResponse"), exports);
49
54
  __exportStar(require("./dtos/responses/FinancierResponse"), exports);
@@ -52,3 +57,4 @@ __exportStar(require("./dtos/responses/SimulationResultResponse"), exports);
52
57
  __exportStar(require("./dtos/responses/PromotionResponse"), exports);
53
58
  __exportStar(require("./dtos/responses/PromotionLogEntryResponse"), exports);
54
59
  __exportStar(require("./dtos/responses/ConsumePromotionResponse"), exports);
60
+ __exportStar(require("./dtos/responses/StorePolicyResponse"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.373.0",
3
+ "version": "3.375.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,12 @@
1
+ import { IsEnum, IsString } from 'class-validator';
2
+ import { RegisterCollectibleStatus } from '../enums/RegisterCollectibleStatus';
3
+
4
+ /**
5
+ * Resultado de dar de alta un cargo cobrable. El `intentId` es la referencia con la que el motor
6
+ * sigue ese cargo, y es la misma tanto si el alta es nueva como si el cargo ya estaba registrado.
7
+ */
8
+ export class RegisterCollectibleResponse {
9
+ @IsEnum(RegisterCollectibleStatus) status!: RegisterCollectibleStatus;
10
+
11
+ @IsString() intentId!: string;
12
+ }
@@ -0,0 +1,6 @@
1
+ export enum RegisterCollectibleStatus {
2
+ /** El cargo se indexó por primera vez y ya entra en los reintentos del motor. */
3
+ REGISTERED = 'REGISTERED',
4
+ /** Ese cargo ya estaba dado de alta. Volver a registrarlo es un no-op. */
5
+ ALREADY_REGISTERED = 'ALREADY_REGISTERED',
6
+ }
@@ -4,6 +4,7 @@ export * from './enums/CollectionState';
4
4
  export * from './enums/SagaStep';
5
5
  export * from './enums/CollectionResultStatus';
6
6
  export * from './enums/DeregisterChargeStatus';
7
+ export * from './enums/RegisterCollectibleStatus';
7
8
 
8
9
  // DTOs
9
10
  export * from './dtos/PendingChargeDto';
@@ -19,6 +20,7 @@ export * from './dtos/CollectionProductConfigDto';
19
20
  export * from './dtos/UpsertProductConfigRequest';
20
21
  export * from './dtos/ApplyCollectionResultRequest';
21
22
  export * from './dtos/DeregisterChargeResponse';
23
+ export * from './dtos/RegisterCollectibleResponse';
22
24
  export * from './dtos/ResolvePendingChargesRequest';
23
25
  export * from './dtos/MoneyInEvent';
24
26
 
@@ -0,0 +1,20 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { StorePolicyStatusEnum } from '../../enums/StorePolicyStatusEnum';
4
+
5
+ /**
6
+ * Body de PUT /store-policies/:policyId/status — publicar, pausar, reanudar o vencer.
7
+ * Transiciones válidas: `DRAFT→PUBLISHED`, `PUBLISHED⇄PAUSED`, `PUBLISHED|PAUSED→EXPIRED`.
8
+ * `reason` acompaña el cambio y queda en la bitácora.
9
+ */
10
+ export class ChangeStorePolicyStatusRequest {
11
+ @Expose()
12
+ @IsEnum(StorePolicyStatusEnum)
13
+ status!: StorePolicyStatusEnum;
14
+
15
+ @Expose()
16
+ @IsOptional()
17
+ @IsString()
18
+ @MaxLength(280)
19
+ reason?: string;
20
+ }
@@ -0,0 +1,156 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import {
3
+ ArrayNotEmpty,
4
+ IsArray,
5
+ IsBoolean,
6
+ IsEnum,
7
+ IsInt,
8
+ IsISO8601,
9
+ IsNumber,
10
+ IsOptional,
11
+ IsString,
12
+ Max,
13
+ MaxLength,
14
+ Min,
15
+ ValidateNested,
16
+ } from 'class-validator';
17
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
18
+
19
+ /** Grupo de palancas que ENDURECEN las condiciones del plan. */
20
+ export class StorePolicyHardeningDto {
21
+ /** Piso de SCI; es compuerta de elegibilidad, no término del crédito. */
22
+ @Expose()
23
+ @IsOptional()
24
+ @IsInt()
25
+ @Min(0)
26
+ @Max(100)
27
+ minSciScore?: number;
28
+
29
+ @Expose()
30
+ @IsOptional()
31
+ @IsNumber()
32
+ @Min(0)
33
+ @Max(1)
34
+ minDownPaymentPct?: number;
35
+
36
+ /** Piso de TNA en decimal: la tasa no puede bajar de ahí. */
37
+ @Expose()
38
+ @IsOptional()
39
+ @IsNumber()
40
+ @Min(0)
41
+ @Max(5)
42
+ tnaAnnualFloor?: number;
43
+
44
+ @Expose()
45
+ @IsOptional()
46
+ @IsInt()
47
+ @Min(0)
48
+ maxFinancedAmountCents?: number;
49
+ }
50
+
51
+ /** Grupo de palancas que AFLOJAN las condiciones del plan. */
52
+ export class StorePolicyEasingDto {
53
+ @Expose()
54
+ @IsOptional()
55
+ @IsNumber()
56
+ @Min(0)
57
+ @Max(1)
58
+ minDownPaymentPct?: number;
59
+
60
+ @Expose()
61
+ @IsOptional()
62
+ @IsNumber()
63
+ @Min(0)
64
+ @Max(5)
65
+ tnaAnnual?: number;
66
+
67
+ @Expose()
68
+ @IsOptional()
69
+ @IsInt()
70
+ @Min(0)
71
+ maxFinancedAmountCents?: number;
72
+ }
73
+
74
+ /**
75
+ * Body de POST /store-policies — alta de una política especial de tienda.
76
+ * Nace en `DRAFT`: el estado, `policyId`, `version` y la auditoría los asigna el lambda y NO viajan
77
+ * en el request. Que haya al menos una palanca o compuerta lo valida el lambda.
78
+ */
79
+ export class CreateStorePolicyRequest {
80
+ @Expose()
81
+ @IsString()
82
+ @MaxLength(120)
83
+ name!: string;
84
+
85
+ @Expose()
86
+ @IsOptional()
87
+ @IsString()
88
+ @MaxLength(500)
89
+ description?: string;
90
+
91
+ @Expose()
92
+ @IsOptional()
93
+ @ValidateNested()
94
+ @Type(() => StorePolicyHardeningDto)
95
+ hardening?: StorePolicyHardeningDto;
96
+
97
+ @Expose()
98
+ @IsOptional()
99
+ @ValidateNested()
100
+ @Type(() => StorePolicyEasingDto)
101
+ easing?: StorePolicyEasingDto;
102
+
103
+ /** Compuerta que niega la venta en las tiendas alcanzadas. */
104
+ @Expose()
105
+ @IsOptional()
106
+ @IsBoolean()
107
+ suspended?: boolean;
108
+
109
+ /** Compuerta: SKUs habilitados. Ausente = sin restricción. */
110
+ @Expose()
111
+ @IsOptional()
112
+ @IsArray()
113
+ @ArrayNotEmpty()
114
+ @IsString({ each: true })
115
+ allowedSkus?: string[];
116
+
117
+ /** Alcance: tiendas alcanzadas. Ausente = toda la red. */
118
+ @Expose()
119
+ @IsOptional()
120
+ @IsArray()
121
+ @ArrayNotEmpty()
122
+ @IsString({ each: true })
123
+ storeIds?: string[];
124
+
125
+ /** Alcance: niveles alcanzados. Ausente = todos los niveles. */
126
+ @Expose()
127
+ @IsOptional()
128
+ @IsArray()
129
+ @ArrayNotEmpty()
130
+ @IsEnum(CreditPlanLevelEnum, { each: true })
131
+ targetLevels?: CreditPlanLevelEnum[];
132
+
133
+ /** Alcance: SKUs alcanzados. Ausente = todos los productos. */
134
+ @Expose()
135
+ @IsOptional()
136
+ @IsArray()
137
+ @ArrayNotEmpty()
138
+ @IsString({ each: true })
139
+ targetSkus?: string[];
140
+
141
+ @Expose()
142
+ @IsOptional()
143
+ @IsISO8601()
144
+ validFrom?: string;
145
+
146
+ @Expose()
147
+ @IsOptional()
148
+ @IsISO8601()
149
+ validUntil?: string;
150
+
151
+ @Expose()
152
+ @IsOptional()
153
+ @IsString()
154
+ @MaxLength(280)
155
+ reason?: string;
156
+ }
@@ -0,0 +1,94 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import {
3
+ ArrayNotEmpty,
4
+ IsArray,
5
+ IsBoolean,
6
+ IsEnum,
7
+ IsISO8601,
8
+ IsOptional,
9
+ IsString,
10
+ MaxLength,
11
+ ValidateNested,
12
+ } from 'class-validator';
13
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
14
+ import { StorePolicyEasingDto, StorePolicyHardeningDto } from './CreateStorePolicyRequest';
15
+
16
+ /**
17
+ * Body de PUT /store-policies/:policyId — edición parcial (todos los campos opcionales).
18
+ * Sube `version`. El cambio de estado va por su endpoint dedicado. Cada grupo de palancas se
19
+ * reemplaza entero cuando viene, no se mergea clave a clave.
20
+ */
21
+ export class UpdateStorePolicyRequest {
22
+ @Expose()
23
+ @IsOptional()
24
+ @IsString()
25
+ @MaxLength(120)
26
+ name?: string;
27
+
28
+ @Expose()
29
+ @IsOptional()
30
+ @IsString()
31
+ @MaxLength(500)
32
+ description?: string;
33
+
34
+ @Expose()
35
+ @IsOptional()
36
+ @ValidateNested()
37
+ @Type(() => StorePolicyHardeningDto)
38
+ hardening?: StorePolicyHardeningDto;
39
+
40
+ @Expose()
41
+ @IsOptional()
42
+ @ValidateNested()
43
+ @Type(() => StorePolicyEasingDto)
44
+ easing?: StorePolicyEasingDto;
45
+
46
+ @Expose()
47
+ @IsOptional()
48
+ @IsBoolean()
49
+ suspended?: boolean;
50
+
51
+ @Expose()
52
+ @IsOptional()
53
+ @IsArray()
54
+ @ArrayNotEmpty()
55
+ @IsString({ each: true })
56
+ allowedSkus?: string[];
57
+
58
+ @Expose()
59
+ @IsOptional()
60
+ @IsArray()
61
+ @ArrayNotEmpty()
62
+ @IsString({ each: true })
63
+ storeIds?: string[];
64
+
65
+ @Expose()
66
+ @IsOptional()
67
+ @IsArray()
68
+ @ArrayNotEmpty()
69
+ @IsEnum(CreditPlanLevelEnum, { each: true })
70
+ targetLevels?: CreditPlanLevelEnum[];
71
+
72
+ @Expose()
73
+ @IsOptional()
74
+ @IsArray()
75
+ @ArrayNotEmpty()
76
+ @IsString({ each: true })
77
+ targetSkus?: string[];
78
+
79
+ @Expose()
80
+ @IsOptional()
81
+ @IsISO8601()
82
+ validFrom?: string;
83
+
84
+ @Expose()
85
+ @IsOptional()
86
+ @IsISO8601()
87
+ validUntil?: string;
88
+
89
+ @Expose()
90
+ @IsOptional()
91
+ @IsString()
92
+ @MaxLength(280)
93
+ reason?: string;
94
+ }
@@ -1,4 +1,5 @@
1
1
  import { PromotionEffectKindEnum } from '../../enums/PromotionEffectKindEnum';
2
+ import { PlanTermProvenance } from './StorePolicyResponse';
2
3
 
3
4
  /**
4
5
  * Un renglón de la tabla de amortización (M2 §3.3). Todos los montos en cents.
@@ -62,4 +63,9 @@ export interface SimulationResultResponse {
62
63
  * incluyen: es el porqué de la cuota, no un extra a sumar.
63
64
  */
64
65
  appliedPromotion: AppliedPromotionResponse | null;
66
+ /**
67
+ * Qué capas tocaron cada término y en qué orden. Va vacío (`{}`) si ninguna política especial
68
+ * alcanzó la venta, y ausente si el lambda todavía no lo emite.
69
+ */
70
+ provenance?: PlanTermProvenance;
65
71
  }
@@ -0,0 +1,63 @@
1
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
2
+ import { StorePolicyPhaseEnum } from '../../enums/StorePolicyPhaseEnum';
3
+ import { StorePolicyStatusEnum } from '../../enums/StorePolicyStatusEnum';
4
+
5
+ /** Capas que pueden tocar un término del plan, en el orden en que se pliegan. */
6
+ export type PlanTermLayer = 'PLAN' | 'EASING' | 'PROMOTION' | 'HARDENING';
7
+
8
+ /**
9
+ * Cadena de capas que tocaron cada término, no una capa única: una palanca puede registrarse como
10
+ * aplicada y quedar pisada después. Va vacío (`{}`) si ninguna política alcanzó la venta.
11
+ */
12
+ export type PlanTermProvenance = Record<string, PlanTermLayer[]>;
13
+
14
+ /** Palancas que ENDURECEN. Se pliegan con `max` sobre pisos y `min` sobre techos. */
15
+ export interface StorePolicyHardening {
16
+ /** Piso de SCI. Es COMPUERTA de elegibilidad, no término del crédito. */
17
+ minSciScore?: number;
18
+ minDownPaymentPct?: number;
19
+ /** Piso de TNA: la tasa no puede bajar de ahí. */
20
+ tnaAnnualFloor?: number;
21
+ maxFinancedAmountCents?: number;
22
+ }
23
+
24
+ /** Palancas que AFLOJAN. Solo aplican si mejoran contra el PLAN CRUDO. */
25
+ export interface StorePolicyEasing {
26
+ minDownPaymentPct?: number;
27
+ tnaAnnual?: number;
28
+ maxFinancedAmountCents?: number;
29
+ }
30
+
31
+ /**
32
+ * Shape de salida de una política especial (GET / POST / PUT de /store-policies).
33
+ * Montos en cents; porcentajes y TNA en decimal. `phase` es DERIVADO y no vive en la tabla.
34
+ */
35
+ export interface StorePolicyResponse {
36
+ policyId: string;
37
+ name: string;
38
+ description: string | null;
39
+ status: StorePolicyStatusEnum;
40
+ /** Derivada de las fechas contra hoy; `null` cuando el estado no es `PUBLISHED`. */
41
+ phase: StorePolicyPhaseEnum | null;
42
+ hardening: StorePolicyHardening;
43
+ easing: StorePolicyEasing;
44
+ /** COMPUERTA: niega la venta. */
45
+ suspended: boolean;
46
+ /** COMPUERTA: `null` = sin restricción. Distinto de `targetSkus`, que es ALCANCE. */
47
+ allowedSkus: string[] | null;
48
+ /** ALCANCE. `null` = toda la red. */
49
+ storeIds: string[] | null;
50
+ /** ALCANCE. `null` = todos los niveles. */
51
+ targetLevels: CreditPlanLevelEnum[] | null;
52
+ /** ALCANCE. `null` = todos los SKUs. */
53
+ targetSkus: string[] | null;
54
+ validFrom: string | null;
55
+ validUntil: string | null;
56
+ reason: string | null;
57
+ version: number;
58
+ createdAt: string;
59
+ updatedAt: string;
60
+ createdBy: string;
61
+ updatedBy: string;
62
+ publishedAt: string | null;
63
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Fase de vigencia de una política especial PUBLICADA, derivada de `validFrom`/`validUntil` contra
3
+ * hoy. No se persiste — así no hace falta un cron que mueva estados a medianoche. `null` cuando el
4
+ * estado persistido no es `PUBLISHED`.
5
+ * @enum {string}
6
+ */
7
+ export enum StorePolicyPhaseEnum {
8
+ SCHEDULED = 'SCHEDULED',
9
+ ACTIVE = 'ACTIVE',
10
+ EXPIRED = 'EXPIRED',
11
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Estado PERSISTIDO de una política especial de tienda. `EXPIRED` es terminal. La fase que ve el
3
+ * operador NO se guarda: se deriva de las fechas — ver `StorePolicyPhaseEnum`.
4
+ * @enum {string}
5
+ */
6
+ export enum StorePolicyStatusEnum {
7
+ DRAFT = 'DRAFT',
8
+ PUBLISHED = 'PUBLISHED',
9
+ PAUSED = 'PAUSED',
10
+ EXPIRED = 'EXPIRED',
11
+ }
@@ -9,6 +9,8 @@ export * from './enums/PromotionStatusEnum';
9
9
  export * from './enums/PromotionEffectKindEnum';
10
10
  export * from './enums/PromotionPhaseEnum';
11
11
  export * from './enums/PromotionLogEventEnum';
12
+ export * from './enums/StorePolicyStatusEnum';
13
+ export * from './enums/StorePolicyPhaseEnum';
12
14
 
13
15
  // Entity DTOs
14
16
  export * from './dtos/CreditPlan';
@@ -30,6 +32,9 @@ export * from './dtos/requests/CreatePromotionRequest';
30
32
  export * from './dtos/requests/UpdatePromotionRequest';
31
33
  export * from './dtos/requests/ChangePromotionStatusRequest';
32
34
  export * from './dtos/requests/ConsumePromotionRequest';
35
+ export * from './dtos/requests/CreateStorePolicyRequest';
36
+ export * from './dtos/requests/UpdateStorePolicyRequest';
37
+ export * from './dtos/requests/ChangeStorePolicyStatusRequest';
33
38
 
34
39
  // Response DTOs
35
40
  export * from './dtos/responses/CreditPlanResponse';
@@ -39,3 +44,4 @@ export * from './dtos/responses/SimulationResultResponse';
39
44
  export * from './dtos/responses/PromotionResponse';
40
45
  export * from './dtos/responses/PromotionLogEntryResponse';
41
46
  export * from './dtos/responses/ConsumePromotionResponse';
47
+ export * from './dtos/responses/StorePolicyResponse';