@fiado/type-kit 3.153.0 → 3.154.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 (31) hide show
  1. package/bin/remittance/dtos/RemittancePromotion.d.ts +90 -0
  2. package/bin/remittance/dtos/RemittancePromotion.js +150 -0
  3. package/bin/remittance/dtos/index.d.ts +1 -0
  4. package/bin/remittance/dtos/index.js +1 -0
  5. package/bin/remittance/dtos/internal/RemittancePromotionReach.d.ts +17 -0
  6. package/bin/remittance/dtos/internal/RemittancePromotionReach.js +44 -0
  7. package/bin/remittance/enums/FeeEffectMode.d.ts +7 -0
  8. package/bin/remittance/enums/FeeEffectMode.js +11 -0
  9. package/bin/remittance/enums/FxEffectMode.d.ts +6 -0
  10. package/bin/remittance/enums/FxEffectMode.js +10 -0
  11. package/bin/remittance/enums/PromotionActivation.d.ts +7 -0
  12. package/bin/remittance/enums/PromotionActivation.js +11 -0
  13. package/bin/remittance/enums/PromotionKind.d.ts +9 -0
  14. package/bin/remittance/enums/PromotionKind.js +13 -0
  15. package/bin/remittance/enums/PromotionStatus.d.ts +7 -0
  16. package/bin/remittance/enums/PromotionStatus.js +11 -0
  17. package/bin/remittance/enums/index.d.ts +5 -0
  18. package/bin/remittance/enums/index.js +5 -0
  19. package/bin/remittance/index.d.ts +1 -0
  20. package/bin/remittance/index.js +1 -0
  21. package/package.json +1 -1
  22. package/src/remittance/dtos/RemittancePromotion.ts +162 -0
  23. package/src/remittance/dtos/index.ts +1 -0
  24. package/src/remittance/dtos/internal/RemittancePromotionReach.ts +31 -0
  25. package/src/remittance/enums/FeeEffectMode.ts +7 -0
  26. package/src/remittance/enums/FxEffectMode.ts +6 -0
  27. package/src/remittance/enums/PromotionActivation.ts +7 -0
  28. package/src/remittance/enums/PromotionKind.ts +9 -0
  29. package/src/remittance/enums/PromotionStatus.ts +7 -0
  30. package/src/remittance/enums/index.ts +5 -0
  31. package/src/remittance/index.ts +1 -0
