@fiado/type-kit 3.610.0 → 3.612.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 (78) hide show
  1. package/_test_/unit/gsfConnector/gsfMessages.test.ts +233 -0
  2. package/_test_/unit/loanCredit/customerReadDtos.test.ts +22 -0
  3. package/_test_/unit/retailLoan/contract.test.ts +5 -0
  4. package/bin/gsfConnector/constants/GsfPatterns.d.ts +15 -0
  5. package/bin/gsfConnector/constants/GsfPatterns.js +18 -0
  6. package/bin/gsfConnector/constants/GsfPaymentOperations.d.ts +6 -0
  7. package/bin/gsfConnector/constants/GsfPaymentOperations.js +16 -0
  8. package/bin/gsfConnector/dtos/GsfAddress.d.ts +13 -0
  9. package/bin/gsfConnector/dtos/GsfAddress.js +81 -0
  10. package/bin/gsfConnector/dtos/GsfCreateCreditMessage.d.ts +17 -0
  11. package/bin/gsfConnector/dtos/GsfCreateCreditMessage.js +78 -0
  12. package/bin/gsfConnector/dtos/GsfCreditTerms.d.ts +17 -0
  13. package/bin/gsfConnector/dtos/GsfCreditTerms.js +71 -0
  14. package/bin/gsfConnector/dtos/GsfCustomer.d.ts +15 -0
  15. package/bin/gsfConnector/dtos/GsfCustomer.js +80 -0
  16. package/bin/gsfConnector/dtos/GsfExpectedState.d.ts +8 -0
  17. package/bin/gsfConnector/dtos/GsfExpectedState.js +38 -0
  18. package/bin/gsfConnector/dtos/GsfPayment.d.ts +16 -0
  19. package/bin/gsfConnector/dtos/GsfPayment.js +75 -0
  20. package/bin/gsfConnector/dtos/GsfPaymentMessage.d.ts +16 -0
  21. package/bin/gsfConnector/dtos/GsfPaymentMessage.js +74 -0
  22. package/bin/gsfConnector/dtos/GsfScheduleInstallment.d.ts +9 -0
  23. package/bin/gsfConnector/dtos/GsfScheduleInstallment.js +60 -0
  24. package/bin/gsfConnector/enums/GsfOperationEnum.d.ts +11 -0
  25. package/bin/gsfConnector/enums/GsfOperationEnum.js +15 -0
  26. package/bin/gsfConnector/enums/GsfPaymentChannelEnum.d.ts +11 -0
  27. package/bin/gsfConnector/enums/GsfPaymentChannelEnum.js +15 -0
  28. package/bin/gsfConnector/enums/GsfPaymentKindEnum.d.ts +11 -0
  29. package/bin/gsfConnector/enums/GsfPaymentKindEnum.js +15 -0
  30. package/bin/gsfConnector/enums/GsfPaymentPeriodicityEnum.d.ts +6 -0
  31. package/bin/gsfConnector/enums/GsfPaymentPeriodicityEnum.js +10 -0
  32. package/bin/gsfConnector/index.d.ts +17 -0
  33. package/bin/gsfConnector/index.js +37 -0
  34. package/bin/gsfConnector/validators/IsGsfCalendarDate.d.ts +6 -0
  35. package/bin/gsfConnector/validators/IsGsfCalendarDate.js +29 -0
  36. package/bin/gsfConnector/validators/IsGsfPaymentKindForOperation.d.ts +6 -0
  37. package/bin/gsfConnector/validators/IsGsfPaymentKindForOperation.js +31 -0
  38. package/bin/gsfConnector/validators/IsGsfPrepaymentScheduleProvided.d.ts +6 -0
  39. package/bin/gsfConnector/validators/IsGsfPrepaymentScheduleProvided.js +28 -0
  40. package/bin/index.d.ts +1 -0
  41. package/bin/index.js +3 -2
  42. package/bin/loanCredit/dtos/responses/LoanCustomerCreditDocument.d.ts +9 -0
  43. package/bin/loanCredit/dtos/responses/LoanCustomerCreditDocument.js +2 -0
  44. package/bin/loanCredit/dtos/responses/LoanCustomerCreditDocumentUrl.d.ts +9 -0
  45. package/bin/loanCredit/dtos/responses/LoanCustomerCreditDocumentUrl.js +2 -0
  46. package/bin/loanCredit/index.d.ts +2 -0
  47. package/bin/loanCredit/index.js +2 -0
  48. package/bin/retailLoan/dtos/MyDocument.d.ts +2 -1
  49. package/bin/retailLoan/enums/MyDocumentGroupIdEnum.d.ts +2 -1
  50. package/bin/retailLoan/enums/MyDocumentGroupIdEnum.js +1 -0
  51. package/bin/retailLoan/enums/MyDocumentKindEnum.d.ts +2 -1
  52. package/bin/retailLoan/enums/MyDocumentKindEnum.js +1 -0
  53. package/package.json +1 -1
  54. package/src/gsfConnector/constants/GsfPatterns.ts +21 -0
  55. package/src/gsfConnector/constants/GsfPaymentOperations.ts +17 -0
  56. package/src/gsfConnector/dtos/GsfAddress.ts +60 -0
  57. package/src/gsfConnector/dtos/GsfCreateCreditMessage.ts +60 -0
  58. package/src/gsfConnector/dtos/GsfCreditTerms.ts +55 -0
  59. package/src/gsfConnector/dtos/GsfCustomer.ts +60 -0
  60. package/src/gsfConnector/dtos/GsfExpectedState.ts +25 -0
  61. package/src/gsfConnector/dtos/GsfPayment.ts +57 -0
  62. package/src/gsfConnector/dtos/GsfPaymentMessage.ts +58 -0
  63. package/src/gsfConnector/dtos/GsfScheduleInstallment.ts +41 -0
  64. package/src/gsfConnector/enums/GsfOperationEnum.ts +11 -0
  65. package/src/gsfConnector/enums/GsfPaymentChannelEnum.ts +11 -0
  66. package/src/gsfConnector/enums/GsfPaymentKindEnum.ts +11 -0
  67. package/src/gsfConnector/enums/GsfPaymentPeriodicityEnum.ts +6 -0
  68. package/src/gsfConnector/index.ts +24 -0
  69. package/src/gsfConnector/validators/IsGsfCalendarDate.ts +19 -0
  70. package/src/gsfConnector/validators/IsGsfPaymentKindForOperation.ts +21 -0
  71. package/src/gsfConnector/validators/IsGsfPrepaymentScheduleProvided.ts +18 -0
  72. package/src/index.ts +1 -0
  73. package/src/loanCredit/dtos/responses/LoanCustomerCreditDocument.ts +10 -0
  74. package/src/loanCredit/dtos/responses/LoanCustomerCreditDocumentUrl.ts +10 -0
  75. package/src/loanCredit/index.ts +2 -0
  76. package/src/retailLoan/dtos/MyDocument.ts +2 -1
  77. package/src/retailLoan/enums/MyDocumentGroupIdEnum.ts +1 -0
  78. package/src/retailLoan/enums/MyDocumentKindEnum.ts +1 -0
