@fiado/type-kit 3.626.0 → 3.628.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/emailVerification/dtos/EmailSetTrustedRequest.test.ts +23 -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/emailVerification/dtos/EmailSetTrustedRequest.d.ts +2 -0
  22. package/bin/emailVerification/dtos/EmailSetTrustedRequest.js +6 -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/emailVerification/dtos/EmailSetTrustedRequest.ts +6 -0
  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
@@ -12,6 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.CreatePiiAccessLogRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
+ const auditInputLimits_1 = require("../../constants/auditInputLimits");
16
+ const IsIsoDateTime_1 = require("../../validators/IsIsoDateTime");
15
17
  const PiiAccessActionEnum_1 = require("../../enums/PiiAccessActionEnum");
16
18
  const PiiResourceTypeEnum_1 = require("../../enums/PiiResourceTypeEnum");
17
19
  /** Body de `POST /private/pii-access-logs` (privateCreatePiiAccessLog); el tenant va en `?tenantId=`. */
@@ -26,7 +28,7 @@ __decorate([
26
28
  ], CreatePiiAccessLogRequest.prototype, "accessId", void 0);
27
29
  __decorate([
28
30
  (0, class_transformer_1.Expose)(),
29
- (0, class_validator_1.IsISO8601)(),
31
+ (0, IsIsoDateTime_1.IsIsoDateTime)(),
30
32
  __metadata("design:type", String)
31
33
  ], CreatePiiAccessLogRequest.prototype, "occurredAt", void 0);
