@fiado/type-kit 3.627.0 → 3.629.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 (212) hide show
  1. package/_test_/unit/collection/collectionCallbackRequests.test.ts +96 -0
  2. package/_test_/unit/gsfConnector/gsfMessages.test.ts +20 -0
  3. package/_test_/unit/loanCollectorAssignment/collectorAssignmentRequests.test.ts +65 -0
  4. package/_test_/unit/loanConfig/parameterWriteRequests.test.ts +62 -0
  5. package/_test_/unit/loanCredit/dtos/loanCreditInputLimits.test.ts +168 -0
  6. package/_test_/unit/loanCredit/signLoanCreditRequest.test.ts +61 -2
  7. package/_test_/unit/loanOfferings/offeringsInputRules.test.ts +254 -0
  8. package/_test_/unit/loanOfferings/promotionRequests.test.ts +1 -1
  9. package/_test_/unit/loanRetailAudit/auditInputLimits.test.ts +114 -0
  10. package/_test_/unit/loanScoring/evaluateSciRequest.test.ts +49 -0
  11. package/bin/collection/constants/CollectionResultLimits.d.ts +16 -0
  12. package/bin/collection/constants/CollectionResultLimits.js +19 -0
  13. package/bin/collection/dtos/ApplyCollectionResultRequest.d.ts +5 -0
  14. package/bin/collection/dtos/ApplyCollectionResultRequest.js +22 -0
  15. package/bin/collection/dtos/ResolvePendingChargesRequest.d.ts +2 -0
  16. package/bin/collection/dtos/ResolvePendingChargesRequest.js +9 -0
  17. package/bin/collection/index.d.ts +2 -0
  18. package/bin/collection/index.js +3 -0
  19. package/bin/collection/validators/IsCentPrecision.d.ts +11 -0
  20. package/bin/collection/validators/IsCentPrecision.js +32 -0
  21. package/bin/gsfConnector/dtos/GsfCreditTerms.d.ts +7 -2
  22. package/bin/gsfConnector/dtos/GsfCreditTerms.js +9 -0
  23. package/bin/loanCollectorAssignment/constants/CollectorAssignmentLimits.d.ts +12 -0
  24. package/bin/loanCollectorAssignment/constants/CollectorAssignmentLimits.js +15 -0
  25. package/bin/loanCollectorAssignment/dtos/requests/AutoAssignRequest.d.ts +1 -0
  26. package/bin/loanCollectorAssignment/dtos/requests/AutoAssignRequest.js +8 -0
  27. package/bin/loanCollectorAssignment/dtos/requests/ListCollectorAssignmentsRequest.d.ts +14 -0
  28. package/bin/loanCollectorAssignment/dtos/requests/ListCollectorAssignmentsRequest.js +62 -0
  29. package/bin/loanCollectorAssignment/dtos/requests/ReassignRequest.d.ts +1 -0
  30. package/bin/loanCollectorAssignment/dtos/requests/ReassignRequest.js +4 -0
  31. package/bin/loanCollectorAssignment/dtos/requests/RedistributeRequest.d.ts +1 -0
  32. package/bin/loanCollectorAssignment/dtos/requests/RedistributeRequest.js +4 -0
  33. package/bin/loanCollectorAssignment/dtos/responses/ListCollectorAssignmentsResponse.d.ts +9 -0
  34. package/bin/loanCollectorAssignment/dtos/responses/ListCollectorAssignmentsResponse.js +2 -0
  35. package/bin/loanCollectorAssignment/index.d.ts +3 -0
  36. package/bin/loanCollectorAssignment/index.js +4 -0
  37. package/bin/loanConfig/constants/ParameterRequestLimits.d.ts +8 -0
  38. package/bin/loanConfig/constants/ParameterRequestLimits.js +11 -0
  39. package/bin/loanConfig/dtos/requests/BulkGetParametersRequest.d.ts +1 -1
  40. package/bin/loanConfig/dtos/requests/BulkGetParametersRequest.js +3 -1
  41. package/bin/loanConfig/dtos/requests/BulkUpdateParametersRequest.d.ts +5 -2
  42. package/bin/loanConfig/dtos/requests/BulkUpdateParametersRequest.js +8 -4
  43. package/bin/loanConfig/dtos/requests/UpdateParameterRequest.d.ts +6 -3
  44. package/bin/loanConfig/dtos/requests/UpdateParameterRequest.js +10 -5
  45. package/bin/loanConfig/index.d.ts +1 -0
  46. package/bin/loanConfig/index.js +1 -0
  47. package/bin/loanCredit/constants/LoanInputLimits.d.ts +24 -0
  48. package/bin/loanCredit/constants/LoanInputLimits.js +27 -0
  49. package/bin/loanCredit/dtos/LoanBeneficiary.d.ts +1 -0
  50. package/bin/loanCredit/dtos/LoanBeneficiary.js +9 -0
  51. package/bin/loanCredit/dtos/LoanContractDetails.d.ts +18 -1
  52. package/bin/loanCredit/dtos/LoanContractDetails.js +2 -1
  53. package/bin/loanCredit/dtos/LoanDeviceNotifyItem.d.ts +5 -0
  54. package/bin/loanCredit/dtos/LoanDeviceNotifyItem.js +12 -3
  55. package/bin/loanCredit/dtos/RestructureTerms.d.ts +1 -1
  56. package/bin/loanCredit/dtos/RestructureTerms.js +2 -0
  57. package/bin/loanCredit/dtos/SignatureContext.d.ts +5 -1
  58. package/bin/loanCredit/dtos/requests/ActivationCheckRequest.d.ts +1 -1
  59. package/bin/loanCredit/dtos/requests/ActivationCheckRequest.js +4 -0
  60. package/bin/loanCredit/dtos/requests/BackofficeApproveRestructureRequest.js +2 -0
  61. package/bin/loanCredit/dtos/requests/BackofficeProposeRestructureRequest.js +2 -0
  62. package/bin/loanCredit/dtos/requests/BackofficeRejectRestructureRequest.js +2 -0
  63. package/bin/loanCredit/dtos/requests/BackofficeWriteOffCreditRequest.js +2 -0
  64. package/bin/loanCredit/dtos/requests/CreateCustomerPaymentRequest.d.ts +5 -0
  65. package/bin/loanCredit/dtos/requests/CreateCustomerPaymentRequest.js +6 -0
  66. package/bin/loanCredit/dtos/requests/CreateSellerPaymentRequest.d.ts +5 -0
  67. package/bin/loanCredit/dtos/requests/CreateSellerPaymentRequest.js +6 -0
  68. package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.d.ts +1 -0
  69. package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.js +7 -1
  70. package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.d.ts +1 -1
  71. package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.js +3 -1
  72. package/bin/loanCredit/dtos/requests/SignLoanCreditRequest.d.ts +2 -0
  73. package/bin/loanCredit/dtos/requests/SignLoanCreditRequest.js +3 -0
  74. package/bin/loanCredit/dtos/requests/UpsertLoanBorrowerRequest.d.ts +1 -0
  75. package/bin/loanCredit/dtos/requests/UpsertLoanBorrowerRequest.js +2 -0
  76. package/bin/loanCredit/index.d.ts +2 -0
  77. package/bin/loanCredit/index.js +2 -0
  78. package/bin/loanCredit/validators/IsContractBirthDate.d.ts +11 -0
  79. package/bin/loanCredit/validators/IsContractBirthDate.js +41 -0
  80. package/bin/loanOfferings/constants/offeringsInputLimits.d.ts +35 -0
  81. package/bin/loanOfferings/constants/offeringsInputLimits.js +38 -0
  82. package/bin/loanOfferings/dtos/requests/ChangeCreditPlanStatusRequest.d.ts +2 -0
  83. package/bin/loanOfferings/dtos/requests/ChangeCreditPlanStatusRequest.js +8 -0
  84. package/bin/loanOfferings/dtos/requests/ChangePromotionStatusRequest.js +2 -0
  85. package/bin/loanOfferings/dtos/requests/ComputeAmortizationScheduleRequest.d.ts +4 -1
  86. package/bin/loanOfferings/dtos/requests/ComputeAmortizationScheduleRequest.js +3 -1
  87. package/bin/loanOfferings/dtos/requests/ConsumePromotionRequest.d.ts +1 -0
  88. package/bin/loanOfferings/dtos/requests/ConsumePromotionRequest.js +3 -0
  89. package/bin/loanOfferings/dtos/requests/CreateCreditPlanRequest.d.ts +3 -0
  90. package/bin/loanOfferings/dtos/requests/CreateCreditPlanRequest.js +11 -2
  91. package/bin/loanOfferings/dtos/requests/CreateFinancierRequest.d.ts +5 -0
  92. package/bin/loanOfferings/dtos/requests/CreateFinancierRequest.js +11 -0
  93. package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.d.ts +2 -2
  94. package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.js +9 -0
  95. package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.d.ts +1 -1
  96. package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.js +3 -0
  97. package/bin/loanOfferings/dtos/requests/CreateStorePolicyRequest.d.ts +1 -1
  98. package/bin/loanOfferings/dtos/requests/CreateStorePolicyRequest.js +3 -0
  99. package/bin/loanOfferings/dtos/requests/ReleasePromotionRequest.d.ts +8 -0
  100. package/bin/loanOfferings/dtos/requests/ReleasePromotionRequest.js +30 -0
  101. package/bin/loanOfferings/dtos/requests/ReservePromotionBonusRequest.d.ts +1 -0
  102. package/bin/loanOfferings/dtos/requests/ReservePromotionBonusRequest.js +3 -0
  103. package/bin/loanOfferings/dtos/requests/SettlePromotionBonusRequest.d.ts +1 -0
  104. package/bin/loanOfferings/dtos/requests/SettlePromotionBonusRequest.js +3 -0
  105. package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.d.ts +1 -0
  106. package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.js +3 -0
  107. package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.d.ts +3 -1
  108. package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.js +5 -2
  109. package/bin/loanOfferings/dtos/requests/UpdateCreditPlanRequest.d.ts +8 -0
  110. package/bin/loanOfferings/dtos/requests/UpdateCreditPlanRequest.js +30 -12
  111. package/bin/loanOfferings/dtos/requests/UpdateFinancierRequest.d.ts +6 -0
  112. package/bin/loanOfferings/dtos/requests/UpdateFinancierRequest.js +13 -2
  113. package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.d.ts +7 -1
  114. package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.js +25 -5
  115. package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.d.ts +5 -2
  116. package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.js +12 -5
  117. package/bin/loanOfferings/dtos/requests/UpdateStorePolicyRequest.d.ts +18 -9
  118. package/bin/loanOfferings/dtos/requests/UpdateStorePolicyRequest.js +12 -4
  119. package/bin/loanOfferings/dtos/responses/ReleasePromotionResponse.d.ts +11 -0
  120. package/bin/loanOfferings/dtos/responses/ReleasePromotionResponse.js +2 -0
  121. package/bin/loanOfferings/index.d.ts +5 -0
  122. package/bin/loanOfferings/index.js +6 -0
  123. package/bin/loanOfferings/validators/IsOptionalNonNull.d.ts +9 -0
  124. package/bin/loanOfferings/validators/IsOptionalNonNull.js +14 -0
  125. package/bin/loanOfferings/validators/MaxJsonBytes.d.ts +5 -0
  126. package/bin/loanOfferings/validators/MaxJsonBytes.js +28 -0
  127. package/bin/loanRetailAudit/constants/auditInputLimits.d.ts +16 -0
  128. package/bin/loanRetailAudit/constants/auditInputLimits.js +19 -0
  129. package/bin/loanRetailAudit/dtos/AuditTrailChange.js +4 -0
  130. package/bin/loanRetailAudit/dtos/AuditTrailContextEntry.js +3 -0
  131. package/bin/loanRetailAudit/dtos/requests/CreatePiiAccessLogRequest.d.ts +7 -1
  132. package/bin/loanRetailAudit/dtos/requests/CreatePiiAccessLogRequest.js +8 -1
  133. package/bin/loanRetailAudit/events/AuditTrailRecordedV1.d.ts +1 -0
  134. package/bin/loanRetailAudit/events/AuditTrailRecordedV1.js +5 -1
  135. package/bin/loanRetailAudit/index.d.ts +2 -0
  136. package/bin/loanRetailAudit/index.js +3 -0
  137. package/bin/loanRetailAudit/validators/IsIsoDateTime.d.ts +13 -0
  138. package/bin/loanRetailAudit/validators/IsIsoDateTime.js +29 -0
  139. package/bin/loanScoring/dtos/ScoringOffer.d.ts +8 -6
  140. package/bin/loanScoring/dtos/requests/EvaluateSciRequest.d.ts +14 -3
  141. package/bin/loanScoring/dtos/requests/EvaluateSciRequest.js +15 -0
  142. package/package.json +1 -1
  143. package/src/collection/constants/CollectionResultLimits.ts +18 -0
  144. package/src/collection/dtos/ApplyCollectionResultRequest.ts +15 -8
  145. package/src/collection/dtos/ResolvePendingChargesRequest.ts +7 -4
  146. package/src/collection/index.ts +4 -0
  147. package/src/collection/validators/IsCentPrecision.ts +33 -0
  148. package/src/gsfConnector/dtos/GsfCreditTerms.ts +15 -3
  149. package/src/loanCollectorAssignment/constants/CollectorAssignmentLimits.ts +16 -0
  150. package/src/loanCollectorAssignment/dtos/requests/AutoAssignRequest.ts +13 -1
  151. package/src/loanCollectorAssignment/dtos/requests/ListCollectorAssignmentsRequest.ts +52 -0
  152. package/src/loanCollectorAssignment/dtos/requests/ReassignRequest.ts +8 -1
  153. package/src/loanCollectorAssignment/dtos/requests/RedistributeRequest.ts +8 -1
  154. package/src/loanCollectorAssignment/dtos/responses/ListCollectorAssignmentsResponse.ts +10 -0
  155. package/src/loanCollectorAssignment/index.ts +5 -0
  156. package/src/loanConfig/constants/ParameterRequestLimits.ts +11 -0
  157. package/src/loanConfig/dtos/requests/BulkGetParametersRequest.ts +4 -2
  158. package/src/loanConfig/dtos/requests/BulkUpdateParametersRequest.ts +26 -6
  159. package/src/loanConfig/dtos/requests/UpdateParameterRequest.ts +15 -7
  160. package/src/loanConfig/index.ts +1 -0
  161. package/src/loanCredit/constants/LoanInputLimits.ts +29 -0
  162. package/src/loanCredit/dtos/LoanBeneficiary.ts +11 -1
  163. package/src/loanCredit/dtos/LoanContractDetails.ts +26 -3
  164. package/src/loanCredit/dtos/LoanDeviceNotifyItem.ts +17 -3
  165. package/src/loanCredit/dtos/RestructureTerms.ts +4 -2
  166. package/src/loanCredit/dtos/SignatureContext.ts +5 -1
  167. package/src/loanCredit/dtos/requests/ActivationCheckRequest.ts +12 -2
  168. package/src/loanCredit/dtos/requests/BackofficeApproveRestructureRequest.ts +3 -1
  169. package/src/loanCredit/dtos/requests/BackofficeProposeRestructureRequest.ts +3 -1
  170. package/src/loanCredit/dtos/requests/BackofficeRejectRestructureRequest.ts +3 -1
  171. package/src/loanCredit/dtos/requests/BackofficeWriteOffCreditRequest.ts +3 -1
  172. package/src/loanCredit/dtos/requests/CreateCustomerPaymentRequest.ts +10 -1
  173. package/src/loanCredit/dtos/requests/CreateSellerPaymentRequest.ts +10 -1
  174. package/src/loanCredit/dtos/requests/OriginateLoanCreditRequest.ts +10 -1
  175. package/src/loanCredit/dtos/requests/SegmentFactsBatchRequest.ts +4 -2
  176. package/src/loanCredit/dtos/requests/SignLoanCreditRequest.ts +6 -1
  177. package/src/loanCredit/dtos/requests/UpsertLoanBorrowerRequest.ts +4 -1
  178. package/src/loanCredit/index.ts +2 -0
  179. package/src/loanCredit/validators/IsContractBirthDate.ts +41 -0
  180. package/src/loanOfferings/constants/offeringsInputLimits.ts +47 -0
  181. package/src/loanOfferings/dtos/requests/ChangeCreditPlanStatusRequest.ts +9 -1
  182. package/src/loanOfferings/dtos/requests/ChangePromotionStatusRequest.ts +3 -1
  183. package/src/loanOfferings/dtos/requests/ComputeAmortizationScheduleRequest.ts +7 -2
  184. package/src/loanOfferings/dtos/requests/ConsumePromotionRequest.ts +5 -1
  185. package/src/loanOfferings/dtos/requests/CreateCreditPlanRequest.ts +24 -2
  186. package/src/loanOfferings/dtos/requests/CreateFinancierRequest.ts +25 -0
  187. package/src/loanOfferings/dtos/requests/CreatePromotionRequest.ts +17 -2
  188. package/src/loanOfferings/dtos/requests/CreateSegmentRequest.ts +4 -1
  189. package/src/loanOfferings/dtos/requests/CreateStorePolicyRequest.ts +6 -1
  190. package/src/loanOfferings/dtos/requests/ReleasePromotionRequest.ts +16 -0
  191. package/src/loanOfferings/dtos/requests/ReservePromotionBonusRequest.ts +5 -1
  192. package/src/loanOfferings/dtos/requests/SettlePromotionBonusRequest.ts +5 -1
  193. package/src/loanOfferings/dtos/requests/SimulateCreditPlanRequest.ts +5 -1
  194. package/src/loanOfferings/dtos/requests/UpdateCohortRequest.ts +6 -3
  195. package/src/loanOfferings/dtos/requests/UpdateCreditPlanRequest.ts +43 -12
  196. package/src/loanOfferings/dtos/requests/UpdateFinancierRequest.ts +26 -2
  197. package/src/loanOfferings/dtos/requests/UpdatePromotionRequest.ts +34 -6
  198. package/src/loanOfferings/dtos/requests/UpdateSegmentRequest.ts +14 -7
  199. package/src/loanOfferings/dtos/requests/UpdateStorePolicyRequest.ts +28 -13
  200. package/src/loanOfferings/dtos/responses/ReleasePromotionResponse.ts +11 -0
  201. package/src/loanOfferings/index.ts +7 -0
  202. package/src/loanOfferings/validators/IsOptionalNonNull.ts +12 -0
  203. package/src/loanOfferings/validators/MaxJsonBytes.ts +28 -0
  204. package/src/loanRetailAudit/constants/auditInputLimits.ts +20 -0
  205. package/src/loanRetailAudit/dtos/AuditTrailChange.ts +5 -1
  206. package/src/loanRetailAudit/dtos/AuditTrailContextEntry.ts +4 -1
  207. package/src/loanRetailAudit/dtos/requests/CreatePiiAccessLogRequest.ts +20 -3
  208. package/src/loanRetailAudit/events/AuditTrailRecordedV1.ts +7 -2
  209. package/src/loanRetailAudit/index.ts +4 -0
  210. package/src/loanRetailAudit/validators/IsIsoDateTime.ts +33 -0
  211. package/src/loanScoring/dtos/ScoringOffer.ts +8 -6
  212. package/src/loanScoring/dtos/requests/EvaluateSciRequest.ts +26 -4