@@ -0,0 +1,233 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate, ValidationError } from 'class-validator';
4
+ import {
5
+ GsfCreateCreditMessage,
6
+ GsfOperationEnum,
7
+ GsfPaymentChannelEnum,
8
+ GsfPaymentKindEnum,
9
+ GsfPaymentMessage,
10
+ GsfPaymentPeriodicityEnum,
11
+ } from '../../../src/gsfConnector/index';
12
+
13
+ const installment = { installmentNumber: 1, dueDate: '2026-11-09', capitalCents: 24181, interestCents: 10096, ivaCents: 1615, totalCents: 35892 };
14
+
15
+ const createCredit = () => ({
16
+ account: 'surekeep',
17
+ operation: GsfOperationEnum.CREATE_CREDIT,
18
+ messageId: 'C1:CREATE:A1',
19
+ externalCreditId: 'C1',
20
+ customer: {
21
+ names: 'ANA MARIA',
22
+ paternalLastName: 'LOPEZ',
23
+ maternalLastName: 'PEREZ',
24
+ rfc: 'LOPA900101AB1',
25
+ curp: 'LOPA900101MDFPRN09',
26
+ birthDate: '1990-01-01',
27
+ mobilePhone: '5512345678',
28
+ address: {
29
+ street: 'REFORMA', externalNumber: '10', neighborhood: 'CENTRO', zipCode: '06000',
30
+ city: 'CIUDAD DE MEXICO', municipality: 'CUAUHTEMOC', state: 'CIUDAD DE MEXICO', country: 'MEXICO',
31
+ },
32
+ },
33
+ terms: {
34
+ amountCents: 350000, installmentCount: 12, periodicity: GsfPaymentPeriodicityEnum.WEEKLY, annualRate: 1.5,
35
+ periodsPerYear: 52, ivaRate: 0.16, signedOn: '2026-11-02', activatedOn: '2026-11-02',
36
+ },
37
+ expectedSchedule: [installment],
38
+ });
39
+
40
+ const payment = () => ({
41
+ account: 'surekeep',
42
+ operation: GsfOperationEnum.APPLY_PREPAYMENT,
43
+ messageId: 'C1:APPLY_PREPAYMENT:P1',
44
+ externalCreditId: 'C1',
45
+ payment: {
46
+ externalPaymentId: 'P1', kind: GsfPaymentKindEnum.PREPAYMENT, channel: GsfPaymentChannelEnum.CASH,
47
+ amountCents: 50000, appliedOn: '2026-12-01',
48
+ },
49
+ expected: { principalAfterCents: 213066, schedule: [installment] },
50
+ });
51
+
52
+ /** Rutas de las propiedades con error, p. ej. `customer.rfc`. */
53
+ const failedPaths = (errors: ValidationError[], parent = ''): string[] =>
54
+ errors.flatMap((error) => {
55
+ const path = parent ? `${parent}.${error.property}` : error.property;
56
+ return error.children?.length ? failedPaths(error.children, path) : [path];
57
+ });
58
+
59
+ const validateAs = async <T extends object>(type: new () => T, plain: unknown) =>
60
+ failedPaths(await validate(plainToInstance(type, plain, { excludeExtraneousValues: true }) as object));
61
+
62
+ describe('GsfCreateCreditMessage', () => {
63
+ it('acepta un alta completa', async () => {
64
+ expect(await validateAs(GsfCreateCreditMessage, createCredit())).toEqual([]);
65
+ });
66
+
67
+ it('descarta los campos que no son del contrato', async () => {
68
+ const dto = plainToInstance(GsfCreateCreditMessage, { ...createCredit(), extra: 'x' }, { excludeExtraneousValues: true });
69
+
70
+ expect(dto).not.toHaveProperty('extra');
71
+ });
72
+
73
+ it('rechaza otra operación', async () => {
74
+ expect(await validateAs(GsfCreateCreditMessage, { ...createCredit(), operation: GsfOperationEnum.APPLY_PAYMENT })).toEqual(['operation']);
75
+ });
76
+
77
+ it('rechaza un RFC, una CURP o un CP con otro formato', async () => {
78
+ const plain = createCredit();
79
+ plain.customer.rfc = 'LOPA900101';
80
+ plain.customer.curp = 'LOPA900101';
81
+ plain.customer.address.zipCode = '6000';
82
+
83
+ expect(await validateAs(GsfCreateCreditMessage, plain)).toEqual(
84
+ expect.arrayContaining(['customer.rfc', 'customer.curp', 'customer.address.zipCode']),
85
+ );
86
+ });
87
+
88
+ it('exige la tabla esperada', async () => {
89
+ expect(await validateAs(GsfCreateCreditMessage, { ...createCredit(), expectedSchedule: [] })).toEqual(['expectedSchedule']);
90
+ });
91
+
92
+ it('valida cada cuota de la tabla', async () => {
93
+ const plain = { ...createCredit(), expectedSchedule: [{ ...installment, capitalCents: 241.81 }] };
94
+
95
+ expect(await validateAs(GsfCreateCreditMessage, plain)).toEqual(['expectedSchedule.0.capitalCents']);
96
+ });
97
+
98
+ it('rechaza una cuenta con otro formato', async () => {
99
+ expect(await validateAs(GsfCreateCreditMessage, { ...createCredit(), account: '../SureKeep' })).toEqual(['account']);
100
+ });
101
+ it('rechaza una fecha que no existe', async () => {
102
+ const plain = createCredit();
103
+ plain.terms.activatedOn = '2026-02-30';
104
+ plain.customer.birthDate = '1990-13-01';
105
+
106
+ expect(await validateAs(GsfCreateCreditMessage, plain)).toEqual(expect.arrayContaining(['terms.activatedOn', 'customer.birthDate']));
107
+ });
108
+
109
+ it('rechaza textos en blanco', async () => {
110
+ const plain = { ...createCredit(), messageId: ' ' };
111
+ plain.customer.names = ' ';
112
+
113
+ expect(await validateAs(GsfCreateCreditMessage, plain)).toEqual(expect.arrayContaining(['messageId', 'customer.names']));
114
+ });
115
+
116
+ it('rechaza un arreglo donde va un objeto', async () => {
117
+ expect(await validateAs(GsfCreateCreditMessage, { ...createCredit(), customer: [], terms: [] }))
118
+ .toEqual(expect.arrayContaining(['customer', 'terms']));
119
+ });
120
+
121
+ it('rechaza cuotas con el mismo número', async () => {
122
+ expect(await validateAs(GsfCreateCreditMessage, { ...createCredit(), expectedSchedule: [installment, installment] }))
123
+ .toEqual(['expectedSchedule']);
124
+ });
125
+
126
+ it('rechaza un email o un celular con otro formato', async () => {
127
+ const plain = createCredit();
128
+ Object.assign(plain.customer, { email: 'ana@', mobilePhone: '55-1234' });
129
+
130
+ expect(await validateAs(GsfCreateCreditMessage, plain)).toEqual(expect.arrayContaining(['customer.email', 'customer.mobilePhone']));
131
+ });
132
+
133
+ it('rechaza un messageId de más de 128 caracteres, el tope de SQS FIFO', async () => {
134
+ expect(await validateAs(GsfCreateCreditMessage, { ...createCredit(), messageId: 'x'.repeat(129) })).toEqual(['messageId']);
135
+ });
136
+
137
+ it('descarta campos extra también en los objetos anidados', async () => {
138
+ const plain = createCredit();
139
+ Object.assign(plain.customer, { extra: 'x' });
140
+ Object.assign(plain.customer.address, { extra: 'x' });
141
+ const dto = plainToInstance(GsfCreateCreditMessage, plain, { excludeExtraneousValues: true });
142
+
143
+ expect(dto.customer).not.toHaveProperty('extra');
144
+ expect(dto.customer.address).not.toHaveProperty('extra');
145
+ });
146
+ });
147
+
148
+ describe('GsfPaymentMessage', () => {
149
+ it('acepta un abono a capital con la tabla recalculada', async () => {
150
+ expect(await validateAs(GsfPaymentMessage, payment())).toEqual([]);
151
+ });
152
+
153
+ it.each([
154
+ [GsfOperationEnum.APPLY_PAYMENT, GsfPaymentKindEnum.INSTALLMENT],
155
+ [GsfOperationEnum.SETTLE_CREDIT, GsfPaymentKindEnum.SETTLEMENT],
156
+ ])('acepta %s sin estado esperado', async (operation, kind) => {
157
+ const { expected: _expected, ...plain } = payment();
158
+
159
+ expect(await validateAs(GsfPaymentMessage, { ...plain, operation, payment: { ...plain.payment, kind } })).toEqual([]);
160
+ });
161
+
162
+ it('rechaza CREATE_CREDIT', async () => {
163
+ expect(await validateAs(GsfPaymentMessage, { ...payment(), operation: GsfOperationEnum.CREATE_CREDIT })).toEqual(['operation']);
164
+ });
165
+
166
+ it('rechaza una clase o un canal desconocidos y un monto en cero', async () => {
167
+ const plain = payment();
168
+ Object.assign(plain.payment, { kind: 'REFUND', channel: 'OXXO', amountCents: 0 });
169
+
170
+ expect(await validateAs(GsfPaymentMessage, plain)).toEqual(
171
+ expect.arrayContaining(['payment.kind', 'payment.channel', 'payment.amountCents']),
172
+ );
173
+ });
174
+
175
+ it('exige el pago', async () => {
176
+ const { payment: _payment, ...plain } = payment();
177
+
178
+ expect(await validateAs(GsfPaymentMessage, plain)).toEqual(['payment']);
179
+ });
180
+ it('exige la tabla recalculada en un abono a capital', async () => {
181
+ const { expected: _expected, ...plain } = payment();
182
+
183
+ expect(await validateAs(GsfPaymentMessage, plain)).toEqual(['expected']);
184
+ expect(await validateAs(GsfPaymentMessage, { ...plain, expected: { principalAfterCents: 1 } })).toEqual(['expected']);
185
+ expect(await validateAs(GsfPaymentMessage, { ...plain, expected: { schedule: [] } })).toEqual(['expected.schedule']);
186
+ });
187
+
188
+ it.each([
189
+ [GsfOperationEnum.APPLY_PREPAYMENT, GsfPaymentKindEnum.INSTALLMENT],
190
+ [GsfOperationEnum.SETTLE_CREDIT, GsfPaymentKindEnum.ADVANCE],
191
+ [GsfOperationEnum.APPLY_PAYMENT, GsfPaymentKindEnum.PREPAYMENT],
192
+ ])('rechaza %s con un pago de clase %s', async (operation, kind) => {
193
+ const plain = { ...payment(), operation };
194
+ plain.payment.kind = kind;
195
+
196
+ expect(await validateAs(GsfPaymentMessage, plain)).toEqual(['payment']);
197
+ });
198
+
199
+ it.each([GsfPaymentKindEnum.INSTALLMENT, GsfPaymentKindEnum.ADVANCE, GsfPaymentKindEnum.SETTLEMENT])(
200
+ 'APPLY_PAYMENT acepta un pago de clase %s', async (kind) => {
201
+ const { expected: _expected, ...plain } = payment();
202
+ const message = { ...plain, operation: GsfOperationEnum.APPLY_PAYMENT, payment: { ...plain.payment, kind } };
203
+
204
+ expect(await validateAs(GsfPaymentMessage, message)).toEqual([]);
205
+ },
206
+ );
207
+
208
+ it('rechaza un arreglo donde va el pago', async () => {
209
+ expect(await validateAs(GsfPaymentMessage, { ...payment(), payment: [] })).toEqual(['payment']);
210
+ });
211
+ it.each(['constructor', 'toString', '__proto__'])('rechaza la operación %p sin romper el validador del pago', async (operation) => {
212
+ expect(await validateAs(GsfPaymentMessage, { ...payment(), operation })).toEqual(['operation']);
213
+ });
214
+
215
+ it('valida el estado esperado de un APPLY_PAYMENT cuando viene', async () => {
216
+ const plain = { ...payment(), operation: GsfOperationEnum.APPLY_PAYMENT, expected: { principalAfterCents: -1 } };
217
+ plain.payment.kind = GsfPaymentKindEnum.INSTALLMENT;
218
+
219
+ expect(await validateAs(GsfPaymentMessage, plain)).toEqual(['expected.principalAfterCents']);
220
+ });
221
+
222
+ it('rechaza cuotas repetidas en la tabla recalculada', async () => {
223
+ expect(await validateAs(GsfPaymentMessage, { ...payment(), expected: { schedule: [installment, installment] } }))
224
+ .toEqual(['expected.schedule']);
225
+ });
226
+
227
+ it('rechaza un municipio vacío: se omite para usar la ciudad', async () => {
228
+ const plain = createCredit();
229
+ plain.customer.address.municipality = ' ';
230
+
231
+ expect(await validateAs(GsfCreateCreditMessage, plain)).toEqual(['customer.address.municipality']);
232
+ });
233
+ });
@@ -3,6 +3,8 @@ import {
3
3
  ContractTypeEnum,
4
4
  CreditSaleContext,
5
5
  LoanContractDownloadUrl,
6
+ LoanCustomerCreditDocument,
7
+ LoanCustomerCreditDocumentUrl,
6
8
  LoanPaymentListItem,
7
9
  LoanPaymentListResponse,
8
10
  } from '../../../src/loanCredit/index';
