@fiado/type-kit 3.613.0 → 3.615.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 (153) hide show
  1. package/_test_/unit/loanCredit/dtos/originateLoanCreditRequest.test.ts +9 -0
  2. package/_test_/unit/loanCredit/segmentFactsDtos.test.ts +80 -0
  3. package/_test_/unit/loanOfferings/promotionRetailerScope.test.ts +79 -0
  4. package/_test_/unit/loanOfferings/segmentCatalog.test.ts +4 -2
  5. package/_test_/unit/loanOfferings/segmentCohorts.test.ts +333 -0
  6. package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.d.ts +2 -0
  7. package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.js +7 -0
  8. package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.d.ts +4 -0
  9. package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.js +27 -0
  10. package/bin/loanCredit/dtos/requests/SegmentFactsPageRequest.d.ts +7 -0
  11. package/bin/loanCredit/dtos/requests/SegmentFactsPageRequest.js +32 -0
  12. package/bin/loanCredit/dtos/responses/BorrowerSegmentFacts.d.ts +22 -0
  13. package/bin/loanCredit/dtos/responses/BorrowerSegmentFacts.js +2 -0
  14. package/bin/loanCredit/dtos/responses/SegmentFactsBatchResponse.d.ts +5 -0
  15. package/bin/loanCredit/dtos/responses/SegmentFactsBatchResponse.js +2 -0
  16. package/bin/loanCredit/dtos/responses/SegmentFactsPageResponse.d.ts +7 -0
  17. package/bin/loanCredit/dtos/responses/SegmentFactsPageResponse.js +2 -0
  18. package/bin/loanCredit/index.d.ts +5 -0
  19. package/bin/loanCredit/index.js +6 -0
  20. package/bin/loanOfferings/constants/promotionRetailerScope.d.ts +2 -0
  21. package/bin/loanOfferings/constants/promotionRetailerScope.js +5 -0
  22. package/bin/loanOfferings/dtos/requests/ChangeCohortStatusRequest.d.ts +9 -0
  23. package/bin/loanOfferings/dtos/requests/ChangeCohortStatusRequest.js +34 -0
  24. package/bin/loanOfferings/dtos/requests/CohortCondition.d.ts +15 -0
  25. package/bin/loanOfferings/dtos/requests/CohortCondition.js +48 -0
  26. package/bin/loanOfferings/dtos/requests/CreateCohortRequest.d.ts +11 -0
  27. package/bin/loanOfferings/dtos/requests/CreateCohortRequest.js +44 -0
  28. package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.d.ts +2 -0
  29. package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.js +10 -0
  30. package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.d.ts +7 -8
  31. package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.js +5 -3
  32. package/bin/loanOfferings/dtos/requests/CustomerSegmentFacts.d.ts +30 -0
  33. package/bin/loanOfferings/dtos/requests/CustomerSegmentFacts.js +92 -0
  34. package/bin/loanOfferings/dtos/requests/ListCohortsQuery.d.ts +5 -0
  35. package/bin/loanOfferings/dtos/requests/ListCohortsQuery.js +25 -0
  36. package/bin/loanOfferings/dtos/requests/ListPromotedSkusRequest.d.ts +2 -0
  37. package/bin/loanOfferings/dtos/requests/ListPromotedSkusRequest.js +7 -0
  38. package/bin/loanOfferings/dtos/requests/ListSkuPromotionsRequest.d.ts +2 -0
  39. package/bin/loanOfferings/dtos/requests/ListSkuPromotionsRequest.js +7 -0
  40. package/bin/loanOfferings/dtos/requests/ResolveCustomerSegmentsRequest.d.ts +4 -20
  41. package/bin/loanOfferings/dtos/requests/ResolveCustomerSegmentsRequest.js +4 -48
  42. package/bin/loanOfferings/dtos/requests/ResolveSegmentMembersRequest.d.ts +8 -0
  43. package/bin/loanOfferings/dtos/requests/ResolveSegmentMembersRequest.js +31 -0
  44. package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.d.ts +2 -0
  45. package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.js +7 -0
  46. package/bin/loanOfferings/dtos/requests/TestCohortRequest.d.ts +9 -0
  47. package/bin/loanOfferings/dtos/requests/TestCohortRequest.js +36 -0
  48. package/bin/loanOfferings/dtos/requests/TestCustomerSegmentsRequest.d.ts +4 -0
  49. package/bin/loanOfferings/dtos/requests/TestCustomerSegmentsRequest.js +23 -0
  50. package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.d.ts +12 -0
  51. package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.js +53 -0
  52. package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.d.ts +2 -0
  53. package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.js +10 -0
  54. package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.d.ts +2 -2
  55. package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.js +3 -1
  56. package/bin/loanOfferings/dtos/responses/CohortCatalogResponse.d.ts +33 -0
  57. package/bin/loanOfferings/dtos/responses/CohortCatalogResponse.js +2 -0
  58. package/bin/loanOfferings/dtos/responses/CohortLogEntryResponse.d.ts +11 -0
  59. package/bin/loanOfferings/dtos/responses/CohortLogEntryResponse.js +2 -0
  60. package/bin/loanOfferings/dtos/responses/CohortResponse.d.ts +43 -0
  61. package/bin/loanOfferings/dtos/responses/CohortResponse.js +2 -0
  62. package/bin/loanOfferings/dtos/responses/PromotionResponse.d.ts +2 -0
  63. package/bin/loanOfferings/dtos/responses/SegmentCatalogResponse.d.ts +5 -2
  64. package/bin/loanOfferings/dtos/responses/SegmentLogEntryResponse.d.ts +11 -0
  65. package/bin/loanOfferings/dtos/responses/SegmentLogEntryResponse.js +2 -0
  66. package/bin/loanOfferings/dtos/responses/SegmentMembersResponse.d.ts +19 -0
  67. package/bin/loanOfferings/dtos/responses/SegmentMembersResponse.js +2 -0
  68. package/bin/loanOfferings/dtos/responses/SegmentResponse.d.ts +12 -6
  69. package/bin/loanOfferings/dtos/responses/SegmentUsageResponse.d.ts +18 -0
  70. package/bin/loanOfferings/dtos/responses/SegmentUsageResponse.js +2 -0
  71. package/bin/loanOfferings/dtos/responses/SegmentationRecountRunResponse.d.ts +23 -0
  72. package/bin/loanOfferings/dtos/responses/SegmentationRecountRunResponse.js +2 -0
  73. package/bin/loanOfferings/dtos/responses/SegmentationRecountStartResponse.d.ts +6 -0
  74. package/bin/loanOfferings/dtos/responses/SegmentationRecountStartResponse.js +2 -0
  75. package/bin/loanOfferings/dtos/responses/TestCohortResponse.d.ts +17 -0
  76. package/bin/loanOfferings/dtos/responses/TestCohortResponse.js +2 -0
  77. package/bin/loanOfferings/dtos/responses/TestCustomerSegmentsResponse.d.ts +23 -0
  78. package/bin/loanOfferings/dtos/responses/TestCustomerSegmentsResponse.js +2 -0
  79. package/bin/loanOfferings/enums/CohortConditionOutcomeEnum.d.ts +10 -0
  80. package/bin/loanOfferings/enums/CohortConditionOutcomeEnum.js +14 -0
  81. package/bin/loanOfferings/enums/CohortFactKeyEnum.d.ts +17 -0
  82. package/bin/loanOfferings/enums/CohortFactKeyEnum.js +21 -0
  83. package/bin/loanOfferings/enums/CohortFactTypeEnum.d.ts +9 -0
  84. package/bin/loanOfferings/enums/CohortFactTypeEnum.js +13 -0
  85. package/bin/loanOfferings/enums/CohortLogEventEnum.d.ts +10 -0
  86. package/bin/loanOfferings/enums/CohortLogEventEnum.js +14 -0
  87. package/bin/loanOfferings/enums/CohortOperatorEnum.d.ts +15 -0
  88. package/bin/loanOfferings/enums/CohortOperatorEnum.js +19 -0
  89. package/bin/loanOfferings/enums/CohortStatusEnum.d.ts +9 -0
  90. package/bin/loanOfferings/enums/CohortStatusEnum.js +13 -0
  91. package/bin/loanOfferings/enums/SegmentFilterIdEnum.d.ts +2 -0
  92. package/bin/loanOfferings/enums/SegmentFilterIdEnum.js +2 -0
  93. package/bin/loanOfferings/enums/SegmentLogEventEnum.d.ts +10 -0
  94. package/bin/loanOfferings/enums/SegmentLogEventEnum.js +14 -0
  95. package/bin/loanOfferings/enums/SegmentMembershipReasonEnum.d.ts +9 -0
  96. package/bin/loanOfferings/enums/SegmentMembershipReasonEnum.js +13 -0
  97. package/bin/loanOfferings/enums/SegmentationRecountStatusEnum.d.ts +9 -0
  98. package/bin/loanOfferings/enums/SegmentationRecountStatusEnum.js +13 -0
  99. package/bin/loanOfferings/enums/SegmentationRecountTriggerEnum.d.ts +8 -0
  100. package/bin/loanOfferings/enums/SegmentationRecountTriggerEnum.js +12 -0
  101. package/bin/loanOfferings/index.d.ts +30 -0
  102. package/bin/loanOfferings/index.js +30 -0
  103. package/package.json +1 -1
  104. package/src/loanCredit/dtos/requests/OriginateLoanCreditRequest.ts +7 -0
  105. package/src/loanCredit/dtos/requests/SegmentFactsBatchRequest.ts +13 -0
  106. package/src/loanCredit/dtos/requests/SegmentFactsPageRequest.ts +19 -0
  107. package/src/loanCredit/dtos/responses/BorrowerSegmentFacts.ts +24 -0
  108. package/src/loanCredit/dtos/responses/SegmentFactsBatchResponse.ts +6 -0
  109. package/src/loanCredit/dtos/responses/SegmentFactsPageResponse.ts +8 -0
  110. package/src/loanCredit/index.ts +7 -0
  111. package/src/loanOfferings/constants/promotionRetailerScope.ts +2 -0
  112. package/src/loanOfferings/dtos/requests/ChangeCohortStatusRequest.ts +19 -0
  113. package/src/loanOfferings/dtos/requests/CohortCondition.ts +33 -0
  114. package/src/loanOfferings/dtos/requests/CreateCohortRequest.ts +29 -0
  115. package/src/loanOfferings/dtos/requests/CreatePromotionRequest.ts +12 -0
  116. package/src/loanOfferings/dtos/requests/CreateSegmentRequest.ts +10 -9
  117. package/src/loanOfferings/dtos/requests/CustomerSegmentFacts.ts +79 -0
  118. package/src/loanOfferings/dtos/requests/ListCohortsQuery.ts +11 -0
  119. package/src/loanOfferings/dtos/requests/ListPromotedSkusRequest.ts +7 -0
  120. package/src/loanOfferings/dtos/requests/ListSkuPromotionsRequest.ts +7 -0
  121. package/src/loanOfferings/dtos/requests/ResolveCustomerSegmentsRequest.ts +5 -49
  122. package/src/loanOfferings/dtos/requests/ResolveSegmentMembersRequest.ts +17 -0
  123. package/src/loanOfferings/dtos/requests/SimulateCreditPlanRequest.ts +8 -1
  124. package/src/loanOfferings/dtos/requests/TestCohortRequest.ts +21 -0
  125. package/src/loanOfferings/dtos/requests/TestCustomerSegmentsRequest.ts +9 -0
  126. package/src/loanOfferings/dtos/requests/UpdateCohortRequest.ts +37 -0
  127. package/src/loanOfferings/dtos/requests/UpdatePromotionRequest.ts +12 -0
  128. package/src/loanOfferings/dtos/requests/UpdateSegmentRequest.ts +5 -3
  129. package/src/loanOfferings/dtos/responses/CohortCatalogResponse.ts +36 -0
  130. package/src/loanOfferings/dtos/responses/CohortLogEntryResponse.ts +12 -0
  131. package/src/loanOfferings/dtos/responses/CohortResponse.ts +47 -0
  132. package/src/loanOfferings/dtos/responses/PromotionResponse.ts +2 -0
  133. package/src/loanOfferings/dtos/responses/SegmentCatalogResponse.ts +5 -2
  134. package/src/loanOfferings/dtos/responses/SegmentLogEntryResponse.ts +12 -0
  135. package/src/loanOfferings/dtos/responses/SegmentMembersResponse.ts +21 -0
  136. package/src/loanOfferings/dtos/responses/SegmentResponse.ts +12 -6
  137. package/src/loanOfferings/dtos/responses/SegmentUsageResponse.ts +20 -0
  138. package/src/loanOfferings/dtos/responses/SegmentationRecountRunResponse.ts +25 -0
  139. package/src/loanOfferings/dtos/responses/SegmentationRecountStartResponse.ts +7 -0
  140. package/src/loanOfferings/dtos/responses/TestCohortResponse.ts +19 -0
  141. package/src/loanOfferings/dtos/responses/TestCustomerSegmentsResponse.ts +25 -0
  142. package/src/loanOfferings/enums/CohortConditionOutcomeEnum.ts +10 -0
  143. package/src/loanOfferings/enums/CohortFactKeyEnum.ts +17 -0
  144. package/src/loanOfferings/enums/CohortFactTypeEnum.ts +9 -0
  145. package/src/loanOfferings/enums/CohortLogEventEnum.ts +10 -0
  146. package/src/loanOfferings/enums/CohortOperatorEnum.ts +15 -0
  147. package/src/loanOfferings/enums/CohortStatusEnum.ts +9 -0
  148. package/src/loanOfferings/enums/SegmentFilterIdEnum.ts +2 -0
  149. package/src/loanOfferings/enums/SegmentLogEventEnum.ts +10 -0
  150. package/src/loanOfferings/enums/SegmentMembershipReasonEnum.ts +9 -0
  151. package/src/loanOfferings/enums/SegmentationRecountStatusEnum.ts +9 -0
  152. package/src/loanOfferings/enums/SegmentationRecountTriggerEnum.ts +8 -0
  153. package/src/loanOfferings/index.ts +30 -0