@@ -0,0 +1,47 @@
1
+ /** Plazo máximo de un plan, en semanas; el mismo techo del alta del crédito (decisión D-3). */
2
+ export const CREDIT_PLAN_MAX_TERM_WEEKS = 104;
3
+
4
+ /** Opciones de plazo por plan: a lo más una por semana posible. */
5
+ export const CREDIT_PLAN_TERM_OPTIONS_MAX_ITEMS = 104;
6
+
7
+ /** TNA máxima de negocio de planes y promociones, en decimal (`2.60` = 260%). */
8
+ export const CREDIT_PLAN_MAX_TNA_ANNUAL = 2.6;
9
+
10
+ /**
11
+ * Techo técnico interino de la TNA en `/private/amortization/schedule`, en decimal (`5` = 500%).
12
+ *
13
+ * No es `CREDIT_PLAN_MAX_TNA_ANNUAL` porque la reestructura de loan-credit suma +0.20 a +0.40 a la
14
+ * TNA del crédito sin tope: un crédito al 2.60 se reestructura al 2.80 o más, y con 2.60 su
15
+ * preview, OTP y ejecución darían 400. Se baja a 2.60 cuando loan-credit acote esa TNA.
16
+ */
17
+ export const AMORTIZATION_TNA_ANNUAL_TECHNICAL_MAX = 5;
18
+
19
+ /** Clientes agregados a mano por segmento (~130 KB, lejos de los 400 KB del ítem). Decisión D-5. */
20
+ export const SEGMENT_MEMBER_IDS_MAX_ITEMS = 5000;
21
+
22
+ /** Tiendas por política o promoción (= `MAX_SCOPE_CATALOG_STORES` del lambda). Decisión D-5. */
23
+ export const SCOPE_STORE_IDS_MAX_ITEMS = 1000;
24
+
25
+ /** SKUs por promoción (= `MAX_SCOPE_CATALOG_PRODUCTS` del lambda). Decisión D-5. */
26
+ export const PROMOTION_PRODUCT_SKUS_MAX_ITEMS = 2000;
27
+
28
+ /** Segmentos del cliente que acepta una cotización. Decisión D-5. */
29
+ export const CUSTOMER_SEGMENT_IDS_MAX_ITEMS = 50;
30
+
31
+ /** Largos de los textos de catálogo (los de segmentos, cohorts y políticas ya usan 120/500). */
32
+ export const OFFERINGS_CODE_MAX_LENGTH = 64;
33
+ export const OFFERINGS_NAME_MAX_LENGTH = 120;
34
+ export const OFFERINGS_DESCRIPTION_MAX_LENGTH = 500;
35
+ export const OFFERINGS_LABEL_MAX_LENGTH = 120;
36
+
37
+ /** Largo máximo del motivo que queda en la bitácora; el mismo del backoffice. */
38
+ export const OFFERINGS_AUDIT_REASON_MAX_LENGTH = 280;
39
+
40
+ /** Largo máximo de un id de crédito o de bono en los privados de promociones (hoy son ULID de 26). */
41
+ export const PROMOTION_CREDIT_ID_MAX_LENGTH = 128;
42
+
43
+ /** Largo máximo de la URL de redirección de una financiera externa. */
44
+ export const FINANCIER_REDIRECT_URL_MAX_LENGTH = 2048;
45
+
46
+ /** Tope de `config` de la financiera, serializado en JSON y medido en bytes UTF-8. */
47
+ export const FINANCIER_CONFIG_MAX_BYTES = 4096;
@@ -1,5 +1,6 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsEnum } from 'class-validator';
2
+ import { IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { OFFERINGS_AUDIT_REASON_MAX_LENGTH } from '../../constants/offeringsInputLimits';
3
4
  import { CreditPlanStatusEnum } from '../../enums/CreditPlanStatusEnum';
4
5
 
5
6
  /**
@@ -10,4 +11,11 @@ export class ChangeCreditPlanStatusRequest {
10
11
  @Expose()
11
12
  @IsEnum(CreditPlanStatusEnum)
12
13
  status!: CreditPlanStatusEnum;
14
+
15
+ /** Motivo del cambio; queda en la bitácora del plan. */
16
+ @Expose()
17
+ @IsOptional()
18
+ @IsString()
19
+ @MaxLength(OFFERINGS_AUDIT_REASON_MAX_LENGTH)
20
+ reason?: string;
13
21
  }