@@ -68,4 +70,24 @@ describe('loanCredit — DTOs de lectura de cliente (I1)', () => {
68
70
  };
69
71
  expect(url.type).toBe(ContractTypeEnum.CREDIT);
70
72
  });
73
+
74
+ it('un documento del ciclo de vida sin PDF todavía no tiene fecha de generación', () => {
75
+ const pending: LoanCustomerCreditDocument = {
76
+ documentType: ContractTypeEnum.PAYMENT_RECEIPT,
77
+ documentKey: '01K8Z5Q2J6V3W4X5Y6Z7A8B9C0',
78
+ generatedAt: null,
79
+ };
80
+ expect(pending.generatedAt).toBeNull();
81
+ });
82
+
83
+ it('la URL de un documento del ciclo de vida trae su tipo, su llave y su vencimiento', () => {
84
+ const url: LoanCustomerCreditDocumentUrl = {
85
+ creditId: 'CR-1',
86
+ documentType: ContractTypeEnum.ACCOUNT_STATEMENT,
87
+ documentKey: '2026-09',
88
+ url: 'https://s3.example/statement.pdf',
89
+ expiresAt: '2026-10-21T15:00:00.000Z',
90
+ };
91
+ expect(url.documentKey).toBe('2026-09');
92
+ });
71
93
  });