@@ -0,0 +1,90 @@
1
+ import { FeeEffectMode } from "../enums/FeeEffectMode";
2
+ import { FxEffectMode } from "../enums/FxEffectMode";
3
+ import { PromotionActivation } from "../enums/PromotionActivation";
4
+ import { PromotionKind } from "../enums/PromotionKind";
5
+ import { PromotionStatus } from "../enums/PromotionStatus";
6
+ import { RemittanceCorridor } from "../enums/RemittanceCorridor";
7
+ /** Audiencia: null en una dimensión = "Cualquiera". */
8
+ export declare class PromotionAudience {
9
+ corridor?: RemittanceCorridor | null;
10
+ segmentId?: string | null;
11
+ cohortId?: string | null;
12
+ }
13
+ /** Efecto FX (spread): DELTA suma bps CON SIGNO al markup base; ABSOLUTE lo reemplaza. */
14
+ export declare class FxEffect {
15
+ mode: FxEffectMode;
16
+ /** bps con signo. Ignorado si mode=NONE (mandar 0). */
17
+ valueBps: number;
18
+ }
19
+ /** Efecto fee: ABSOLUTE = $; DELTA = ±$; PERCENTAGE = −% del fee (0-100). */
20
+ export declare class FeeEffect {
21
+ mode: FeeEffectMode;
22
+ value: number;
23
+ }
24
+ export declare class CreatePromotionRequest {
25
+ name: string;
26
+ kind: PromotionKind;
27
+ activation: PromotionActivation;
28
+ /** Requerido si activation=CODE (regla en manager); único case-insensitive. */
29
+ code?: string | null;
30
+ audience: PromotionAudience;
31
+ /** ISO date (YYYY-MM-DD). */
32
+ effectiveFrom: string;
33
+ /** ISO date; null/ausente = permanente (∞). */
34
+ effectiveTo?: string | null;
35
+ fxEffect: FxEffect;
36
+ feeEffect: FeeEffect;
37
+ notes?: string | null;
38
+ }
39
+ /** PUT — reemplazo completo (mismos campos que create). */
40
+ export declare class UpdatePromotionRequest extends CreatePromotionRequest {
41
+ }
42
+ /** Promoción completa (response de list/create/update). */
43
+ export declare class Promotion {
44
+ id: string;
45
+ name: string;
46
+ kind: PromotionKind;
47
+ activation: PromotionActivation;
48
+ code: string | null;
49
+ audience: {
50
+ corridor: RemittanceCorridor | null;
51
+ segmentId: string | null;
52
+ cohortId: string | null;
53
+ };
54
+ /** Display: nombres resueltos de segmento/cohort (null = "Cualquiera" o no resoluble). */
55
+ audienceDisplay: {
56
+ corridor: string | null;
57
+ segmentName: string | null;
58
+ cohortName: string | null;
59
+ };
60
+ effectiveFrom: string;
61
+ effectiveTo: string | null;
62
+ fxEffect: {
63
+ mode: FxEffectMode;
64
+ valueBps: number;
65
+ };
66
+ feeEffect: {
67
+ mode: FeeEffectMode;
68
+ value: number;
69
+ };
70
+ /** Derivado de la vigencia vs hoy (UTC). */
71
+ status: PromotionStatus;
72
+ /** Legible para la columna EFECTO: "MU −30 bps + Fee = $0". */
73
+ effectSummary: string;
74
+ notes: string | null;
75
+ createdAt: string;
76
+ updatedAt: string;
77
+ createdBy: string;
78
+ updatedBy: string;
79
+ }
80
+ /** Response de GET /backoffice/pricing/promotions. */
81
+ export declare class PromotionListResponse {
82
+ items: Promotion[];
83
+ }
84
+ /** Response de GET /backoffice/pricing/promotions/reach. */
85
+ export declare class PromotionReachResponse {
86
+ /** Clientes en la intersección corridor × segmento × cohort. */
87
+ reach: number;
88
+ /** Universo (todos los RemittanceUsers) — para el % del picker. */
89
+ total: number;
90
+ }
@@ -0,0 +1,150 @@
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.PromotionReachResponse = exports.PromotionListResponse = exports.Promotion = exports.UpdatePromotionRequest = exports.CreatePromotionRequest = exports.FeeEffect = exports.FxEffect = exports.PromotionAudience = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const FeeEffectMode_1 = require("../enums/FeeEffectMode");
16
+ const FxEffectMode_1 = require("../enums/FxEffectMode");
17
+ const PromotionActivation_1 = require("../enums/PromotionActivation");
18
+ const PromotionKind_1 = require("../enums/PromotionKind");
19
+ const RemittanceCorridor_1 = require("../enums/RemittanceCorridor");
20
+ /**
21
+ * DTOs de Promociones (Dashboard Ops · Variables Operativas §2).
22
+ *
23
+ * UniTeller NO participa (no hay motor de promos en API Lite): toda la lógica
24
+ * vive en Fiado. Una promo es un OVERRIDE de Precio Base (markup y/o fee) para
25
+ * una audiencia (corridor × segmento × cohort, null = Cualquiera) y vigencia.
26
+ * Dueño de la tabla: remittance-business (RemittancePromotions_GT). La
27
+ * resolución en send-time (capas: base → PRICE_CHANGE → mejor-para-el-cliente)
28
+ * es Fase B — estos DTOs cubren la config.
29
+ */
30
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
31
+ /** Audiencia: null en una dimensión = "Cualquiera". */
32
+ class PromotionAudience {
33
+ }
34
+ exports.PromotionAudience = PromotionAudience;
35
+ __decorate([
36
+ (0, class_validator_1.IsOptional)(),
37
+ (0, class_validator_1.IsEnum)(RemittanceCorridor_1.RemittanceCorridor),
38
+ __metadata("design:type", String)
39
+ ], PromotionAudience.prototype, "corridor", void 0);
40
+ __decorate([
41
+ (0, class_validator_1.IsOptional)(),
42
+ (0, class_validator_1.IsString)(),
43
+ (0, class_validator_1.Length)(1, 100),
44
+ __metadata("design:type", String)
45
+ ], PromotionAudience.prototype, "segmentId", void 0);
46
+ __decorate([
47
+ (0, class_validator_1.IsOptional)(),
48
+ (0, class_validator_1.IsString)(),
49
+ (0, class_validator_1.Length)(1, 100),
50
+ __metadata("design:type", String)
51
+ ], PromotionAudience.prototype, "cohortId", void 0);
52
+ /** Efecto FX (spread): DELTA suma bps CON SIGNO al markup base; ABSOLUTE lo reemplaza. */
53
+ class FxEffect {
54
+ }
55
+ exports.FxEffect = FxEffect;
56
+ __decorate([
57
+ (0, class_validator_1.IsEnum)(FxEffectMode_1.FxEffectMode),
58
+ __metadata("design:type", String)
59
+ ], FxEffect.prototype, "mode", void 0);
60
+ __decorate([
61
+ (0, class_validator_1.IsInt)(),
62
+ (0, class_validator_1.Min)(-500),
63
+ (0, class_validator_1.Max)(500),
64
+ __metadata("design:type", Number)
65
+ ], FxEffect.prototype, "valueBps", void 0);
66
+ /** Efecto fee: ABSOLUTE = $; DELTA = ±$; PERCENTAGE = −% del fee (0-100). */
67
+ class FeeEffect {
68
+ }
69
+ exports.FeeEffect = FeeEffect;
70
+ __decorate([
71
+ (0, class_validator_1.IsEnum)(FeeEffectMode_1.FeeEffectMode),
72
+ __metadata("design:type", String)
73
+ ], FeeEffect.prototype, "mode", void 0);
74
+ __decorate([
75
+ (0, class_validator_1.IsNumber)(),
76
+ (0, class_validator_1.Min)(-100),
77
+ (0, class_validator_1.Max)(100),
78
+ __metadata("design:type", Number)
79
+ ], FeeEffect.prototype, "value", void 0);
80
+ class CreatePromotionRequest {
81
+ }
82
+ exports.CreatePromotionRequest = CreatePromotionRequest;
83
+ __decorate([
84
+ (0, class_validator_1.IsString)(),
85
+ (0, class_validator_1.Length)(3, 100),
86
+ __metadata("design:type", String)
87
+ ], CreatePromotionRequest.prototype, "name", void 0);
88
+ __decorate([
89
+ (0, class_validator_1.IsEnum)(PromotionKind_1.PromotionKind),
90
+ __metadata("design:type", String)
91
+ ], CreatePromotionRequest.prototype, "kind", void 0);
92
+ __decorate([
93
+ (0, class_validator_1.IsEnum)(PromotionActivation_1.PromotionActivation),
94
+ __metadata("design:type", String)
95
+ ], CreatePromotionRequest.prototype, "activation", void 0);
96
+ __decorate([
97
+ (0, class_validator_1.IsOptional)(),
98
+ (0, class_validator_1.IsString)(),
99
+ (0, class_validator_1.Length)(3, 30),
100
+ (0, class_validator_1.Matches)(/^[A-Z0-9_-]+$/i),
101
+ __metadata("design:type", String)
102
+ ], CreatePromotionRequest.prototype, "code", void 0);
103
+ __decorate([
104
+ (0, class_validator_1.ValidateNested)(),
105
+ (0, class_transformer_1.Type)(() => PromotionAudience),
106
+ __metadata("design:type", PromotionAudience)
107
+ ], CreatePromotionRequest.prototype, "audience", void 0);
108
+ __decorate([
109
+ (0, class_validator_1.IsString)(),
110
+ (0, class_validator_1.Matches)(ISO_DATE),
111
+ __metadata("design:type", String)
112
+ ], CreatePromotionRequest.prototype, "effectiveFrom", void 0);
113
+ __decorate([
114
+ (0, class_validator_1.IsOptional)(),
115
+ (0, class_validator_1.IsString)(),
116
+ (0, class_validator_1.Matches)(ISO_DATE),
117
+ __metadata("design:type", String)
118
+ ], CreatePromotionRequest.prototype, "effectiveTo", void 0);
119
+ __decorate([
120
+ (0, class_validator_1.ValidateNested)(),
121
+ (0, class_transformer_1.Type)(() => FxEffect),
122
+ __metadata("design:type", FxEffect)
123
+ ], CreatePromotionRequest.prototype, "fxEffect", void 0);
124
+ __decorate([
125
+ (0, class_validator_1.ValidateNested)(),
126
+ (0, class_transformer_1.Type)(() => FeeEffect),
127
+ __metadata("design:type", FeeEffect)
128
+ ], CreatePromotionRequest.prototype, "feeEffect", void 0);
129
+ __decorate([
130
+ (0, class_validator_1.IsOptional)(),
131
+ (0, class_validator_1.IsString)(),
132
+ (0, class_validator_1.MaxLength)(500),
133
+ __metadata("design:type", String)
134
+ ], CreatePromotionRequest.prototype, "notes", void 0);
135
+ /** PUT — reemplazo completo (mismos campos que create). */
136
+ class UpdatePromotionRequest extends CreatePromotionRequest {
137
+ }
138
+ exports.UpdatePromotionRequest = UpdatePromotionRequest;
139
+ /** Promoción completa (response de list/create/update). */
140
+ class Promotion {
141
+ }
142
+ exports.Promotion = Promotion;
143
+ /** Response de GET /backoffice/pricing/promotions. */
144
+ class PromotionListResponse {
145
+ }
146
+ exports.PromotionListResponse = PromotionListResponse;
147
+ /** Response de GET /backoffice/pricing/promotions/reach. */
148
+ class PromotionReachResponse {
149
+ }
150
+ exports.PromotionReachResponse = PromotionReachResponse;
@@ -41,3 +41,4 @@ export * from "./RemittanceAuditLog";
41
41
  export * from "./RemittanceSegment";
