@fiado/type-kit 3.612.0 → 3.614.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/loanCredit/segmentFactsDtos.test.ts +80 -0
- package/_test_/unit/loanOfferings/segmentCatalog.test.ts +4 -2
- package/_test_/unit/loanOfferings/segmentCohorts.test.ts +333 -0
- package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.d.ts +4 -0
- package/bin/loanCredit/dtos/requests/SegmentFactsBatchRequest.js +27 -0
- package/bin/loanCredit/dtos/requests/SegmentFactsPageRequest.d.ts +7 -0
- package/bin/loanCredit/dtos/requests/SegmentFactsPageRequest.js +32 -0
- package/bin/loanCredit/dtos/responses/BorrowerSegmentFacts.d.ts +22 -0
- package/bin/loanCredit/dtos/responses/BorrowerSegmentFacts.js +2 -0
- package/bin/loanCredit/dtos/responses/SegmentFactsBatchResponse.d.ts +5 -0
- package/bin/loanCredit/dtos/responses/SegmentFactsBatchResponse.js +2 -0
- package/bin/loanCredit/dtos/responses/SegmentFactsPageResponse.d.ts +7 -0
- package/bin/loanCredit/dtos/responses/SegmentFactsPageResponse.js +2 -0
- package/bin/loanCredit/index.d.ts +5 -0
- package/bin/loanCredit/index.js +6 -0
- package/bin/loanOfferings/dtos/requests/ChangeCohortStatusRequest.d.ts +9 -0
- package/bin/loanOfferings/dtos/requests/ChangeCohortStatusRequest.js +34 -0
- package/bin/loanOfferings/dtos/requests/CohortCondition.d.ts +15 -0
- package/bin/loanOfferings/dtos/requests/CohortCondition.js +48 -0
- package/bin/loanOfferings/dtos/requests/CreateCohortRequest.d.ts +11 -0
- package/bin/loanOfferings/dtos/requests/CreateCohortRequest.js +44 -0
- package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.d.ts +7 -8
- package/bin/loanOfferings/dtos/requests/CreateSegmentRequest.js +5 -3
- package/bin/loanOfferings/dtos/requests/CustomerSegmentFacts.d.ts +30 -0
- package/bin/loanOfferings/dtos/requests/CustomerSegmentFacts.js +92 -0
- package/bin/loanOfferings/dtos/requests/ListCohortsQuery.d.ts +5 -0
- package/bin/loanOfferings/dtos/requests/ListCohortsQuery.js +25 -0
- package/bin/loanOfferings/dtos/requests/ResolveCustomerSegmentsRequest.d.ts +4 -20
- package/bin/loanOfferings/dtos/requests/ResolveCustomerSegmentsRequest.js +4 -48
- package/bin/loanOfferings/dtos/requests/ResolveSegmentMembersRequest.d.ts +8 -0
- package/bin/loanOfferings/dtos/requests/ResolveSegmentMembersRequest.js +31 -0
- package/bin/loanOfferings/dtos/requests/TestCohortRequest.d.ts +9 -0
- package/bin/loanOfferings/dtos/requests/TestCohortRequest.js +36 -0
- package/bin/loanOfferings/dtos/requests/TestCustomerSegmentsRequest.d.ts +4 -0
- package/bin/loanOfferings/dtos/requests/TestCustomerSegmentsRequest.js +23 -0
- package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.d.ts +12 -0
- package/bin/loanOfferings/dtos/requests/UpdateCohortRequest.js +53 -0
- package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.d.ts +2 -2
- package/bin/loanOfferings/dtos/requests/UpdateSegmentRequest.js +3 -1
- package/bin/loanOfferings/dtos/responses/CohortCatalogResponse.d.ts +33 -0
- package/bin/loanOfferings/dtos/responses/CohortCatalogResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/CohortLogEntryResponse.d.ts +11 -0
- package/bin/loanOfferings/dtos/responses/CohortLogEntryResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/CohortResponse.d.ts +43 -0
- package/bin/loanOfferings/dtos/responses/CohortResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/SegmentCatalogResponse.d.ts +5 -2
- package/bin/loanOfferings/dtos/responses/SegmentLogEntryResponse.d.ts +11 -0
- package/bin/loanOfferings/dtos/responses/SegmentLogEntryResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/SegmentMembersResponse.d.ts +19 -0
- package/bin/loanOfferings/dtos/responses/SegmentMembersResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/SegmentResponse.d.ts +12 -6
- package/bin/loanOfferings/dtos/responses/SegmentUsageResponse.d.ts +18 -0
- package/bin/loanOfferings/dtos/responses/SegmentUsageResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/SegmentationRecountRunResponse.d.ts +23 -0
- package/bin/loanOfferings/dtos/responses/SegmentationRecountRunResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/SegmentationRecountStartResponse.d.ts +6 -0
- package/bin/loanOfferings/dtos/responses/SegmentationRecountStartResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/TestCohortResponse.d.ts +17 -0
- package/bin/loanOfferings/dtos/responses/TestCohortResponse.js +2 -0
- package/bin/loanOfferings/dtos/responses/TestCustomerSegmentsResponse.d.ts +23 -0
- package/bin/loanOfferings/dtos/responses/TestCustomerSegmentsResponse.js +2 -0
- package/bin/loanOfferings/enums/CohortConditionOutcomeEnum.d.ts +10 -0
- package/bin/loanOfferings/enums/CohortConditionOutcomeEnum.js +14 -0
- package/bin/loanOfferings/enums/CohortFactKeyEnum.d.ts +17 -0
- package/bin/loanOfferings/enums/CohortFactKeyEnum.js +21 -0
- package/bin/loanOfferings/enums/CohortFactTypeEnum.d.ts +9 -0
- package/bin/loanOfferings/enums/CohortFactTypeEnum.js +13 -0
- package/bin/loanOfferings/enums/CohortLogEventEnum.d.ts +10 -0
- package/bin/loanOfferings/enums/CohortLogEventEnum.js +14 -0
- package/bin/loanOfferings/enums/CohortOperatorEnum.d.ts +15 -0
- package/bin/loanOfferings/enums/CohortOperatorEnum.js +19 -0
- package/bin/loanOfferings/enums/CohortStatusEnum.d.ts +9 -0
- package/bin/loanOfferings/enums/CohortStatusEnum.js +13 -0
- package/bin/loanOfferings/enums/SegmentFilterIdEnum.d.ts +2 -0
- package/bin/loanOfferings/enums/SegmentFilterIdEnum.js +2 -0
- package/bin/loanOfferings/enums/SegmentLogEventEnum.d.ts +10 -0
- package/bin/loanOfferings/enums/SegmentLogEventEnum.js +14 -0
- package/bin/loanOfferings/enums/SegmentMembershipReasonEnum.d.ts +9 -0
- package/bin/loanOfferings/enums/SegmentMembershipReasonEnum.js +13 -0
- package/bin/loanOfferings/enums/SegmentationRecountStatusEnum.d.ts +9 -0
- package/bin/loanOfferings/enums/SegmentationRecountStatusEnum.js +13 -0
- package/bin/loanOfferings/enums/SegmentationRecountTriggerEnum.d.ts +8 -0
- package/bin/loanOfferings/enums/SegmentationRecountTriggerEnum.js +12 -0
- package/bin/loanOfferings/index.d.ts +29 -0
- package/bin/loanOfferings/index.js +29 -0
- package/bin/onboarding/events/SponsorChangedEventDetail.d.ts +16 -0
- package/bin/onboarding/events/SponsorChangedEventDetail.js +14 -0
- package/bin/onboarding/index.d.ts +1 -0
- package/bin/onboarding/index.js +2 -0
- package/package.json +1 -1
- package/src/loanCredit/dtos/requests/SegmentFactsBatchRequest.ts +13 -0
- package/src/loanCredit/dtos/requests/SegmentFactsPageRequest.ts +19 -0
- package/src/loanCredit/dtos/responses/BorrowerSegmentFacts.ts +24 -0
- package/src/loanCredit/dtos/responses/SegmentFactsBatchResponse.ts +6 -0
- package/src/loanCredit/dtos/responses/SegmentFactsPageResponse.ts +8 -0
- package/src/loanCredit/index.ts +7 -0
- package/src/loanOfferings/dtos/requests/ChangeCohortStatusRequest.ts +19 -0
- package/src/loanOfferings/dtos/requests/CohortCondition.ts +33 -0
- package/src/loanOfferings/dtos/requests/CreateCohortRequest.ts +29 -0
- package/src/loanOfferings/dtos/requests/CreateSegmentRequest.ts +10 -9
- package/src/loanOfferings/dtos/requests/CustomerSegmentFacts.ts +79 -0
- package/src/loanOfferings/dtos/requests/ListCohortsQuery.ts +11 -0
- package/src/loanOfferings/dtos/requests/ResolveCustomerSegmentsRequest.ts +5 -49
- package/src/loanOfferings/dtos/requests/ResolveSegmentMembersRequest.ts +17 -0
- package/src/loanOfferings/dtos/requests/TestCohortRequest.ts +21 -0
- package/src/loanOfferings/dtos/requests/TestCustomerSegmentsRequest.ts +9 -0
- package/src/loanOfferings/dtos/requests/UpdateCohortRequest.ts +37 -0
- package/src/loanOfferings/dtos/requests/UpdateSegmentRequest.ts +5 -3
- package/src/loanOfferings/dtos/responses/CohortCatalogResponse.ts +36 -0
- package/src/loanOfferings/dtos/responses/CohortLogEntryResponse.ts +12 -0
- package/src/loanOfferings/dtos/responses/CohortResponse.ts +47 -0
- package/src/loanOfferings/dtos/responses/SegmentCatalogResponse.ts +5 -2
- package/src/loanOfferings/dtos/responses/SegmentLogEntryResponse.ts +12 -0
- package/src/loanOfferings/dtos/responses/SegmentMembersResponse.ts +21 -0
- package/src/loanOfferings/dtos/responses/SegmentResponse.ts +12 -6
- package/src/loanOfferings/dtos/responses/SegmentUsageResponse.ts +20 -0
- package/src/loanOfferings/dtos/responses/SegmentationRecountRunResponse.ts +25 -0
- package/src/loanOfferings/dtos/responses/SegmentationRecountStartResponse.ts +7 -0
- package/src/loanOfferings/dtos/responses/TestCohortResponse.ts +19 -0
- package/src/loanOfferings/dtos/responses/TestCustomerSegmentsResponse.ts +25 -0
- package/src/loanOfferings/enums/CohortConditionOutcomeEnum.ts +10 -0
- package/src/loanOfferings/enums/CohortFactKeyEnum.ts +17 -0
- package/src/loanOfferings/enums/CohortFactTypeEnum.ts +9 -0
- package/src/loanOfferings/enums/CohortLogEventEnum.ts +10 -0
- package/src/loanOfferings/enums/CohortOperatorEnum.ts +15 -0
- package/src/loanOfferings/enums/CohortStatusEnum.ts +9 -0
- package/src/loanOfferings/enums/SegmentFilterIdEnum.ts +2 -0
- package/src/loanOfferings/enums/SegmentLogEventEnum.ts +10 -0
- package/src/loanOfferings/enums/SegmentMembershipReasonEnum.ts +9 -0
- package/src/loanOfferings/enums/SegmentationRecountStatusEnum.ts +9 -0
- package/src/loanOfferings/enums/SegmentationRecountTriggerEnum.ts +8 -0
- package/src/loanOfferings/index.ts +29 -0
- package/src/onboarding/events/SponsorChangedEventDetail.ts +20 -0
- package/src/onboarding/index.ts +3 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
SegmentFactsBatchRequest,
|
|
6
|
+
SegmentFactsBatchResponse,
|
|
7
|
+
SegmentFactsPageRequest,
|
|
8
|
+
SegmentFactsPageResponse,
|
|
9
|
+
} from '../../../src/loanCredit/index';
|
|
10
|
+
import { CreditPlanLevelEnum, CustomerSegmentFacts } from '../../../src/loanOfferings/index';
|
|
11
|
+
|
|
12
|
+
type Ctor<T> = new () => T;
|
|
13
|
+
|
|
14
|
+
const errorProperties = async <T extends object>(cls: Ctor<T>, raw: Record<string, unknown>): Promise<string[]> =>
|
|
15
|
+
(await validate(plainToInstance(cls, raw, { excludeExtraneousValues: true }))).map((error) => error.property);
|
|
16
|
+
|
|
17
|
+
describe('SegmentFactsBatchRequest', () => {
|
|
18
|
+
it('acepta de 1 a 100 ids', async () => {
|
|
19
|
+
expect(await errorProperties(SegmentFactsBatchRequest, { retailCustomerIds: ['RC-1'] })).toEqual([]);
|
|
20
|
+
const hundred = Array.from({ length: 100 }, (_, i) => `RC-${i}`);
|
|
21
|
+
expect(await errorProperties(SegmentFactsBatchRequest, { retailCustomerIds: hundred })).toEqual([]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('rechaza el lote vacío, el de más de 100 y los ids que no son texto', async () => {
|
|
25
|
+
expect(await errorProperties(SegmentFactsBatchRequest, { retailCustomerIds: [] })).toEqual(['retailCustomerIds']);
|
|
26
|
+
const tooMany = Array.from({ length: 101 }, (_, i) => `RC-${i}`);
|
|
27
|
+
expect(await errorProperties(SegmentFactsBatchRequest, { retailCustomerIds: tooMany })).toEqual(['retailCustomerIds']);
|
|
28
|
+
expect(await errorProperties(SegmentFactsBatchRequest, { retailCustomerIds: [1] })).toEqual(['retailCustomerIds']);
|
|
29
|
+
expect(await errorProperties(SegmentFactsBatchRequest, {})).toEqual(['retailCustomerIds']);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('rechaza ids vacíos', async () => {
|
|
33
|
+
expect(await errorProperties(SegmentFactsBatchRequest, { retailCustomerIds: ['RC-1', ''] })).toEqual(['retailCustomerIds']);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('SegmentFactsPageRequest', () => {
|
|
38
|
+
it('la primera página va sin cursor ni límite', async () => {
|
|
39
|
+
expect(await errorProperties(SegmentFactsPageRequest, {})).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('acepta cursor y un límite entre 1 y 100', async () => {
|
|
43
|
+
expect(await errorProperties(SegmentFactsPageRequest, { cursor: 'abc', limit: 100 })).toEqual([]);
|
|
44
|
+
expect(await errorProperties(SegmentFactsPageRequest, { limit: 0 })).toEqual(['limit']);
|
|
45
|
+
expect(await errorProperties(SegmentFactsPageRequest, { limit: 101 })).toEqual(['limit']);
|
|
46
|
+
expect(await errorProperties(SegmentFactsPageRequest, { limit: 2.5 })).toEqual(['limit']);
|
|
47
|
+
expect(await errorProperties(SegmentFactsPageRequest, { limit: '50' })).toEqual(['limit']);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Responses de segment-facts', () => {
|
|
52
|
+
it('los datos del acreditado sirven directo como datos del cliente para segmentar', () => {
|
|
53
|
+
const batch: SegmentFactsBatchResponse = {
|
|
54
|
+
items: [
|
|
55
|
+
{
|
|
56
|
+
retailCustomerId: 'RC-1',
|
|
57
|
+
borrowerId: null,
|
|
58
|
+
facts: {
|
|
59
|
+
totalCredits: 0,
|
|
60
|
+
activeCredits: 0,
|
|
61
|
+
completedCredits: 0,
|
|
62
|
+
lifetimeWriteOffs: 0,
|
|
63
|
+
currentArrearsDays: 0,
|
|
64
|
+
delinquencyDaysLast6M: 0,
|
|
65
|
+
lifetimeRestructures: 0,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
const page: SegmentFactsPageResponse = {
|
|
71
|
+
items: [{ ...batch.items[0], borrowerId: 'BRW-1', facts: { ...batch.items[0].facts, sciLevel: CreditPlanLevelEnum.GOLD } }],
|
|
72
|
+
nextCursor: null,
|
|
73
|
+
};
|
|
74
|
+
const facts: CustomerSegmentFacts = page.items[0].facts;
|
|
75
|
+
|
|
76
|
+
expect(facts.sciLevel).toBe(CreditPlanLevelEnum.GOLD);
|
|
77
|
+
expect(batch.items[0].facts.sciLevel).toBeUndefined();
|
|
78
|
+
expect(page.nextCursor).toBeNull();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
ListSegmentCatalogQuery,
|
|
6
6
|
SegmentCatalogItem,
|
|
7
7
|
SegmentCatalogResponse,
|
|
8
|
-
SegmentFilterIdEnum,
|
|
9
8
|
SegmentStatusEnum,
|
|
10
9
|
} from '../../../src/loanOfferings/index';
|
|
11
10
|
|
|
@@ -45,10 +44,13 @@ describe('SegmentCatalogResponse', () => {
|
|
|
45
44
|
segmentId: 'seg-1',
|
|
46
45
|
name: 'Nuevos',
|
|
47
46
|
status: SegmentStatusEnum.ACTIVE,
|
|
48
|
-
|
|
47
|
+
cohortIds: ['COH-LEVEL-GOLD'],
|
|
48
|
+
dependsOnFacts: true,
|
|
49
|
+
filterIds: ['COH-LEVEL-GOLD'],
|
|
49
50
|
isDefault: false,
|
|
50
51
|
};
|
|
51
52
|
const response: SegmentCatalogResponse = { segments: [item] };
|
|
52
53
|
expect(response.segments[0].segmentId).toBe('seg-1');
|
|
54
|
+
expect(response.segments[0].filterIds).toEqual(response.segments[0].cohortIds);
|
|
53
55
|
});
|
|
54
56
|
});
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate, ValidationError } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
ChangeCohortStatusRequest,
|
|
6
|
+
CohortConditionOutcomeEnum,
|
|
7
|
+
CohortFactKeyEnum,
|
|
8
|
+
CohortOperatorEnum,
|
|
9
|
+
CohortResponse,
|
|
10
|
+
CohortStatusEnum,
|
|
11
|
+
CreateCohortRequest,
|
|
12
|
+
CreateSegmentRequest,
|
|
13
|
+
CreditPlanLevelEnum,
|
|
14
|
+
CustomerSegmentFacts,
|
|
15
|
+
ListCohortsQuery,
|
|
16
|
+
ResolveCustomerSegmentsRequest,
|
|
17
|
+
ResolveSegmentMembersRequest,
|
|
18
|
+
SegmentMembersResponse,
|
|
19
|
+
SegmentMembershipReasonEnum,
|
|
20
|
+
SegmentResponse,
|
|
21
|
+
SegmentationRecountRunsResponse,
|
|
22
|
+
SegmentationRecountStatusEnum,
|
|
23
|
+
SegmentationRecountTriggerEnum,
|
|
24
|
+
SegmentColorSlotEnum,
|
|
25
|
+
SegmentStatusEnum,
|
|
26
|
+
TestCohortRequest,
|
|
27
|
+
TestCohortResponse,
|
|
28
|
+
TestCustomerSegmentsRequest,
|
|
29
|
+
TestCustomerSegmentsResponse,
|
|
30
|
+
UpdateCohortRequest,
|
|
31
|
+
UpdateSegmentRequest,
|
|
32
|
+
} from '../../../src/loanOfferings/index';
|
|
33
|
+
|
|
34
|
+
type Ctor<T> = new () => T;
|
|
35
|
+
|
|
36
|
+
const toDto = <T extends object>(cls: Ctor<T>, raw: Record<string, unknown>): T =>
|
|
37
|
+
plainToInstance(cls, raw, { excludeExtraneousValues: true });
|
|
38
|
+
|
|
39
|
+
const errorProperties = async <T extends object>(cls: Ctor<T>, raw: Record<string, unknown>): Promise<string[]> =>
|
|
40
|
+
(await validate(toDto(cls, raw))).map((error) => error.property).sort();
|
|
41
|
+
|
|
42
|
+
const nestedErrors = (errors: ValidationError[]): string[] =>
|
|
43
|
+
errors.flatMap((error) => [error.property, ...nestedErrors(error.children ?? [])]);
|
|
44
|
+
|
|
45
|
+
const GOLD = { field: CohortFactKeyEnum.SCI_LEVEL, op: CohortOperatorEnum.EQUALS, value: 'GOLD' };
|
|
46
|
+
const COMPLETED_GTE_3 = { field: CohortFactKeyEnum.COMPLETED_CREDITS, op: CohortOperatorEnum.GTE, value: 3 };
|
|
47
|
+
|
|
48
|
+
describe('Enums de cohorts', () => {
|
|
49
|
+
it('las llaves del catálogo coinciden con los campos de CustomerSegmentFacts', () => {
|
|
50
|
+
expect(Object.values(CohortFactKeyEnum).sort()).toEqual(
|
|
51
|
+
[
|
|
52
|
+
'activeCredits',
|
|
53
|
+
'completedCredits',
|
|
54
|
+
'currentArrearsDays',
|
|
55
|
+
'delinquencyDaysLast6M',
|
|
56
|
+
'hasPcfAccount',
|
|
57
|
+
'isEmployee',
|
|
58
|
+
'lifetimeRestructures',
|
|
59
|
+
'lifetimeWriteOffs',
|
|
60
|
+
'sciLevel',
|
|
61
|
+
'totalCredits',
|
|
62
|
+
].sort(),
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('declara los operadores del contrato', () => {
|
|
67
|
+
expect(Object.values(CohortOperatorEnum)).toEqual(['EQUALS', 'NOT_EQUALS', 'GT', 'GTE', 'LT', 'LTE', 'IN', 'NOT_IN']);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('CustomerSegmentFacts y ResolveCustomerSegmentsRequest', () => {
|
|
72
|
+
const FULL_FACTS = {
|
|
73
|
+
sciLevel: CreditPlanLevelEnum.GOLD,
|
|
74
|
+
totalCredits: 4,
|
|
75
|
+
activeCredits: 1,
|
|
76
|
+
completedCredits: 3,
|
|
77
|
+
lifetimeWriteOffs: 0,
|
|
78
|
+
currentArrearsDays: 0,
|
|
79
|
+
delinquencyDaysLast6M: 0,
|
|
80
|
+
lifetimeRestructures: 0,
|
|
81
|
+
isEmployee: false,
|
|
82
|
+
hasPcfAccount: true,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
it('acepta todos los datos opcionales vacíos', async () => {
|
|
86
|
+
expect(await errorProperties(CustomerSegmentFacts, {})).toEqual([]);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('acepta el juego completo de datos', async () => {
|
|
90
|
+
expect(await errorProperties(CustomerSegmentFacts, FULL_FACTS)).toEqual([]);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('rechaza conteos negativos, con decimales o como texto', async () => {
|
|
94
|
+
expect(await errorProperties(CustomerSegmentFacts, { totalCredits: -1 })).toEqual(['totalCredits']);
|
|
95
|
+
expect(await errorProperties(CustomerSegmentFacts, { activeCredits: 1.5 })).toEqual(['activeCredits']);
|
|
96
|
+
expect(await errorProperties(CustomerSegmentFacts, { currentArrearsDays: '3' })).toEqual(['currentArrearsDays']);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('rechaza un nivel fuera del enum y un booleano como texto', async () => {
|
|
100
|
+
expect(await errorProperties(CustomerSegmentFacts, { sciLevel: 'PLATINUM' })).toEqual(['sciLevel']);
|
|
101
|
+
expect(await errorProperties(CustomerSegmentFacts, { hasPcfAccount: 'true' })).toEqual(['hasPcfAccount']);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('el resolve sigue aceptando solo el retailCustomerId', async () => {
|
|
105
|
+
expect(await errorProperties(ResolveCustomerSegmentsRequest, { retailCustomerId: 'RC-1' })).toEqual([]);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('el resolve hereda y conserva los datos del cliente', async () => {
|
|
109
|
+
const dto = toDto(ResolveCustomerSegmentsRequest, { retailCustomerId: 'RC-1', ...FULL_FACTS, extra: 'x' });
|
|
110
|
+
expect(await validate(dto)).toHaveLength(0);
|
|
111
|
+
expect(dto).toEqual({ retailCustomerId: 'RC-1', ...FULL_FACTS });
|
|
112
|
+
expect(await errorProperties(ResolveCustomerSegmentsRequest, { retailCustomerId: 'RC-1', totalCredits: -1 })).toEqual([
|
|
113
|
+
'totalCredits',
|
|
114
|
+
]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('el resolve exige retailCustomerId', async () => {
|
|
118
|
+
expect(await errorProperties(ResolveCustomerSegmentsRequest, {})).toEqual(['retailCustomerId']);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('CreateCohortRequest', () => {
|
|
123
|
+
it('acepta un cohort con condiciones de número y de selección', async () => {
|
|
124
|
+
expect(await errorProperties(CreateCohortRequest, { name: 'VIP', conditions: [GOLD, COMPLETED_GTE_3] })).toEqual([]);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('acepta IN con lista de valores', async () => {
|
|
128
|
+
const condition = { field: CohortFactKeyEnum.SCI_LEVEL, op: CohortOperatorEnum.IN, values: ['GOLD', 'SILVER'] };
|
|
129
|
+
expect(await errorProperties(CreateCohortRequest, { name: 'Oro o Plata', conditions: [condition] })).toEqual([]);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('exige entre 1 y 10 condiciones', async () => {
|
|
133
|
+
expect(await errorProperties(CreateCohortRequest, { name: 'Vacío', conditions: [] })).toEqual(['conditions']);
|
|
134
|
+
expect(
|
|
135
|
+
await errorProperties(CreateCohortRequest, { name: 'Largo', conditions: Array.from({ length: 11 }, () => GOLD) }),
|
|
136
|
+
).toEqual(['conditions']);
|
|
137
|
+
expect(await errorProperties(CreateCohortRequest, { name: 'Sin condiciones' })).toEqual(['conditions']);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('valida cada condición: campo y operador del catálogo, lista de hasta 10 textos', async () => {
|
|
141
|
+
const dto = toDto(CreateCohortRequest, {
|
|
142
|
+
name: 'Malo',
|
|
143
|
+
conditions: [
|
|
144
|
+
{ field: 'age', op: CohortOperatorEnum.GT, value: 18 },
|
|
145
|
+
{ field: CohortFactKeyEnum.SCI_LEVEL, op: 'CONTAINS', value: 'G' },
|
|
146
|
+
{ field: CohortFactKeyEnum.SCI_LEVEL, op: CohortOperatorEnum.IN, values: Array.from({ length: 11 }, () => 'GOLD') },
|
|
147
|
+
{ field: CohortFactKeyEnum.SCI_LEVEL, op: CohortOperatorEnum.IN, values: [1] },
|
|
148
|
+
],
|
|
149
|
+
});
|
|
150
|
+
const errors = nestedErrors(await validate(dto));
|
|
151
|
+
expect(errors.filter((property) => ['field', 'op', 'values'].includes(property)).sort()).toEqual([
|
|
152
|
+
'field',
|
|
153
|
+
'op',
|
|
154
|
+
'values',
|
|
155
|
+
'values',
|
|
156
|
+
]);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('rechaza opciones vacías en la lista de valores', async () => {
|
|
160
|
+
const condition = { field: CohortFactKeyEnum.SCI_LEVEL, op: CohortOperatorEnum.IN, values: ['GOLD', ''] };
|
|
161
|
+
const errors = nestedErrors(await validate(toDto(CreateCohortRequest, { name: 'Vacía', conditions: [condition] })));
|
|
162
|
+
expect(errors).toContain('values');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('limita el nombre a 120 y la descripción a 500', async () => {
|
|
166
|
+
expect(
|
|
167
|
+
await errorProperties(CreateCohortRequest, {
|
|
168
|
+
name: 'n'.repeat(121),
|
|
169
|
+
description: 'd'.repeat(501),
|
|
170
|
+
conditions: [GOLD],
|
|
171
|
+
}),
|
|
172
|
+
).toEqual(['description', 'name']);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe('UpdateCohortRequest', () => {
|
|
177
|
+
it('es parcial: acepta un body vacío', async () => {
|
|
178
|
+
expect(await errorProperties(UpdateCohortRequest, {})).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('si trae condiciones, aplica las mismas reglas que el alta', async () => {
|
|
182
|
+
expect(await errorProperties(UpdateCohortRequest, { conditions: [] })).toEqual(['conditions']);
|
|
183
|
+
expect(await errorProperties(UpdateCohortRequest, { conditions: [COMPLETED_GTE_3], reason: 'Ajuste' })).toEqual([]);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('limita el motivo a 280', async () => {
|
|
187
|
+
expect(await errorProperties(UpdateCohortRequest, { reason: 'r'.repeat(281) })).toEqual(['reason']);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe('ChangeCohortStatusRequest, TestCohortRequest y ListCohortsQuery', () => {
|
|
192
|
+
it('cambia el estado con un valor del enum', async () => {
|
|
193
|
+
expect(await errorProperties(ChangeCohortStatusRequest, { status: CohortStatusEnum.ARCHIVED })).toEqual([]);
|
|
194
|
+
expect(await errorProperties(ChangeCohortStatusRequest, { status: 'DELETED' })).toEqual(['status']);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('prueba exige cliente y condiciones', async () => {
|
|
198
|
+
expect(await errorProperties(TestCohortRequest, { retailCustomerId: 'RC-1', conditions: [GOLD] })).toEqual([]);
|
|
199
|
+
expect(await errorProperties(TestCohortRequest, {})).toEqual(['conditions', 'retailCustomerId']);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('la lista filtra por estado opcional', async () => {
|
|
203
|
+
expect(await errorProperties(ListCohortsQuery, {})).toEqual([]);
|
|
204
|
+
expect(await errorProperties(ListCohortsQuery, { status: CohortStatusEnum.ACTIVE })).toEqual([]);
|
|
205
|
+
expect(await errorProperties(ListCohortsQuery, { status: 'DRAFT' })).toEqual(['status']);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe('Segmento con cohorts', () => {
|
|
210
|
+
it('el alta acepta cohortIds y descarta los filterIds viejos', async () => {
|
|
211
|
+
const dto = toDto(CreateSegmentRequest, {
|
|
212
|
+
name: 'VIP',
|
|
213
|
+
colorSlot: SegmentColorSlotEnum.SLATE,
|
|
214
|
+
cohortIds: ['COH-LEVEL-GOLD'],
|
|
215
|
+
filterIds: ['levelGold'],
|
|
216
|
+
});
|
|
217
|
+
expect(await validate(dto)).toHaveLength(0);
|
|
218
|
+
expect(dto.cohortIds).toEqual(['COH-LEVEL-GOLD']);
|
|
219
|
+
expect('filterIds' in dto).toBe(false);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('limita los cohorts a 20 y exige textos', async () => {
|
|
223
|
+
const many = Array.from({ length: 21 }, (_, i) => `COH-${i}`);
|
|
224
|
+
expect(await errorProperties(CreateSegmentRequest, { name: 'X', cohortIds: many })).toEqual(['cohortIds']);
|
|
225
|
+
expect(await errorProperties(UpdateSegmentRequest, { cohortIds: many })).toEqual(['cohortIds']);
|
|
226
|
+
expect(await errorProperties(UpdateSegmentRequest, { cohortIds: [1] })).toEqual(['cohortIds']);
|
|
227
|
+
expect(await errorProperties(UpdateSegmentRequest, { cohortIds: [] })).toEqual([]);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('rechaza ids de cohort vacíos', async () => {
|
|
231
|
+
expect(await errorProperties(CreateSegmentRequest, { name: 'X', cohortIds: ['COH-A', ''] })).toEqual(['cohortIds']);
|
|
232
|
+
expect(await errorProperties(UpdateSegmentRequest, { cohortIds: ['COH-A', ''] })).toEqual(['cohortIds']);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('members en lote exige entre 1 y 100 clientes y valida cada uno', async () => {
|
|
236
|
+
expect(await errorProperties(ResolveSegmentMembersRequest, { customers: [{ retailCustomerId: 'RC-1' }] })).toEqual([]);
|
|
237
|
+
expect(await errorProperties(ResolveSegmentMembersRequest, { customers: [] })).toEqual(['customers']);
|
|
238
|
+
expect(
|
|
239
|
+
await errorProperties(ResolveSegmentMembersRequest, {
|
|
240
|
+
customers: Array.from({ length: 101 }, (_, i) => ({ retailCustomerId: `RC-${i}` })),
|
|
241
|
+
}),
|
|
242
|
+
).toEqual(['customers']);
|
|
243
|
+
|
|
244
|
+
const dto = toDto(ResolveSegmentMembersRequest, { customers: [{ retailCustomerId: 'RC-1', completedCredits: -2 }] });
|
|
245
|
+
expect(dto.customers[0]).toBeInstanceOf(ResolveCustomerSegmentsRequest);
|
|
246
|
+
expect(nestedErrors(await validate(dto))).toContain('completedCredits');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('probar segmentos exige el cliente', async () => {
|
|
250
|
+
expect(await errorProperties(TestCustomerSegmentsRequest, { retailCustomerId: 'RC-1' })).toEqual([]);
|
|
251
|
+
expect(await errorProperties(TestCustomerSegmentsRequest, {})).toEqual(['retailCustomerId']);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe('Responses de cohorts y segmentos', () => {
|
|
256
|
+
it('tipan las formas del contrato', () => {
|
|
257
|
+
const cohort: CohortResponse = {
|
|
258
|
+
cohortId: 'COH-LEVEL-GOLD',
|
|
259
|
+
name: 'Nivel Oro',
|
|
260
|
+
description: null,
|
|
261
|
+
conditions: [{ field: CohortFactKeyEnum.SCI_LEVEL, op: CohortOperatorEnum.EQUALS, value: 'GOLD', values: null }],
|
|
262
|
+
status: CohortStatusEnum.ACTIVE,
|
|
263
|
+
version: 1,
|
|
264
|
+
memberCount: null,
|
|
265
|
+
pctTotal: null,
|
|
266
|
+
countedAt: null,
|
|
267
|
+
countPending: true,
|
|
268
|
+
usedBySegments: [{ segmentId: 'SEG-VIP', name: 'VIP' }],
|
|
269
|
+
createdAt: '2026-10-29T00:00:00.000Z',
|
|
270
|
+
updatedAt: '2026-10-29T00:00:00.000Z',
|
|
271
|
+
createdBy: 'system',
|
|
272
|
+
updatedBy: 'system',
|
|
273
|
+
};
|
|
274
|
+
const segment: SegmentResponse = {
|
|
275
|
+
segmentId: 'SEG-VIP',
|
|
276
|
+
name: 'VIP',
|
|
277
|
+
description: null,
|
|
278
|
+
colorSlot: SegmentColorSlotEnum.SLATE,
|
|
279
|
+
cohortIds: [cohort.cohortId],
|
|
280
|
+
memberIds: [],
|
|
281
|
+
isDefault: false,
|
|
282
|
+
status: SegmentStatusEnum.ACTIVE,
|
|
283
|
+
version: 1,
|
|
284
|
+
clientCount: 10,
|
|
285
|
+
pctTotal: 40,
|
|
286
|
+
countedAt: '2026-10-29T09:00:00.000Z',
|
|
287
|
+
countPending: false,
|
|
288
|
+
createdAt: '2026-10-29T00:00:00.000Z',
|
|
289
|
+
updatedAt: '2026-10-29T00:00:00.000Z',
|
|
290
|
+
createdBy: 'system',
|
|
291
|
+
updatedBy: 'system',
|
|
292
|
+
};
|
|
293
|
+
const test: TestCohortResponse = {
|
|
294
|
+
retailCustomerId: 'RC-1',
|
|
295
|
+
matched: false,
|
|
296
|
+
facts: { completedCredits: 2 },
|
|
297
|
+
conditions: [{ ...COMPLETED_GTE_3, values: null, actual: 2, outcome: CohortConditionOutcomeEnum.NO_MATCH }],
|
|
298
|
+
};
|
|
299
|
+
const trace: TestCustomerSegmentsResponse = {
|
|
300
|
+
retailCustomerId: 'RC-1',
|
|
301
|
+
facts: {},
|
|
302
|
+
segments: [
|
|
303
|
+
{ segmentId: 'SEG-VIP', name: 'VIP', matched: true, reason: SegmentMembershipReasonEnum.COHORT, matchedCohortIds: ['COH-LEVEL-GOLD'] },
|
|
304
|
+
],
|
|
305
|
+
defaultApplies: false,
|
|
306
|
+
evaluatorAvailable: true,
|
|
307
|
+
};
|
|
308
|
+
const members: SegmentMembersResponse = {
|
|
309
|
+
items: [{ retailCustomerId: 'RC-1', segments: [{ segmentId: 'SEG-VIP', name: 'VIP', isDefault: false }] }],
|
|
310
|
+
};
|
|
311
|
+
const runs: SegmentationRecountRunsResponse = {
|
|
312
|
+
runs: [
|
|
313
|
+
{
|
|
314
|
+
runId: 'RUN-1',
|
|
315
|
+
trigger: SegmentationRecountTriggerEnum.NIGHTLY,
|
|
316
|
+
status: SegmentationRecountStatusEnum.RUNNING,
|
|
317
|
+
actor: 'system',
|
|
318
|
+
startedAt: '2026-10-29T09:00:00.000Z',
|
|
319
|
+
finishedAt: null,
|
|
320
|
+
evaluated: null,
|
|
321
|
+
durationMs: null,
|
|
322
|
+
error: null,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
expect(segment.cohortIds).toEqual([cohort.cohortId]);
|
|
328
|
+
expect(test.conditions[0].outcome).toBe('NO_MATCH');
|
|
329
|
+
expect(trace.segments[0].reason).toBe('COHORT');
|
|
330
|
+
expect(members.items[0].segments).toHaveLength(1);
|
|
331
|
+
expect(runs.runs[0].status).toBe('RUNNING');
|
|
332
|
+
});
|
|
333
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SegmentFactsBatchRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/** Body de `POST /private/borrowers/segment-facts`: datos para segmentar de hasta 100 clientes retail. */
|
|
16
|
+
class SegmentFactsBatchRequest {
|
|
17
|
+
}
|
|
18
|
+
exports.SegmentFactsBatchRequest = SegmentFactsBatchRequest;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_transformer_1.Expose)(),
|
|
21
|
+
(0, class_validator_1.IsArray)(),
|
|
22
|
+
(0, class_validator_1.ArrayMinSize)(1),
|
|
23
|
+
(0, class_validator_1.ArrayMaxSize)(100),
|
|
24
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
25
|
+
(0, class_validator_1.IsNotEmpty)({ each: true }),
|
|
26
|
+
__metadata("design:type", Array)
|
|
27
|
+
], SegmentFactsBatchRequest.prototype, "retailCustomerIds", void 0);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Body de `POST /private/borrowers/segment-facts/page`: una página de la cartera de acreditados. */
|
|
2
|
+
export declare class SegmentFactsPageRequest {
|
|
3
|
+
/** Cursor opaco de la página anterior. Ausente en la primera página. */
|
|
4
|
+
cursor?: string;
|
|
5
|
+
/** Acreditados por página. Ausente = 100. */
|
|
6
|
+
limit?: number;
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SegmentFactsPageRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/** Body de `POST /private/borrowers/segment-facts/page`: una página de la cartera de acreditados. */
|
|
16
|
+
class SegmentFactsPageRequest {
|
|
17
|
+
}
|
|
18
|
+
exports.SegmentFactsPageRequest = SegmentFactsPageRequest;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_transformer_1.Expose)(),
|
|
21
|
+
(0, class_validator_1.IsOptional)(),
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], SegmentFactsPageRequest.prototype, "cursor", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_transformer_1.Expose)(),
|
|
27
|
+
(0, class_validator_1.IsOptional)(),
|
|
28
|
+
(0, class_validator_1.IsInt)(),
|
|
29
|
+
(0, class_validator_1.Min)(1),
|
|
30
|
+
(0, class_validator_1.Max)(100),
|
|
31
|
+
__metadata("design:type", Number)
|
|
32
|
+
], SegmentFactsPageRequest.prototype, "limit", void 0);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CreditPlanLevelEnum } from '../../../loanOfferings/enums/CreditPlanLevelEnum';
|
|
2
|
+
/**
|
|
3
|
+
* Datos del acreditado para evaluar cohorts, ya normalizados: sin acreditado, conteos y días en
|
|
4
|
+
* `0`; `sciLevel` ausente si no hay evaluación o el nivel es `ALL` / `NOT_ELIGIBLE`.
|
|
5
|
+
*/
|
|
6
|
+
export interface BorrowerSegmentFacts {
|
|
7
|
+
sciLevel?: CreditPlanLevelEnum;
|
|
8
|
+
totalCredits: number;
|
|
9
|
+
activeCredits: number;
|
|
10
|
+
completedCredits: number;
|
|
11
|
+
lifetimeWriteOffs: number;
|
|
12
|
+
currentArrearsDays: number;
|
|
13
|
+
/** Sin cuotas en la ventana de 180 días cuenta como `0`. */
|
|
14
|
+
delinquencyDaysLast6M: number;
|
|
15
|
+
lifetimeRestructures: number;
|
|
16
|
+
}
|
|
17
|
+
/** Un cliente retail y sus datos para segmentar. `borrowerId` en `null` = no tiene acreditado. */
|
|
18
|
+
export interface BorrowerSegmentFactsItem {
|
|
19
|
+
retailCustomerId: string;
|
|
20
|
+
borrowerId: string | null;
|
|
21
|
+
facts: BorrowerSegmentFacts;
|
|
22
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BorrowerSegmentFactsItem } from './BorrowerSegmentFacts';
|
|
2
|
+
/** Respuesta de `POST /private/borrowers/segment-facts/page`. */
|
|
3
|
+
export interface SegmentFactsPageResponse {
|
|
4
|
+
items: BorrowerSegmentFactsItem[];
|
|
5
|
+
/** Cursor de la siguiente página. `null` = ya no quedan acreditados. */
|
|
6
|
+
nextCursor: string | null;
|
|
7
|
+
}
|
|
@@ -168,3 +168,8 @@ export * from './dtos/requests/UpdateReconcileModeRequest';
|
|
|
168
168
|
export * from './dtos/responses/ReconcileModeView';
|
|
169
169
|
export * from './dtos/requests/RunDevicePostureBackfillRequest';
|
|
170
170
|
export * from './dtos/responses/DevicePostureBackfillResult';
|
|
171
|
+
export * from './dtos/requests/SegmentFactsBatchRequest';
|
|
172
|
+
export * from './dtos/requests/SegmentFactsPageRequest';
|
|
173
|
+
export * from './dtos/responses/BorrowerSegmentFacts';
|
|
174
|
+
export * from './dtos/responses/SegmentFactsBatchResponse';
|
|
175
|
+
export * from './dtos/responses/SegmentFactsPageResponse';
|
package/bin/loanCredit/index.js
CHANGED
|
@@ -213,3 +213,9 @@ __exportStar(require("./dtos/requests/UpdateReconcileModeRequest"), exports);
|
|
|
213
213
|
__exportStar(require("./dtos/responses/ReconcileModeView"), exports);
|
|
214
214
|
__exportStar(require("./dtos/requests/RunDevicePostureBackfillRequest"), exports);
|
|
215
215
|
__exportStar(require("./dtos/responses/DevicePostureBackfillResult"), exports);
|
|
216
|
+
// Datos del cliente para evaluar cohorts de segmentos
|
|
217
|
+
__exportStar(require("./dtos/requests/SegmentFactsBatchRequest"), exports);
|
|
218
|
+
__exportStar(require("./dtos/requests/SegmentFactsPageRequest"), exports);
|
|
219
|
+
__exportStar(require("./dtos/responses/BorrowerSegmentFacts"), exports);
|
|
220
|
+
__exportStar(require("./dtos/responses/SegmentFactsBatchResponse"), exports);
|
|
221
|
+
__exportStar(require("./dtos/responses/SegmentFactsPageResponse"), exports);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CohortStatusEnum } from '../../enums/CohortStatusEnum';
|
|
2
|
+
/**
|
|
3
|
+
* Body de PUT /cohorts/:cohortId/status — archiva o reactiva un cohort. No se archiva uno que use
|
|
4
|
+
* un segmento activo. `reason` queda en la bitácora.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ChangeCohortStatusRequest {
|
|
7
|
+
status: CohortStatusEnum;
|
|
8
|
+
reason?: string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ChangeCohortStatusRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const CohortStatusEnum_1 = require("../../enums/CohortStatusEnum");
|
|
16
|
+
/**
|
|
17
|
+
* Body de PUT /cohorts/:cohortId/status — archiva o reactiva un cohort. No se archiva uno que use
|
|
18
|
+
* un segmento activo. `reason` queda en la bitácora.
|
|
19
|
+
*/
|
|
20
|
+
class ChangeCohortStatusRequest {
|
|
21
|
+
}
|
|
22
|
+
exports.ChangeCohortStatusRequest = ChangeCohortStatusRequest;
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, class_transformer_1.Expose)(),
|
|
25
|
+
(0, class_validator_1.IsEnum)(CohortStatusEnum_1.CohortStatusEnum),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], ChangeCohortStatusRequest.prototype, "status", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_transformer_1.Expose)(),
|
|
30
|
+
(0, class_validator_1.IsOptional)(),
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
(0, class_validator_1.MaxLength)(280),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], ChangeCohortStatusRequest.prototype, "reason", void 0);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CohortFactKeyEnum } from '../../enums/CohortFactKeyEnum';
|
|
2
|
+
import { CohortOperatorEnum } from '../../enums/CohortOperatorEnum';
|
|
3
|
+
/**
|
|
4
|
+
* Una condición de cohort: «dato operador valor». Las condiciones de un cohort se unen con Y.
|
|
5
|
+
* Que el operador aplique al tipo del dato y que el valor tenga el tipo correcto lo valida el
|
|
6
|
+
* lambda (422), contra el catálogo.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CohortCondition {
|
|
9
|
+
field: CohortFactKeyEnum;
|
|
10
|
+
op: CohortOperatorEnum;
|
|
11
|
+
/** Valor a comparar en los operadores de un solo valor. Tipado estricto: `3` no es `"3"`. */
|
|
12
|
+
value?: number | boolean | string;
|
|
13
|
+
/** Lista de opciones; solo con `IN` y `NOT_IN`. */
|
|
14
|
+
values?: string[];
|
|
15
|
+
}
|