@@ -18,6 +18,11 @@ describe('retailLoan — contrato app ↔ retail-loan-business (I1)', () => {
18
18
  it('los ids de grupo de documentos son los que espera el módulo de la app', () => {
19
19
  expect(MyDocumentGroupIdEnum.CONTRACT).toBe('contract');
20
20
  expect(MyDocumentGroupIdEnum.MONTHLY).toBe('monthly');
21
+ expect(MyDocumentGroupIdEnum.PAYMENT_RECEIPTS).toBe('receipts');
22
+ });
23
+
24
+ it('un comprobante de pago es su propio tipo de documento', () => {
25
+ expect(MyDocumentKindEnum.PAYMENT_RECEIPT).toBe('PAYMENT_RECEIPT');
21
26
  });
22
27
 
23
28
  it('el detalle del crédito va en pesos y con frecuencia semanal', () => {
@@ -0,0 +1,15 @@
1
+ /** Fecha calendario `YYYY-MM-DD`; `IsGsfCalendarDate` además rechaza días que no existen. */
2
+ export declare const GSF_DATE_PATTERN: RegExp;
3
+ /** Slug de la cuenta de SofomCloud: elige las credenciales del conector. */
4
+ export declare const GSF_ACCOUNT_PATTERN: RegExp;
5
+ export declare const GSF_ACCOUNT_MAX_LENGTH = 64;
6
+ /** RFC de persona física: 13 caracteres. GSF pide 13 en PF. */
7
+ export declare const GSF_RFC_PF_PATTERN: RegExp;
8
+ /** Al menos un carácter que no sea espacio. */
9
+ export declare const GSF_NOT_BLANK_PATTERN: RegExp;
10
+ /** Tope de SQS FIFO para MessageGroupId y MessageDeduplicationId. */
11
+ export declare const GSF_QUEUE_ID_MAX_LENGTH = 128;
12
+ export declare const GSF_MAX_CENTS: number;
13
+ export declare const GSF_MAX_INSTALLMENTS = 1000;
14
+ /** Tasa anual máxima en decimal: 100 = 10,000 %. */
15
+ export declare const GSF_MAX_ANNUAL_RATE = 100;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GSF_MAX_ANNUAL_RATE = exports.GSF_MAX_INSTALLMENTS = exports.GSF_MAX_CENTS = exports.GSF_QUEUE_ID_MAX_LENGTH = exports.GSF_NOT_BLANK_PATTERN = exports.GSF_RFC_PF_PATTERN = exports.GSF_ACCOUNT_MAX_LENGTH = exports.GSF_ACCOUNT_PATTERN = exports.GSF_DATE_PATTERN = void 0;
4
+ /** Fecha calendario `YYYY-MM-DD`; `IsGsfCalendarDate` además rechaza días que no existen. */
5
+ exports.GSF_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
6
+ /** Slug de la cuenta de SofomCloud: elige las credenciales del conector. */
7
+ exports.GSF_ACCOUNT_PATTERN = /^[a-z][a-z0-9-]*$/;
8
+ exports.GSF_ACCOUNT_MAX_LENGTH = 64;
9
+ /** RFC de persona física: 13 caracteres. GSF pide 13 en PF. */
10
+ exports.GSF_RFC_PF_PATTERN = /^[A-ZÑ&]{4}\d{6}[A-Z0-9]{3}$/;
11
+ /** Al menos un carácter que no sea espacio. */
12
+ exports.GSF_NOT_BLANK_PATTERN = /\S/;
13
+ /** Tope de SQS FIFO para MessageGroupId y MessageDeduplicationId. */
14
+ exports.GSF_QUEUE_ID_MAX_LENGTH = 128;
15
+ exports.GSF_MAX_CENTS = Number.MAX_SAFE_INTEGER;
16
+ exports.GSF_MAX_INSTALLMENTS = 1000;
17
+ /** Tasa anual máxima en decimal: 100 = 10,000 %. */
18
+ exports.GSF_MAX_ANNUAL_RATE = 100;
@@ -0,0 +1,6 @@
1
+ import { GsfOperationEnum } from '../enums/GsfOperationEnum';
2
+ import { GsfPaymentKindEnum } from '../enums/GsfPaymentKindEnum';
3
+ export declare const GSF_PAYMENT_OPERATIONS: readonly [GsfOperationEnum.APPLY_PAYMENT, GsfOperationEnum.APPLY_PREPAYMENT, GsfOperationEnum.SETTLE_CREDIT];
4
+ export type GsfPaymentOperation = (typeof GSF_PAYMENT_OPERATIONS)[number];
5
+ /** Clases de pago que admite cada operación. Una liquidación parcial viaja como `APPLY_PAYMENT`. */
6
+ export declare const GSF_PAYMENT_KINDS_BY_OPERATION: Record<GsfPaymentOperation, readonly GsfPaymentKindEnum[]>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GSF_PAYMENT_KINDS_BY_OPERATION = exports.GSF_PAYMENT_OPERATIONS = void 0;
4
+ const GsfOperationEnum_1 = require("../enums/GsfOperationEnum");
5
+ const GsfPaymentKindEnum_1 = require("../enums/GsfPaymentKindEnum");
6
+ exports.GSF_PAYMENT_OPERATIONS = [
7
+ GsfOperationEnum_1.GsfOperationEnum.APPLY_PAYMENT,
8
+ GsfOperationEnum_1.GsfOperationEnum.APPLY_PREPAYMENT,
9
+ GsfOperationEnum_1.GsfOperationEnum.SETTLE_CREDIT,
10
+ ];
11
+ /** Clases de pago que admite cada operación. Una liquidación parcial viaja como `APPLY_PAYMENT`. */
12
+ exports.GSF_PAYMENT_KINDS_BY_OPERATION = {
13
+ [GsfOperationEnum_1.GsfOperationEnum.APPLY_PAYMENT]: [GsfPaymentKindEnum_1.GsfPaymentKindEnum.INSTALLMENT, GsfPaymentKindEnum_1.GsfPaymentKindEnum.ADVANCE, GsfPaymentKindEnum_1.GsfPaymentKindEnum.SETTLEMENT],
14
+ [GsfOperationEnum_1.GsfOperationEnum.APPLY_PREPAYMENT]: [GsfPaymentKindEnum_1.GsfPaymentKindEnum.PREPAYMENT],
15
+ [GsfOperationEnum_1.GsfOperationEnum.SETTLE_CREDIT]: [GsfPaymentKindEnum_1.GsfPaymentKindEnum.SETTLEMENT],
16
+ };
@@ -0,0 +1,13 @@
1
+ /** Domicilio del cliente con nombres; el conector los traduce a los catálogos de geografía de GSF. */
2
+ export declare class GsfAddress {
3
+ street: string;
4
+ externalNumber: string;
5
+ internalNumber?: string;
6
+ neighborhood: string;
7
+ zipCode: string;
8
+ city: string;
9
+ /** Si falta, el conector usa la ciudad. Vacío no vale: se omite. */
10
+ municipality?: string;
11
+ state: string;
12
+ country: string;
13
+ }
@@ -0,0 +1,81 @@
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.GsfAddress = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const InputPatterns_1 = require("../../common/constants/InputPatterns");
16
+ const GsfPatterns_1 = require("../constants/GsfPatterns");
17
+ /** Domicilio del cliente con nombres; el conector los traduce a los catálogos de geografía de GSF. */
18
+ class GsfAddress {
19
+ }
20
+ exports.GsfAddress = GsfAddress;
21
+ __decorate([
22
+ (0, class_transformer_1.Expose)(),
23
+ (0, class_validator_1.IsString)(),
24
+ (0, class_validator_1.IsNotEmpty)(),
25
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
26
+ __metadata("design:type", String)
27
+ ], GsfAddress.prototype, "street", void 0);
28
+ __decorate([
29
+ (0, class_transformer_1.Expose)(),
30
+ (0, class_validator_1.IsString)(),
31
+ (0, class_validator_1.IsNotEmpty)(),
32
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
33
+ __metadata("design:type", String)
34
+ ], GsfAddress.prototype, "externalNumber", void 0);
35
+ __decorate([
36
+ (0, class_transformer_1.Expose)(),
37
+ (0, class_validator_1.IsOptional)(),
38
+ (0, class_validator_1.IsString)(),
39
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
40
+ __metadata("design:type", String)
41
+ ], GsfAddress.prototype, "internalNumber", void 0);
42
+ __decorate([
43
+ (0, class_transformer_1.Expose)(),
44
+ (0, class_validator_1.IsString)(),
45
+ (0, class_validator_1.IsNotEmpty)(),
46
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
47
+ __metadata("design:type", String)
48
+ ], GsfAddress.prototype, "neighborhood", void 0);
49
+ __decorate([
50
+ (0, class_transformer_1.Expose)(),
51
+ (0, class_validator_1.Matches)(InputPatterns_1.ZIP_CODE_MX_PATTERN),
52
+ __metadata("design:type", String)
53
+ ], GsfAddress.prototype, "zipCode", void 0);
54
+ __decorate([
55
+ (0, class_transformer_1.Expose)(),
56
+ (0, class_validator_1.IsString)(),
57
+ (0, class_validator_1.IsNotEmpty)(),
58
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
59
+ __metadata("design:type", String)
60
+ ], GsfAddress.prototype, "city", void 0);
61
+ __decorate([
62
+ (0, class_transformer_1.Expose)(),
63
+ (0, class_validator_1.IsOptional)(),
64
+ (0, class_validator_1.IsString)(),
65
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
66
+ __metadata("design:type", String)
67
+ ], GsfAddress.prototype, "municipality", void 0);
68
+ __decorate([
69
+ (0, class_transformer_1.Expose)(),
70
+ (0, class_validator_1.IsString)(),
71
+ (0, class_validator_1.IsNotEmpty)(),
72
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
73
+ __metadata("design:type", String)
74
+ ], GsfAddress.prototype, "state", void 0);
75
+ __decorate([
76
+ (0, class_transformer_1.Expose)(),
77
+ (0, class_validator_1.IsString)(),
78
+ (0, class_validator_1.IsNotEmpty)(),
79
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
80
+ __metadata("design:type", String)
81
+ ], GsfAddress.prototype, "country", void 0);
@@ -0,0 +1,17 @@
1
+ import { GsfOperationEnum } from '../enums/GsfOperationEnum';
2
+ import { GsfCustomer } from './GsfCustomer';
3
+ import { GsfCreditTerms } from './GsfCreditTerms';
4
+ import { GsfScheduleInstallment } from './GsfScheduleInstallment';
5
+ /**
6
+ * Mensaje `CREATE_CREDIT` de `GsfSyncQueue.fifo`: el crédito ya está activo en el origen. MessageGroupId =
7
+ * `externalCreditId`, MessageDeduplicationId = `messageId`.
8
+ */
9
+ export declare class GsfCreateCreditMessage {
10
+ account: string;
11
+ operation: GsfOperationEnum.CREATE_CREDIT;
12
+ messageId: string;
13
+ externalCreditId: string;
14
+ customer: GsfCustomer;
15
+ terms: GsfCreditTerms;
16
+ expectedSchedule: GsfScheduleInstallment[];
17
+ }
@@ -0,0 +1,78 @@
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.GsfCreateCreditMessage = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const GsfOperationEnum_1 = require("../enums/GsfOperationEnum");
16
+ const GsfCustomer_1 = require("./GsfCustomer");
17
+ const GsfCreditTerms_1 = require("./GsfCreditTerms");
18
+ const GsfScheduleInstallment_1 = require("./GsfScheduleInstallment");
19
+ const GsfPatterns_1 = require("../constants/GsfPatterns");
20
+ /**
21
+ * Mensaje `CREATE_CREDIT` de `GsfSyncQueue.fifo`: el crédito ya está activo en el origen. MessageGroupId =
22
+ * `externalCreditId`, MessageDeduplicationId = `messageId`.
23
+ */
24
+ class GsfCreateCreditMessage {
25
+ }
26
+ exports.GsfCreateCreditMessage = GsfCreateCreditMessage;
27
+ __decorate([
28
+ (0, class_transformer_1.Expose)(),
29
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_ACCOUNT_PATTERN),
30
+ (0, class_validator_1.MaxLength)(GsfPatterns_1.GSF_ACCOUNT_MAX_LENGTH),
31
+ __metadata("design:type", String)
32
+ ], GsfCreateCreditMessage.prototype, "account", void 0);
33
+ __decorate([
34
+ (0, class_transformer_1.Expose)(),
35
+ (0, class_validator_1.Equals)(GsfOperationEnum_1.GsfOperationEnum.CREATE_CREDIT),
36
+ __metadata("design:type", String)
37
+ ], GsfCreateCreditMessage.prototype, "operation", void 0);
38
+ __decorate([
39
+ (0, class_transformer_1.Expose)(),
40
+ (0, class_validator_1.IsString)(),
41
+ (0, class_validator_1.IsNotEmpty)(),
42
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
43
+ (0, class_validator_1.MaxLength)(GsfPatterns_1.GSF_QUEUE_ID_MAX_LENGTH),
44
+ __metadata("design:type", String)
45
+ ], GsfCreateCreditMessage.prototype, "messageId", void 0);
46
+ __decorate([
47
+ (0, class_transformer_1.Expose)(),
48
+ (0, class_validator_1.IsString)(),
49
+ (0, class_validator_1.IsNotEmpty)(),
50
+ (0, class_validator_1.Matches)(GsfPatterns_1.GSF_NOT_BLANK_PATTERN),
51
+ (0, class_validator_1.MaxLength)(GsfPatterns_1.GSF_QUEUE_ID_MAX_LENGTH),
52
+ __metadata("design:type", String)
53
+ ], GsfCreateCreditMessage.prototype, "externalCreditId", void 0);
54
+ __decorate([
55
+ (0, class_transformer_1.Expose)(),
56
+ (0, class_validator_1.IsDefined)(),
57
+ (0, class_validator_1.IsObject)(),
58
+ (0, class_validator_1.ValidateNested)(),
59
+ (0, class_transformer_1.Type)(() => GsfCustomer_1.GsfCustomer),
60
+ __metadata("design:type", GsfCustomer_1.GsfCustomer)
61
+ ], GsfCreateCreditMessage.prototype, "customer", void 0);
62
+ __decorate([
63
+ (0, class_transformer_1.Expose)(),
64
+ (0, class_validator_1.IsDefined)(),
65
+ (0, class_validator_1.IsObject)(),
66
+ (0, class_validator_1.ValidateNested)(),
67
+ (0, class_transformer_1.Type)(() => GsfCreditTerms_1.GsfCreditTerms),
68
+ __metadata("design:type", GsfCreditTerms_1.GsfCreditTerms)
69
+ ], GsfCreateCreditMessage.prototype, "terms", void 0);
70
+ __decorate([
71
+ (0, class_transformer_1.Expose)(),
72
+ (0, class_validator_1.IsArray)(),
73
+ (0, class_validator_1.ArrayMinSize)(1),
74
+ (0, class_validator_1.ArrayUnique)((installment) => installment?.installmentNumber),
75
+ (0, class_validator_1.ValidateNested)({ each: true }),
76
+ (0, class_transformer_1.Type)(() => GsfScheduleInstallment_1.GsfScheduleInstallment),
77
+ __metadata("design:type", Array)
78
+ ], GsfCreateCreditMessage.prototype, "expectedSchedule", void 0);
@@ -0,0 +1,17 @@
1
+ import { GsfPaymentPeriodicityEnum } from '../enums/GsfPaymentPeriodicityEnum';
2
+ /** Condiciones del crédito tal como quedaron firmadas. */
3
+ export declare class GsfCreditTerms {
4
+ /** Monto que se amortiza, comisiones financiadas incluidas. */
5
+ amountCents: number;
6
+ installmentCount: number;
7
+ periodicity: GsfPaymentPeriodicityEnum;
8
+ /** Tasa anual del contrato en decimal: 2.30 = 230 %. Puede ser 0 por una promoción. */
9
+ annualRate: number;
10
+ /** Entre cuántos periodos divide el origen la tasa anual: 52 si el interés semanal es tasa / 52. */
11
+ periodsPerYear: number;
12
+ /** IVA sobre el interés en decimal: 0.16. */
13
+ ivaRate: number;
14
+ signedOn: string;
15
+ /** Inicio del calendario de pagos. */
16
+ activatedOn: string;
17
+ }
@@ -0,0 +1,71 @@
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.GsfCreditTerms = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const GsfPaymentPeriodicityEnum_1 = require("../enums/GsfPaymentPeriodicityEnum");
16
+ const GsfPatterns_1 = require("../constants/GsfPatterns");
17
+ const IsGsfCalendarDate_1 = require("../validators/IsGsfCalendarDate");
18
+ /** Condiciones del crédito tal como quedaron firmadas. */
19
+ class GsfCreditTerms {
20
+ }
21
+ exports.GsfCreditTerms = GsfCreditTerms;
22
+ __decorate([
23
+ (0, class_transformer_1.Expose)(),
24
+ (0, class_validator_1.IsInt)(),
25
+ (0, class_validator_1.Min)(1),
26
+ (0, class_validator_1.Max)(GsfPatterns_1.GSF_MAX_CENTS),
27
+ __metadata("design:type", Number)
28
+ ], GsfCreditTerms.prototype, "amountCents", void 0);
29
+ __decorate([
30
+ (0, class_transformer_1.Expose)(),
31
+ (0, class_validator_1.IsInt)(),
32
+ (0, class_validator_1.Min)(1),
33
+ (0, class_validator_1.Max)(GsfPatterns_1.GSF_MAX_INSTALLMENTS),
34
+ __metadata("design:type", Number)
35
+ ], GsfCreditTerms.prototype, "installmentCount", void 0);
36
+ __decorate([
37
+ (0, class_transformer_1.Expose)(),
38
+ (0, class_validator_1.IsEnum)(GsfPaymentPeriodicityEnum_1.GsfPaymentPeriodicityEnum),
39
+ __metadata("design:type", String)
40
+ ], GsfCreditTerms.prototype, "periodicity", void 0);
41
+ __decorate([
42
+ (0, class_transformer_1.Expose)(),
43
+ (0, class_validator_1.IsNumber)({ allowNaN: false, allowInfinity: false }),
44
+ (0, class_validator_1.Min)(0),
45
+ (0, class_validator_1.Max)(GsfPatterns_1.GSF_MAX_ANNUAL_RATE),
46
+ __metadata("design:type", Number)
47
+ ], GsfCreditTerms.prototype, "annualRate", void 0);
48
+ __decorate([
49
+ (0, class_transformer_1.Expose)(),
50
+ (0, class_validator_1.IsInt)(),
51
+ (0, class_validator_1.Min)(1),
52
+ (0, class_validator_1.Max)(365),
53
+ __metadata("design:type", Number)
54
+ ], GsfCreditTerms.prototype, "periodsPerYear", void 0);
55
+ __decorate([
56
+ (0, class_transformer_1.Expose)(),
57
+ (0, class_validator_1.IsNumber)({ allowNaN: false, allowInfinity: false }),
58
+ (0, class_validator_1.Min)(0),
59
+ (0, class_validator_1.Max)(1),
60
+ __metadata("design:type", Number)
61
+ ], GsfCreditTerms.prototype, "ivaRate", void 0);
62
+ __decorate([
63
+ (0, class_transformer_1.Expose)(),
64
+ (0, class_validator_1.Validate)(IsGsfCalendarDate_1.IsGsfCalendarDate),
65
+ __metadata("design:type", String)
66
+ ], GsfCreditTerms.prototype, "signedOn", void 0);
67
+ __decorate([
68
+ (0, class_transformer_1.Expose)(),
69
+ (0, class_validator_1.Validate)(IsGsfCalendarDate_1.IsGsfCalendarDate),
70
+ __metadata("design:type", String)
71
+ ], GsfCreditTerms.prototype, "activatedOn", void 0);
@@ -0,0 +1,15 @@
1
+ import { GsfAddress } from './GsfAddress';
2
+ /** Cliente persona física. Lleva datos personales: nunca se loguea. */
3
+ export declare class GsfCustomer {
4
+ names: string;
5
+ paternalLastName: string;
6
+ maternalLastName?: string;
7
+ rfc: string;
8
+ /** El conector deriva de la CURP el género y el estado de nacimiento. */
9
+ curp: string;
10
+ birthDate: string;
11
+ email?: string;
12
+ /** 10 dígitos, con o sin `+52`; el conector manda los 10 dígitos. */
13
+ mobilePhone?: string;
14
+ address: GsfAddress;
15
+ }