42
42
  export * from "./RemittanceCommittee";
43
43
  export * from "./RemittancePricing";
44
+ export * from "./RemittancePromotion";
@@ -57,3 +57,4 @@ __exportStar(require("./RemittanceAuditLog"), exports);
57
57
  __exportStar(require("./RemittanceSegment"), exports);
58
58
  __exportStar(require("./RemittanceCommittee"), exports);
59
59
  __exportStar(require("./RemittancePricing"), exports);
60
+ __exportStar(require("./RemittancePromotion"), exports);
@@ -0,0 +1,17 @@
1
+ import { CohortCondition } from "../RemittanceCohort";
2
+ import { RemittanceCorridor } from "../../enums/RemittanceCorridor";
3
+ /**
4
+ * Contrato interno del reach de Promociones (puente Opción A):
5
+ * POST /backoffice/config/promotions/reach (privado connector). rb resuelve las
6
+ * dimensiones a datos crudos — segmento → directoryIds; cohort → conditions;
7
+ * corredor → corridor — y el connector computa la intersección sobre el universo
8
+ * de RemittanceUsers. Toda dimensión AUSENTE = no filtra ("Cualquiera").
9
+ */
10
+ export declare class PromotionReachRequest {
11
+ /** Miembros del segmento (resueltos por rb). Ausente = todos los usuarios. */
12
+ directoryIds?: string[];
13
+ /** Condiciones del cohort (AND, evaluadas como en cohortCount). Ausente = sin filtro. */
14
+ conditions?: CohortCondition[];
15
+ /** Filtro por corredor (countryISO de CORRIDOR_INFO, ≥1 tx no-cancelada histórica). Ausente = sin filtro. */
16
+ corridor?: RemittanceCorridor;
17
+ }
@@ -0,0 +1,44 @@
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.PromotionReachRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const RemittanceCohort_1 = require("../RemittanceCohort");
16
+ const RemittanceCorridor_1 = require("../../enums/RemittanceCorridor");
17
+ /**
18
+ * Contrato interno del reach de Promociones (puente Opción A):
19
+ * POST /backoffice/config/promotions/reach (privado connector). rb resuelve las
20
+ * dimensiones a datos crudos — segmento → directoryIds; cohort → conditions;
21
+ * corredor → corridor — y el connector computa la intersección sobre el universo
22
+ * de RemittanceUsers. Toda dimensión AUSENTE = no filtra ("Cualquiera").
23
+ */
24
+ class PromotionReachRequest {
25
+ }
26
+ exports.PromotionReachRequest = PromotionReachRequest;
27
+ __decorate([
28
+ (0, class_validator_1.IsOptional)(),
29
+ (0, class_validator_1.IsArray)(),
30
+ (0, class_validator_1.IsUUID)("4", { each: true }),
31
+ __metadata("design:type", Array)
32
+ ], PromotionReachRequest.prototype, "directoryIds", void 0);
33
+ __decorate([
34
+ (0, class_validator_1.IsOptional)(),
35
+ (0, class_validator_1.IsArray)(),
36
+ (0, class_validator_1.ValidateNested)({ each: true }),
37
+ (0, class_transformer_1.Type)(() => RemittanceCohort_1.CohortCondition),
38
+ __metadata("design:type", Array)
39
+ ], PromotionReachRequest.prototype, "conditions", void 0);
40
+ __decorate([
41
+ (0, class_validator_1.IsOptional)(),
42
+ (0, class_validator_1.IsEnum)(RemittanceCorridor_1.RemittanceCorridor),
43
+ __metadata("design:type", String)
44
+ ], PromotionReachRequest.prototype, "corridor", void 0);
@@ -0,0 +1,7 @@
1
+ /** Efecto de la promo sobre el service fee (relativo a la base efectiva). */
2
+ export declare enum FeeEffectMode {
3
+ NONE = "NONE",// sin cambio
4
+ ABSOLUTE = "ABSOLUTE",// fee = value (USD)
5
+ DELTA = "DELTA",// baseFee + value (CON SIGNO)
6
+ PERCENTAGE = "PERCENTAGE"
7
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FeeEffectMode = void 0;
4
+ /** Efecto de la promo sobre el service fee (relativo a la base efectiva). */
5
+ var FeeEffectMode;
6
+ (function (FeeEffectMode) {
7
+ FeeEffectMode["NONE"] = "NONE";
8
+ FeeEffectMode["ABSOLUTE"] = "ABSOLUTE";
9
+ FeeEffectMode["DELTA"] = "DELTA";
10
+ FeeEffectMode["PERCENTAGE"] = "PERCENTAGE";
11
+ })(FeeEffectMode || (exports.FeeEffectMode = FeeEffectMode = {}));
@@ -0,0 +1,6 @@
1
+ /** Efecto de la promo sobre el spread FX (relativo a la base efectiva). */
2
+ export declare enum FxEffectMode {
3
+ NONE = "NONE",// sin cambio
4
+ DELTA = "DELTA",// baseMarkup + valueBps (CON SIGNO)
5
+ ABSOLUTE = "ABSOLUTE"
6
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FxEffectMode = void 0;
4
+ /** Efecto de la promo sobre el spread FX (relativo a la base efectiva). */
5
+ var FxEffectMode;
6
+ (function (FxEffectMode) {
7
+ FxEffectMode["NONE"] = "NONE";
8
+ FxEffectMode["DELTA"] = "DELTA";
9
+ FxEffectMode["ABSOLUTE"] = "ABSOLUTE";
10
+ })(FxEffectMode || (exports.FxEffectMode = FxEffectMode = {}));
@@ -0,0 +1,7 @@
1
+ /** Cómo se activa la promo para el cliente. */
2
+ export declare enum PromotionActivation {
3
+ /** Auto-aplica a toda la audiencia. */
4
+ AUTOMATIC = "AUTOMATIC",
5
+ /** El cliente teclea el código en la app (habilita SOLO esa promo). */
6
+ CODE = "CODE"
7
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromotionActivation = void 0;
4
+ /** Cómo se activa la promo para el cliente. */
5
+ var PromotionActivation;
6
+ (function (PromotionActivation) {
7
+ /** Auto-aplica a toda la audiencia. */
8
+ PromotionActivation["AUTOMATIC"] = "AUTOMATIC";
9
+ /** El cliente teclea el código en la app (habilita SOLO esa promo). */
10
+ PromotionActivation["CODE"] = "CODE";
11
+ })(PromotionActivation || (exports.PromotionActivation = PromotionActivation = {}));
@@ -0,0 +1,9 @@
1
+ /** Tipo de promoción (Variables Operativas › Promociones — mockup). */
2
+ export declare enum PromotionKind {
3
+ /** Descuento promocional temporal (puede tener código). */
4
+ PROMO = "PROMO",
5
+ /** Cambio de BASE programado (overlay absoluto; NO muta RemittancePricing_GT). */
6
+ PRICE_CHANGE = "PRICE_CHANGE",
7
+ /** Override permanente por audiencia (VIP, Onboarding sin fee, …). */
8
+ PREFERENTIAL = "PREFERENTIAL"
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromotionKind = void 0;
4
+ /** Tipo de promoción (Variables Operativas › Promociones — mockup). */
5
+ var PromotionKind;
6
+ (function (PromotionKind) {
7
+ /** Descuento promocional temporal (puede tener código). */
8
+ PromotionKind["PROMO"] = "PROMO";
9
+ /** Cambio de BASE programado (overlay absoluto; NO muta RemittancePricing_GT). */
10
+ PromotionKind["PRICE_CHANGE"] = "PRICE_CHANGE";
11
+ /** Override permanente por audiencia (VIP, Onboarding sin fee, …). */
12
+ PromotionKind["PREFERENTIAL"] = "PREFERENTIAL";
13
+ })(PromotionKind || (exports.PromotionKind = PromotionKind = {}));
@@ -0,0 +1,7 @@
1
+ /** Estado DERIVADO de effectiveFrom/To vs hoy (UTC). NO se persiste. */
2
+ export declare enum PromotionStatus {
3
+ ACTIVE = "ACTIVE",// vigente con fecha de fin
4
+ SCHEDULED = "SCHEDULED",// programada (hoy < from)
5
+ PERMANENT = "PERMANENT",// vigente sin fin (effectiveTo null)
6
+ EXPIRED = "EXPIRED"
7
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromotionStatus = void 0;
4
+ /** Estado DERIVADO de effectiveFrom/To vs hoy (UTC). NO se persiste. */
5
+ var PromotionStatus;
6
+ (function (PromotionStatus) {
7
+ PromotionStatus["ACTIVE"] = "ACTIVE";
8
+ PromotionStatus["SCHEDULED"] = "SCHEDULED";
9
+ PromotionStatus["PERMANENT"] = "PERMANENT";
10
+ PromotionStatus["EXPIRED"] = "EXPIRED";
11
+ })(PromotionStatus || (exports.PromotionStatus = PromotionStatus = {}));
@@ -12,3 +12,8 @@ export * from "./AuditAction";
12
12
  export * from "./AuditEntityType";
13
13
  export * from "./SegmentMemberType";
14
14
  export * from "./RemittanceCorridor";
15
+ export * from "./PromotionKind";
16
+ export * from "./PromotionActivation";
17
+ export * from "./PromotionStatus";
18
+ export * from "./FxEffectMode";
19
+ export * from "./FeeEffectMode";
@@ -28,3 +28,8 @@ __exportStar(require("./AuditAction"), exports);
28
28
  __exportStar(require("./AuditEntityType"), exports);
29
29
  __exportStar(require("./SegmentMemberType"), exports);
30
30
  __exportStar(require("./RemittanceCorridor"), exports);
31
+ __exportStar(require("./PromotionKind"), exports);
32
+ __exportStar(require("./PromotionActivation"), exports);
33
+ __exportStar(require("./PromotionStatus"), exports);
34
+ __exportStar(require("./FxEffectMode"), exports);
35
+ __exportStar(require("./FeeEffectMode"), exports);
@@ -5,3 +5,4 @@ export * from "./dtos/internal/RemittanceCreditBackResponse";
5
5
  export * from "./dtos/internal/RemittanceCohortCount";
6
6
  export * from "./dtos/internal/RemittanceSegmentMetrics";
7
7
  export * from "./dtos/internal/RemittancePricingBridge";
8
+ export * from "./dtos/internal/RemittancePromotionReach";
@@ -23,3 +23,4 @@ __exportStar(require("./dtos/internal/RemittanceCreditBackResponse"), exports);
23
23
  __exportStar(require("./dtos/internal/RemittanceCohortCount"), exports);
24
24
  __exportStar(require("./dtos/internal/RemittanceSegmentMetrics"), exports);
25
25
  __exportStar(require("./dtos/internal/RemittancePricingBridge"), exports);
26
+ __exportStar(require("./dtos/internal/RemittancePromotionReach"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.153.0",
3
+ "version": "3.154.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,162 @@
1
+ import { Type } from "class-transformer";
2
+ import {
3
+ IsEnum,
4
+ IsInt,
5
+ IsNumber,
6
+ IsOptional,
7
+ IsString,
8
+ Length,
9
+ Matches,
10
+ Max,
11
+ MaxLength,
12
+ Min,
13
+ ValidateNested,
14
+ } from "class-validator";
15
+ import { FeeEffectMode } from "../enums/FeeEffectMode";
16
+ import { FxEffectMode } from "../enums/FxEffectMode";
17
+ import { PromotionActivation } from "../enums/PromotionActivation";
18
+ import { PromotionKind } from "../enums/PromotionKind";
19
+ import { PromotionStatus } from "../enums/PromotionStatus";
20
+ import { RemittanceCorridor } from "../enums/RemittanceCorridor";
21
+
22
+ /**
23
+ * DTOs de Promociones (Dashboard Ops · Variables Operativas §2).
24
+ *
25
+ * UniTeller NO participa (no hay motor de promos en API Lite): toda la lógica
26
+ * vive en Fiado. Una promo es un OVERRIDE de Precio Base (markup y/o fee) para
27
+ * una audiencia (corridor × segmento × cohort, null = Cualquiera) y vigencia.
28
+ * Dueño de la tabla: remittance-business (RemittancePromotions_GT). La
29
+ * resolución en send-time (capas: base → PRICE_CHANGE → mejor-para-el-cliente)
30
+ * es Fase B — estos DTOs cubren la config.
31
+ */
32
+
33
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
34
+
35
+ /** Audiencia: null en una dimensión = "Cualquiera". */
36
+ export class PromotionAudience {
37
+ @IsOptional()
38
+ @IsEnum(RemittanceCorridor)
39
+ corridor?: RemittanceCorridor | null;
40
+
41
+ @IsOptional()
42
+ @IsString()
43
+ @Length(1, 100)
44
+ segmentId?: string | null;
45
+
46
+ @IsOptional()
47
+ @IsString()
48
+ @Length(1, 100)
49
+ cohortId?: string | null;
50
+ }
51
+
52
+ /** Efecto FX (spread): DELTA suma bps CON SIGNO al markup base; ABSOLUTE lo reemplaza. */
53
+ export class FxEffect {
54
+ @IsEnum(FxEffectMode)
55
+ mode!: FxEffectMode;
56
+
57
+ /** bps con signo. Ignorado si mode=NONE (mandar 0). */
58
+ @IsInt()
59
+ @Min(-500)
60
+ @Max(500)
61
+ valueBps!: number;
62
+ }
63
+
64
+ /** Efecto fee: ABSOLUTE = $; DELTA = ±$; PERCENTAGE = −% del fee (0-100). */
65
+ export class FeeEffect {
66
+ @IsEnum(FeeEffectMode)
67
+ mode!: FeeEffectMode;
68
+
69
+ @IsNumber()
70
+ @Min(-100)
71
+ @Max(100)
72
+ value!: number;
73
+ }
74
+
75
+ export class CreatePromotionRequest {
76
+ @IsString()
77
+ @Length(3, 100)
78
+ name!: string;
79
+
80
+ @IsEnum(PromotionKind)
81
+ kind!: PromotionKind;
82
+
83
+ @IsEnum(PromotionActivation)
84
+ activation!: PromotionActivation;
85
+
86
+ /** Requerido si activation=CODE (regla en manager); único case-insensitive. */
87
+ @IsOptional()
88
+ @IsString()
89
+ @Length(3, 30)
90
+ @Matches(/^[A-Z0-9_-]+$/i)
91
+ code?: string | null;
92
+
93
+ @ValidateNested()
94
+ @Type(() => PromotionAudience)
95
+ audience!: PromotionAudience;
96
+
97
+ /** ISO date (YYYY-MM-DD). */
98
+ @IsString()
99
+ @Matches(ISO_DATE)
100
+ effectiveFrom!: string;
101
+
102
+ /** ISO date; null/ausente = permanente (∞). */
103
+ @IsOptional()
104
+ @IsString()
105
+ @Matches(ISO_DATE)
106
+ effectiveTo?: string | null;
107
+
108
+ @ValidateNested()
109
+ @Type(() => FxEffect)
110
+ fxEffect!: FxEffect;
111
+
112
+ @ValidateNested()
113
+ @Type(() => FeeEffect)
114
+ feeEffect!: FeeEffect;
115
+
116
+ @IsOptional()
117
+ @IsString()
118
+ @MaxLength(500)
119
+ notes?: string | null;
120
+ }
121
+
122
+ /** PUT — reemplazo completo (mismos campos que create). */
123
+ export class UpdatePromotionRequest extends CreatePromotionRequest {
124
+ }
125
+
126
+ /** Promoción completa (response de list/create/update). */
127
+ export class Promotion {
128
+ id!: string;
129
+ name!: string;
130
+ kind!: PromotionKind;
131
+ activation!: PromotionActivation;
132
+ code!: string | null;
133
+ audience!: { corridor: RemittanceCorridor | null; segmentId: string | null; cohortId: string | null };
134
+ /** Display: nombres resueltos de segmento/cohort (null = "Cualquiera" o no resoluble). */
135
+ audienceDisplay!: { corridor: string | null; segmentName: string | null; cohortName: string | null };
136
+ effectiveFrom!: string;
137
+ effectiveTo!: string | null;
138
+ fxEffect!: { mode: FxEffectMode; valueBps: number };
139
+ feeEffect!: { mode: FeeEffectMode; value: number };
140
+ /** Derivado de la vigencia vs hoy (UTC). */
141
+ status!: PromotionStatus;
142
+ /** Legible para la columna EFECTO: "MU −30 bps + Fee = $0". */
143
+ effectSummary!: string;
144
+ notes!: string | null;
145
+ createdAt!: string;
146
+ updatedAt!: string;
147
+ createdBy!: string;
148
+ updatedBy!: string;
149
+ }
150
+
151
+ /** Response de GET /backoffice/pricing/promotions. */
152
+ export class PromotionListResponse {
153
+ items!: Promotion[];
154
+ }
155
+
156
+ /** Response de GET /backoffice/pricing/promotions/reach. */
157
+ export class PromotionReachResponse {
158
+ /** Clientes en la intersección corridor × segmento × cohort. */
159
+ reach!: number;
160
+ /** Universo (todos los RemittanceUsers) — para el % del picker. */
161
+ total!: number;
162
+ }
@@ -41,3 +41,4 @@ export * from "./RemittanceAuditLog";
41
41
  export * from "./RemittanceSegment";
42
42
  export * from "./RemittanceCommittee";
43
43
  export * from "./RemittancePricing";
44
+ export * from "./RemittancePromotion";
@@ -0,0 +1,31 @@
1
+ import { Type } from "class-transformer";
2
+ import { IsArray, IsEnum, IsOptional, IsUUID, ValidateNested } from "class-validator";
3
+ import { CohortCondition } from "../RemittanceCohort";
4
+ import { RemittanceCorridor } from "../../enums/RemittanceCorridor";
5
+
6
+ /**
7
+ * Contrato interno del reach de Promociones (puente Opción A):
8
+ * POST /backoffice/config/promotions/reach (privado connector). rb resuelve las
9
+ * dimensiones a datos crudos — segmento → directoryIds; cohort → conditions;
10
+ * corredor → corridor — y el connector computa la intersección sobre el universo
11
+ * de RemittanceUsers. Toda dimensión AUSENTE = no filtra ("Cualquiera").
12
+ */
13
+ export class PromotionReachRequest {
14
+ /** Miembros del segmento (resueltos por rb). Ausente = todos los usuarios. */
15
+ @IsOptional()
16
+ @IsArray()
17
+ @IsUUID("4", { each: true })
18
+ directoryIds?: string[];
19
+
20
+ /** Condiciones del cohort (AND, evaluadas como en cohortCount). Ausente = sin filtro. */
21
+ @IsOptional()
22
+ @IsArray()
23
+ @ValidateNested({ each: true })
24
+ @Type(() => CohortCondition)
25
+ conditions?: CohortCondition[];
26
+
27
+ /** Filtro por corredor (countryISO de CORRIDOR_INFO, ≥1 tx no-cancelada histórica). Ausente = sin filtro. */
28
+ @IsOptional()
29
+ @IsEnum(RemittanceCorridor)
30
+ corridor?: RemittanceCorridor;
31
+ }
@@ -0,0 +1,7 @@
1
+ /** Efecto de la promo sobre el service fee (relativo a la base efectiva). */
2
+ export enum FeeEffectMode {
3
+ NONE = "NONE", // sin cambio
4
+ ABSOLUTE = "ABSOLUTE", // fee = value (USD)
5
+ DELTA = "DELTA", // baseFee + value (CON SIGNO)
6
+ PERCENTAGE = "PERCENTAGE", // baseFee × (1 − value/100), value 0-100
7
+ }
@@ -0,0 +1,6 @@
1
+ /** Efecto de la promo sobre el spread FX (relativo a la base efectiva). */
2
+ export enum FxEffectMode {
3
+ NONE = "NONE", // sin cambio
4
+ DELTA = "DELTA", // baseMarkup + valueBps (CON SIGNO)
5
+ ABSOLUTE = "ABSOLUTE", // markup = valueBps
6
+ }
@@ -0,0 +1,7 @@
1
+ /** Cómo se activa la promo para el cliente. */
2
+ export enum PromotionActivation {
3
+ /** Auto-aplica a toda la audiencia. */
4
+ AUTOMATIC = "AUTOMATIC",
5
+ /** El cliente teclea el código en la app (habilita SOLO esa promo). */
6
+ CODE = "CODE",
7
+ }
@@ -0,0 +1,9 @@
1
+ /** Tipo de promoción (Variables Operativas › Promociones — mockup). */
2
+ export enum PromotionKind {
3
+ /** Descuento promocional temporal (puede tener código). */
4
+ PROMO = "PROMO",
5
+ /** Cambio de BASE programado (overlay absoluto; NO muta RemittancePricing_GT). */
6
+ PRICE_CHANGE = "PRICE_CHANGE",
7
+ /** Override permanente por audiencia (VIP, Onboarding sin fee, …). */
8
+ PREFERENTIAL = "PREFERENTIAL",
9
+ }
@@ -0,0 +1,7 @@
1
+ /** Estado DERIVADO de effectiveFrom/To vs hoy (UTC). NO se persiste. */
2
+ export enum PromotionStatus {
3
+ ACTIVE = "ACTIVE", // vigente con fecha de fin
4
+ SCHEDULED = "SCHEDULED", // programada (hoy < from)
5
+ PERMANENT = "PERMANENT", // vigente sin fin (effectiveTo null)
6
+ EXPIRED = "EXPIRED", // vencida (hoy > to)
7
+ }
@@ -12,3 +12,8 @@ export * from "./AuditAction";
12
12
  export * from "./AuditEntityType";
13
13
  export * from "./SegmentMemberType";
14
14
  export * from "./RemittanceCorridor";
15
+ export * from "./PromotionKind";
16
+ export * from "./PromotionActivation";
17
+ export * from "./PromotionStatus";
18
+ export * from "./FxEffectMode";
19
+ export * from "./FeeEffectMode";
@@ -7,3 +7,4 @@ export * from "./dtos/internal/RemittanceCreditBackResponse";
7
7
  export * from "./dtos/internal/RemittanceCohortCount";
8
8
  export * from "./dtos/internal/RemittanceSegmentMetrics";
9
9
  export * from "./dtos/internal/RemittancePricingBridge";
10
+ export * from "./dtos/internal/RemittancePromotionReach";