32
34
  __decorate([
@@ -73,7 +75,10 @@ __decorate([
73
75
  (0, class_transformer_1.Expose)(),
74
76
  (0, class_validator_1.IsArray)(),
75
77
  (0, class_validator_1.ArrayNotEmpty)(),
78
+ (0, class_validator_1.ArrayMaxSize)(auditInputLimits_1.PII_ACCESS_FIELDS_MAX_ITEMS),
76
79
  (0, class_validator_1.IsString)({ each: true }),
80
+ (0, class_validator_1.IsNotEmpty)({ each: true }),
81
+ (0, class_validator_1.MaxLength)(auditInputLimits_1.AUDIT_FIELD_NAME_MAX_LENGTH, { each: true }),
77
82
  __metadata("design:type", Array)
78
83
  ], CreatePiiAccessLogRequest.prototype, "fields", void 0);
79
84
  __decorate([
@@ -81,5 +86,7 @@ __decorate([
81
86
  (0, class_validator_1.IsOptional)(),
82
87
  (0, class_validator_1.IsArray)(),
83
88
  (0, class_validator_1.IsString)({ each: true }),
89
+ (0, class_validator_1.IsNotEmpty)({ each: true }),
90
+ (0, class_validator_1.MaxLength)(auditInputLimits_1.PII_RESOURCE_ID_MAX_LENGTH, { each: true }),
84
91
  __metadata("design:type", Array)
85
92
  ], CreatePiiAccessLogRequest.prototype, "resourceIds", void 0);
@@ -13,6 +13,7 @@ export declare class AuditTrailRecordedV1 {
13
13
  /** userId del actor; nunca `system`: sin usuario va el nombre del lambda que lo disparó. */
14
14
  performedBy: string;
15
15
  sourceLambda: string;
16
+ /** Fecha-hora ISO-8601 completa con zona, como `toISOString()`. */
16
17
  occurredAt: string;
17
18
  tenantId?: string;
18
19
  reason?: string;
@@ -12,6 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.AuditTrailRecordedV1 = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
+ const auditInputLimits_1 = require("../constants/auditInputLimits");
16
+ const IsIsoDateTime_1 = require("../validators/IsIsoDateTime");
15
17
  const auditTrailEntityTypes_1 = require("../constants/auditTrailEntityTypes");
16
18
  const AuditTrailChange_1 = require("../dtos/AuditTrailChange");
17
19
  const AuditTrailContextEntry_1 = require("../dtos/AuditTrailContextEntry");
@@ -45,6 +47,7 @@ __decorate([
45
47
  __decorate([
46
48
  (0, class_transformer_1.Expose)(),
47
49
  (0, class_validator_1.IsArray)(),
50
+ (0, class_validator_1.ArrayMaxSize)(auditInputLimits_1.AUDIT_TRAIL_CHANGES_MAX_ITEMS),
48
51
  (0, class_validator_1.ValidateNested)({ each: true }),
49
52
  (0, class_transformer_1.Type)(() => AuditTrailChange_1.AuditTrailChange),
50
53
  __metadata("design:type", Array)
@@ -52,6 +55,7 @@ __decorate([
52
55
  __decorate([
53
56
  (0, class_transformer_1.Expose)(),
54
57
  (0, class_validator_1.IsArray)(),
58
+ (0, class_validator_1.ArrayMaxSize)(auditInputLimits_1.AUDIT_TRAIL_CONTEXT_MAX_ITEMS),
55
59
  (0, class_validator_1.ValidateNested)({ each: true }),
56
60
  (0, class_transformer_1.Type)(() => AuditTrailContextEntry_1.AuditTrailContextEntry),
57
61
  __metadata("design:type", Array)
@@ -70,7 +74,7 @@ __decorate([
70
74
  ], AuditTrailRecordedV1.prototype, "sourceLambda", void 0);
71
75
  __decorate([
72
76
  (0, class_transformer_1.Expose)(),
73
- (0, class_validator_1.IsISO8601)(),
77
+ (0, IsIsoDateTime_1.IsIsoDateTime)(),
74
78
  __metadata("design:type", String)
75
79
  ], AuditTrailRecordedV1.prototype, "occurredAt", void 0);
76
80
  __decorate([
@@ -4,6 +4,8 @@ export * from './enums/AuditTrailActionEnum';
4
4
  export * from './enums/PiiResourceTypeEnum';
5
5
  export * from './enums/PiiAccessActionEnum';
6
6
  export * from './constants/auditTrailEntityTypes';
7
+ export * from './constants/auditInputLimits';
8
+ export * from './validators/IsIsoDateTime';
7
9
  export * from './dtos/AuditTrailChange';
8
10
  export * from './dtos/AuditTrailContextEntry';
9
11
  export * from './dtos/requests/CreatePiiAccessLogRequest';
@@ -22,6 +22,9 @@ __exportStar(require("./enums/PiiResourceTypeEnum"), exports);
22
22
  __exportStar(require("./enums/PiiAccessActionEnum"), exports);
23
23
  // Constantes
24
24
  __exportStar(require("./constants/auditTrailEntityTypes"), exports);
25
+ __exportStar(require("./constants/auditInputLimits"), exports);
26
+ // Validadores
27
+ __exportStar(require("./validators/IsIsoDateTime"), exports);
25
28
  // DTOs
26
29
  __exportStar(require("./dtos/AuditTrailChange"), exports);
27
30
  __exportStar(require("./dtos/AuditTrailContextEntry"), exports);
@@ -0,0 +1,13 @@
1
+ import { ValidationOptions } from 'class-validator';
2
+ /**
3
+ * `true` si el valor es una fecha-hora ISO-8601 completa, con zona, que existe en el calendario y
4
+ * que `Date.parse` entiende.
5
+ */
6
+ export declare const isIsoDateTime: (value: unknown) => boolean;
7
+ /**
8
+ * Fecha-hora ISO-8601 completa con zona (L-188).
9
+ *
10
+ * `@IsISO8601()` acepta `2026-W44-1`, `2026-305` o `2026`, que `new Date()` no entiende, y la fecha
11
+ * sin zona, que cada runtime lee distinto. El central calcula el vencimiento del registro con ella.
12
+ */
13
+ export declare const IsIsoDateTime: (validationOptions?: ValidationOptions) => PropertyDecorator;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IsIsoDateTime = exports.isIsoDateTime = void 0;
4
+ const class_validator_1 = require("class-validator");
5
+ /** Fecha-hora completa: fecha, hora con segundos y zona (`Z` u offset). Como `toISOString()`. */
6
+ const ISO_DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/;
7
+ /**
8
+ * `true` si el valor es una fecha-hora ISO-8601 completa, con zona, que existe en el calendario y
9
+ * que `Date.parse` entiende.
10
+ */
11
+ const isIsoDateTime = (value) => typeof value === 'string' &&
12
+ ISO_DATE_TIME_PATTERN.test(value) &&
13
+ (0, class_validator_1.isISO8601)(value, { strict: true, strictSeparator: true }) &&
14
+ Number.isFinite(Date.parse(value));
15
+ exports.isIsoDateTime = isIsoDateTime;
16
+ /**
17
+ * Fecha-hora ISO-8601 completa con zona (L-188).
18
+ *
19
+ * `@IsISO8601()` acepta `2026-W44-1`, `2026-305` o `2026`, que `new Date()` no entiende, y la fecha
20
+ * sin zona, que cada runtime lee distinto. El central calcula el vencimiento del registro con ella.
21
+ */
22
+ const IsIsoDateTime = (validationOptions) => (0, class_validator_1.ValidateBy)({
23
+ name: 'isIsoDateTime',
24
+ validator: {
25
+ validate: (value) => (0, exports.isIsoDateTime)(value),
26
+ defaultMessage: () => '$property debe ser una fecha-hora ISO-8601 completa con zona (p. ej. 2026-11-03T10:00:00.000Z)',
27
+ },
28
+ }, validationOptions);
29
+ exports.IsIsoDateTime = IsIsoDateTime;
@@ -3,16 +3,18 @@
3
3
  * Modelias la devuelve completa; el camino Círculo+SCI no produce oferta, el plan lo resuelve
4
4
  * loan-offerings por nivel).
5
5
  *
6
- * ⚠️ Los valores numéricos se transportan TAL CUAL los entrega el proveedor (el contrato Modelias
7
- * no confirma unidades de `linea_credito`/`enganche` — ver TD del módulo modelias). NO asumir cents.
6
+ * Se guarda TAL CUAL la entrega el proveedor, sin convertir unidades (decisión D-4 de la auditoría,
7
+ * L-181). Unidades observadas contra Modelias DEV (A9 de loan-scoring, `docs/F2/ASSUMPTIONS.md`):
8
+ * `linea_credito` 10000/7500/4000 y `enganche` 0.1/0.2/0.35. Quien la use para originar convierte
9
+ * a centavos y a porcentaje; no la sumes a montos en centavos.
8
10
  */
9
11
  export interface ScoringOffer {
10
- /** Línea de crédito aprobada (unidad según proveedor). */
12
+ /** Línea de crédito aprobada, en PESOS MXN enteros (no centavos): `10000` = $10,000. */
11
13
  creditLine: number | null;
12
- /** Enganche requerido (unidad/base según proveedor). */
14
+ /** Enganche requerido como FRACCIÓN del precio (no monto ni porcentaje): `0.2` = 20%. */
13
15
  downPayment: number | null;
14
- /** Plazos ofrecidos, en semanas. */
16
+ /** Plazos ofrecidos, en semanas (Modelias usa múltiplos de 13). */
15
17
  termsWeeks: number[];
16
- /** Tasas por plazo (clave = plazo, valor = tasa decimal). */
18
+ /** Tasas por plazo: clave = plazo en semanas, valor = tasa en decimal. */
17
19
  rates: Record<string, number>;
18
20
  }
@@ -4,18 +4,29 @@ import { SciInternalHistoryInput } from './SciInternalHistoryInput';
4
4
  * crédito, vía api-invoker). El proveedor NO se elige acá: lo resuelve el `ScoringProviderRouter`
5
5
  * por configuración del tenant (spec 12). El tenant viaja por query `?tenantId=` (convención de
6
6
  * los privados Fiado), no en este body.
7
+ *
8
+ * La consulta al proveedor se cobra: celular e ids llegan con su formato (L-177); el CURP, acotado.
7
9
  */
8
10
  export declare class EvaluateSciRequest {
9
- /** Acreditado a evaluar (`LoanBorrower`). La evaluación queda ligada a él en el historial. */
11
+ /**
12
+ * Llave del intento, opcional (L-173): el mismo valor devuelve la misma evaluación sin volver a
13
+ * consultar al proveedor. Sin ella, cada llamada es una evaluación nueva, como hasta ahora.
14
+ */
15
+ idempotencyKey?: string;
16
+ /** Acreditado a evaluar (`LoanBorrower`, ULID). La evaluación queda ligada a él en el historial. */
10
17
  borrowerId: string;
11
18
  /**
12
19
  * Cliente retail dueño del acreditado. Se guarda en el snapshot para que el listado del
13
20
  * backoffice resuelva el nombre sin volver a preguntarle a loan-credit de quién es.
14
21
  */
15
22
  retailCustomerId?: string;
16
- /** CURP del solicitante (requerido por los proveedores de scoring). */
23
+ /**
24
+ * CURP del solicitante (requerido por los proveedores de scoring). Solo con tope de largo:
25
+ * retail-customer guarda el CURP de Metamap sin validar su formato, y exigir `regexCurp` aquí
26
+ * tumbaría la evaluación del wizard. El formato lo revisa loan-scoring antes de consultar (L-177, A).
27
+ */
17
28
  curp: string;
18
- /** Celular del solicitante (requerido por Modelias). */
29
+ /** Celular del solicitante: 10 dígitos, sin `+52` (requerido por Modelias). */
19
30
  cellphone: string;
20
31
  email?: string;
21
32
  /**
@@ -12,35 +12,50 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EvaluateSciRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
+ const InputPatterns_1 = require("../../../common/constants/InputPatterns");
16
+ const CreditIdPattern_1 = require("../../../common/constants/CreditIdPattern");
15
17
  const SciInternalHistoryInput_1 = require("./SciInternalHistoryInput");
16
18
  /**
17
19
  * Body de `POST /private/scoring/evaluations` de loan-scoring-business (wizard paso 05 / motor de
18
20
  * crédito, vía api-invoker). El proveedor NO se elige acá: lo resuelve el `ScoringProviderRouter`
19
21
  * por configuración del tenant (spec 12). El tenant viaja por query `?tenantId=` (convención de
20
22
  * los privados Fiado), no en este body.
23
+ *
24
+ * La consulta al proveedor se cobra: celular e ids llegan con su formato (L-177); el CURP, acotado.
21
25
  */
22
26
  class EvaluateSciRequest {
23
27
  }
24
28
  exports.EvaluateSciRequest = EvaluateSciRequest;
29
+ __decorate([
30
+ (0, class_validator_1.IsOptional)(),
31
+ (0, class_validator_1.IsString)(),
32
+ (0, class_validator_1.IsNotEmpty)(),
33
+ (0, class_validator_1.MaxLength)(128),
34
+ __metadata("design:type", String)
35
+ ], EvaluateSciRequest.prototype, "idempotencyKey", void 0);
25
36
  __decorate([
26
37
  (0, class_validator_1.IsString)(),
27
38
  (0, class_validator_1.IsNotEmpty)(),
39
+ (0, class_validator_1.Matches)(CreditIdPattern_1.CREDIT_ID_PATTERN, { message: 'borrowerId debe ser un ULID de 26 caracteres' }),
28
40
  __metadata("design:type", String)
29
41
  ], EvaluateSciRequest.prototype, "borrowerId", void 0);
30
42
  __decorate([
31
43
  (0, class_validator_1.IsOptional)(),
32
44
  (0, class_validator_1.IsString)(),
33
45
  (0, class_validator_1.IsNotEmpty)(),
46
+ (0, class_validator_1.MaxLength)(64),
34
47
  __metadata("design:type", String)
35
48
  ], EvaluateSciRequest.prototype, "retailCustomerId", void 0);
36
49
  __decorate([
37
50
  (0, class_validator_1.IsString)(),
38
51
  (0, class_validator_1.IsNotEmpty)(),
52
+ (0, class_validator_1.MaxLength)(64),
39
53
  __metadata("design:type", String)
40
54
  ], EvaluateSciRequest.prototype, "curp", void 0);
41
55
  __decorate([
42
56
  (0, class_validator_1.IsString)(),
43
57
  (0, class_validator_1.IsNotEmpty)(),
58
+ (0, class_validator_1.Matches)(InputPatterns_1.PHONE_MX_PATTERN, { message: 'cellphone debe tener 10 dígitos' }),
44
59
  __metadata("design:type", String)
45
60
  ], EvaluateSciRequest.prototype, "cellphone", void 0);
46
61
  __decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.626.0",
3
+ "version": "3.628.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Largo máximo de los ids que el motor manda en `apply-result` (`attemptId`, `intentId`, `chargeId`,
3
+ * `holdTxId`). Los reales miden menos de 100: `attemptId` = `<intentId>#<proveedor>#<mecanismo>#<ciclo>`.
4
+ * Con 256 cabe la llave compuesta del dominio sin acercarse a los 2 KB de la pk de DynamoDB.
5
+ */
6
+ export const COLLECTION_RESULT_ID_MAX_LENGTH = 256;
7
+
8
+ /** Largo máximo de `domain`, `directoryId` y `tenantId` en `resolve-charges`. */
9
+ export const COLLECTION_RESOLVE_FIELD_MAX_LENGTH = 128;
10
+
11
+ /**
12
+ * Techo técnico de un monto del motor, en PESOS (o en la moneda de la wallet): 1 000 millones.
13
+ *
14
+ * No es política de negocio: un equipo de SureKeep cuesta decenas de miles de pesos. Hasta este techo un
15
+ * `double` representa el monto con resolución de ~0.00001 centavos, así que `Math.round(monto * 100)`
16
+ * da el centavo exacto y el resultado queda muy por debajo de `Number.MAX_SAFE_INTEGER`.
17
+ */
18
+ export const COLLECTION_AMOUNT_MAX = 1_000_000_000;
@@ -1,4 +1,6 @@
1
- import { IsString, IsEnum, IsOptional, IsNumber } from 'class-validator';
1
+ import { IsString, IsEnum, IsOptional, IsNumber, IsNotEmpty, MaxLength, Min, Max } from 'class-validator';
2
+ import { COLLECTION_AMOUNT_MAX, COLLECTION_RESULT_ID_MAX_LENGTH } from '../constants/CollectionResultLimits';
3
+ import { IsCentPrecision } from '../validators/IsCentPrecision';
2
4
  import { CollectionResultStatus } from '../enums/CollectionResultStatus';
3
5
  import { MechanismType } from '../enums/MechanismType';
4
6
  import { CurrencyId } from '../../currency/enums/CurrencyId';
@@ -10,23 +12,28 @@ import { CurrencyId } from '../../currency/enums/CurrencyId';
10
12
  * respuesta se lee como no entregada y el mismo resultado vuelve más tarde, así que aplicarlo tiene
11
13
  * que ser idempotente: el dominio deduplica por `attemptId`, que identifica ESE intento y no el cobro
12
14
  * entero.
15
+ *
16
+ * Los ids no vacíos y con tope evitan que un `attemptId` vacío colapse la deduplicación (L-005). Los
17
+ * montos van en pesos, con centavos, sin negativos y bajo un techo técnico (L-022).
13
18
  */
14
19
  export class ApplyCollectionResultRequest {
15
- @IsString() attemptId!: string; // dedupe idempotente en el dominio
16
- @IsString() intentId!: string;
17
- @IsString() chargeId!: string;
20
+ @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESULT_ID_MAX_LENGTH) attemptId!: string; // dedupe idempotente en el dominio
21
+ @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESULT_ID_MAX_LENGTH) intentId!: string;
22
+ @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESULT_ID_MAX_LENGTH) chargeId!: string;
18
23
  @IsString() domain!: string;
19
24
  @IsString() tenantId!: string;
20
25
  @IsEnum(CollectionResultStatus) result!: CollectionResultStatus;
21
- @IsNumber() amountCollected!: number;
22
- @IsNumber() amountReserved!: number;
26
+ /** Pesos cobrados (débito directo). */
27
+ @IsNumber() @IsCentPrecision() @Min(0) @Max(COLLECTION_AMOUNT_MAX) amountCollected!: number;
28
+ /** Pesos retenidos (preautorización). */
29
+ @IsNumber() @IsCentPrecision() @Min(0) @Max(COLLECTION_AMOUNT_MAX) amountReserved!: number;
23
30
  @IsEnum(MechanismType) mechanism!: MechanismType;
24
- @IsOptional() @IsString() holdTxId?: string;
31
+ @IsOptional() @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESULT_ID_MAX_LENGTH) holdTxId?: string;
25
32
  /**
26
33
  * Monto que salió de la wallet, en `walletCurrency`. Sólo viene cuando se retuvo o debitó dinero
27
34
  * (ausente en NONE); en USD_PREAUTH son los USD retenidos, que el dominio usa como `amountBlocked`.
28
35
  */
29
- @IsOptional() @IsNumber() walletAmount?: number;
36
+ @IsOptional() @IsNumber() @IsCentPrecision() @Min(0) @Max(COLLECTION_AMOUNT_MAX) walletAmount?: number;
30
37
  /** Moneda de `walletAmount`. Viene junto con él, sólo cuando se retuvo o debitó dinero. */
31
38
  @IsOptional() @IsEnum(CurrencyId) walletCurrency?: CurrencyId;
32
39
  }
@@ -1,4 +1,5 @@
1
- import { IsString } from 'class-validator';
1
+ import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
2
+ import { COLLECTION_RESOLVE_FIELD_MAX_LENGTH } from '../constants/CollectionResultLimits';
2
3
 
3
4
  /**
4
5
  * El motor pregunta al dominio qué debe un titular ahora mismo.
@@ -6,9 +7,11 @@ import { IsString } from 'class-validator';
6
7
  * No lleva importe: el monto es justo lo que se está preguntando. Puede haber cambiado desde que el
7
8
  * cargo se dio de alta —por mora, o porque el cliente pagó por otra vía— y sólo el dominio, que es
8
9
  * quien aplica sus propias reglas, sabe cuánto queda vivo.
10
+ *
11
+ * Los tres campos son llave de búsqueda: vacíos o sin tope terminaban en 500 en el dominio (L-064).
9
12
  */
10
13
  export class ResolvePendingChargesRequest {
11
- @IsString() domain!: string;
12
- @IsString() directoryId!: string;
13
- @IsString() tenantId!: string;
14
+ @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESOLVE_FIELD_MAX_LENGTH) domain!: string;
15
+ @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESOLVE_FIELD_MAX_LENGTH) directoryId!: string;
16
+ @IsString() @IsNotEmpty() @MaxLength(COLLECTION_RESOLVE_FIELD_MAX_LENGTH) tenantId!: string;
14
17
  }
@@ -13,6 +13,10 @@ export * from './enums/AckIntentStatus';
13
13
  export * from './enums/RedriveOutboxStatus';
14
14
  export * from './enums/DisbursementType';
15
15
 
16
+ // Constantes y validadores
17
+ export * from './constants/CollectionResultLimits';
18
+ export * from './validators/IsCentPrecision';
19
+
16
20
  // DTOs
17
21
  export * from './dtos/PendingChargeDto';
18
22
  export * from './dtos/CollectRequest';
@@ -0,0 +1,33 @@
1
+ import { ValidateBy, ValidationOptions } from 'class-validator';
2
+
3
+ /**
4
+ * Ruido de punto flotante tolerado, en centavos. Restar montos en `double` deja colas como
5
+ * `648.2299999999999`; un tercer decimal real (0.001 pesos = 0.1 centavos) queda muy por encima.
6
+ */
7
+ const FLOAT_NOISE_CENTS = 1e-3;
8
+
9
+ /** `true` si el número no tiene fracción de centavo, salvo ruido de punto flotante. */
10
+ export const hasCentPrecision = (value: unknown): boolean => {
11
+ if (typeof value !== 'number' || !Number.isFinite(value)) return false;
12
+ const cents = value * 100;
13
+ return Math.abs(cents - Math.round(cents)) < FLOAT_NOISE_CENTS;
14
+ };
15
+
16
+ /**
17
+ * Monto con a lo más dos decimales (centavos).
18
+ *
19
+ * No se usa `@IsNumber({ maxDecimalPlaces: 2 })` porque cuenta los dígitos del `toString()`: rechaza
20
+ * `648.2299999999999`, que es `648.23` con ruido de una resta. El motor de cobro deja ese ruido al
21
+ * restar lo cobrado de lo pendiente, y rechazar un resultado con dinero ya cobrado lo manda a la DLQ.
22
+ */
23
+ export const IsCentPrecision = (validationOptions?: ValidationOptions): PropertyDecorator =>
24
+ ValidateBy(
25
+ {
26
+ name: 'isCentPrecision',
27
+ validator: {
28
+ validate: (value: unknown): boolean => hasCentPrecision(value),
29
+ defaultMessage: (): string => '$property debe ser un monto con a lo más dos decimales',
30
+ },
31
+ },
32
+ validationOptions,
33
+ );
@@ -24,4 +24,10 @@ export class EmailSetTrustedRequest {
24
24
  @IsOptional()
25
25
  @IsBoolean()
26
26
  isPrincipal?: boolean;
27
+
28
+ /** En true, rechaza el correo si otro directorio ya lo tiene verificado. Sin el campo, no lo revisa. */
29
+ @Expose()
30
+ @IsOptional()
31
+ @IsBoolean()
32
+ dedup?: boolean;
27
33
  }
@@ -0,0 +1,16 @@
1
+ /** Largo máximo de un motivo de reasignación o redistribución. */
2
+ export const COLLECTOR_REASON_MAX_LENGTH = 500;
3
+
4
+ /** Al menos un carácter que no sea espacio: un motivo en blanco no explica nada. */
5
+ export const COLLECTOR_REASON_NON_BLANK_PATTERN = /\S/;
6
+
7
+ /** Ids de cadena, tienda, crédito y usuario: hoy ULID de 26; se acepta hasta 64 con guion y guion bajo. */
8
+ export const COLLECTOR_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
9
+ export const COLLECTOR_ID_MAX_LENGTH = 64;
10
+ export const COLLECTOR_ID_MESSAGE = 'El id admite letras, números, guion y guion bajo (máximo 64)';
11
+
12
+ /** Asignaciones por página del listado. */
13
+ export const COLLECTOR_ASSIGNMENTS_LIST_MAX_LIMIT = 100;
14
+
15
+ /** Largo máximo del cursor opaco del listado. */
16
+ export const COLLECTOR_ASSIGNMENTS_NEXT_TOKEN_MAX_LENGTH = 1024;
@@ -1,23 +1,35 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsNotEmpty, IsString } from 'class-validator';
2
+ import { IsNotEmpty, IsString, Matches, MaxLength } from 'class-validator';
3
+ import {
4
+ COLLECTOR_ID_MAX_LENGTH,
5
+ COLLECTOR_ID_MESSAGE,
6
+ COLLECTOR_ID_PATTERN,
7
+ } from '../../constants/CollectorAssignmentLimits';
3
8
 
4
9
  /**
5
10
  * Body de POST /private/collector-assignments/auto-assign (hot path). Lo invoca loan-credit-business
6
11
  * al crearse un crédito (F3+); en F1 se prueba con `creditId` dummy. Elige cobrador y persiste ACTIVE.
12
+ * Los ids son llave en DynamoDB: largo y forma acotados (L-171).
7
13
  */
8
14
  export class AutoAssignRequest {
9
15
  @Expose()
10
16
  @IsString()
11
17
  @IsNotEmpty()
18
+ @MaxLength(COLLECTOR_ID_MAX_LENGTH)
19
+ @Matches(COLLECTOR_ID_PATTERN, { message: COLLECTOR_ID_MESSAGE })
12
20
  retailerId!: string;
13
21
 
14
22
  @Expose()
15
23
  @IsString()
16
24
  @IsNotEmpty()
25
+ @MaxLength(COLLECTOR_ID_MAX_LENGTH)
26
+ @Matches(COLLECTOR_ID_PATTERN, { message: COLLECTOR_ID_MESSAGE })
17
27
  creditId!: string;
18
28
 
19
29
  @Expose()
20
30
  @IsString()
21
31
  @IsNotEmpty()
32
+ @MaxLength(COLLECTOR_ID_MAX_LENGTH)
33
+ @Matches(COLLECTOR_ID_PATTERN, { message: COLLECTOR_ID_MESSAGE })
22
34
  storeId!: string;
23
35
  }
@@ -0,0 +1,52 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, Matches, Max, MaxLength, Min } from 'class-validator';
3
+ import {
4
+ COLLECTOR_ASSIGNMENTS_LIST_MAX_LIMIT,
5
+ COLLECTOR_ASSIGNMENTS_NEXT_TOKEN_MAX_LENGTH,
6
+ COLLECTOR_ID_MAX_LENGTH,
7
+ COLLECTOR_ID_MESSAGE,
8
+ COLLECTOR_ID_PATTERN,
9
+ } from '../../constants/CollectorAssignmentLimits';
10
+ import { AssignmentStatusEnum } from '../../enums/AssignmentStatusEnum';
11
+
12
+ /**
13
+ * Query de `GET /retailers/:retailerId/collector-assignments`. Todos opcionales: sin filtros lista
14
+ * la cadena completa, página por página (L-161, L-170). Los filtros llegan validados, no crudos.
15
+ */
16
+ export class ListCollectorAssignmentsRequest {
17
+ @Expose()
18
+ @IsOptional()
19
+ @IsEnum(AssignmentStatusEnum)
20
+ status?: AssignmentStatusEnum;
21
+
22
+ @Expose()
23
+ @IsOptional()
24
+ @IsString()
25
+ @MaxLength(COLLECTOR_ID_MAX_LENGTH)
26
+ @Matches(COLLECTOR_ID_PATTERN, { message: COLLECTOR_ID_MESSAGE })
27
+ storeId?: string;
28
+
29
+ @Expose()
30
+ @IsOptional()
31
+ @IsString()
32
+ @MaxLength(COLLECTOR_ID_MAX_LENGTH)
33
+ @Matches(COLLECTOR_ID_PATTERN, { message: COLLECTOR_ID_MESSAGE })
34
+ collectorUserId?: string;
35
+
36
+ /** Asignaciones por página, de 1 a 100. Sin él, el lambda pone su default. */
37
+ @Expose()
38
+ @IsOptional()
39
+ @Type(() => Number)
40
+ @IsInt()
41
+ @Min(1)
42
+ @Max(COLLECTOR_ASSIGNMENTS_LIST_MAX_LIMIT)
43
+ limit?: number;
44
+
45
+ /** Cursor opaco que devolvió la página anterior. */
46
+ @Expose()
47
+ @IsOptional()
48
+ @IsString()
49
+ @IsNotEmpty()
50
+ @MaxLength(COLLECTOR_ASSIGNMENTS_NEXT_TOKEN_MAX_LENGTH)
51
+ nextToken?: string;
52
+ }
@@ -1,13 +1,20 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsNotEmpty, IsString } from 'class-validator';
2
+ import { IsNotEmpty, IsString, Matches, MaxLength } from 'class-validator';
3
+ import {
4
+ COLLECTOR_REASON_MAX_LENGTH,
5
+ COLLECTOR_REASON_NON_BLANK_PATTERN,
6
+ } from '../../constants/CollectorAssignmentLimits';
3
7
 
4
8
  /**
5
9
  * Body de POST /retailers/:retailerId/collector-assignments/:assignmentId/reassign (reasignación manual).
6
10
  * `reason` obligatorio (auditoría de acción crítica — modelo-datos §10).
11
+ * Motivo no en blanco y de hasta 500 caracteres (L-171).
7
12
  */
8
13
  export class ReassignRequest {
9
14
  @Expose()
10
15
  @IsString()
11
16
  @IsNotEmpty()
17
+ @Matches(COLLECTOR_REASON_NON_BLANK_PATTERN, { message: 'reason no puede ir en blanco' })
18
+ @MaxLength(COLLECTOR_REASON_MAX_LENGTH)
12
19
  reason!: string;
13
20
  }
@@ -1,13 +1,20 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsNotEmpty, IsString } from 'class-validator';
2
+ import { IsNotEmpty, IsString, Matches, MaxLength } from 'class-validator';
3
+ import {
4
+ COLLECTOR_REASON_MAX_LENGTH,
5
+ COLLECTOR_REASON_NON_BLANK_PATTERN,
6
+ } from '../../constants/CollectorAssignmentLimits';
3
7
 
4
8
  /**
5
9
  * Body de POST /retailers/:retailerId/collectors/:userId/redistribute. Redistribuye la cartera activa de
6
10
  * un cobrador (ej. al desactivarlo). `reason` obligatorio (ej. `USER_INACTIVATED`) — auditoría §10.
11
+ * Motivo no en blanco y de hasta 500 caracteres (L-171).
7
12
  */
8
13
  export class RedistributeRequest {
9
14
  @Expose()
10
15
  @IsString()
11
16
  @IsNotEmpty()
17
+ @Matches(COLLECTOR_REASON_NON_BLANK_PATTERN, { message: 'reason no puede ir en blanco' })
18
+ @MaxLength(COLLECTOR_REASON_MAX_LENGTH)
12
19
  reason!: string;
13
20
  }
@@ -0,0 +1,10 @@
1
+ import { CollectorAssignmentResponse } from './CollectorAssignmentResponse';
2
+
3
+ /**
4
+ * Respuesta de `GET /retailers/:retailerId/collector-assignments`. Conserva la clave `assignments`
5
+ * que ya lee la webapp; `nextToken` viene solo si hay otra página (ausente en la última).
6
+ */
7
+ export interface ListCollectorAssignmentsResponse {
8
+ assignments: CollectorAssignmentResponse[];
9
+ nextToken?: string;
10
+ }
@@ -2,6 +2,9 @@
2
2
  export * from './enums/AssignmentStrategyEnum';
3
3
  export * from './enums/AssignmentStatusEnum';
4
4
 
5
+ // Constantes
6
+ export * from './constants/CollectorAssignmentLimits';
7
+
5
8
  // Shared DTOs
6
9
  export * from './dtos/PriorityWeights';
7
10
 
@@ -11,9 +14,11 @@ export * from './dtos/requests/UpdateAssignmentRuleRequest';
11
14
  export * from './dtos/requests/AutoAssignRequest';
12
15
  export * from './dtos/requests/ReassignRequest';
13
16
  export * from './dtos/requests/RedistributeRequest';
17
+ export * from './dtos/requests/ListCollectorAssignmentsRequest';
14
18
 
15
19
  // Response DTOs
16
20
  export * from './dtos/responses/AssignmentRuleResponse';
17
21
  export * from './dtos/responses/CollectorAssignmentResponse';
18
22
  export * from './dtos/responses/CollectorLoadResponse';
19
23
  export * from './dtos/responses/RedistributeSummaryResponse';
24
+ export * from './dtos/responses/ListCollectorAssignmentsResponse';
@@ -0,0 +1,11 @@
1
+ /** Claves por llamada a bulk-get: el límite de BatchGetItem. Los consumidores mandan 20 o menos. */
2
+ export const BULK_GET_PARAMETERS_MAX_ITEMS = 100;
3
+
4
+ /** Parámetros por llamada a bulk-update; la webapp manda solo los editados (hoy 22 como máximo). */
5
+ export const BULK_UPDATE_PARAMETERS_MAX_ITEMS = 50;
6
+
7
+ /** Largo máximo del motivo de un cambio de parámetro. */
8
+ export const PARAMETER_REASON_MAX_LENGTH = 500;
9
+
10
+ /** Al menos un carácter que no sea espacio: un motivo en blanco no explica nada. */
11
+ export const PARAMETER_REASON_NON_BLANK_PATTERN = /\S/;
@@ -1,5 +1,6 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
- import { ArrayNotEmpty, IsArray, IsEnum, IsString, ValidateNested } from 'class-validator';
2
+ import { ArrayMaxSize, ArrayNotEmpty, IsArray, IsEnum, IsString, ValidateNested } from 'class-validator';
3
+ import { BULK_GET_PARAMETERS_MAX_ITEMS } from '../../constants/ParameterRequestLimits';
3
4
  import { ParameterTypeEnum } from '../../enums/ParameterTypeEnum';
4
5
 
5
6
  export class ParameterKeyRef {
@@ -12,11 +13,12 @@ export class ParameterKeyRef {
12
13
  key!: string;
13
14
  }
14
15
 
15
- /** Body de POST /private/parameters/bulk-get — hot path para consumers (cachean 5 min). */
16
+ /** Body de POST /private/parameters/bulk-get — hot path para consumers (cachean 5 min). Hasta 100 claves. */
16
17
  export class BulkGetParametersRequest {
17
18
  @Expose()
18
19
  @IsArray()
19
20
  @ArrayNotEmpty()
21
+ @ArrayMaxSize(BULK_GET_PARAMETERS_MAX_ITEMS)
20
22
  @ValidateNested({ each: true })
21
23
  @Type(() => ParameterKeyRef)
22
24
  items!: ParameterKeyRef[];