@@ -1,12 +1,12 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsArray, IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
2
+ import { ArrayMaxSize, IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
3
  import { SegmentColorSlotEnum } from '../../enums/SegmentColorSlotEnum';
4
4
 
5
5
  /**
6
6
  * Body de POST /segments — alta de un segmento de clientes.
7
7
  * Nace en `ACTIVE`: `segmentId`, `status`, `version`, `isDefault` y la auditoría los asigna el
8
- * lambda y NO viajan en el request. Que cada filtro exista en el catálogo y tenga fuente lo valida
9
- * el lambda contra `GET /segments/filters`.
8
+ * lambda y NO viajan en el request. Que cada cohort exista y esté activo lo valida el lambda, igual
9
+ * que la regla de tener al menos un cohort o un individuo.
10
10
  */
11
11
  export class CreateSegmentRequest {
12
12
  @Expose()
@@ -27,19 +27,20 @@ export class CreateSegmentRequest {
27
27
  colorSlot?: SegmentColorSlotEnum;
28
28
 
29
29
  /**
30
- * Filtros del catálogo cerrado. Un cliente pertenece si cumple AL MENOS UNO — es un OR, no un
31
- * AND. Se valida contra el catálogo en el lambda (422), no acá, para poder nombrar el filtro
32
- * desconocido y el que todavía no tiene fuente.
30
+ * Cohorts del segmento. Un cliente pertenece si cumple AL MENOS UNO — es un OR entre cohorts;
31
+ * dentro de cada cohort las condiciones se unen con Y.
33
32
  */
34
33
  @Expose()
35
34
  @IsOptional()
36
35
  @IsArray()
37
36
  @IsString({ each: true })
38
- filterIds?: string[];
37
+ @IsNotEmpty({ each: true })
38
+ @ArrayMaxSize(20)
39
+ cohortIds?: string[];
39
40
 
40
41
  /**
41
- * Clientes agregados a mano por `retailCustomerId`. Ganan siempre, cumplan o no un filtro.
42
- * Un segmento puede nacer SOLO con esta lista, sin ningún filtro activo.
42
+ * Clientes agregados a mano por `retailCustomerId`. Ganan siempre, cumplan o no un cohort.
43
+ * Un segmento puede nacer SOLO con esta lista, sin ningún cohort.
43
44
  */
44
45
  @Expose()
45
46
  @IsOptional()
@@ -0,0 +1,79 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsBoolean, IsEnum, IsInt, IsOptional, Min } from 'class-validator';
3
+ import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
4
+
5
+ /**
6
+ * Datos del cliente contra los que se evalúan los cohorts. Las llaves son las de
7
+ * `CohortFactKeyEnum`. Todos opcionales: un dato ausente hace que su condición no se cumpla.
8
+ *
9
+ * Cliente sin acreditado: conteos y días en `0`, `sciLevel` ausente. `sciLevel` en `ALL` o
10
+ * `NOT_ELIGIBLE` se manda ausente.
11
+ */
12
+ export class CustomerSegmentFacts {
13
+ /** Nivel de la última evaluación SCI del acreditado. */
14
+ @Expose()
15
+ @IsOptional()
16
+ @IsEnum(CreditPlanLevelEnum)
17
+ sciLevel?: CreditPlanLevelEnum;
18
+
19
+ /** Créditos en toda la vida del cliente, en cualquier estado. */
20
+ @Expose()
21
+ @IsOptional()
22
+ @IsInt()
23
+ @Min(0)
24
+ totalCredits?: number;
25
+
26
+ /** Créditos vivos hoy. */
27
+ @Expose()
28
+ @IsOptional()
29
+ @IsInt()
30
+ @Min(0)
31
+ activeCredits?: number;
32
+
33
+ /** Créditos liquidados en toda la vida del cliente. */
34
+ @Expose()
35
+ @IsOptional()
36
+ @IsInt()
37
+ @Min(0)
38
+ completedCredits?: number;
39
+
40
+ /** Créditos con baja contable en toda la vida del cliente. `0` es ninguno. */
41
+ @Expose()
42
+ @IsOptional()
43
+ @IsInt()
44
+ @Min(0)
45
+ lifetimeWriteOffs?: number;
46
+
47
+ /** Días de atraso hoy. `0` es al corriente. */
48
+ @Expose()
49
+ @IsOptional()
50
+ @IsInt()
51
+ @Min(0)
52
+ currentArrearsDays?: number;
53
+
54
+ /** Días de mora en la ventana de 180 días. Sin cuotas en la ventana cuenta como `0`. */
55
+ @Expose()
56
+ @IsOptional()
57
+ @IsInt()
58
+ @Min(0)
59
+ delinquencyDaysLast6M?: number;
60
+
61
+ /** Reestructuras en toda la vida del cliente. `0` es ninguna. */
62
+ @Expose()
63
+ @IsOptional()
64
+ @IsInt()
65
+ @Min(0)
66
+ lifetimeRestructures?: number;
67
+
68
+ /** Colaborador de la red. Hoy ningún sistema lo produce: se usa la lista manual del segmento. */
69
+ @Expose()
70
+ @IsOptional()
71
+ @IsBoolean()
72
+ isEmployee?: boolean;
73
+
74
+ /** Tiene cuenta PCF. Sin fuente mientras no se defina qué cuenta como cuenta PCF. */
75
+ @Expose()
76
+ @IsOptional()
77
+ @IsBoolean()
78
+ hasPcfAccount?: boolean;
79
+ }
@@ -0,0 +1,11 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsEnum, IsOptional } from 'class-validator';
3
+ import { CohortStatusEnum } from '../../enums/CohortStatusEnum';
4
+
5
+ /** Query de GET /cohorts (backoffice). El tenant sale del token. Sin `status` devuelve todos. */
6
+ export class ListCohortsQuery {
7
+ @Expose()
8
+ @IsOptional()
9
+ @IsEnum(CohortStatusEnum)
10
+ status?: CohortStatusEnum;
11
+ }
@@ -11,6 +11,13 @@ export class ListPromotedSkusRequest {
11
11
  @IsNotEmpty()
12
12
  storeId!: string;
13
13
 
14
+ /** Cadena de la tienda; sin ella no se resuelven las promociones acotadas por cadena. */
15
+ @Expose()
16
+ @IsOptional()
17
+ @IsString()
18
+ @IsNotEmpty()
19
+ retailerId?: string;
20
+
14
21
  /** Nivel del cliente si loan-scoring ya corrió. */
15
22
  @Expose()
16
23
  @IsOptional()
@@ -11,6 +11,13 @@ export class ListSkuPromotionsRequest {
11
11
  @IsNotEmpty()
12
12
  storeId!: string;
13
13
 
14
+ /** Cadena de la tienda; sin ella no se resuelven las promociones acotadas por cadena. */
15
+ @Expose()
16
+ @IsOptional()
17
+ @IsString()
18
+ @IsNotEmpty()
19
+ retailerId?: string;
20
+
14
21
  /** Nivel del cliente si loan-scoring ya corrió. */
15
22
  @Expose()
16
23
  @IsOptional()
@@ -1,57 +1,13 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsBoolean, IsEnum, IsInt, IsOptional, IsString, Min } from 'class-validator';
3
- import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
2
+ import { IsString } from 'class-validator';
3
+ import { CustomerSegmentFacts } from './CustomerSegmentFacts';
4
4
 
5
5
  /**
6
- * Body de POST /private/segments/resolve — los hechos del cliente contra los que se evalúan los
7
- * filtros. Los junta quien ya tiene al cliente delante (el wizard o el motor de crédito); este
8
- * lambda no sale a buscarlos a otro silo en el camino caliente.
9
- *
10
- * Un hecho AUSENTE hace que su filtro NO se cumpla: sin el dato no se puede afirmar que el cliente
11
- * califica, y de las dos salidas la segura es dejarlo fuera.
6
+ * Body de POST /private/segments/resolve — el cliente y, opcionalmente, sus datos para evaluar los
7
+ * cohorts. Si el llamador no manda los datos, loan-offerings los pide a loan-credit.
12
8
  */
13
- export class ResolveCustomerSegmentsRequest {
9
+ export class ResolveCustomerSegmentsRequest extends CustomerSegmentFacts {
14
10
  @Expose()
15
11
  @IsString()
16
12
  retailCustomerId!: string;
17
-
18
- /** Colaborador de la red. Hoy ningún sistema lo produce — ver la lista de individuos. */
19
- @Expose()
20
- @IsOptional()
21
- @IsBoolean()
22
- isEmployee?: boolean;
23
-
24
- /** Nivel que resolvió loan-scoring a partir del SCI. */
25
- @Expose()
26
- @IsOptional()
27
- @IsEnum(CreditPlanLevelEnum)
28
- sciLevel?: CreditPlanLevelEnum;
29
-
30
- /** Créditos cerrados en toda la vida del cliente. */
31
- @Expose()
32
- @IsOptional()
33
- @IsInt()
34
- @Min(0)
35
- completedCredits?: number;
36
-
37
- /** Días de mora acumulados en la ventana de 180 días. `0` es sin mora. */
38
- @Expose()
39
- @IsOptional()
40
- @IsInt()
41
- @Min(0)
42
- delinquencyDaysLast6M?: number;
43
-
44
- /** Bajas contables vitalicias. `0` es ninguna. */
45
- @Expose()
46
- @IsOptional()
47
- @IsInt()
48
- @Min(0)
49
- lifetimeWriteOffs?: number;
50
-
51
- /** Reestructuras vitalicias. `0` es ninguna. */
52
- @Expose()
53
- @IsOptional()
54
- @IsInt()
55
- @Min(0)
56
- lifetimeRestructures?: number;
57
13
  }
@@ -0,0 +1,17 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { ArrayMaxSize, ArrayMinSize, IsArray, ValidateNested } from 'class-validator';
3
+ import { ResolveCustomerSegmentsRequest } from './ResolveCustomerSegmentsRequest';
4
+
5
+ /**
6
+ * Body de POST /private/segments/members — pertenencia a segmentos en lote, con cohorts. Cada
7
+ * cliente viaja con sus datos si el llamador los tiene; los que falten los pide loan-offerings.
8
+ */
9
+ export class ResolveSegmentMembersRequest {
10
+ @Expose()
11
+ @IsArray()
12
+ @ArrayMinSize(1)
13
+ @ArrayMaxSize(100)
14
+ @ValidateNested({ each: true })
15
+ @Type(() => ResolveCustomerSegmentsRequest)
16
+ customers!: ResolveCustomerSegmentsRequest[];
17
+ }
@@ -1,5 +1,5 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsArray, IsEnum, IsInt, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
2
+ import { IsArray, IsEnum, IsInt, IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
3
3
  import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
4
4
  import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
5
5
 
@@ -61,6 +61,13 @@ export class SimulateCreditPlanRequest {
61
61
  @IsEnum(ProductTierEnum)
62
62
  productTier?: ProductTierEnum;
63
63
 
64
+ /** Cadena de la tienda que cotiza; sin ella no se resuelven las promociones acotadas por cadena. */
65
+ @Expose()
66
+ @IsOptional()
67
+ @IsString()
68
+ @IsNotEmpty()
69
+ retailerId?: string;
70
+
64
71
  /**
65
72
  * Segmentos del cliente, los que devolvió `POST /private/segments/resolve`. Un arreglo vacío
66
73
  * declara que el cliente no está en ninguno; ausente declara que el caller no lo consultó.
@@ -0,0 +1,21 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { ArrayMaxSize, ArrayMinSize, IsArray, IsString, ValidateNested } from 'class-validator';
3
+ import { CohortCondition } from './CohortCondition';
4
+
5
+ /**
6
+ * Body de POST /cohorts/test — prueba unas condiciones, guardadas o no, con un cliente. Devuelve
7
+ * los datos del cliente y el resultado de cada condición.
8
+ */
9
+ export class TestCohortRequest {
10
+ @Expose()
11
+ @IsString()
12
+ retailCustomerId!: string;
13
+
14
+ @Expose()
15
+ @IsArray()
16
+ @ArrayMinSize(1)
17
+ @ArrayMaxSize(10)
18
+ @ValidateNested({ each: true })
19
+ @Type(() => CohortCondition)
20
+ conditions!: CohortCondition[];
21
+ }
@@ -0,0 +1,9 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsString } from 'class-validator';
3
+
4
+ /** Body de POST /segments/test — en qué segmentos cae un cliente y por qué. */
5
+ export class TestCustomerSegmentsRequest {
6
+ @Expose()
7
+ @IsString()
8
+ retailCustomerId!: string;
9
+ }
@@ -0,0 +1,37 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { ArrayMaxSize, ArrayMinSize, IsArray, IsOptional, IsString, MaxLength, ValidateNested } from 'class-validator';
3
+ import { CohortCondition } from './CohortCondition';
4
+
5
+ /**
6
+ * Body de PUT /cohorts/:cohortId — edición parcial; ausente deja el campo como está. Sube
7
+ * `version`. El cambio de estado va por su endpoint dedicado.
8
+ */
9
+ export class UpdateCohortRequest {
10
+ @Expose()
11
+ @IsOptional()
12
+ @IsString()
13
+ @MaxLength(120)
14
+ name?: string;
15
+
16
+ @Expose()
17
+ @IsOptional()
18
+ @IsString()
19
+ @MaxLength(500)
20
+ description?: string;
21
+
22
+ /** Reemplaza todas las condiciones. */
23
+ @Expose()
24
+ @IsOptional()
25
+ @IsArray()
26
+ @ArrayMinSize(1)
27
+ @ArrayMaxSize(10)
28
+ @ValidateNested({ each: true })
29
+ @Type(() => CohortCondition)
30
+ conditions?: CohortCondition[];
31
+
32
+ @Expose()
33
+ @IsOptional()
34
+ @IsString()
35
+ @MaxLength(280)
36
+ reason?: string;
37
+ }
@@ -1,14 +1,17 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import {
3
+ ArrayMaxSize,
3
4
  ArrayNotEmpty,
4
5
  IsArray,
5
6
  IsEnum,
6
7
  IsInt,
7
8
  IsISO8601,
9
+ IsNotEmpty,
8
10
  IsOptional,
9
11
  IsString,
10
12
  ValidateNested,
11
13
  } from 'class-validator';
14
+ import { PROMOTION_RETAILER_IDS_MAX_ITEMS } from '../../constants/promotionRetailerScope';
12
15
  import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
13
16
  import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
14
17
  import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
@@ -68,6 +71,15 @@ export class UpdatePromotionRequest {
68
71
  @IsEnum(ProductTierEnum, { each: true })
69
72
  tiers?: ProductTierEnum[] | null;
70
73
 
74
+ /** Cadenas alcanzadas; ausente, `null` o vacío = todas las cadenas. */
75
+ @Expose()
76
+ @IsOptional()
77
+ @IsArray()
78
+ @ArrayMaxSize(PROMOTION_RETAILER_IDS_MAX_ITEMS)
79
+ @IsString({ each: true })
80
+ @IsNotEmpty({ each: true })
81
+ retailerIds?: string[] | null;
82
+
71
83
  /** Tiendas alcanzadas. `null` o ausente = todas. */
72
84
  @Expose()
73
85
  @IsOptional()
@@ -1,5 +1,5 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsArray, IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
2
+ import { ArrayMaxSize, IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
3
  import { SegmentColorSlotEnum } from '../../enums/SegmentColorSlotEnum';
4
4
 
5
5
  /**
@@ -27,12 +27,14 @@ export class UpdateSegmentRequest {
27
27
  @IsEnum(SegmentColorSlotEnum)
28
28
  colorSlot?: SegmentColorSlotEnum;
29
29
 
30
- /** Reemplaza la lista entera; `[]` deja el segmento sin filtros. */
30
+ /** Reemplaza la lista entera; `[]` deja el segmento sin cohorts. */
31
31
  @Expose()
32
32
  @IsOptional()
33
33
  @IsArray()
34
34
  @IsString({ each: true })
35
- filterIds?: string[];
35
+ @IsNotEmpty({ each: true })
36
+ @ArrayMaxSize(20)
37
+ cohortIds?: string[];
36
38
 
37
39
  /** Reemplaza la lista entera; `[]` saca a todos los agregados a mano. */
38
40
  @Expose()
@@ -0,0 +1,36 @@
1
+ import { CohortFactKeyEnum } from '../../enums/CohortFactKeyEnum';
2
+ import { CohortFactTypeEnum } from '../../enums/CohortFactTypeEnum';
3
+ import { CohortOperatorEnum } from '../../enums/CohortOperatorEnum';
4
+
5
+ /** Una opción de un dato de tipo `SELECT`. */
6
+ export interface CohortFactOption {
7
+ value: string;
8
+ label: string;
9
+ }
10
+
11
+ /**
12
+ * Un dato del cliente tal como lo pinta el armador de cohorts. El front lo toma de acá en vez de
13
+ * duplicar la lista.
14
+ */
15
+ export interface CohortFactFieldResponse {
16
+ key: CohortFactKeyEnum;
17
+ type: CohortFactTypeEnum;
18
+ label: string;
19
+ unit: string | null;
20
+ /** Solo en `SELECT`. */
21
+ options: CohortFactOption[] | null;
22
+ /** Operadores que admite su tipo. */
23
+ operators: CohortOperatorEnum[];
24
+ /**
25
+ * `false` cuando ningún sistema produce el dato: el armador lo muestra deshabilitado y el lambda
26
+ * rechaza guardar un cohort que lo use (422).
27
+ */
28
+ hasSource: boolean;
29
+ /** Por qué no tiene fuente. `null` cuando `hasSource` es `true`. */
30
+ missingSourceReason: string | null;
31
+ }
32
+
33
+ /** Respuesta de GET /cohorts/catalog. */
34
+ export interface CohortCatalogResponse {
35
+ fields: CohortFactFieldResponse[];
36
+ }
@@ -0,0 +1,12 @@
1
+ import { CohortLogEventEnum } from '../../enums/CohortLogEventEnum';
2
+
3
+ /** Un evento de la bitácora de un cohort. */
4
+ export interface CohortLogEntryResponse {
5
+ cohortId: string;
6
+ cohortName: string;
7
+ event: CohortLogEventEnum;
8
+ occurredAt: string;
9
+ performedBy: string;
10
+ reason: string | null;
11
+ version: number;
12
+ }
@@ -0,0 +1,47 @@
1
+ import { CohortFactKeyEnum } from '../../enums/CohortFactKeyEnum';
2
+ import { CohortOperatorEnum } from '../../enums/CohortOperatorEnum';
3
+ import { CohortStatusEnum } from '../../enums/CohortStatusEnum';
4
+
5
+ /** Una condición guardada. `value` y `values` van en `null` cuando el operador no los usa. */
6
+ export interface CohortConditionResponse {
7
+ field: CohortFactKeyEnum;
8
+ op: CohortOperatorEnum;
9
+ value: number | boolean | string | null;
10
+ values: string[] | null;
11
+ }
12
+
13
+ /** Un segmento que usa el cohort, con lo mínimo para enlazarlo. */
14
+ export interface CohortSegmentRef {
15
+ segmentId: string;
16
+ name: string;
17
+ }
18
+
19
+ /**
20
+ * Shape de salida de un cohort (GET / POST / PUT de /cohorts). Sus condiciones se unen con Y.
21
+ * Los conteos salen del último recálculo; `null` = sin calcular.
22
+ */
23
+ export interface CohortResponse {
24
+ cohortId: string;
25
+ name: string;
26
+ description: string | null;
27
+ conditions: CohortConditionResponse[];
28
+ status: CohortStatusEnum;
29
+ version: number;
30
+ memberCount: number | null;
31
+ /** Porcentaje de los acreditados del tenant, de 0 a 100 con un decimal. `null` = sin calcular. */
32
+ pctTotal: number | null;
33
+ countedAt: string | null;
34
+ /** `true` si nunca se contó o se editó después del último recálculo. */
35
+ countPending: boolean;
36
+ /** Segmentos ACTIVE que lo referencian. */
37
+ usedBySegments: CohortSegmentRef[];
38
+ createdAt: string;
39
+ updatedAt: string;
40
+ createdBy: string;
41
+ updatedBy: string;
42
+ }
43
+
44
+ /** Respuesta de GET /cohorts. */
45
+ export interface CohortListResponse {
46
+ cohorts: CohortResponse[];
47
+ }
@@ -28,6 +28,8 @@ export interface PromotionResponse {
28
28
  productCategories: ProductCategoryEnum[] | null;
29
29
  /** `null` = alcanza a todas las gamas. */
30
30
  tiers: ProductTierEnum[] | null;
31
+ /** `null` = alcanza a todas las cadenas. */
32
+ retailerIds: string[] | null;
31
33
  /** `null` = alcanza a todas las tiendas. Dimensión «Tienda / canal» del alcance. */
32
34
  storeIds: string[] | null;
33
35
  validFrom: string | null;
@@ -1,4 +1,3 @@
1
- import { SegmentFilterIdEnum } from '../../enums/SegmentFilterIdEnum';
2
1
  import { SegmentStatusEnum } from '../../enums/SegmentStatusEnum';
3
2
 
4
3
  /** Un segmento como lo necesita un selector: sin miembros ni metadatos de edición. */
@@ -6,7 +5,11 @@ export interface SegmentCatalogItem {
6
5
  segmentId: string;
7
6
  name: string;
8
7
  status: SegmentStatusEnum;
9
- filterIds: SegmentFilterIdEnum[];
8
+ cohortIds: string[];
9
+ /** `true` si el segmento tiene cohorts: su pertenencia depende de los datos del cliente. */
10
+ dependsOnFacts: boolean;
11
+ /** @deprecated Mismo contenido que `cohortIds`; usar `cohortIds` o `dependsOnFacts`. */
12
+ filterIds: string[];
10
13
  /** `true` solo en el catch-all, que el resolve nunca devuelve. */
11
14
  isDefault: boolean;
12
15
  }
@@ -0,0 +1,12 @@
1
+ import { SegmentLogEventEnum } from '../../enums/SegmentLogEventEnum';
2
+
3
+ /** Un evento de la bitácora de un segmento. */
4
+ export interface SegmentLogEntryResponse {
5
+ segmentId: string;
6
+ segmentName: string;
7
+ event: SegmentLogEventEnum;
8
+ occurredAt: string;
9
+ performedBy: string;
10
+ reason: string | null;
11
+ version: number;
12
+ }
@@ -0,0 +1,21 @@
1
+ /** Un segmento como lo pinta una celda de la tabla de clientes. */
2
+ export interface CustomerSegmentRef {
3
+ segmentId: string;
4
+ name: string;
5
+ /** `true` solo en el catch-all: el cliente no pertenece a ningún otro segmento. */
6
+ isDefault: boolean;
7
+ }
8
+
9
+ /** Un cliente pedido y sus segmentos. */
10
+ export interface CustomerSegmentsItem {
11
+ retailCustomerId: string;
12
+ segments: CustomerSegmentRef[];
13
+ }
14
+
15
+ /**
16
+ * Respuesta de la pertenencia a segmentos en lote: una fila por id pedido, en el orden en que
17
+ * llegaron, así el llamador distingue «ninguno» de «no vino».
18
+ */
19
+ export interface SegmentMembersResponse {
20
+ items: CustomerSegmentsItem[];
21
+ }
@@ -1,11 +1,10 @@
1
1
  import { SegmentColorSlotEnum } from '../../enums/SegmentColorSlotEnum';
2
- import { SegmentFilterIdEnum } from '../../enums/SegmentFilterIdEnum';
3
2
  import { SegmentStatusEnum } from '../../enums/SegmentStatusEnum';
4
3
 
5
4
  /**
6
5
  * Shape de salida de un segmento (GET / POST / PUT de /segments).
7
6
  *
8
- * Un cliente pertenece si cumple AL MENOS UNO de los `filterIds` (OR) **o** está en `memberIds`.
7
+ * Un cliente pertenece si cumple AL MENOS UNO de los `cohortIds` (OR) **o** está en `memberIds`.
9
8
  * No hay prioridad ni desempate: el cliente puede estar en varios segmentos a la vez.
10
9
  */
11
10
  export interface SegmentResponse {
@@ -13,14 +12,21 @@ export interface SegmentResponse {
13
12
  name: string;
14
13
  description: string | null;
15
14
  colorSlot: SegmentColorSlotEnum;
16
- /** Ids del catálogo cerrado. Vacío = no alcanza a nadie por regla. */
17
- filterIds: SegmentFilterIdEnum[];
18
- /** `retailCustomerId` agregados a mano. Ganan aunque el cliente no cumpla ningún filtro. */
15
+ /** Cohorts del segmento. Vacío = no alcanza a nadie por regla. */
16
+ cohortIds: string[];
17
+ /** `retailCustomerId` agregados a mano. Ganan aunque el cliente no cumpla ningún cohort. */
19
18
  memberIds: string[];
20
- /** El catch-all implícito. No acepta filtros ni individuos, no se archiva y solo se renombra. */
19
+ /** El catch-all implícito. No acepta cohorts ni individuos, no se archiva y solo se renombra. */
21
20
  isDefault: boolean;
22
21
  status: SegmentStatusEnum;
23
22
  version: number;
23
+ /** Clientes del último recálculo. En el catch-all, los que no cayeron en ningún segmento. `null` = sin calcular. */
24
+ clientCount: number | null;
25
+ /** Porcentaje de los acreditados del tenant, de 0 a 100 con un decimal. `null` = sin calcular. */
26
+ pctTotal: number | null;
27
+ countedAt: string | null;
28
+ /** `true` si nunca se contó o se editó después del último recálculo. */
29
+ countPending: boolean;
24
30
  createdAt: string;
25
31
  updatedAt: string;
26
32
  createdBy: string;
@@ -0,0 +1,20 @@
1
+ /** Una política de tienda que apunta al segmento. */
2
+ export interface SegmentUsagePolicyRef {
3
+ policyId: string;
4
+ name: string;
5
+ status: string;
6
+ }
7
+
8
+ /** Una promoción que apunta al segmento. */
9
+ export interface SegmentUsagePromotionRef {
10
+ promotionId: string;
11
+ name: string;
12
+ status: string;
13
+ }
14
+
15
+ /** Respuesta de GET /segments/:segmentId/usage: dónde se aplica el segmento, con su estado. */
16
+ export interface SegmentUsageResponse {
17
+ segmentId: string;
18
+ policies: SegmentUsagePolicyRef[];
19
+ promotions: SegmentUsagePromotionRef[];
20
+ }
@@ -0,0 +1,25 @@
1
+ import { SegmentationRecountStatusEnum } from '../../enums/SegmentationRecountStatusEnum';
2
+ import { SegmentationRecountTriggerEnum } from '../../enums/SegmentationRecountTriggerEnum';
3
+
4
+ /**
5
+ * Una corrida del recálculo de conteos de cohorts y segmentos. Los campos de cierre van en `null`
6
+ * mientras corre.
7
+ */
8
+ export interface SegmentationRecountRunResponse {
9
+ runId: string;
10
+ trigger: SegmentationRecountTriggerEnum;
11
+ status: SegmentationRecountStatusEnum;
12
+ /** Quién la disparó. */
13
+ actor: string;
14
+ startedAt: string;
15
+ finishedAt: string | null;
16
+ /** Acreditados evaluados. */
17
+ evaluated: number | null;
18
+ durationMs: number | null;
19
+ error: string | null;
20
+ }
21
+
22
+ /** Respuesta de GET /segmentation/recount/runs: la más reciente primero, máximo 50. */
23
+ export interface SegmentationRecountRunsResponse {
24
+ runs: SegmentationRecountRunResponse[];
25
+ }
@@ -0,0 +1,7 @@
1
+ import { SegmentationRecountStatusEnum } from '../../enums/SegmentationRecountStatusEnum';
2
+
3
+ /** Respuesta de POST /segmentation/recount: la corrida arranca en segundo plano. */
4
+ export interface SegmentationRecountStartResponse {
5
+ runId: string;
6
+ status: SegmentationRecountStatusEnum;
7
+ }