@@ -1,5 +1,6 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsEnum, IsOptional, IsString } from 'class-validator';
2
+ import { IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { OFFERINGS_AUDIT_REASON_MAX_LENGTH } from '../../constants/offeringsInputLimits';
3
4
  import { PromotionStatusEnum } from '../../enums/PromotionStatusEnum';
4
5
 
5
6
  /**
@@ -16,5 +17,6 @@ export class ChangePromotionStatusRequest {
16
17
  @Expose()
17
18
  @IsOptional()
18
19
  @IsString()
20
+ @MaxLength(OFFERINGS_AUDIT_REASON_MAX_LENGTH)
19
21
  reason?: string | null;
20
22
  }
@@ -1,5 +1,6 @@
1
1
  import { Expose } from 'class-transformer';
2
2
  import { IsInt, IsNumber, Max, Min } from 'class-validator';
3
+ import { AMORTIZATION_TNA_ANNUAL_TECHNICAL_MAX, CREDIT_PLAN_MAX_TERM_WEEKS } from '../../constants/offeringsInputLimits';
3
4
 
4
5
  /** Body de `POST /private/amortization/schedule` (loan-offerings-business). Tabla francesa semanal sin fechas. */
5
6
  export class ComputeAmortizationScheduleRequest {
@@ -9,17 +10,21 @@ export class ComputeAmortizationScheduleRequest {
9
10
  @Min(1)
10
11
  financedAmountCents!: number;
11
12
 
12
- /** TNA en decimal (`2.30` = 230%). */
13
+ /**
14
+ * TNA en decimal (`2.30` = 230%). El techo es técnico (5 = 500%), no el 2.60 de los planes: la
15
+ * reestructura sube la TNA del crédito por encima de ese valor (ver `AMORTIZATION_TNA_ANNUAL_TECHNICAL_MAX`).
16
+ */
13
17
  @Expose()
14
18
  @IsNumber()
15
19
  @Min(0)
20
+ @Max(AMORTIZATION_TNA_ANNUAL_TECHNICAL_MAX)
16
21
  tnaAnnual!: number;
17
22
 
18
23
  /** Número de cuotas semanales. */
19
24
  @Expose()
20
25
  @IsInt()
21
26
  @Min(1)
22
- @Max(104)
27
+ @Max(CREDIT_PLAN_MAX_TERM_WEEKS)
23
28
  termWeeks!: number;
24
29
 
25
30
  /** IVA sobre interés en decimal (`0.16`). */
@@ -1,12 +1,16 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsString } from 'class-validator';
2
+ import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
3
+ import { PROMOTION_CREDIT_ID_MAX_LENGTH } from '../../constants/offeringsInputLimits';
3
4
 
4
5
  /**
5
6
  * Body de POST /private/promotions/:promotionId/consume — el crédito que acaba de activarse bajo
6
7
  * esta promoción. `creditId` es la llave de idempotencia: reenviarlo NO vuelve a contar.
7
8
  */
8
9
  export class ConsumePromotionRequest {
10
+ /** Llave de idempotencia: vacía colapsaría todos los créditos en una sola fila (L-104). */
9
11
  @Expose()
10
12
  @IsString()
13
+ @IsNotEmpty()
14
+ @MaxLength(PROMOTION_CREDIT_ID_MAX_LENGTH)
11
15
  creditId!: string;
12
16
  }
@@ -1,17 +1,28 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import {
3
+ ArrayMaxSize,
3
4
  ArrayNotEmpty,
4
5
  IsArray,
5
6
  IsBoolean,
6
7
  IsEnum,
7
8
  IsInt,
9
+ IsISO8601,
10
+ IsNotEmpty,
8
11
  IsNumber,
9
12
  IsOptional,
10
13
  IsString,
11
14
  Max,
15
+ MaxLength,
12
16
  Min,
13
17
  ValidateNested,
14
18
  } from 'class-validator';
19
+ import {
20
+ CREDIT_PLAN_MAX_TERM_WEEKS,
21
+ CREDIT_PLAN_TERM_OPTIONS_MAX_ITEMS,
22
+ OFFERINGS_CODE_MAX_LENGTH,
23
+ OFFERINGS_DESCRIPTION_MAX_LENGTH,
24
+ OFFERINGS_NAME_MAX_LENGTH,
25
+ } from '../../constants/offeringsInputLimits';
15
26
  import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
16
27
  import { ProductTierEnum } from '../../enums/ProductTierEnum';
17
28
  import { SaleTypeEnum } from '../../enums/SaleTypeEnum';
@@ -25,14 +36,20 @@ import { PrepaymentMinimum } from '../PrepaymentMinimum';
25
36
  export class CreateCreditPlanRequest {
26
37
  @Expose()
27
38
  @IsString()
39
+ @IsNotEmpty()
40
+ @MaxLength(OFFERINGS_CODE_MAX_LENGTH)
28
41
  code!: string;
29
42
 
30
43
  @Expose()
31
44
  @IsString()
45
+ @IsNotEmpty()
46
+ @MaxLength(OFFERINGS_NAME_MAX_LENGTH)
32
47
  name!: string;
33
48
 
34
49
  @Expose()
35
50
  @IsString()
51
+ @IsNotEmpty()
52
+ @MaxLength(OFFERINGS_DESCRIPTION_MAX_LENGTH)
36
53
  description!: string;
37
54
 
38
55
  @Expose()
@@ -64,11 +81,14 @@ export class CreateCreditPlanRequest {
64
81
  @Max(1)
65
82
  maxDownPaymentPct?: number | null;
66
83
 
84
+ /** Plazos ofrecidos, en semanas: de 1 a 104 cada uno. */
67
85
  @Expose()
68
86
  @IsArray()
69
87
  @ArrayNotEmpty()
88
+ @ArrayMaxSize(CREDIT_PLAN_TERM_OPTIONS_MAX_ITEMS)
70
89
  @IsInt({ each: true })
71
90
  @Min(1, { each: true })
91
+ @Max(CREDIT_PLAN_MAX_TERM_WEEKS, { each: true })
72
92
  termWeeksOptions!: number[];
73
93
 
74
94
  @Expose()
@@ -108,14 +128,16 @@ export class CreateCreditPlanRequest {
108
128
  @Max(100)
109
129
  maxSciScore?: number | null;
110
130
 
131
+ /** Inicio de vigencia en ISO-8601; ausente o `null` = sin inicio. */
111
132
  @Expose()
112
133
  @IsOptional()
113
- @IsString()
134
+ @IsISO8601()
114
135
  validFrom?: string | null;
115
136
 
137
+ /** Fin de vigencia en ISO-8601; ausente o `null` = sin fin. */
116
138
  @Expose()
117
139
  @IsOptional()
118
- @IsString()
140
+ @IsISO8601()
119
141
  validUntil?: string | null;
120
142
 
121
143
  /** Mínimo del abono a capital; ausente = sin cambios (en el alta: `ANY`). */
@@ -3,11 +3,22 @@ import {
3
3
  IsArray,
4
4
  IsEnum,
5
5
  IsInt,
6
+ IsNotEmpty,
6
7
  IsObject,
7
8
  IsOptional,
8
9
  IsString,
10
+ IsUrl,
11
+ MaxLength,
9
12
  Min,
10
13
  } from 'class-validator';
14
+ import {
15
+ FINANCIER_CONFIG_MAX_BYTES,
16
+ FINANCIER_REDIRECT_URL_MAX_LENGTH,
17
+ OFFERINGS_CODE_MAX_LENGTH,
18
+ OFFERINGS_LABEL_MAX_LENGTH,
19
+ OFFERINGS_NAME_MAX_LENGTH,
20
+ } from '../../constants/offeringsInputLimits';
21
+ import { MaxJsonBytes } from '../../validators/MaxJsonBytes';
11
22
  import { FinancierTypeEnum } from '../../enums/FinancierTypeEnum';
12
23
  import { ProductTierEnum } from '../../enums/ProductTierEnum';
13
24
 
@@ -19,10 +30,14 @@ import { ProductTierEnum } from '../../enums/ProductTierEnum';
19
30
  export class CreateFinancierRequest {
20
31
  @Expose()
21
32
  @IsString()
33
+ @IsNotEmpty()
34
+ @MaxLength(OFFERINGS_CODE_MAX_LENGTH)
22
35
  code!: string;
23
36
 
24
37
  @Expose()
25
38
  @IsString()
39
+ @IsNotEmpty()
40
+ @MaxLength(OFFERINGS_NAME_MAX_LENGTH)
26
41
  name!: string;
27
42
 
28
43
  @Expose()
@@ -37,11 +52,16 @@ export class CreateFinancierRequest {
37
52
 
38
53
  @Expose()
39
54
  @IsString()
55
+ @IsNotEmpty()
56
+ @MaxLength(OFFERINGS_LABEL_MAX_LENGTH)
40
57
  label!: string;
41
58
 
59
+ /** URL https a la que se redirige al cliente; `null` = sin redirección. */
42
60
  @Expose()
43
61
  @IsOptional()
44
62
  @IsString()
63
+ @MaxLength(FINANCIER_REDIRECT_URL_MAX_LENGTH)
64
+ @IsUrl({ protocols: ['https'], require_protocol: true })
45
65
  externalRedirectUrl?: string | null;
46
66
 
47
67
  @Expose()
@@ -50,8 +70,13 @@ export class CreateFinancierRequest {
50
70
  @IsEnum(ProductTierEnum, { each: true })
51
71
  eligibleTiers?: ProductTierEnum[] | null;
52
72
 
73
+ /**
74
+ * @deprecated Ningún consumidor lo lee (TD-019 de loan-offerings) y se va a eliminar (decisión
75
+ * D-9). Mientras tanto, a lo más 4 KB serializado.
76
+ */
53
77
  @Expose()
54
78
  @IsOptional()
55
79
  @IsObject()
80
+ @MaxJsonBytes(FINANCIER_CONFIG_MAX_BYTES)
56
81
  config?: Record<string, unknown> | null;
57
82
  }
@@ -9,8 +9,15 @@ import {
9
9
  IsNotEmpty,
10
10
  IsOptional,
11
11
  IsString,
12
+ MaxLength,
12
13
  ValidateNested,
13
14
  } from 'class-validator';
15
+ import {
16
+ OFFERINGS_DESCRIPTION_MAX_LENGTH,
17
+ OFFERINGS_NAME_MAX_LENGTH,
18
+ PROMOTION_PRODUCT_SKUS_MAX_ITEMS,
19
+ SCOPE_STORE_IDS_MAX_ITEMS,
20
+ } from '../../constants/offeringsInputLimits';
14
21
  import { PROMOTION_RETAILER_IDS_MAX_ITEMS } from '../../constants/promotionRetailerScope';
15
22
  import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
16
23
  import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
@@ -25,10 +32,14 @@ import { PromotionEffectInput } from './PromotionEffectInput';
25
32
  export class CreatePromotionRequest {
26
33
  @Expose()
27
34
  @IsString()
35
+ @IsNotEmpty()
36
+ @MaxLength(OFFERINGS_NAME_MAX_LENGTH)
28
37
  name!: string;
29
38
 
30
39
  @Expose()
31
40
  @IsString()
41
+ @IsNotEmpty()
42
+ @MaxLength(OFFERINGS_DESCRIPTION_MAX_LENGTH)
32
43
  description!: string;
33
44
 
34
45
  @Expose()
@@ -47,11 +58,13 @@ export class CreatePromotionRequest {
47
58
  @IsEnum(CreditPlanLevelEnum, { each: true })
48
59
  targetLevels!: CreditPlanLevelEnum[];
49
60
 
50
- /** SKUs alcanzados; ausente o `null` = todos los productos. */
61
+ /** SKUs alcanzados; ausente o `null` = todos los productos. Hasta 2 000. */
51
62
  @Expose()
52
63
  @IsOptional()
53
64
  @IsArray()
65
+ @ArrayMaxSize(PROMOTION_PRODUCT_SKUS_MAX_ITEMS)
54
66
  @IsString({ each: true })
67
+ @IsNotEmpty({ each: true })
55
68
  productSkus?: string[] | null;
56
69
 
57
70
  /** Tipos de producto alcanzados; ausente o `null` = todos los tipos. */
@@ -77,11 +90,13 @@ export class CreatePromotionRequest {
77
90
  @IsNotEmpty({ each: true })
78
91
  retailerIds?: string[] | null;
79
92
 
80
- /** Tiendas alcanzadas. `null` o ausente = todas. */
93
+ /** Tiendas alcanzadas. `null` o ausente = todas. Hasta 1 000. */
81
94
  @Expose()
82
95
  @IsOptional()
83
96
  @IsArray()
97
+ @ArrayMaxSize(SCOPE_STORE_IDS_MAX_ITEMS)
84
98
  @IsString({ each: true })
99
+ @IsNotEmpty({ each: true })
85
100
  storeIds?: string[] | null;
86
101
 
87
102
  @Expose()
@@ -1,5 +1,6 @@
1
1
  import { Expose } from 'class-transformer';
2
2
  import { ArrayMaxSize, IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { SEGMENT_MEMBER_IDS_MAX_ITEMS } from '../../constants/offeringsInputLimits';
3
4
  import { SegmentColorSlotEnum } from '../../enums/SegmentColorSlotEnum';
4
5
 
5
6
  /**
@@ -47,11 +48,13 @@ export class CreateSegmentRequest {
47
48
 
48
49
  /**
49
50
  * Clientes agregados a mano por `retailCustomerId`. Ganan siempre, cumplan o no un cohort.
50
- * Un segmento puede nacer SOLO con esta lista, sin ningún cohort.
51
+ * Un segmento puede nacer SOLO con esta lista, sin ningún cohort. Hasta 5 000, sin ids vacíos.
51
52
  */
52
53
  @Expose()
53
54
  @IsOptional()
54
55
  @IsArray()
56
+ @ArrayMaxSize(SEGMENT_MEMBER_IDS_MAX_ITEMS)
55
57
  @IsString({ each: true })
58
+ @IsNotEmpty({ each: true })
56
59
  memberIds?: string[];
57
60
  }
@@ -1,11 +1,13 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import {
3
+ ArrayMaxSize,
3
4
  ArrayNotEmpty,
4
5
  IsArray,
5
6
  IsBoolean,
6
7
  IsEnum,
7
8
  IsInt,
8
9
  IsISO8601,
10
+ IsNotEmpty,
9
11
  IsNumber,
10
12
  IsOptional,
11
13
  IsString,
@@ -14,6 +16,7 @@ import {
14
16
  Min,
15
17
  ValidateNested,
16
18
  } from 'class-validator';
19
+ import { SCOPE_STORE_IDS_MAX_ITEMS } from '../../constants/offeringsInputLimits';
17
20
  import { CreditPlanLevelEnum } from '../../enums/CreditPlanLevelEnum';
18
21
 
19
22
  /** Grupo de palancas que ENDURECEN las condiciones del plan. */
@@ -114,12 +117,14 @@ export class CreateStorePolicyRequest {
114
117
  @IsString({ each: true })
115
118
  allowedSkus?: string[];
116
119
 
117
- /** Alcance: tiendas alcanzadas. Ausente = toda la red. */
120
+ /** Alcance: tiendas alcanzadas. Ausente = toda la red. Hasta 1 000. */
118
121
  @Expose()
119
122
  @IsOptional()
120
123
  @IsArray()
121
124
  @ArrayNotEmpty()
125
+ @ArrayMaxSize(SCOPE_STORE_IDS_MAX_ITEMS)
122
126
  @IsString({ each: true })
127
+ @IsNotEmpty({ each: true })
123
128
  storeIds?: string[];
124
129
 
125
130
  /** Alcance: niveles alcanzados. Ausente = todos los niveles. */
@@ -0,0 +1,16 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
3
+ import { PROMOTION_CREDIT_ID_MAX_LENGTH } from '../../constants/offeringsInputLimits';
4
+
5
+ /**
6
+ * Body de POST /private/promotions/:promotionId/release — el crédito con promoción que se canceló.
7
+ * Baja `creditsGenerated` una sola vez por crédito: `creditId` es la llave de idempotencia, así que
8
+ * reenviarlo no vuelve a restar. El bono PCF no vuelve al presupuesto: es irreversible (L-052, D-2).
9
+ */
10
+ export class ReleasePromotionRequest {
11
+ @Expose()
12
+ @IsString()
13
+ @IsNotEmpty()
14
+ @MaxLength(PROMOTION_CREDIT_ID_MAX_LENGTH)
15
+ creditId!: string;
16
+ }
@@ -1,12 +1,16 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsString } from 'class-validator';
2
+ import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
3
+ import { PROMOTION_CREDIT_ID_MAX_LENGTH } from '../../constants/offeringsInputLimits';
3
4
 
4
5
  /**
5
6
  * Body de POST /private/promotions/:promotionId/bonus-payment — el crédito recién activado que va a
6
7
  * cobrar el bono. `creditId` es el candado: reenviarlo devuelve `reserved: false`, no un segundo pago.
7
8
  */
8
9
  export class ReservePromotionBonusRequest {
10
+ /** Llave de idempotencia: vacía colapsaría todos los créditos en una sola fila (L-104). */
9
11
  @Expose()
10
12
  @IsString()
13
+ @IsNotEmpty()
14
+ @MaxLength(PROMOTION_CREDIT_ID_MAX_LENGTH)
11
15
  creditId!: string;
12
16
  }
@@ -1,5 +1,6 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsEnum, IsOptional, IsString } from 'class-validator';
2
+ import { IsEnum, IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { PROMOTION_CREDIT_ID_MAX_LENGTH } from '../../constants/offeringsInputLimits';
3
4
  import { PromotionBonusStatusEnum } from '../../enums/PromotionBonusStatusEnum';
4
5
 
5
6
  /**
@@ -7,8 +8,11 @@ import { PromotionBonusStatusEnum } from '../../enums/PromotionBonusStatusEnum';
7
8
  * contestó el processor. `RESERVED` no se acepta: es el estado del que se sale, no al que se llega.
8
9
  */
9
10
  export class SettlePromotionBonusRequest {
11
+ /** Llave de idempotencia: vacía colapsaría todos los créditos en una sola fila (L-104). */
10
12
  @Expose()
11
13
  @IsString()
14
+ @IsNotEmpty()
15
+ @MaxLength(PROMOTION_CREDIT_ID_MAX_LENGTH)
12
16
  bonusId!: string;
13
17
 
14
18
  @Expose()
@@ -1,5 +1,6 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsArray, IsEnum, IsInt, IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
2
+ import { ArrayMaxSize, IsArray, IsEnum, IsInt, IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
3
+ import { CUSTOMER_SEGMENT_IDS_MAX_ITEMS } from '../../constants/offeringsInputLimits';
3
4
  import { ProductCategoryEnum } from '../../../retailCatalog/enums/ProductCategoryEnum';
4
5
  import { ProductTierEnum } from '../../../retailCatalog/enums/ProductTierEnum';
5
6
 
@@ -71,10 +72,13 @@ export class SimulateCreditPlanRequest {
71
72
  /**
72
73
  * Segmentos del cliente, los que devolvió `POST /private/segments/resolve`. Un arreglo vacío
73
74
  * declara que el cliente no está en ninguno; ausente declara que el caller no lo consultó.
75
+ * Hasta 50, sin ids vacíos.
74
76
  */
75
77
  @Expose()
76
78
  @IsOptional()
77
79
  @IsArray()
80
+ @ArrayMaxSize(CUSTOMER_SEGMENT_IDS_MAX_ITEMS)
78
81
  @IsString({ each: true })
82
+ @IsNotEmpty({ each: true })
79
83
  customerSegmentIds?: string[];
80
84
  }
@@ -1,14 +1,17 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import { ArrayMaxSize, ArrayMinSize, IsArray, IsOptional, IsString, MaxLength, ValidateNested } from 'class-validator';
3
+ import { IsOptionalNonNull } from '../../validators/IsOptionalNonNull';
3
4
  import { CohortCondition } from './CohortCondition';
4
5
 
5
6
  /**
6
7
  * Body de PUT /cohorts/:cohortId — edición parcial; ausente deja el campo como está. Sube
7
8
  * `version`. El cambio de estado va por su endpoint dedicado.
9
+ *
10
+ * `null` solo se acepta en `description`, donde la borra; en `name` y `conditions` da 400.
8
11
  */
9
12
  export class UpdateCohortRequest {
10
13
  @Expose()
11
- @IsOptional()
14
+ @IsOptionalNonNull()
12
15
  @IsString()
13
16
  @MaxLength(120)
14
17
  name?: string;
@@ -17,11 +20,11 @@ export class UpdateCohortRequest {
17
20
  @IsOptional()
18
21
  @IsString()
19
22
  @MaxLength(500)
20
- description?: string;
23
+ description?: string | null;
21
24
 
22
25
  /** Reemplaza todas las condiciones. */
23
26
  @Expose()
24
- @IsOptional()
27
+ @IsOptionalNonNull()
25
28
  @IsArray()
26
29
  @ArrayMinSize(1)
27
30
  @ArrayMaxSize(10)
@@ -1,19 +1,31 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import {
3
+ ArrayMaxSize,
3
4
  ArrayNotEmpty,
4
5
  IsArray,
5
6
  IsBoolean,
6
7
  IsEnum,
7
8
  IsInt,
9
+ IsISO8601,
10
+ IsNotEmpty,
8
11
  IsNumber,
9
12
  IsOptional,
10
13
  IsString,
11
14
  Max,
15
+ MaxLength,
12
16
  Min,
13
17
  ValidateNested,
14
18
  } from 'class-validator';
19
+ import {
20
+ CREDIT_PLAN_MAX_TERM_WEEKS,
21
+ CREDIT_PLAN_TERM_OPTIONS_MAX_ITEMS,
22
+ OFFERINGS_AUDIT_REASON_MAX_LENGTH,
23
+ OFFERINGS_DESCRIPTION_MAX_LENGTH,
24
+ OFFERINGS_NAME_MAX_LENGTH,
25
+ } from '../../constants/offeringsInputLimits';
15
26
  import { ProductTierEnum } from '../../enums/ProductTierEnum';
16
27
  import { SaleTypeEnum } from '../../enums/SaleTypeEnum';
28
+ import { IsOptionalNonNull } from '../../validators/IsOptionalNonNull';
17
29
  import { PrepaymentMinimum } from '../PrepaymentMinimum';
18
30
 
19
31
  /**
@@ -21,20 +33,27 @@ import { PrepaymentMinimum } from '../PrepaymentMinimum';
21
33
  * En F1 el PUT puede editar `min/maxSciScore` por-plan (DEC-004); el guard atómico anti-huecos
22
34
  * entre planes (21-100) es F2/F3. El cambio de `status` va por su endpoint dedicado.
23
35
  * `code` y `level` no se editan aquí (identidad/segmentación del plan).
36
+ *
37
+ * Ausente deja el campo como está. `null` solo se acepta en los campos que lo declaran
38
+ * (`eligibleTiers`, `maxDownPaymentPct`, `min/maxSciScore`, `validFrom/Until`); en el resto da 400.
24
39
  */
25
40
  export class UpdateCreditPlanRequest {
26
41
  @Expose()
27
- @IsOptional()
42
+ @IsOptionalNonNull()
28
43
  @IsString()
44
+ @IsNotEmpty()
45
+ @MaxLength(OFFERINGS_NAME_MAX_LENGTH)
29
46
  name?: string;
30
47
 
31
48
  @Expose()
32
- @IsOptional()
49
+ @IsOptionalNonNull()
33
50
  @IsString()
51
+ @IsNotEmpty()
52
+ @MaxLength(OFFERINGS_DESCRIPTION_MAX_LENGTH)
34
53
  description?: string;
35
54
 
36
55
  @Expose()
37
- @IsOptional()
56
+ @IsOptionalNonNull()
38
57
  @IsArray()
39
58
  @ArrayNotEmpty()
40
59
  @IsEnum(SaleTypeEnum, { each: true })
@@ -47,7 +66,7 @@ export class UpdateCreditPlanRequest {
47
66
  eligibleTiers?: ProductTierEnum[] | null;
48
67
 
49
68
  @Expose()
50
- @IsOptional()
69
+ @IsOptionalNonNull()
51
70
  @IsNumber()
52
71
  @Min(0)
53
72
  @Max(1)
@@ -60,36 +79,39 @@ export class UpdateCreditPlanRequest {
60
79
  @Max(1)
61
80
  maxDownPaymentPct?: number | null;
62
81
 
82
+ /** Plazos ofrecidos, en semanas: de 1 a 104 cada uno. */
63
83
  @Expose()
64
- @IsOptional()
84
+ @IsOptionalNonNull()
65
85
  @IsArray()
66
86
  @ArrayNotEmpty()
87
+ @ArrayMaxSize(CREDIT_PLAN_TERM_OPTIONS_MAX_ITEMS)
67
88
  @IsInt({ each: true })
68
89
  @Min(1, { each: true })
90
+ @Max(CREDIT_PLAN_MAX_TERM_WEEKS, { each: true })
69
91
  termWeeksOptions?: number[];
70
92
 
71
93
  @Expose()
72
- @IsOptional()
94
+ @IsOptionalNonNull()
73
95
  @IsInt()
74
96
  @Min(0)
75
97
  maxFinancedAmountCents?: number;
76
98
 
77
99
  @Expose()
78
- @IsOptional()
100
+ @IsOptionalNonNull()
79
101
  @IsNumber()
80
102
  @Min(2.0)
81
103
  @Max(2.6)
82
104
  tnaAnnual?: number;
83
105
 
84
106
  @Expose()
85
- @IsOptional()
107
+ @IsOptionalNonNull()
86
108
  @IsNumber()
87
109
  @Min(0)
88
110
  @Max(1)
89
111
  openingCommissionPct?: number;
90
112
 
91
113
  @Expose()
92
- @IsOptional()
114
+ @IsOptionalNonNull()
93
115
  @IsBoolean()
94
116
  paymentShift?: boolean;
95
117
 
@@ -107,20 +129,29 @@ export class UpdateCreditPlanRequest {
107
129
  @Max(100)
108
130
  maxSciScore?: number | null;
109
131
 
132
+ /** Inicio de vigencia en ISO-8601; `null` la quita. */
110
133
  @Expose()
111
134
  @IsOptional()
112
- @IsString()
135
+ @IsISO8601()
113
136
  validFrom?: string | null;
114
137
 
138
+ /** Fin de vigencia en ISO-8601; `null` la quita. */
115
139
  @Expose()
116
140
  @IsOptional()
117
- @IsString()
141
+ @IsISO8601()
118
142
  validUntil?: string | null;
119
143
 
120
144
  /** Mínimo del abono a capital; ausente = sin cambios (en el alta: `ANY`). */
121
145
  @Expose()
122
- @IsOptional()
146
+ @IsOptionalNonNull()
123
147
  @ValidateNested()
124
148
  @Type(() => PrepaymentMinimum)
125
149
  prepaymentMinimum?: PrepaymentMinimum;
150
+
151
+ /** Motivo del cambio; queda en la bitácora del plan. */
152
+ @Expose()
153
+ @IsOptional()
154
+ @IsString()
155
+ @MaxLength(OFFERINGS_AUDIT_REASON_MAX_LENGTH)
156
+ reason?: string;
126
157
  }