@fiado/type-kit 3.354.0 → 3.355.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/webhookBusiness/WebhookEventEnvelope.test.ts +147 -0
- package/_test_/unit/webhookBusiness/webhookEvents.test.ts +197 -0
- package/_test_/unit/webhookBusiness/webhookSubscriptionRequests.test.ts +60 -0
- package/bin/index.d.ts +1 -0
- package/bin/index.js +5 -1
- package/bin/productCatalog/enums/ProductSubtypeEnum.d.ts +1 -1
- package/bin/productCatalog/enums/ProductSubtypeEnum.js +2 -2
- package/bin/productCatalog/enums/ProductTypeEnum.d.ts +4 -4
- package/bin/productCatalog/enums/ProductTypeEnum.js +4 -4
- package/bin/transactionProcessor/dtos/{AuthorizeWelcomeBonusRequest.d.ts → AuthorizeBonusRequest.d.ts} +3 -3
- package/bin/transactionProcessor/dtos/{AuthorizeWelcomeBonusRequest.js → AuthorizeBonusRequest.js} +10 -10
- package/bin/transactionProcessor/index.d.ts +1 -1
- package/bin/transactionProcessor/index.js +1 -1
- package/bin/webhookBusiness/constants/CaseRefPattern.d.ts +8 -0
- package/bin/webhookBusiness/constants/CaseRefPattern.js +11 -0
- package/bin/webhookBusiness/constants/WebhookFieldLimits.d.ts +6 -0
- package/bin/webhookBusiness/constants/WebhookFieldLimits.js +9 -0
- package/bin/webhookBusiness/dtos/WebhookDeliveryView.d.ts +28 -0
- package/bin/webhookBusiness/dtos/WebhookDeliveryView.js +2 -0
- package/bin/webhookBusiness/dtos/WebhookEventEnvelope.d.ts +27 -0
- package/bin/webhookBusiness/dtos/WebhookEventEnvelope.js +62 -0
- package/bin/webhookBusiness/dtos/WebhookOutboundMessage.d.ts +10 -0
- package/bin/webhookBusiness/dtos/WebhookOutboundMessage.js +2 -0
- package/bin/webhookBusiness/dtos/WebhookSubscriptionView.d.ts +23 -0
- package/bin/webhookBusiness/dtos/WebhookSubscriptionView.js +2 -0
- package/bin/webhookBusiness/dtos/requests/DeactivateWebhookSubscriptionRequest.d.ts +11 -0
- package/bin/webhookBusiness/dtos/requests/DeactivateWebhookSubscriptionRequest.js +42 -0
- package/bin/webhookBusiness/dtos/requests/GetWebhookSubscriptionRequest.d.ts +9 -0
- package/bin/webhookBusiness/dtos/requests/GetWebhookSubscriptionRequest.js +35 -0
- package/bin/webhookBusiness/dtos/requests/ListWebhookDeliveriesRequest.d.ts +9 -0
- package/bin/webhookBusiness/dtos/requests/ListWebhookDeliveriesRequest.js +35 -0
- package/bin/webhookBusiness/dtos/requests/RedeliverWebhookEventRequest.d.ts +11 -0
- package/bin/webhookBusiness/dtos/requests/RedeliverWebhookEventRequest.js +43 -0
- package/bin/webhookBusiness/dtos/requests/UpsertWebhookSubscriptionRequest.d.ts +22 -0
- package/bin/webhookBusiness/dtos/requests/UpsertWebhookSubscriptionRequest.js +89 -0
- package/bin/webhookBusiness/dtos/responses/DeactivateWebhookSubscriptionResponse.d.ts +5 -0
- package/bin/webhookBusiness/dtos/responses/DeactivateWebhookSubscriptionResponse.js +2 -0
- package/bin/webhookBusiness/dtos/responses/GetWebhookSubscriptionResponse.d.ts +5 -0
- package/bin/webhookBusiness/dtos/responses/GetWebhookSubscriptionResponse.js +2 -0
- package/bin/webhookBusiness/dtos/responses/ListWebhookDeliveriesResponse.d.ts +10 -0
- package/bin/webhookBusiness/dtos/responses/ListWebhookDeliveriesResponse.js +2 -0
- package/bin/webhookBusiness/dtos/responses/ListWebhookSubscriptionsResponse.d.ts +10 -0
- package/bin/webhookBusiness/dtos/responses/ListWebhookSubscriptionsResponse.js +2 -0
- package/bin/webhookBusiness/dtos/responses/RedeliverWebhookEventResponse.d.ts +11 -0
- package/bin/webhookBusiness/dtos/responses/RedeliverWebhookEventResponse.js +2 -0
- package/bin/webhookBusiness/dtos/responses/UpsertWebhookSubscriptionResponse.d.ts +7 -0
- package/bin/webhookBusiness/dtos/responses/UpsertWebhookSubscriptionResponse.js +2 -0
- package/bin/webhookBusiness/enums/ComplianceDecisionEnum.d.ts +11 -0
- package/bin/webhookBusiness/enums/ComplianceDecisionEnum.js +15 -0
- package/bin/webhookBusiness/enums/DeliveryOutcomeEnum.d.ts +15 -0
- package/bin/webhookBusiness/enums/DeliveryOutcomeEnum.js +19 -0
- package/bin/webhookBusiness/enums/SubscriptionStatusEnum.d.ts +5 -0
- package/bin/webhookBusiness/enums/SubscriptionStatusEnum.js +9 -0
- package/bin/webhookBusiness/enums/SubscriptionVisibilityEnum.d.ts +10 -0
- package/bin/webhookBusiness/enums/SubscriptionVisibilityEnum.js +14 -0
- package/bin/webhookBusiness/enums/WebhookEventType.d.ts +10 -0
- package/bin/webhookBusiness/enums/WebhookEventType.js +14 -0
- package/bin/webhookBusiness/events/AccountIssuanceCompletedV1.d.ts +19 -0
- package/bin/webhookBusiness/events/AccountIssuanceCompletedV1.js +47 -0
- package/bin/webhookBusiness/events/ComplianceDecisionV1.d.ts +25 -0
- package/bin/webhookBusiness/events/ComplianceDecisionV1.js +51 -0
- package/bin/webhookBusiness/index.d.ts +24 -0
- package/bin/webhookBusiness/index.js +47 -0
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/productCatalog/enums/ProductSubtypeEnum.ts +2 -2
- package/src/productCatalog/enums/ProductTypeEnum.ts +4 -4
- package/src/transactionProcessor/dtos/{AuthorizeWelcomeBonusRequest.ts → AuthorizeBonusRequest.ts} +3 -3
- package/src/transactionProcessor/index.ts +1 -1
- package/src/webhookBusiness/constants/CaseRefPattern.ts +9 -0
- package/src/webhookBusiness/constants/WebhookFieldLimits.ts +8 -0
- package/src/webhookBusiness/dtos/WebhookDeliveryView.ts +29 -0
- package/src/webhookBusiness/dtos/WebhookEventEnvelope.ts +42 -0
- package/src/webhookBusiness/dtos/WebhookOutboundMessage.ts +18 -0
- package/src/webhookBusiness/dtos/WebhookSubscriptionView.ts +24 -0
- package/src/webhookBusiness/dtos/requests/DeactivateWebhookSubscriptionRequest.ts +27 -0
- package/src/webhookBusiness/dtos/requests/GetWebhookSubscriptionRequest.ts +20 -0
- package/src/webhookBusiness/dtos/requests/ListWebhookDeliveriesRequest.ts +21 -0
- package/src/webhookBusiness/dtos/requests/RedeliverWebhookEventRequest.ts +28 -0
- package/src/webhookBusiness/dtos/requests/UpsertWebhookSubscriptionRequest.ts +69 -0
- package/src/webhookBusiness/dtos/responses/DeactivateWebhookSubscriptionResponse.ts +6 -0
- package/src/webhookBusiness/dtos/responses/GetWebhookSubscriptionResponse.ts +6 -0
- package/src/webhookBusiness/dtos/responses/ListWebhookDeliveriesResponse.ts +11 -0
- package/src/webhookBusiness/dtos/responses/ListWebhookSubscriptionsResponse.ts +11 -0
- package/src/webhookBusiness/dtos/responses/RedeliverWebhookEventResponse.ts +12 -0
- package/src/webhookBusiness/dtos/responses/UpsertWebhookSubscriptionResponse.ts +8 -0
- package/src/webhookBusiness/enums/ComplianceDecisionEnum.ts +11 -0
- package/src/webhookBusiness/enums/DeliveryOutcomeEnum.ts +15 -0
- package/src/webhookBusiness/enums/SubscriptionStatusEnum.ts +5 -0
- package/src/webhookBusiness/enums/SubscriptionVisibilityEnum.ts +10 -0
- package/src/webhookBusiness/enums/WebhookEventType.ts +10 -0
- package/src/webhookBusiness/events/AccountIssuanceCompletedV1.ts +30 -0
- package/src/webhookBusiness/events/ComplianceDecisionV1.ts +36 -0
- package/src/webhookBusiness/index.ts +37 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
AccountIssuanceCompletedV1,
|
|
6
|
+
ComplianceDecisionV1,
|
|
7
|
+
WebhookEventEnvelope,
|
|
8
|
+
WebhookEventType,
|
|
9
|
+
WebhookOutboundMessage,
|
|
10
|
+
} from '../../../src/webhookBusiness/index';
|
|
11
|
+
|
|
12
|
+
const validEnvelope = {
|
|
13
|
+
eventId: 'evt-1',
|
|
14
|
+
eventType: WebhookEventType.AccountIssuanceCompleted,
|
|
15
|
+
source: 'retail-customer-business',
|
|
16
|
+
directoryId: 'dir-1',
|
|
17
|
+
occurredAt: '2026-08-22T10:05:00.000Z',
|
|
18
|
+
payload: { peopleId: 'ppl-1', status: 'OPEN' },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
describe('WebhookEventEnvelope', () => {
|
|
22
|
+
it('valida el sobre completo', async () => {
|
|
23
|
+
const dto = plainToInstance(WebhookEventEnvelope, validEnvelope, { excludeExtraneousValues: true });
|
|
24
|
+
|
|
25
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Candado del bug que el diseño original traía: con `@Type(() => Object)` el payload llegaba {}.
|
|
29
|
+
it('no destruye el payload al deserializar con excludeExtraneousValues', () => {
|
|
30
|
+
const dto = plainToInstance(WebhookEventEnvelope, validEnvelope, { excludeExtraneousValues: true });
|
|
31
|
+
|
|
32
|
+
expect(dto.payload).toEqual({ peopleId: 'ppl-1', status: 'OPEN' });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it.each(['eventId', 'source', 'directoryId'])('rechaza %s vacío', async (field) => {
|
|
36
|
+
const dto = plainToInstance(
|
|
37
|
+
WebhookEventEnvelope,
|
|
38
|
+
{ ...validEnvelope, [field]: '' },
|
|
39
|
+
{ excludeExtraneousValues: true },
|
|
40
|
+
);
|
|
41
|
+
const errors = await validate(dto as object);
|
|
42
|
+
|
|
43
|
+
expect(errors.map((e) => e.property)).toContain(field);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Sin directoryId no hay tag `wh:*` que resolver, o sea que no hay destinatario posible.
|
|
47
|
+
it('rechaza un sobre sin directoryId', async () => {
|
|
48
|
+
const { directoryId, ...raw } = validEnvelope;
|
|
49
|
+
const dto = plainToInstance(WebhookEventEnvelope, raw, { excludeExtraneousValues: true });
|
|
50
|
+
const errors = await validate(dto as object);
|
|
51
|
+
|
|
52
|
+
expect(errors.map((e) => e.property)).toContain('directoryId');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Mismo tope que `RedeliverWebhookEventRequest.eventId`: es la misma llave en los dos contratos.
|
|
56
|
+
it('rechaza un eventId mas largo que el tope', async () => {
|
|
57
|
+
const dto = plainToInstance(
|
|
58
|
+
WebhookEventEnvelope,
|
|
59
|
+
{ ...validEnvelope, eventId: 'e'.repeat(129) },
|
|
60
|
+
{ excludeExtraneousValues: true },
|
|
61
|
+
);
|
|
62
|
+
const errors = await validate(dto as object);
|
|
63
|
+
|
|
64
|
+
expect(errors.map((e) => e.property)).toContain('eventId');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('rechaza un payload vacío', async () => {
|
|
68
|
+
const dto = plainToInstance(
|
|
69
|
+
WebhookEventEnvelope,
|
|
70
|
+
{ ...validEnvelope, payload: {} },
|
|
71
|
+
{ excludeExtraneousValues: true },
|
|
72
|
+
);
|
|
73
|
+
const errors = await validate(dto as object);
|
|
74
|
+
|
|
75
|
+
expect(errors.map((e) => e.property)).toContain('payload');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('rechaza un eventType fuera del catálogo cerrado', async () => {
|
|
79
|
+
const dto = plainToInstance(
|
|
80
|
+
WebhookEventEnvelope,
|
|
81
|
+
{ ...validEnvelope, eventType: 'AccountOpenedV1' },
|
|
82
|
+
{ excludeExtraneousValues: true },
|
|
83
|
+
);
|
|
84
|
+
const errors = await validate(dto as object);
|
|
85
|
+
|
|
86
|
+
expect(errors.map((e) => e.property)).toContain('eventType');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('rechaza un occurredAt que no es ISO-8601', async () => {
|
|
90
|
+
const dto = plainToInstance(
|
|
91
|
+
WebhookEventEnvelope,
|
|
92
|
+
{ ...validEnvelope, occurredAt: '22/08/2026' },
|
|
93
|
+
{ excludeExtraneousValues: true },
|
|
94
|
+
);
|
|
95
|
+
const errors = await validate(dto as object);
|
|
96
|
+
|
|
97
|
+
expect(errors.map((e) => e.property)).toContain('occurredAt');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('WebhookOutboundMessage', () => {
|
|
102
|
+
it('acepta los dos sobres del corte 1', () => {
|
|
103
|
+
const account: WebhookOutboundMessage = plainToInstance(
|
|
104
|
+
WebhookEventEnvelope<AccountIssuanceCompletedV1, WebhookEventType.AccountIssuanceCompleted>,
|
|
105
|
+
validEnvelope,
|
|
106
|
+
{ excludeExtraneousValues: true },
|
|
107
|
+
);
|
|
108
|
+
const compliance: WebhookOutboundMessage = plainToInstance(
|
|
109
|
+
WebhookEventEnvelope<ComplianceDecisionV1, WebhookEventType.ComplianceDecision>,
|
|
110
|
+
{
|
|
111
|
+
...validEnvelope,
|
|
112
|
+
eventType: WebhookEventType.ComplianceDecision,
|
|
113
|
+
payload: { peopleId: 'ppl-1', decision: 'CLEARED', decidedAt: '2026-08-22T10:05:00.000Z' },
|
|
114
|
+
},
|
|
115
|
+
{ excludeExtraneousValues: true },
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect([account.eventType, compliance.eventType]).toEqual([
|
|
119
|
+
WebhookEventType.AccountIssuanceCompleted,
|
|
120
|
+
WebhookEventType.ComplianceDecision,
|
|
121
|
+
]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Cada variante fija el par (eventType, payload): el tipo de un evento con el payload de otro
|
|
125
|
+
// no compila. Sin el `@ts-expect-error` este archivo falla, que es el candado.
|
|
126
|
+
it('no acepta el eventType de un evento con el payload de otro', () => {
|
|
127
|
+
// @ts-expect-error un payload de AccountIssuanceCompletedV1 no viaja como ComplianceDecision
|
|
128
|
+
const mismatched: WebhookOutboundMessage = {
|
|
129
|
+
...validEnvelope,
|
|
130
|
+
eventType: WebhookEventType.ComplianceDecision,
|
|
131
|
+
payload: { peopleId: 'ppl-1', status: 'OPEN' } as unknown as AccountIssuanceCompletedV1,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
expect(mismatched.eventType).toBe(WebhookEventType.ComplianceDecision);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// La unión cubre TODO el catálogo. `WebhookOutboundMessage.ts` lo garantiza en compilación;
|
|
138
|
+
// esta lista lo vuelve a fallar en jest si alguien agrega un evento y no toca la unión.
|
|
139
|
+
it('cubre todos los eventos del catálogo', () => {
|
|
140
|
+
const covered: WebhookOutboundMessage['eventType'][] = [
|
|
141
|
+
WebhookEventType.AccountIssuanceCompleted,
|
|
142
|
+
WebhookEventType.ComplianceDecision,
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
expect(covered.sort()).toEqual(Object.values(WebhookEventType).sort());
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
AccountIssuanceCompletedV1,
|
|
6
|
+
ComplianceDecisionEnum,
|
|
7
|
+
ComplianceDecisionV1,
|
|
8
|
+
} from '../../../src/webhookBusiness/index';
|
|
9
|
+
import { AccountStatusEnum } from '../../../src/retailCustomer/enums/AccountStatusEnum';
|
|
10
|
+
|
|
11
|
+
const validCaseRef = 'case_01JCVK8ZQXW3NBTR7YHMD5EA2F';
|
|
12
|
+
|
|
13
|
+
describe('AccountIssuanceCompletedV1', () => {
|
|
14
|
+
it('valida el desenlace OPEN con nivel de cuenta', async () => {
|
|
15
|
+
const dto = plainToInstance(
|
|
16
|
+
AccountIssuanceCompletedV1,
|
|
17
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.OPEN, pcfAccountLevel: 2 },
|
|
18
|
+
{ excludeExtraneousValues: true },
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// El campo espeja `RetailCustomer.AccountResultRequest`, donde el receptor ya lo lee así.
|
|
25
|
+
it('descarta el nombre viejo accountLevel', () => {
|
|
26
|
+
const dto = plainToInstance(
|
|
27
|
+
AccountIssuanceCompletedV1,
|
|
28
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.OPEN, accountLevel: 2 },
|
|
29
|
+
{ excludeExtraneousValues: true },
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
expect(dto).not.toHaveProperty('accountLevel');
|
|
33
|
+
expect(dto.pcfAccountLevel).toBeUndefined();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('valida el desenlace FAILED con failReason', async () => {
|
|
37
|
+
const dto = plainToInstance(
|
|
38
|
+
AccountIssuanceCompletedV1,
|
|
39
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.FAILED, failReason: 'CURP duplicada en el core' },
|
|
40
|
+
{ excludeExtraneousValues: true },
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Texto libre del core que sale a un tercero: sin tope, un volcado del core viaja entero.
|
|
47
|
+
it('rechaza un failReason mas largo que el tope', async () => {
|
|
48
|
+
const dto = plainToInstance(
|
|
49
|
+
AccountIssuanceCompletedV1,
|
|
50
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.FAILED, failReason: 'x'.repeat(513) },
|
|
51
|
+
{ excludeExtraneousValues: true },
|
|
52
|
+
);
|
|
53
|
+
const errors = await validate(dto as object);
|
|
54
|
+
|
|
55
|
+
expect(errors.map((e) => e.property)).toContain('failReason');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('acepta un failReason en el tope exacto', async () => {
|
|
59
|
+
const dto = plainToInstance(
|
|
60
|
+
AccountIssuanceCompletedV1,
|
|
61
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.FAILED, failReason: 'x'.repeat(512) },
|
|
62
|
+
{ excludeExtraneousValues: true },
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Este evento reporta el desenlace, no el trámite en curso ni la cuenta preexistente.
|
|
69
|
+
it.each([AccountStatusEnum.OPENING, AccountStatusEnum.LINKED])('rechaza el status no terminal %s', async (status) => {
|
|
70
|
+
const dto = plainToInstance(
|
|
71
|
+
AccountIssuanceCompletedV1,
|
|
72
|
+
{ peopleId: 'ppl-1', status },
|
|
73
|
+
{ excludeExtraneousValues: true },
|
|
74
|
+
);
|
|
75
|
+
const errors = await validate(dto as object);
|
|
76
|
+
|
|
77
|
+
expect(errors.map((e) => e.property)).toContain('status');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('rechaza un peopleId vacío', async () => {
|
|
81
|
+
const dto = plainToInstance(
|
|
82
|
+
AccountIssuanceCompletedV1,
|
|
83
|
+
{ peopleId: '', status: AccountStatusEnum.OPEN },
|
|
84
|
+
{ excludeExtraneousValues: true },
|
|
85
|
+
);
|
|
86
|
+
const errors = await validate(dto as object);
|
|
87
|
+
|
|
88
|
+
expect(errors.map((e) => e.property)).toContain('peopleId');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('rechaza un pcfAccountLevel fuera de 1 y 2', async () => {
|
|
92
|
+
const dto = plainToInstance(
|
|
93
|
+
AccountIssuanceCompletedV1,
|
|
94
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.OPEN, pcfAccountLevel: 3 },
|
|
95
|
+
{ excludeExtraneousValues: true },
|
|
96
|
+
);
|
|
97
|
+
const errors = await validate(dto as object);
|
|
98
|
+
|
|
99
|
+
expect(errors.map((e) => e.property)).toContain('pcfAccountLevel');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// La CLABE no viaja en este evento: se resuelve por el Cliente 360, enmascarada.
|
|
103
|
+
it('descarta la CLABE si un productor la mete de contrabando', () => {
|
|
104
|
+
const dto = plainToInstance(
|
|
105
|
+
AccountIssuanceCompletedV1,
|
|
106
|
+
{ peopleId: 'ppl-1', status: AccountStatusEnum.OPEN, clabe: '646180000000000000' },
|
|
107
|
+
{ excludeExtraneousValues: true },
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
expect(dto).not.toHaveProperty('clabe');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('ComplianceDecisionV1', () => {
|
|
115
|
+
it.each([ComplianceDecisionEnum.CLEARED, ComplianceDecisionEnum.REJECTED])(
|
|
116
|
+
'valida el dictamen %s',
|
|
117
|
+
async (decision) => {
|
|
118
|
+
const dto = plainToInstance(
|
|
119
|
+
ComplianceDecisionV1,
|
|
120
|
+
{ peopleId: 'ppl-1', decision, decidedAt: '2026-08-22T10:05:00.000Z', caseRef: validCaseRef },
|
|
121
|
+
{ excludeExtraneousValues: true },
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
it('acepta el dictamen sin caseRef', async () => {
|
|
129
|
+
const dto = plainToInstance(
|
|
130
|
+
ComplianceDecisionV1,
|
|
131
|
+
{ peopleId: 'ppl-1', decision: ComplianceDecisionEnum.CLEARED, decidedAt: '2026-08-22T10:05:00.000Z' },
|
|
132
|
+
{ excludeExtraneousValues: true },
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// El prefijo `case_` es el guardrail: obliga a acuñar la referencia, no a reciclar un id de PLD.
|
|
139
|
+
it.each([
|
|
140
|
+
['un UUID crudo, que es la forma de un alertId', '3f2504e0-4f89-11d3-9a0c-0305e82c3301'],
|
|
141
|
+
['un alertId determinista', 'stuck-9f2b41c8'],
|
|
142
|
+
['el prefijo sin cuerpo ULID', 'case_1'],
|
|
143
|
+
['un ULID sin prefijo', '01JCVK8ZQXW3NBTR7YHMD5EA2F'],
|
|
144
|
+
['el prefijo con caracteres fuera de Crockford base32', 'case_01JCVK8ZQXW3NBTR7YHMD5EAIL'],
|
|
145
|
+
])('rechaza un caseRef que es %s', async (_caso, caseRef) => {
|
|
146
|
+
const dto = plainToInstance(
|
|
147
|
+
ComplianceDecisionV1,
|
|
148
|
+
{ peopleId: 'ppl-1', decision: ComplianceDecisionEnum.REJECTED, decidedAt: '2026-08-22T10:05:00.000Z', caseRef },
|
|
149
|
+
{ excludeExtraneousValues: true },
|
|
150
|
+
);
|
|
151
|
+
const errors = await validate(dto as object);
|
|
152
|
+
|
|
153
|
+
expect(errors.map((e) => e.property)).toContain('caseRef');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('rechaza un decidedAt que no es ISO-8601', async () => {
|
|
157
|
+
const dto = plainToInstance(
|
|
158
|
+
ComplianceDecisionV1,
|
|
159
|
+
{ peopleId: 'ppl-1', decision: ComplianceDecisionEnum.REJECTED, decidedAt: 'ayer' },
|
|
160
|
+
{ excludeExtraneousValues: true },
|
|
161
|
+
);
|
|
162
|
+
const errors = await validate(dto as object);
|
|
163
|
+
|
|
164
|
+
expect(errors.map((e) => e.property)).toContain('decidedAt');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('rechaza un dictamen fuera del enum', async () => {
|
|
168
|
+
const dto = plainToInstance(
|
|
169
|
+
ComplianceDecisionV1,
|
|
170
|
+
{ peopleId: 'ppl-1', decision: 'UNDER_REVIEW', decidedAt: '2026-08-22T10:05:00.000Z' },
|
|
171
|
+
{ excludeExtraneousValues: true },
|
|
172
|
+
);
|
|
173
|
+
const errors = await validate(dto as object);
|
|
174
|
+
|
|
175
|
+
expect(errors.map((e) => e.property)).toContain('decision');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Restricción legal: avisar de una coincidencia en listas es delito. Ninguno de estos campos
|
|
179
|
+
// puede sobrevivir a la deserialización, ni siquiera si el productor los manda.
|
|
180
|
+
it.each(['fiadoList', 'blackList', 'cnbv', 'reason', 'justification', 'by', 'reviewedBy', 'alertId'])(
|
|
181
|
+
'no deja pasar el campo prohibido %s',
|
|
182
|
+
(field) => {
|
|
183
|
+
const dto = plainToInstance(
|
|
184
|
+
ComplianceDecisionV1,
|
|
185
|
+
{
|
|
186
|
+
peopleId: 'ppl-1',
|
|
187
|
+
decision: ComplianceDecisionEnum.REJECTED,
|
|
188
|
+
decidedAt: '2026-08-22T10:05:00.000Z',
|
|
189
|
+
[field]: 'lo que sea',
|
|
190
|
+
},
|
|
191
|
+
{ excludeExtraneousValues: true },
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
expect(dto).not.toHaveProperty(field);
|
|
195
|
+
},
|
|
196
|
+
);
|
|
197
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validate } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
DeactivateWebhookSubscriptionRequest,
|
|
6
|
+
GetWebhookSubscriptionRequest,
|
|
7
|
+
UpsertWebhookSubscriptionRequest,
|
|
8
|
+
WebhookEventType,
|
|
9
|
+
} from '../../../src/webhookBusiness/index';
|
|
10
|
+
|
|
11
|
+
const validUpsert = {
|
|
12
|
+
tag: 'wh:acme',
|
|
13
|
+
eventType: WebhookEventType.AccountIssuanceCompleted,
|
|
14
|
+
subscriberName: 'ACME',
|
|
15
|
+
url: 'https://acme.example/webhooks/fiado',
|
|
16
|
+
visibility: 'PUBLIC',
|
|
17
|
+
status: 'ACTIVE',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// El `tag` es la misma llave en los tres contratos, así que lleva el mismo tope en los tres.
|
|
21
|
+
describe('tope del tag del padrón', () => {
|
|
22
|
+
const longTag = `wh:${'x'.repeat(130)}`;
|
|
23
|
+
|
|
24
|
+
it.each([
|
|
25
|
+
['UpsertWebhookSubscriptionRequest', UpsertWebhookSubscriptionRequest, validUpsert],
|
|
26
|
+
[
|
|
27
|
+
'DeactivateWebhookSubscriptionRequest',
|
|
28
|
+
DeactivateWebhookSubscriptionRequest,
|
|
29
|
+
{ tag: 'wh:acme', eventType: WebhookEventType.AccountIssuanceCompleted },
|
|
30
|
+
],
|
|
31
|
+
[
|
|
32
|
+
'GetWebhookSubscriptionRequest',
|
|
33
|
+
GetWebhookSubscriptionRequest,
|
|
34
|
+
{ tag: 'wh:acme', eventType: WebhookEventType.AccountIssuanceCompleted },
|
|
35
|
+
],
|
|
36
|
+
])('%s rechaza un tag mas largo que el tope', async (_name, cls, valid) => {
|
|
37
|
+
const dto = plainToInstance(cls, { ...valid, tag: longTag }, { excludeExtraneousValues: true });
|
|
38
|
+
const errors = await validate(dto as object);
|
|
39
|
+
|
|
40
|
+
expect(errors.map((e) => e.property)).toContain('tag');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it.each([
|
|
44
|
+
['UpsertWebhookSubscriptionRequest', UpsertWebhookSubscriptionRequest, validUpsert],
|
|
45
|
+
[
|
|
46
|
+
'DeactivateWebhookSubscriptionRequest',
|
|
47
|
+
DeactivateWebhookSubscriptionRequest,
|
|
48
|
+
{ tag: 'wh:acme', eventType: WebhookEventType.AccountIssuanceCompleted },
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
'GetWebhookSubscriptionRequest',
|
|
52
|
+
GetWebhookSubscriptionRequest,
|
|
53
|
+
{ tag: 'wh:acme', eventType: WebhookEventType.AccountIssuanceCompleted },
|
|
54
|
+
],
|
|
55
|
+
])('%s acepta un tag dentro del tope', async (_name, cls, valid) => {
|
|
56
|
+
const dto = plainToInstance(cls, valid, { excludeExtraneousValues: true });
|
|
57
|
+
|
|
58
|
+
expect(await validate(dto as object)).toHaveLength(0);
|
|
59
|
+
});
|
|
60
|
+
});
|
package/bin/index.d.ts
CHANGED
package/bin/index.js
CHANGED
|
@@ -38,7 +38,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.IssuanceBusiness = exports.Blacklist = exports.CentralPayments = exports.Helpdesk = exports.FiadoApiResponse = exports.Auth = exports.LegalDocumentsBusiness = exports.Role = exports.STPAccount = exports.RiskProfile = exports.FraudPreventionEngine = exports.BBVARst = exports.Stp = exports.BenefitCenter = exports.BankAccount = exports.P2pContact = exports.CreditContract = exports.Contract = exports.ProductCatalog = exports.ContactInfo = exports.TransactionAnalytics = exports.Transaction = exports.TransactionProcessor = exports.GenericMessage = exports.EventBridgeMessage = exports.SessionActivity = exports.NotificationMessages = exports.ServicePayment = exports.Header = exports.Identity = exports.UserTags = exports.Group = exports.File = exports.ExchangeRate = exports.Directory = exports.Currency = exports.Country = exports.Card = exports.Authentication = exports.AppContent = exports.App = exports.Offices = exports.Places = exports.Address = exports.Beneficiary = exports.Activity = exports.Biometrics = exports.MetamapConnector = exports.Account = exports.Crypto = void 0;
|
|
40
40
|
exports.LoanConfig = exports.DatalakeQuery = exports.RetailWizard = exports.RetailCustomer = exports.RetailCards = exports.RetailCatalog = exports.RetailCommission = exports.RetailOrg = exports.EmailVerification = exports.NetworkConnector = exports.Modelias = exports.TotpSecurity = exports.Passport = exports.WalletFunding = exports.Remittance = exports.PlatformRbac = exports.CognitoBackofficeConnector = exports.TwilioConnector = exports.MessagesConnector = exports.Mdm = exports.MilestoneBusiness = exports.CirculoCredito = exports.CreditStatements = exports.Sentry = exports.AiEngine = exports.Funnel = exports.TeamsConnector = exports.PlatformErrorEvents = exports.CustomerFile = exports.CreditBackoffice = exports.CreditDashboard = exports.CreditEngine = exports.Credit = exports.ComissionBusiness = exports.ReferralBusiness = exports.ZendeskMessaging = exports.NotificationWS = exports.Event = exports.PayrollBusiness = exports.Cnbv = exports.DirectorySetting = exports.InvoiceCollector = exports.Collector = exports.Pricelist = exports.Company = exports.Services = exports.AccountIssuanceBusiness = exports.AppSelectionData = exports.Device = exports.Observations = void 0;
|
|
41
|
-
exports.PeopleBusiness = exports.UserConfirmations = exports.Collection = exports.Shipping = exports.PhoneSales = exports.Onboarding = exports.Kyc = exports.LoanScoring = exports.LoanCredit = exports.LoanCollectorAssignment = exports.LoanOfferings = exports.Shortlink = void 0;
|
|
41
|
+
exports.WebhookBusiness = exports.PeopleBusiness = exports.UserConfirmations = exports.Collection = exports.Shipping = exports.PhoneSales = exports.Onboarding = exports.Kyc = exports.LoanScoring = exports.LoanCredit = exports.LoanCollectorAssignment = exports.LoanOfferings = exports.Shortlink = void 0;
|
|
42
42
|
exports.Crypto = __importStar(require("./crypto"));
|
|
43
43
|
exports.Account = __importStar(require("./account"));
|
|
44
44
|
exports.MetamapConnector = __importStar(require("./metamapConnector"));
|
|
@@ -209,3 +209,7 @@ exports.Collection = __importStar(require("./collection"));
|
|
|
209
209
|
exports.UserConfirmations = __importStar(require("./userConfirmations"));
|
|
210
210
|
// PeopleBusiness: contrato de lectura por lote de People_GT + AccountRequirementControl_GT.
|
|
211
211
|
exports.PeopleBusiness = __importStar(require("./peopleBusiness"));
|
|
212
|
+
// WebhookBusiness: contrato de la cola del lambda webhook-business — entrega de eventos de Fiado a
|
|
213
|
+
// suscriptores externos. Sobre común `WebhookEventEnvelope<T>` + los dos eventos del corte 1.
|
|
214
|
+
// El evento del oficial de cumplimiento NO dice sobre qué se dictaminó (restricción legal).
|
|
215
|
+
exports.WebhookBusiness = __importStar(require("./webhookBusiness"));
|
|
@@ -64,6 +64,6 @@ var ProductSubtypeEnum;
|
|
|
64
64
|
ProductSubtypeEnum["CREDIT_DISBURSEMENT"] = "DISBURSEMENT";
|
|
65
65
|
// EQ_CASH_SA (Equality/Passport — depósito en efectivo en tiendas afiliadas)
|
|
66
66
|
ProductSubtypeEnum["EQ_CASH_SA_CASH_IN"] = "CASH_IN";
|
|
67
|
-
//
|
|
68
|
-
ProductSubtypeEnum["
|
|
67
|
+
//SUREKEEP
|
|
68
|
+
ProductSubtypeEnum["SUREKEEP_BONUS_MX"] = "BONUS_MX";
|
|
69
69
|
})(ProductSubtypeEnum || (exports.ProductSubtypeEnum = ProductSubtypeEnum = {}));
|
|
@@ -19,9 +19,9 @@ export declare enum ProductTypeEnum {
|
|
|
19
19
|
*/
|
|
20
20
|
EQ_CASH_SA = "EQ_CASH_SA",
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* Categoría de las transacciones de SureKeep. Agrupa; el motivo va en el subtipo. Deliberadamente
|
|
23
|
+
* FUERA del switch de `CreateTransactionManager`: el camino por defecto es el que escribe el par
|
|
24
|
+
* de asientos FiadoTx + PagoConFiadoTx.
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
SUREKEEP = "SUREKEEP"
|
|
27
27
|
}
|
|
@@ -23,9 +23,9 @@ var ProductTypeEnum;
|
|
|
23
23
|
*/
|
|
24
24
|
ProductTypeEnum["EQ_CASH_SA"] = "EQ_CASH_SA";
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* Categoría de las transacciones de SureKeep. Agrupa; el motivo va en el subtipo. Deliberadamente
|
|
27
|
+
* FUERA del switch de `CreateTransactionManager`: el camino por defecto es el que escribe el par
|
|
28
|
+
* de asientos FiadoTx + PagoConFiadoTx.
|
|
29
29
|
*/
|
|
30
|
-
ProductTypeEnum["
|
|
30
|
+
ProductTypeEnum["SUREKEEP"] = "SUREKEEP";
|
|
31
31
|
})(ProductTypeEnum || (exports.ProductTypeEnum = ProductTypeEnum = {}));
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Acreditación de un bono
|
|
2
|
+
* Acreditación de un bono a la wallet PagoConfiado de una persona.
|
|
3
3
|
*
|
|
4
4
|
* NO lleva `operation`: un bono solo suma, y el servicio hardcodea `ADD`. Con el campo en el
|
|
5
5
|
* request, un caller equivocado debitaría la wallet con el producto del bono.
|
|
6
6
|
*
|
|
7
7
|
* NO lleva `peopleId`: `initialize()` lo resuelve desde el directorio y pisa cualquier valor.
|
|
8
8
|
*/
|
|
9
|
-
export declare class
|
|
9
|
+
export declare class AuthorizeBonusRequest {
|
|
10
10
|
/** Es el `bonusId` del asiento: única por intento, para que un reintento real vuelva a ejecutar. */
|
|
11
11
|
idempotencyKey: string;
|
|
12
12
|
productCatalogId: string;
|
|
@@ -16,4 +16,4 @@ export declare class AuthorizeWelcomeBonusRequest {
|
|
|
16
16
|
/** Lo que el cliente ve como descripción de su movimiento. */
|
|
17
17
|
concept: string;
|
|
18
18
|
}
|
|
19
|
-
export default
|
|
19
|
+
export default AuthorizeBonusRequest;
|
package/bin/transactionProcessor/dtos/{AuthorizeWelcomeBonusRequest.js → AuthorizeBonusRequest.js}
RENAMED
|
@@ -9,42 +9,42 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.AuthorizeBonusRequest = void 0;
|
|
13
13
|
const class_validator_1 = require("class-validator");
|
|
14
14
|
/**
|
|
15
|
-
* Acreditación de un bono
|
|
15
|
+
* Acreditación de un bono a la wallet PagoConfiado de una persona.
|
|
16
16
|
*
|
|
17
17
|
* NO lleva `operation`: un bono solo suma, y el servicio hardcodea `ADD`. Con el campo en el
|
|
18
18
|
* request, un caller equivocado debitaría la wallet con el producto del bono.
|
|
19
19
|
*
|
|
20
20
|
* NO lleva `peopleId`: `initialize()` lo resuelve desde el directorio y pisa cualquier valor.
|
|
21
21
|
*/
|
|
22
|
-
class
|
|
22
|
+
class AuthorizeBonusRequest {
|
|
23
23
|
}
|
|
24
|
-
exports.
|
|
24
|
+
exports.AuthorizeBonusRequest = AuthorizeBonusRequest;
|
|
25
25
|
__decorate([
|
|
26
26
|
(0, class_validator_1.IsString)(),
|
|
27
27
|
(0, class_validator_1.IsNotEmpty)(),
|
|
28
28
|
__metadata("design:type", String)
|
|
29
|
-
],
|
|
29
|
+
], AuthorizeBonusRequest.prototype, "idempotencyKey", void 0);
|
|
30
30
|
__decorate([
|
|
31
31
|
(0, class_validator_1.IsString)(),
|
|
32
32
|
(0, class_validator_1.IsNotEmpty)(),
|
|
33
33
|
__metadata("design:type", String)
|
|
34
|
-
],
|
|
34
|
+
], AuthorizeBonusRequest.prototype, "productCatalogId", void 0);
|
|
35
35
|
__decorate([
|
|
36
36
|
(0, class_validator_1.IsNumber)(),
|
|
37
37
|
(0, class_validator_1.IsPositive)(),
|
|
38
38
|
__metadata("design:type", Number)
|
|
39
|
-
],
|
|
39
|
+
], AuthorizeBonusRequest.prototype, "amount", void 0);
|
|
40
40
|
__decorate([
|
|
41
41
|
(0, class_validator_1.IsString)(),
|
|
42
42
|
(0, class_validator_1.IsNotEmpty)(),
|
|
43
43
|
__metadata("design:type", String)
|
|
44
|
-
],
|
|
44
|
+
], AuthorizeBonusRequest.prototype, "directoryId", void 0);
|
|
45
45
|
__decorate([
|
|
46
46
|
(0, class_validator_1.IsString)(),
|
|
47
47
|
(0, class_validator_1.MaxLength)(120),
|
|
48
48
|
__metadata("design:type", String)
|
|
49
|
-
],
|
|
50
|
-
exports.default =
|
|
49
|
+
], AuthorizeBonusRequest.prototype, "concept", void 0);
|
|
50
|
+
exports.default = AuthorizeBonusRequest;
|
|
@@ -10,7 +10,7 @@ export * from './dtos/AuthorizeSpeiMexBankTransferInRequest';
|
|
|
10
10
|
export * from './dtos/AuthorizeSpeiBankTransferNcRequest';
|
|
11
11
|
export * from './dtos/AuthorizeCollectorTransactionRequest';
|
|
12
12
|
export * from './dtos/AuthorizeDisputeTransactionRequest';
|
|
13
|
-
export * from './dtos/
|
|
13
|
+
export * from './dtos/AuthorizeBonusRequest';
|
|
14
14
|
export * from './dtos/CardInfo';
|
|
15
15
|
export * from './dtos/InstallmentsInfo';
|
|
16
16
|
export * from './dtos/MerchantInfo';
|
|
@@ -26,7 +26,7 @@ __exportStar(require("./dtos/AuthorizeSpeiMexBankTransferInRequest"), exports);
|
|
|
26
26
|
__exportStar(require("./dtos/AuthorizeSpeiBankTransferNcRequest"), exports);
|
|
27
27
|
__exportStar(require("./dtos/AuthorizeCollectorTransactionRequest"), exports);
|
|
28
28
|
__exportStar(require("./dtos/AuthorizeDisputeTransactionRequest"), exports);
|
|
29
|
-
__exportStar(require("./dtos/
|
|
29
|
+
__exportStar(require("./dtos/AuthorizeBonusRequest"), exports);
|
|
30
30
|
__exportStar(require("./dtos/CardInfo"), exports);
|
|
31
31
|
__exportStar(require("./dtos/InstallmentsInfo"), exports);
|
|
32
32
|
__exportStar(require("./dtos/MerchantInfo"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formato de `caseRef`: prefijo `case_` más un ULID de 26 caracteres en Crockford base32, el mismo
|
|
3
|
+
* cuerpo que `CREDIT_ID_PATTERN`. El prefijo obliga a acuñar la referencia para el webhook, así que
|
|
4
|
+
* un `alertId` de PLD (UUID crudo o `stuck-<id>`) no lo satisface y no puede colarse.
|
|
5
|
+
*/
|
|
6
|
+
export declare const WEBHOOK_CASE_REF_PATTERN: RegExp;
|
|
7
|
+
/** Mensaje único, para que el productor no tenga que adivinar el formato. */
|
|
8
|
+
export declare const WEBHOOK_CASE_REF_MESSAGE = "caseRef debe ser case_ seguido de un ULID de 26 caracteres";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WEBHOOK_CASE_REF_MESSAGE = exports.WEBHOOK_CASE_REF_PATTERN = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Formato de `caseRef`: prefijo `case_` más un ULID de 26 caracteres en Crockford base32, el mismo
|
|
6
|
+
* cuerpo que `CREDIT_ID_PATTERN`. El prefijo obliga a acuñar la referencia para el webhook, así que
|
|
7
|
+
* un `alertId` de PLD (UUID crudo o `stuck-<id>`) no lo satisface y no puede colarse.
|
|
8
|
+
*/
|
|
9
|
+
exports.WEBHOOK_CASE_REF_PATTERN = /^case_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
|
|
10
|
+
/** Mensaje único, para que el productor no tenga que adivinar el formato. */
|
|
11
|
+
exports.WEBHOOK_CASE_REF_MESSAGE = 'caseRef debe ser case_ seguido de un ULID de 26 caracteres';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Tope del `tag` del padrón, común a los tres contratos que lo llevan. */
|
|
2
|
+
export declare const WEBHOOK_TAG_MAX_LENGTH = 128;
|
|
3
|
+
/** Tope del `eventId`, común al sobre de la cola y al request de reposición. */
|
|
4
|
+
export declare const WEBHOOK_EVENT_ID_MAX_LENGTH = 128;
|
|
5
|
+
/** Tope del `failReason` del core, que sale sin transformar hacia un receptor externo. */
|
|
6
|
+
export declare const WEBHOOK_FAIL_REASON_MAX_LENGTH = 512;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WEBHOOK_FAIL_REASON_MAX_LENGTH = exports.WEBHOOK_EVENT_ID_MAX_LENGTH = exports.WEBHOOK_TAG_MAX_LENGTH = void 0;
|
|
4
|
+
/** Tope del `tag` del padrón, común a los tres contratos que lo llevan. */
|
|
5
|
+
exports.WEBHOOK_TAG_MAX_LENGTH = 128;
|
|
6
|
+
/** Tope del `eventId`, común al sobre de la cola y al request de reposición. */
|
|
7
|
+
exports.WEBHOOK_EVENT_ID_MAX_LENGTH = 128;
|
|
8
|
+
/** Tope del `failReason` del core, que sale sin transformar hacia un receptor externo. */
|
|
9
|
+
exports.WEBHOOK_FAIL_REASON_MAX_LENGTH = 512;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { WebhookEventType } from '../enums/WebhookEventType';
|
|
2
|
+
import type { DeliveryOutcomeEnum } from '../enums/DeliveryOutcomeEnum';
|
|
3
|
+
import type { SubscriptionVisibilityEnum } from '../enums/SubscriptionVisibilityEnum';
|
|
4
|
+
/**
|
|
5
|
+
* Un asiento de la bitácora de entregas: qué evento salió, a quién y cómo terminó.
|
|
6
|
+
* Nunca lleva el payload del evento, sólo identificadores operacionales y el desenlace.
|
|
7
|
+
*/
|
|
8
|
+
export interface WebhookDeliveryView {
|
|
9
|
+
eventId: string;
|
|
10
|
+
eventType: WebhookEventType;
|
|
11
|
+
/** Lambda que produjo el evento. */
|
|
12
|
+
source: string;
|
|
13
|
+
directoryId: string;
|
|
14
|
+
occurredAt: string;
|
|
15
|
+
outcome: DeliveryOutcomeEnum;
|
|
16
|
+
tag?: string;
|
|
17
|
+
subscriberName?: string;
|
|
18
|
+
visibility?: SubscriptionVisibilityEnum;
|
|
19
|
+
url?: string;
|
|
20
|
+
attempt?: number;
|
|
21
|
+
/** Status con el que respondió el receptor. Ausente si nunca hubo respuesta. */
|
|
22
|
+
receiverHttpStatus?: number;
|
|
23
|
+
errorCode?: string;
|
|
24
|
+
/** Motivo del fallo, recortado. Nunca la respuesta entera del receptor. */
|
|
25
|
+
failureReason?: string;
|
|
26
|
+
latencyMs?: number;
|
|
27
|
+
createdAt?: number;
|
|
28
|
+
}
|