@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.
- package/_test_/unit/collection/collectionCallbackRequests.test.ts +96 -0
- package/_test_/unit/gsfConnector/gsfMessages.test.ts +20 -0
- package/_test_/unit/loanCollectorAssignment/collectorAssignmentRequests.test.ts +65 -0
- package/_test_/unit/loanConfig/parameterWriteRequests.test.ts +62 -0
- package/_test_/unit/loanCredit/dtos/loanCreditInputLimits.test.ts +168 -0
- package/_test_/unit/loanCredit/signLoanCreditRequest.test.ts +61 -2
- package/_test_/unit/loanOfferings/offeringsInputRules.test.ts +254 -0
- package/_test_/unit/loanOfferings/promotionRequests.test.ts +1 -1
- package/_test_/unit/loanRetailAudit/auditInputLimits.test.ts +114 -0
- package/_test_/unit/loanScoring/evaluateSciRequest.test.ts +49 -0
- package/bin/collection/constants/CollectionResultLimits.d.ts +16 -0
- package/bin/collection/constants/CollectionResultLimits.js +19 -0
- package/bin/collection/dtos/ApplyCollectionResultRequest.d.ts +5 -0
- package/bin/collection/dtos/ApplyCollectionResultRequest.js +22 -0
- package/bin/collection/dtos/ResolvePendingChargesRequest.d.ts +2 -0
- package/bin/collection/dtos/ResolvePendingChargesRequest.js +9 -0
- package/bin/collection/index.d.ts +2 -0
- package/bin/collection/index.js +3 -0
- package/bin/collection/validators/IsCentPrecision.d.ts +11 -0
- package/bin/collection/validators/IsCentPrecision.js +32 -0
- package/bin/gsfConnector/dtos/GsfCreditTerms.d.ts +7 -2
- package/bin/gsfConnector/dtos/GsfCreditTerms.js +9 -0
- package/bin/loanCollectorAssignment/constants/CollectorAssignmentLimits.d.ts +12 -0
- package/bin/loanCollectorAssignment/constants/CollectorAssignmentLimits.js +15 -0
- package/bin/loanCollectorAssignment/dtos/requests/AutoAssignRequest.d.ts +1 -0
- package/bin/loanCollectorAssignment/dtos/requests/AutoAssignRequest.js +8 -0
- package/bin/loanCollectorAssignment/dtos/requests/ListCollectorAssignmentsRequest.d.ts +14 -0
- package/bin/loanCollectorAssignment/dtos/requests/ListCollectorAssignmentsRequest.js +62 -0
- package/bin/loanCollectorAssignment/dtos/requests/ReassignRequest.d.ts +1 -0
- package/bin/loanCollectorAssignment/dtos/requests/ReassignRequest.js +4 -0
- package/bin/loanCollectorAssignment/dtos/requests/RedistributeRequest.d.ts +1 -0
- package/bin/loanCollectorAssignment/dtos/requests/RedistributeRequest.js +4 -0
- package/bin/loanCollectorAssignment/dtos/responses/ListCollectorAssignmentsResponse.d.ts +9 -0
- package/bin/loanCollectorAssignment/dtos/responses/ListCollectorAssignmentsResponse.js +2 -0
- package/bin/loanCollectorAssignment/index.d.ts +3 -0
- package/bin/loanCollectorAssignment/index.js +4 -0
- package/bin/loanConfig/constants/ParameterRequestLimits.d.ts +8 -0
- package/bin/loanConfig/constants/ParameterRequestLimits.js +11 -0
- package/bin/loanConfig/dtos/requests/BulkGetParametersRequest.d.ts +1 -1
- package/bin/loanConfig/dtos/requests/BulkGetParametersRequest.js +3 -1
- package/bin/loanConfig/dtos/requests/BulkUpdateParametersRequest.d.ts +5 -2
- package/bin/loanConfig/dtos/requests/BulkUpdateParametersRequest.js +8 -4
- package/bin/loanConfig/dtos/requests/UpdateParameterRequest.d.ts +6 -3
- package/bin/loanConfig/dtos/requests/UpdateParameterRequest.js +10 -5
- package/bin/loanConfig/index.d.ts +1 -0
- package/bin/loanConfig/index.js +1 -0
- package/bin/loanCredit/constants/LoanInputLimits.d.ts +24 -0
- package/bin/loanCredit/constants/LoanInputLimits.js +27 -0
- package/bin/loanCredit/dtos/LoanBeneficiary.d.ts +1 -0
- package/bin/loanCredit/dtos/LoanBeneficiary.js +9 -0
- package/bin/loanCredit/dtos/LoanContractDetails.d.ts +18 -1
- package/bin/loanCredit/dtos/LoanContractDetails.js +2 -1
- package/bin/loanCredit/dtos/LoanDeviceNotifyItem.d.ts +5 -0
- package/bin/loanCredit/dtos/LoanDeviceNotifyItem.js +12 -3
- package/bin/loanCredit/dtos/RestructureTerms.d.ts +1 -1
- package/bin/loanCredit/dtos/RestructureTerms.js +2 -0
- package/bin/loanCredit/dtos/SignatureContext.d.ts +5 -1
- package/bin/loanCredit/dtos/requests/ActivationCheckRequest.d.ts +1 -1
- package/bin/loanCredit/dtos/requests/ActivationCheckRequest.js +4 -0
- package/bin/loanCredit/dtos/requests/BackofficeApproveRestructureRequest.js +2 -0
- package/bin/loanCredit/dtos/requests/BackofficeProposeRestructureRequest.js +2 -0
- package/bin/loanCredit/dtos/requests/BackofficeRejectRestructureRequest.js +2 -0
- package/bin/loanCredit/dtos/requests/BackofficeWriteOffCreditRequest.js +2 -0
- package/bin/loanCredit/dtos/requests/CreateCustomerPaymentRequest.d.ts +5 -0
- package/bin/loanCredit/dtos/requests/CreateCustomerPaymentRequest.js +6 -0
- package/bin/loanCredit/dtos/requests/CreateSellerPaymentRequest.d.ts +5 -0
- package/bin/loanCredit/dtos/requests/CreateSellerPaymentRequest.js +6 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.d.ts +1 -0
- package/bin/loanCredit/dtos/requests/OriginateLoanCreditRequest.js +7 -1
- package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.d.ts +1 -1
- package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.js +3 -1
- package/bin/loanCredit/dtos/requests/SignLoanCreditRequest.d.ts +2 -0
- package/bin/loanCredit/dtos/requests/SignLoanCreditRequest.js +3 -0
- package/bin/loanCredit/dtos/requests/UpsertLoanBorrowerRequest.d.ts +1 -0
- package/bin/loanCredit/dtos/requests/UpsertLoanBorrowerRequest.js +2 -0
- package/bin/loanCredit/index.d.ts +2 -0
- package/bin/loanCredit/index.js +2 -0
- package/bin/loanCredit/validators/IsContractBirthDate.d.ts +11 -0
- package/bin/loanCredit/validators/IsContractBirthDate.js +41 -0
- package/bin/loanOfferings/constants/offeringsInputLimits.d.ts +35 -0
- package/bin/loanOfferings/constants/offeringsInputLimits.js +38 -0
- package/bin/loanOfferings/dtos/requests/ChangeCreditPlanStatusRequest.d.ts +2 -0
- package/bin/loanOfferings/dtos/requests/ChangeCreditPlanStatusRequest.js +8 -0
- package/bin/loanOfferings/dtos/requests/ChangePromotionStatusRequest.js +2 -0
- package/bin/loanOfferings/dtos/requests/ComputeAmortizationScheduleRequest.d.ts +4 -1
- package/bin/loanOfferings/dtos/requests/ComputeAmortizationScheduleRequest.js +3 -1
- package/bin/loanOfferings/dtos/requests/ConsumePromotionRequest.d.ts +1 -0
- package/bin/loanOfferings/dtos/requests/ConsumePromotionRequest.js +3 -0
- package/bin/loanOfferings/dtos/requests/CreateCreditPlanRequest.d.ts +3 -0
- package/bin/loanOfferings/dtos/requests/CreateCreditPlanRequest.js +11 -2
- package/bin/loanOfferings/dtos/requests/CreateFinancierRequest.d.ts +5 -0
- package/bin/loanOfferings/dtos/requests/CreateFinancierRequest.js +11 -0
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.d.ts +2 -2
- package/bin/loanOfferings/dtos/requests/CreatePromotionRequest.js +9 -0
- package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.d.ts +1 -1
- package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.js +3 -0
- package/bin/loanOfferings/dtos/requests/CreateStorePolicyRequest.d.ts +1 -1
- package/bin/loanOfferings/dtos/requests/CreateStorePolicyRequest.js +3 -0
- package/bin/loanOfferings/dtos/requests/ReleasePromotionRequest.d.ts +8 -0
- package/bin/loanOfferings/dtos/requests/ReleasePromotionRequest.js +30 -0
- package/bin/loanOfferings/dtos/requests/ReservePromotionBonusRequest.d.ts +1 -0
- package/bin/loanOfferings/dtos/requests/ReservePromotionBonusRequest.js +3 -0
- package/bin/loanOfferings/dtos/requests/SettlePromotionBonusRequest.d.ts +1 -0
- package/bin/loanOfferings/dtos/requests/SettlePromotionBonusRequest.js +3 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.d.ts +1 -0
- package/bin/loanOfferings/dtos/requests/SimulateCreditPlanRequest.js +3 -0
- package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.d.ts +3 -1
- package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.js +5 -2
- package/bin/loanOfferings/dtos/requests/UpdateCreditPlanRequest.d.ts +8 -0
- package/bin/loanOfferings/dtos/requests/UpdateCreditPlanRequest.js +30 -12
- package/bin/loanOfferings/dtos/requests/UpdateFinancierRequest.d.ts +6 -0
- package/bin/loanOfferings/dtos/requests/UpdateFinancierRequest.js +13 -2
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.d.ts +7 -1
- package/bin/loanOfferings/dtos/requests/UpdatePromotionRequest.js +25 -5
- package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.d.ts +5 -2
- package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.js +12 -5
- package/bin/loanOfferings/dtos/requests/UpdateStorePolicyRequest.d.ts +18 -9
- package/bin/loanOfferings/dtos/requests/UpdateStorePolicyRequest.js +12 -4
- package/bin/loanOfferings/dtos/responses/ReleasePromotionResponse.d.ts +11 -0
- package/bin/loanOfferings/dtos/responses/ReleasePromotionResponse.js +2 -0
- package/bin/loanOfferings/index.d.ts +5 -0
- package/bin/loanOfferings/index.js +6 -0
- package/bin/loanOfferings/validators/IsOptionalNonNull.d.ts +9 -0
- package/bin/loanOfferings/validators/IsOptionalNonNull.js +14 -0
- package/bin/loanOfferings/validators/MaxJsonBytes.d.ts +5 -0
- package/bin/loanOfferings/validators/MaxJsonBytes.js +28 -0
- package/bin/loanRetailAudit/constants/auditInputLimits.d.ts +16 -0
- package/bin/loanRetailAudit/constants/auditInputLimits.js +19 -0
- package/bin/loanRetailAudit/dtos/AuditTrailChange.js +4 -0
- package/bin/loanRetailAudit/dtos/AuditTrailContextEntry.js +3 -0
- package/bin/loanRetailAudit/dtos/requests/CreatePiiAccessLogRequest.d.ts +7 -1
- package/bin/loanRetailAudit/dtos/requests/CreatePiiAccessLogRequest.js +8 -1
- package/bin/loanRetailAudit/events/AuditTrailRecordedV1.d.ts +1 -0
- package/bin/loanRetailAudit/events/AuditTrailRecordedV1.js +5 -1
- package/bin/loanRetailAudit/index.d.ts +2 -0
- package/bin/loanRetailAudit/index.js +3 -0
- package/bin/loanRetailAudit/validators/IsIsoDateTime.d.ts +13 -0
- package/bin/loanRetailAudit/validators/IsIsoDateTime.js +29 -0
- package/bin/loanScoring/dtos/ScoringOffer.d.ts +8 -6
- package/bin/loanScoring/dtos/requests/EvaluateSciRequest.d.ts +14 -3
- package/bin/loanScoring/dtos/requests/EvaluateSciRequest.js +15 -0
- package/package.json +1 -1
- package/src/collection/constants/CollectionResultLimits.ts +18 -0
- package/src/collection/dtos/ApplyCollectionResultRequest.ts +15 -8
- package/src/collection/dtos/ResolvePendingChargesRequest.ts +7 -4
- package/src/collection/index.ts +4 -0
- package/src/collection/validators/IsCentPrecision.ts +33 -0
- package/src/gsfConnector/dtos/GsfCreditTerms.ts +15 -3
- package/src/loanCollectorAssignment/constants/CollectorAssignmentLimits.ts +16 -0
- package/src/loanCollectorAssignment/dtos/requests/AutoAssignRequest.ts +13 -1
- package/src/loanCollectorAssignment/dtos/requests/ListCollectorAssignmentsRequest.ts +52 -0
- package/src/loanCollectorAssignment/dtos/requests/ReassignRequest.ts +8 -1
- package/src/loanCollectorAssignment/dtos/requests/RedistributeRequest.ts +8 -1
- package/src/loanCollectorAssignment/dtos/responses/ListCollectorAssignmentsResponse.ts +10 -0
- package/src/loanCollectorAssignment/index.ts +5 -0
- package/src/loanConfig/constants/ParameterRequestLimits.ts +11 -0
- package/src/loanConfig/dtos/requests/BulkGetParametersRequest.ts +4 -2
- package/src/loanConfig/dtos/requests/BulkUpdateParametersRequest.ts +26 -6
- package/src/loanConfig/dtos/requests/UpdateParameterRequest.ts +15 -7
- package/src/loanConfig/index.ts +1 -0
- package/src/loanCredit/constants/LoanInputLimits.ts +29 -0
- package/src/loanCredit/dtos/LoanBeneficiary.ts +11 -1
- package/src/loanCredit/dtos/LoanContractDetails.ts +26 -3
- package/src/loanCredit/dtos/LoanDeviceNotifyItem.ts +17 -3
- package/src/loanCredit/dtos/RestructureTerms.ts +4 -2
- package/src/loanCredit/dtos/SignatureContext.ts +5 -1
- package/src/loanCredit/dtos/requests/ActivationCheckRequest.ts +12 -2
- package/src/loanCredit/dtos/requests/BackofficeApproveRestructureRequest.ts +3 -1
- package/src/loanCredit/dtos/requests/BackofficeProposeRestructureRequest.ts +3 -1
- package/src/loanCredit/dtos/requests/BackofficeRejectRestructureRequest.ts +3 -1
- package/src/loanCredit/dtos/requests/BackofficeWriteOffCreditRequest.ts +3 -1
- package/src/loanCredit/dtos/requests/CreateCustomerPaymentRequest.ts +10 -1
- package/src/loanCredit/dtos/requests/CreateSellerPaymentRequest.ts +10 -1
- package/src/loanCredit/dtos/requests/OriginateLoanCreditRequest.ts +10 -1
- package/src/loanCredit/dtos/requests/SegmentFactsBatchRequest.ts +4 -2
- package/src/loanCredit/dtos/requests/SignLoanCreditRequest.ts +6 -1
- package/src/loanCredit/dtos/requests/UpsertLoanBorrowerRequest.ts +4 -1
- package/src/loanCredit/index.ts +2 -0
- package/src/loanCredit/validators/IsContractBirthDate.ts +41 -0
- package/src/loanOfferings/constants/offeringsInputLimits.ts +47 -0
- package/src/loanOfferings/dtos/requests/ChangeCreditPlanStatusRequest.ts +9 -1
- package/src/loanOfferings/dtos/requests/ChangePromotionStatusRequest.ts +3 -1
- package/src/loanOfferings/dtos/requests/ComputeAmortizationScheduleRequest.ts +7 -2
- package/src/loanOfferings/dtos/requests/ConsumePromotionRequest.ts +5 -1
- package/src/loanOfferings/dtos/requests/CreateCreditPlanRequest.ts +24 -2
- package/src/loanOfferings/dtos/requests/CreateFinancierRequest.ts +25 -0
- package/src/loanOfferings/dtos/requests/CreatePromotionRequest.ts +17 -2
- package/src/loanOfferings/dtos/requests/CreateSegmentRequest.ts +4 -1
- package/src/loanOfferings/dtos/requests/CreateStorePolicyRequest.ts +6 -1
- package/src/loanOfferings/dtos/requests/ReleasePromotionRequest.ts +16 -0
- package/src/loanOfferings/dtos/requests/ReservePromotionBonusRequest.ts +5 -1
- package/src/loanOfferings/dtos/requests/SettlePromotionBonusRequest.ts +5 -1
- package/src/loanOfferings/dtos/requests/SimulateCreditPlanRequest.ts +5 -1
- package/src/loanOfferings/dtos/requests/UpdateCohortRequest.ts +6 -3
- package/src/loanOfferings/dtos/requests/UpdateCreditPlanRequest.ts +43 -12
- package/src/loanOfferings/dtos/requests/UpdateFinancierRequest.ts +26 -2
- package/src/loanOfferings/dtos/requests/UpdatePromotionRequest.ts +34 -6
- package/src/loanOfferings/dtos/requests/UpdateSegmentRequest.ts +14 -7
- package/src/loanOfferings/dtos/requests/UpdateStorePolicyRequest.ts +28 -13
- package/src/loanOfferings/dtos/responses/ReleasePromotionResponse.ts +11 -0
- package/src/loanOfferings/index.ts +7 -0
- package/src/loanOfferings/validators/IsOptionalNonNull.ts +12 -0
- package/src/loanOfferings/validators/MaxJsonBytes.ts +28 -0
- package/src/loanRetailAudit/constants/auditInputLimits.ts +20 -0
- package/src/loanRetailAudit/dtos/AuditTrailChange.ts +5 -1
- package/src/loanRetailAudit/dtos/AuditTrailContextEntry.ts +4 -1
- package/src/loanRetailAudit/dtos/requests/CreatePiiAccessLogRequest.ts +20 -3
- package/src/loanRetailAudit/events/AuditTrailRecordedV1.ts +7 -2
- package/src/loanRetailAudit/index.ts +4 -0
- package/src/loanRetailAudit/validators/IsIsoDateTime.ts +33 -0
- package/src/loanScoring/dtos/ScoringOffer.ts +8 -6
- 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,
|
|
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,
|
|
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
|
-
*
|
|
7
|
-
*
|
|
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 (
|
|
12
|
+
/** Línea de crédito aprobada, en PESOS MXN enteros (no centavos): `10000` = $10,000. */
|
|
11
13
|
creditLine: number | null;
|
|
12
|
-
/** Enganche requerido (
|
|
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
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
@@ -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;
|
|
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
|
-
|
|
22
|
-
@IsNumber()
|
|
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
|
}
|
package/src/collection/index.ts
CHANGED
|
@@ -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
|
+
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Expose } from 'class-transformer';
|
|
2
|
-
import { IsEnum, IsInt, IsNumber, Max, Min, Validate } from 'class-validator';
|
|
2
|
+
import { IsEnum, IsInt, IsNumber, IsOptional, Max, Min, Validate, ValidateIf } from 'class-validator';
|
|
3
3
|
import { GsfPaymentPeriodicityEnum } from '../enums/GsfPaymentPeriodicityEnum';
|
|
4
4
|
import { GSF_MAX_ANNUAL_RATE, GSF_MAX_CENTS, GSF_MAX_INSTALLMENTS } from '../constants/GsfPatterns';
|
|
5
5
|
import { IsGsfCalendarDate } from '../validators/IsGsfCalendarDate';
|
|
@@ -30,12 +30,24 @@ export class GsfCreditTerms {
|
|
|
30
30
|
@Max(GSF_MAX_ANNUAL_RATE)
|
|
31
31
|
annualRate: number;
|
|
32
32
|
|
|
33
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Entre cuántos periodos divide el origen la tasa anual: 52 si el interés semanal es tasa / 52.
|
|
35
|
+
* Obligatorio si no viene `rateYearDays`.
|
|
36
|
+
*/
|
|
34
37
|
@Expose()
|
|
38
|
+
@ValidateIf((terms: GsfCreditTerms) => terms.rateYearDays === undefined)
|
|
35
39
|
@IsInt()
|
|
36
40
|
@Min(1)
|
|
37
41
|
@Max(365)
|
|
38
|
-
periodsPerYear
|
|
42
|
+
periodsPerYear?: number;
|
|
43
|
+
|
|
44
|
+
/** Días del año con que el origen cobra el interés por día: 360 si el de un periodo es tasa × días / 360. */
|
|
45
|
+
@Expose()
|
|
46
|
+
@IsOptional()
|
|
47
|
+
@IsInt()
|
|
48
|
+
@Min(360)
|
|
49
|
+
@Max(366)
|
|
50
|
+
rateYearDays?: number;
|
|
39
51
|
|
|
40
52
|
/** IVA sobre el interés en decimal: 0.16. */
|
|
41
53
|
@Expose()
|
|
@@ -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/;
|