@fiado/type-kit 3.584.0 → 3.586.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_test_/unit/collection/disburseRequest.test.ts +10 -0
- package/_test_/unit/collection/disbursementType.test.ts +7 -2
- package/_test_/unit/platformRbac/dtos/UpdateTenantUserEmailRequest.test.ts +24 -0
- package/_test_/unit/platformRbac/enums/__snapshots__/permissionBits.test.ts.snap +2 -1
- package/_test_/unit/platformRbac/enums/apiUserPermission.test.ts +3 -2
- package/_test_/unit/platformRbac/enums/retailIntegrationPermission.test.ts +13 -0
- package/_test_/unit/productCatalog/rewardEnums.test.ts +19 -0
- package/_test_/unit/retailIntegration/reconciliationContracts.test.ts +3 -3
- package/_test_/unit/retailIntegration/retailMovementsContracts.test.ts +109 -0
- package/_test_/unit/retailIntegration/retailSystemResponses.test.ts +120 -0
- package/_test_/unit/rewards/enums.test.ts +1 -1
- package/_test_/unit/rewards/waitingLimit.test.ts +43 -0
- package/bin/collection/enums/DisbursementType.d.ts +3 -1
- package/bin/collection/enums/DisbursementType.js +2 -0
- package/bin/platformRbac/dtos/CreateTenantUserRequest.d.ts +2 -1
- package/bin/platformRbac/dtos/CreateTenantUserRequest.js +2 -1
- package/bin/platformRbac/dtos/UpdateTenantUserEmailRequest.d.ts +5 -0
- package/bin/platformRbac/dtos/UpdateTenantUserEmailRequest.js +30 -0
- package/bin/platformRbac/enums/Permission.d.ts +2 -1
- package/bin/platformRbac/enums/Permission.js +3 -0
- package/bin/platformRbac/index.d.ts +1 -0
- package/bin/platformRbac/index.js +1 -0
- package/bin/productCatalog/enums/ProductSubtypeEnum.d.ts +1 -0
- package/bin/productCatalog/enums/ProductSubtypeEnum.js +3 -0
- package/bin/productCatalog/enums/ProductTypeEnum.d.ts +3 -1
- package/bin/productCatalog/enums/ProductTypeEnum.js +2 -0
- package/bin/retailIntegration/constants/retailIntegrationLimits.d.ts +11 -0
- package/bin/retailIntegration/constants/retailIntegrationLimits.js +12 -1
- package/bin/retailIntegration/dtos/CheckRetailInventoryRequest.d.ts +4 -1
- package/bin/retailIntegration/dtos/CheckRetailInventoryRequest.js +4 -1
- package/bin/retailIntegration/dtos/GetRetailInventoryRequest.d.ts +3 -3
- package/bin/retailIntegration/dtos/GetRetailInventoryRequest.js +3 -3
- package/bin/retailIntegration/dtos/ListRetailInventoryMovementsRequest.d.ts +6 -0
- package/bin/retailIntegration/dtos/ListRetailInventoryMovementsRequest.js +29 -0
- package/bin/retailIntegration/dtos/ReconciliationPageMessage.d.ts +6 -0
- package/bin/retailIntegration/dtos/ReconciliationPageMessage.js +20 -0
- package/bin/retailIntegration/dtos/RetailOutboundResponses.d.ts +10 -2
- package/bin/retailIntegration/dtos/RetailSystemResponses.d.ts +41 -0
- package/bin/retailIntegration/dtos/RetailSystemResponses.js +136 -0
- package/bin/retailIntegration/enums/ReconciliationEntityEnum.d.ts +2 -1
- package/bin/retailIntegration/enums/ReconciliationEntityEnum.js +1 -0
- package/bin/retailIntegration/enums/ReconciliationTriggerEnum.d.ts +4 -2
- package/bin/retailIntegration/enums/ReconciliationTriggerEnum.js +3 -1
- package/bin/retailIntegration/index.d.ts +3 -0
- package/bin/retailIntegration/index.js +3 -0
- package/bin/retailIntegration/models/RetailPageMeta.d.ts +3 -1
- package/bin/retailIntegration/models/RetailSystemInventory.d.ts +9 -1
- package/bin/retailIntegration/validators/IsMovementsRangeValid.d.ts +6 -0
- package/bin/retailIntegration/validators/IsMovementsRangeValid.js +28 -0
- package/bin/rewards/dtos/backoffice/BackofficeGrantItemResponse.d.ts +9 -0
- package/bin/rewards/enums/GrantItemStatusEnum.d.ts +2 -0
- package/bin/rewards/enums/GrantItemStatusEnum.js +2 -0
- package/bin/rewards/enums/LimitWaitReasonEnum.d.ts +7 -0
- package/bin/rewards/enums/LimitWaitReasonEnum.js +11 -0
- package/bin/rewards/enums/RewardItemCodeEnum.d.ts +9 -0
- package/bin/rewards/enums/RewardItemCodeEnum.js +13 -0
- package/bin/rewards/index.d.ts +2 -0
- package/bin/rewards/index.js +2 -0
- package/package.json +1 -1
- package/src/collection/enums/DisbursementType.ts +2 -0
- package/src/platformRbac/dtos/CreateTenantUserRequest.ts +2 -1
- package/src/platformRbac/dtos/UpdateTenantUserEmailRequest.ts +12 -0
- package/src/platformRbac/enums/Permission.ts +3 -0
- package/src/platformRbac/index.ts +1 -0
- package/src/productCatalog/enums/ProductSubtypeEnum.ts +4 -0
- package/src/productCatalog/enums/ProductTypeEnum.ts +3 -1
- package/src/retailIntegration/constants/retailIntegrationLimits.ts +16 -0
- package/src/retailIntegration/dtos/CheckRetailInventoryRequest.ts +4 -1
- package/src/retailIntegration/dtos/GetRetailInventoryRequest.ts +3 -3
- package/src/retailIntegration/dtos/ListRetailInventoryMovementsRequest.ts +14 -0
- package/src/retailIntegration/dtos/ReconciliationPageMessage.ts +21 -1
- package/src/retailIntegration/dtos/RetailOutboundResponses.ts +11 -2
- package/src/retailIntegration/dtos/RetailSystemResponses.ts +75 -0
- package/src/retailIntegration/enums/ReconciliationEntityEnum.ts +1 -0
- package/src/retailIntegration/enums/ReconciliationTriggerEnum.ts +3 -1
- package/src/retailIntegration/index.ts +3 -0
- package/src/retailIntegration/models/RetailPageMeta.ts +3 -1
- package/src/retailIntegration/models/RetailSystemInventory.ts +10 -1
- package/src/retailIntegration/validators/IsMovementsRangeValid.ts +17 -0
- package/src/rewards/dtos/backoffice/BackofficeGrantItemResponse.ts +9 -0
- package/src/rewards/enums/GrantItemStatusEnum.ts +2 -0
- package/src/rewards/enums/LimitWaitReasonEnum.ts +7 -0
- package/src/rewards/enums/RewardItemCodeEnum.ts +9 -0
- package/src/rewards/index.ts +2 -0
|
@@ -26,6 +26,16 @@ describe('DisburseRequest', () => {
|
|
|
26
26
|
expect(await invalidProperties(VALID)).toEqual([]);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
it('acepta disbursementType MEX_REWARD', async () => {
|
|
30
|
+
expect(await invalidProperties({ ...VALID, disbursementType: 'MEX_REWARD' })).toEqual([]);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('acepta una idempotencyKey de 80 caracteres (sin límite de largo)', async () => {
|
|
34
|
+
const key = ('RW-' + 'a'.repeat(32) + '-' + 'k'.repeat(28) + '-12').padEnd(80, 'x');
|
|
35
|
+
expect(key).toHaveLength(80);
|
|
36
|
+
expect(await invalidProperties({ ...VALID, disbursementType: 'MEX_REWARD', idempotencyKey: key })).toEqual([]);
|
|
37
|
+
});
|
|
38
|
+
|
|
29
39
|
it('reference es opcional', async () => {
|
|
30
40
|
const { reference: _omit, ...withoutReference } = VALID;
|
|
31
41
|
expect(await invalidProperties(withoutReference)).toEqual([]);
|
|
@@ -3,8 +3,12 @@ import { Collection } from '../../../src/index';
|
|
|
3
3
|
import { DisbursementType } from '../../../src/collection/index';
|
|
4
4
|
|
|
5
5
|
describe('DisbursementType', () => {
|
|
6
|
-
it('trae los productos de bono
|
|
7
|
-
expect(Object.values(DisbursementType)).toEqual(['MEX_BONUS', 'MEX_SELLER_COMMISSION']);
|
|
6
|
+
it('trae los productos de bono, comisión de vendedor y recompensa', () => {
|
|
7
|
+
expect(Object.values(DisbursementType)).toEqual(['MEX_BONUS', 'MEX_SELLER_COMMISSION', 'MEX_REWARD']);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('MEX_REWARD vale MEX_REWARD', () => {
|
|
11
|
+
expect(DisbursementType.MEX_REWARD).toBe('MEX_REWARD');
|
|
8
12
|
});
|
|
9
13
|
|
|
10
14
|
it('cada clave es igual a su valor', () => {
|
|
@@ -16,5 +20,6 @@ describe('DisbursementType', () => {
|
|
|
16
20
|
it('sale por el index raíz', () => {
|
|
17
21
|
expect(Collection.DisbursementType.MEX_BONUS).toBe('MEX_BONUS');
|
|
18
22
|
expect(Collection.DisbursementType.MEX_SELLER_COMMISSION).toBe('MEX_SELLER_COMMISSION');
|
|
23
|
+
expect(Collection.DisbursementType.MEX_REWARD).toBe('MEX_REWARD');
|
|
19
24
|
});
|
|
20
25
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
import { UpdateTenantUserEmailRequest } from '../../../../src/platformRbac';
|
|
5
|
+
|
|
6
|
+
function propsWithErrors(payload: object): string[] {
|
|
7
|
+
return validateSync(plainToInstance(UpdateTenantUserEmailRequest, payload)).map((e) => e.property);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
describe('UpdateTenantUserEmailRequest', () => {
|
|
11
|
+
it('normaliza el correo a minúsculas sin espacios', () => {
|
|
12
|
+
const dto = plainToInstance(UpdateTenantUserEmailRequest, { email: ' Ana.Perez@Example.COM ', actedBy: 'retail-org-business' });
|
|
13
|
+
expect(dto.email).toBe('ana.perez@example.com');
|
|
14
|
+
expect(validateSync(dto)).toEqual([]);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it.each([undefined, '', 'no-es-correo', 42])('rechaza email=%p', (email) => {
|
|
18
|
+
expect(propsWithErrors({ email, actedBy: 'retail-org-business' })).toEqual(['email']);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it.each([undefined, '', 7])('rechaza actedBy=%p', (actedBy) => {
|
|
22
|
+
expect(propsWithErrors({ email: 'ana@example.com', actedBy })).toEqual(['actedBy']);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
2
2
|
|
|
3
|
-
exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `
|
|
3
|
+
exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `1071810597`;
|
|
4
4
|
|
|
5
5
|
exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción) 1`] = `
|
|
6
6
|
[
|
|
@@ -96,5 +96,6 @@ exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe an
|
|
|
96
96
|
"platform.integration.key.revoke",
|
|
97
97
|
"tenant.integration.diagnostic",
|
|
98
98
|
"tenant.api_user.manage",
|
|
99
|
+
"platform.retail_integration.activate",
|
|
99
100
|
]
|
|
100
101
|
`;
|
|
@@ -5,7 +5,8 @@ describe('Permiso de administración de usuarios de API', () => {
|
|
|
5
5
|
expect(Permission.TENANT_API_USER_MANAGE).toBe('tenant.api_user.manage');
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
it('
|
|
9
|
-
|
|
8
|
+
it('conserva su bit después de las integraciones M2M (append-only)', () => {
|
|
9
|
+
const index = PERMISSION_BIT_ORDER.indexOf(Permission.TENANT_API_USER_MANAGE);
|
|
10
|
+
expect(PERMISSION_BIT_ORDER[index - 1]).toBe(Permission.TENANT_INTEGRATION_DIAGNOSTIC);
|
|
10
11
|
});
|
|
11
12
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Permission, PERMISSION_BIT_ORDER } from '../../../../src/platformRbac/enums/Permission';
|
|
2
|
+
|
|
3
|
+
describe('Permiso de activación de la integración retail', () => {
|
|
4
|
+
it('existe con la llave platform.retail_integration.activate (scope PLATFORM)', () => {
|
|
5
|
+
expect(Permission.PLATFORM_RETAIL_INTEGRATION_ACTIVATE).toBe('platform.retail_integration.activate');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it('va al FINAL del orden de bits, justo después de tenant.api_user.manage', () => {
|
|
9
|
+
const last = PERMISSION_BIT_ORDER.length - 1;
|
|
10
|
+
expect(PERMISSION_BIT_ORDER[last]).toBe(Permission.PLATFORM_RETAIL_INTEGRATION_ACTIVATE);
|
|
11
|
+
expect(PERMISSION_BIT_ORDER[last - 1]).toBe(Permission.TENANT_API_USER_MANAGE);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ProductSubtypeEnum } from '../../../src/productCatalog/enums/ProductSubtypeEnum';
|
|
2
|
+
import { ProductTypeEnum } from '../../../src/productCatalog/enums/ProductTypeEnum';
|
|
3
|
+
|
|
4
|
+
describe('enums de recompensas del catálogo de productos', () => {
|
|
5
|
+
it('ProductSubtypeEnum.REWARD_MX vale "REWARD_MX"', () => {
|
|
6
|
+
expect(ProductSubtypeEnum.REWARD_MX).toBe('REWARD_MX');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('ProductTypeEnum.REWARDS vale "REWARDS"', () => {
|
|
10
|
+
expect(ProductTypeEnum.REWARDS).toBe('REWARDS');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('ningún otro miembro de ProductSubtypeEnum vale "REWARD_MX"', () => {
|
|
14
|
+
const colisiones = Object.entries(ProductSubtypeEnum).filter(
|
|
15
|
+
([key, value]) => key !== 'REWARD_MX' && value === 'REWARD_MX',
|
|
16
|
+
);
|
|
17
|
+
expect(colisiones).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -20,8 +20,8 @@ function propsWithErrors<T extends object>(cls: ClassConstructor<T>, payload: ob
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
describe('enums de la revisión', () => {
|
|
23
|
-
it('ReconciliationEntityEnum trae las
|
|
24
|
-
expect(Object.values(ReconciliationEntityEnum)).toEqual(['STORES', 'USERS', 'CATALOG', 'INVENTORY']);
|
|
23
|
+
it('ReconciliationEntityEnum trae las cinco entidades', () => {
|
|
24
|
+
expect(Object.values(ReconciliationEntityEnum)).toEqual(['STORES', 'USERS', 'CATALOG', 'INVENTORY', 'MOVEMENTS']);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('ReconciliationRunStatusEnum trae los cuatro estados de la corrida', () => {
|
|
@@ -29,7 +29,7 @@ describe('enums de la revisión', () => {
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
it('ReconciliationTriggerEnum distingue el reloj del botón', () => {
|
|
32
|
-
expect(Object.values(ReconciliationTriggerEnum)).toEqual(['SCHEDULED', 'MANUAL', 'ACTIVATION']);
|
|
32
|
+
expect(Object.values(ReconciliationTriggerEnum)).toEqual(['SCHEDULED', 'MANUAL', 'ACTIVATION', 'DISCREPANCY', 'DAILY']);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
it('InactiveReasonEnum distingue la baja de la revisión de la del evento', () => {
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance, type ClassConstructor } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
GetRetailInventoryRequest,
|
|
6
|
+
type GetRetailInventoryResponse,
|
|
7
|
+
ListRetailInventoryMovementsRequest,
|
|
8
|
+
type ListRetailInventoryMovementsResponse,
|
|
9
|
+
ReconciliationEntityEnum,
|
|
10
|
+
ReconciliationPageMessage,
|
|
11
|
+
ReconciliationTriggerEnum,
|
|
12
|
+
} from '../../../src/retailIntegration';
|
|
13
|
+
|
|
14
|
+
function propsWithErrors<T extends object>(cls: ClassConstructor<T>, payload: object): string[] {
|
|
15
|
+
return validateSync(plainToInstance(cls, payload)).map((e) => e.property);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const tenant = { tenantId: 'surekeep', retailerId: 'ret-1' };
|
|
19
|
+
|
|
20
|
+
describe('ListRetailInventoryMovementsRequest', () => {
|
|
21
|
+
const valid = { ...tenant, from: '2026-08-17T19:55:00Z', to: '2026-08-17T21:00:00Z' };
|
|
22
|
+
|
|
23
|
+
it('acepta el rango con y sin paginación', () => {
|
|
24
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, valid)).toEqual([]);
|
|
25
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, { ...valid, limit: '200', nextToken: 'abc', runId: 'run-1' })).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('acepta un rango de 7 días exactos', () => {
|
|
29
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, { ...tenant, from: '2026-08-10T00:00:00Z', to: '2026-08-17T00:00:00Z' })).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it.each([
|
|
33
|
+
['to igual a from', '2026-08-17T20:00:00Z', '2026-08-17T20:00:00Z'],
|
|
34
|
+
['to antes de from', '2026-08-17T20:00:00Z', '2026-08-17T19:00:00Z'],
|
|
35
|
+
['más de 7 días', '2026-08-10T00:00:00Z', '2026-08-17T00:00:01Z'],
|
|
36
|
+
])('rechaza %s', (_label, from, to) => {
|
|
37
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, { ...tenant, from, to })).toEqual(['to']);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it.each(['from', 'to'])('rechaza sin %s o con fecha sin zona', (field) => {
|
|
41
|
+
const payload: Record<string, unknown> = { ...valid };
|
|
42
|
+
delete payload[field];
|
|
43
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, payload)).toContain(field);
|
|
44
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, { ...valid, [field]: '2026-08-17T20:00:00' })).toContain(field);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it.each(['0', '201'])('rechaza limit=%p', (limit) => {
|
|
48
|
+
expect(propsWithErrors(ListRetailInventoryMovementsRequest, { ...valid, limit })).toEqual(['limit']);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('la respuesta trae items y meta de página', () => {
|
|
52
|
+
const response: ListRetailInventoryMovementsResponse = {
|
|
53
|
+
items: [
|
|
54
|
+
{
|
|
55
|
+
eventId: 'evt-1',
|
|
56
|
+
eventType: 'InventoryMovementV1',
|
|
57
|
+
occurredAt: '2026-08-17T20:32:07Z',
|
|
58
|
+
payload: { movementType: 'SALE', storeId: '12', targetStoreId: null, pieces: [], stock: [] },
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
meta: { count: 1, nextToken: null },
|
|
62
|
+
};
|
|
63
|
+
expect(response.meta.nextToken).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('GetRetailInventoryRequest paginado', () => {
|
|
68
|
+
it('acepta limit y nextToken opcionales', () => {
|
|
69
|
+
expect(propsWithErrors(GetRetailInventoryRequest, { ...tenant, storeId: '12', limit: '50', nextToken: 'abc' })).toEqual([]);
|
|
70
|
+
expect(propsWithErrors(GetRetailInventoryRequest, { ...tenant, storeId: '12', limit: '0' })).toEqual(['limit']);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('la respuesta admite meta.count y meta.nextToken', () => {
|
|
74
|
+
const response: GetRetailInventoryResponse = {
|
|
75
|
+
pieces: [],
|
|
76
|
+
stock: [],
|
|
77
|
+
meta: { storeId: '12', generatedAt: '2026-08-17T15:00:00Z', count: 0, nextToken: null },
|
|
78
|
+
};
|
|
79
|
+
expect(response.meta.count).toBe(0);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('enums de revisión para movimientos', () => {
|
|
84
|
+
it('ReconciliationEntityEnum suma MOVEMENTS', () => {
|
|
85
|
+
expect(ReconciliationEntityEnum.MOVEMENTS).toBe('MOVEMENTS');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('ReconciliationTriggerEnum suma DISCREPANCY y DAILY', () => {
|
|
89
|
+
expect(ReconciliationTriggerEnum.DISCREPANCY).toBe('DISCREPANCY');
|
|
90
|
+
expect(ReconciliationTriggerEnum.DAILY).toBe('DAILY');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('ReconciliationPageMessage con cursor y rango', () => {
|
|
95
|
+
const base = { ...tenant, runId: 'run-1', pageIndex: 0 };
|
|
96
|
+
|
|
97
|
+
it('acepta nextToken en inventario y from/to en movimientos', () => {
|
|
98
|
+
expect(propsWithErrors(ReconciliationPageMessage, { ...base, entity: 'INVENTORY', storeId: '12', nextToken: 'abc' })).toEqual([]);
|
|
99
|
+
expect(
|
|
100
|
+
propsWithErrors(ReconciliationPageMessage, { ...base, entity: 'MOVEMENTS', from: '2026-08-17T19:55:00Z', to: '2026-08-17T21:00:00Z' }),
|
|
101
|
+
).toEqual([]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('rechaza nextToken vacío y fechas sin zona', () => {
|
|
105
|
+
expect(propsWithErrors(ReconciliationPageMessage, { ...base, entity: 'INVENTORY', nextToken: '' })).toEqual(['nextToken']);
|
|
106
|
+
expect(propsWithErrors(ReconciliationPageMessage, { ...base, entity: 'MOVEMENTS', from: '2026-08-17' })).toEqual(['from']);
|
|
107
|
+
expect(propsWithErrors(ReconciliationPageMessage, { ...base, entity: 'MOVEMENTS', to: 'ayer' })).toEqual(['to']);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance, type ClassConstructor } from 'class-transformer';
|
|
3
|
+
import { validateSync, type ValidationError } from 'class-validator';
|
|
4
|
+
import {
|
|
5
|
+
RetailSystemErrorBody,
|
|
6
|
+
RetailSystemInventoryResponse,
|
|
7
|
+
RetailSystemMovementsResponse,
|
|
8
|
+
RetailSystemPageMeta,
|
|
9
|
+
RetailSystemPageResponse,
|
|
10
|
+
RetailSystemSaleResponse,
|
|
11
|
+
} from '../../../src/retailIntegration';
|
|
12
|
+
|
|
13
|
+
function errorPaths(errors: ValidationError[], prefix = ''): string[] {
|
|
14
|
+
return errors.flatMap((error) => {
|
|
15
|
+
const path = prefix ? `${prefix}.${error.property}` : error.property;
|
|
16
|
+
return error.children?.length ? errorPaths(error.children, path) : [path];
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function pathsWithErrors<T extends object>(cls: ClassConstructor<T>, payload: object): string[] {
|
|
21
|
+
return errorPaths(validateSync(plainToInstance(cls, payload)));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const movement = {
|
|
25
|
+
eventId: 'evt_01J8ZE5M8Y2Q4R7T1V3W6X8Z1C',
|
|
26
|
+
eventType: 'InventoryMovementV1',
|
|
27
|
+
occurredAt: '2026-08-17T20:32:07Z',
|
|
28
|
+
payload: { movementType: 'SALE', storeId: '12', targetStoreId: null, pieces: [], stock: [] },
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe('RetailSystemPageMeta', () => {
|
|
32
|
+
it('acepta la última página y una intermedia', () => {
|
|
33
|
+
expect(pathsWithErrors(RetailSystemPageMeta, { count: 0, nextToken: null })).toEqual([]);
|
|
34
|
+
expect(pathsWithErrors(RetailSystemPageMeta, { count: 200, nextToken: 'eyJpZCI6MTQwMH0' })).toEqual([]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it.each([-1, 1.5, '3', undefined])('rechaza count=%p', (count) => {
|
|
38
|
+
expect(pathsWithErrors(RetailSystemPageMeta, { count, nextToken: null })).toEqual(['count']);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it.each([undefined, 7, 'x'.repeat(2049)])('rechaza nextToken=%p', (nextToken) => {
|
|
42
|
+
expect(pathsWithErrors(RetailSystemPageMeta, { count: 1, nextToken })).toEqual(['nextToken']);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('RetailSystemPageResponse', () => {
|
|
47
|
+
it('acepta data con renglones crudos', () => {
|
|
48
|
+
expect(pathsWithErrors(RetailSystemPageResponse, { data: [{ any: 'row' }], meta: { count: 1, nextToken: null } })).toEqual([]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('rechaza data que no es arreglo y meta inválida', () => {
|
|
52
|
+
expect(pathsWithErrors(RetailSystemPageResponse, { data: {}, meta: { count: 1, nextToken: null } })).toEqual(['data']);
|
|
53
|
+
expect(pathsWithErrors(RetailSystemPageResponse, { data: [], meta: { count: -1, nextToken: null } })).toEqual(['meta.count']);
|
|
54
|
+
expect(pathsWithErrors(RetailSystemPageResponse, { data: [] })).toEqual(['meta']);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('RetailSystemInventoryResponse', () => {
|
|
59
|
+
const valid = {
|
|
60
|
+
data: { pieces: [{ sku: 'SAM-A17' }], stock: [] },
|
|
61
|
+
meta: { storeId: '12', generatedAt: '2026-08-17T15:00:00Z', count: 1, nextToken: null },
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
it('acepta una página del inventario', () => {
|
|
65
|
+
expect(pathsWithErrors(RetailSystemInventoryResponse, valid)).toEqual([]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('rechaza pieces o stock que no son arreglo', () => {
|
|
69
|
+
expect(pathsWithErrors(RetailSystemInventoryResponse, { ...valid, data: { pieces: null, stock: [] } })).toEqual(['data.pieces']);
|
|
70
|
+
expect(pathsWithErrors(RetailSystemInventoryResponse, { ...valid, data: { pieces: [] } })).toEqual(['data.stock']);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it.each([
|
|
74
|
+
['storeId', 'tienda/12'],
|
|
75
|
+
['generatedAt', '2026-08-17 15:00'],
|
|
76
|
+
['count', -2],
|
|
77
|
+
['nextToken', ''.padEnd(2049, 'a')],
|
|
78
|
+
])('rechaza meta.%s inválido', (field, value) => {
|
|
79
|
+
expect(pathsWithErrors(RetailSystemInventoryResponse, { ...valid, meta: { ...valid.meta, [field]: value } })).toEqual([`meta.${field}`]);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('RetailSystemSaleResponse', () => {
|
|
84
|
+
it.each(['58812', 'SALE-12_a.b:c', 'a/b#ñ'])('acepta externalSaleId=%p', (externalSaleId) => {
|
|
85
|
+
expect(pathsWithErrors(RetailSystemSaleResponse, { externalSaleId })).toEqual([]);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it.each(['', 'con espacio', ' 58812', 'x'.repeat(65), 58812, undefined])('rechaza externalSaleId=%p', (externalSaleId) => {
|
|
89
|
+
expect(pathsWithErrors(RetailSystemSaleResponse, { externalSaleId })).toEqual(['externalSaleId']);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('RetailSystemErrorBody', () => {
|
|
94
|
+
it('acepta el error con y sin lineIndex', () => {
|
|
95
|
+
expect(pathsWithErrors(RetailSystemErrorBody, { code: 'IDENTIFIER_NOT_AVAILABLE', msg: 'texto', lineIndex: 1 })).toEqual([]);
|
|
96
|
+
expect(pathsWithErrors(RetailSystemErrorBody, { code: 'VALIDATION_ERROR' })).toEqual([]);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('rechaza code ausente o largo y lineIndex fuera de rango', () => {
|
|
100
|
+
expect(pathsWithErrors(RetailSystemErrorBody, {})).toEqual(['code']);
|
|
101
|
+
expect(pathsWithErrors(RetailSystemErrorBody, { code: 'X'.repeat(65) })).toEqual(['code']);
|
|
102
|
+
expect(pathsWithErrors(RetailSystemErrorBody, { code: 'X', lineIndex: 1000 })).toEqual(['lineIndex']);
|
|
103
|
+
expect(pathsWithErrors(RetailSystemErrorBody, { code: 'X', lineIndex: -1 })).toEqual(['lineIndex']);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('RetailSystemMovementsResponse', () => {
|
|
108
|
+
it('acepta movimientos con el sobre del webhook', () => {
|
|
109
|
+
expect(pathsWithErrors(RetailSystemMovementsResponse, { data: [movement], meta: { count: 1, nextToken: null } })).toEqual([]);
|
|
110
|
+
expect(pathsWithErrors(RetailSystemMovementsResponse, { data: [], meta: { count: 0, nextToken: null } })).toEqual([]);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('rechaza un movimiento con sobre inválido', () => {
|
|
114
|
+
const bad = { ...movement, eventType: 'StoreUpsertedV1', occurredAt: '2026-08-17' };
|
|
115
|
+
expect(pathsWithErrors(RetailSystemMovementsResponse, { data: [bad], meta: { count: 1, nextToken: null } }).sort()).toEqual([
|
|
116
|
+
'data.0.eventType',
|
|
117
|
+
'data.0.occurredAt',
|
|
118
|
+
]);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -29,7 +29,7 @@ describe('rewards: enums (los valores viajan por cola y por HTTP: no se renombra
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
it('GrantItemStatusEnum coincide con spec A 7.1', () => {
|
|
32
|
-
expect(Object.values(GrantItemStatusEnum).sort()).toEqual(['FAILED', 'GRANTED', 'PENDING', 'PROCESSING', 'SKIPPED']);
|
|
32
|
+
expect(Object.values(GrantItemStatusEnum).sort()).toEqual(['FAILED', 'GRANTED', 'PENDING', 'PROCESSING', 'SKIPPED', 'WAITING_LIMIT']);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
it('ItemErrorCategoryEnum coincide con spec A §8', () => {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import {
|
|
3
|
+
BackofficeGrantItemResponse,
|
|
4
|
+
GrantItemStatusEnum,
|
|
5
|
+
LimitWaitReasonEnum,
|
|
6
|
+
RewardItemCodeEnum,
|
|
7
|
+
} from '../../../src/rewards/index';
|
|
8
|
+
import { Rewards } from '../../../src/index';
|
|
9
|
+
|
|
10
|
+
describe('espera por tope de nivel (WAITING_LIMIT)', () => {
|
|
11
|
+
it('GrantItemStatusEnum.WAITING_LIMIT vale WAITING_LIMIT', () => {
|
|
12
|
+
expect(GrantItemStatusEnum.WAITING_LIMIT).toBe('WAITING_LIMIT');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('LimitWaitReasonEnum tiene exactamente los processorCode del spec', () => {
|
|
16
|
+
expect(LimitWaitReasonEnum.MONTHLY_AMOUNT_EXCEEDED).toBe('ACCOUNT_LEVEL_MAX_MONTHLY_AMOUNT_EXCEEDED');
|
|
17
|
+
expect(LimitWaitReasonEnum.AVAILABLE_BALANCE_EXCEEDED).toBe('ACCOUNT_LEVEL_MAX_AVAILABLE_BALANCE_EXCEEDED');
|
|
18
|
+
expect(Object.values(LimitWaitReasonEnum)).toHaveLength(2);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('RewardItemCodeEnum contiene los tres códigos', () => {
|
|
22
|
+
expect(Object.values(RewardItemCodeEnum)).toEqual(
|
|
23
|
+
expect.arrayContaining(['AMOUNT_ABOVE_MAX', 'LIMIT_WAIT_EXPIRED', 'OUTCOME_UNKNOWN']),
|
|
24
|
+
);
|
|
25
|
+
expect(Object.values(RewardItemCodeEnum)).toHaveLength(3);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('BackofficeGrantItemResponse acepta los campos de espera', () => {
|
|
29
|
+
const parcial = {
|
|
30
|
+
waitReason: LimitWaitReasonEnum.MONTHLY_AMOUNT_EXCEEDED,
|
|
31
|
+
retryNotBefore: 1_790_000_000_000,
|
|
32
|
+
waitingSince: 1_789_000_000_000,
|
|
33
|
+
limitRejections: 2,
|
|
34
|
+
} satisfies Partial<BackofficeGrantItemResponse>;
|
|
35
|
+
expect(parcial.limitRejections).toBe(2);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('sale por el index raíz', () => {
|
|
39
|
+
expect(Rewards.GrantItemStatusEnum.WAITING_LIMIT).toBe('WAITING_LIMIT');
|
|
40
|
+
expect(Rewards.LimitWaitReasonEnum.AVAILABLE_BALANCE_EXCEEDED).toBeDefined();
|
|
41
|
+
expect(Rewards.RewardItemCodeEnum.OUTCOME_UNKNOWN).toBe('OUTCOME_UNKNOWN');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -6,5 +6,7 @@ export declare enum DisbursementType {
|
|
|
6
6
|
/** Bono. */
|
|
7
7
|
MEX_BONUS = "MEX_BONUS",
|
|
8
8
|
/** Comisión de vendedor. */
|
|
9
|
-
MEX_SELLER_COMMISSION = "MEX_SELLER_COMMISSION"
|
|
9
|
+
MEX_SELLER_COMMISSION = "MEX_SELLER_COMMISSION",
|
|
10
|
+
/** Abono de recompensas de `rewards-business`. */
|
|
11
|
+
MEX_REWARD = "MEX_REWARD"
|
|
10
12
|
}
|
|
@@ -11,4 +11,6 @@ var DisbursementType;
|
|
|
11
11
|
DisbursementType["MEX_BONUS"] = "MEX_BONUS";
|
|
12
12
|
/** Comisión de vendedor. */
|
|
13
13
|
DisbursementType["MEX_SELLER_COMMISSION"] = "MEX_SELLER_COMMISSION";
|
|
14
|
+
/** Abono de recompensas de `rewards-business`. */
|
|
15
|
+
DisbursementType["MEX_REWARD"] = "MEX_REWARD";
|
|
14
16
|
})(DisbursementType || (exports.DisbursementType = DisbursementType = {}));
|
|
@@ -6,7 +6,8 @@ import { PermissionScope } from '../enums/PermissionScope';
|
|
|
6
6
|
* Consumido por el alta de usuario orquestada de SureKeep F1 (retail-org → RBAC → RetailUser) vía api-invoker.
|
|
7
7
|
* - Usuario provisionado en estado INVITED (mitiga orphan si el paso siguiente en retail-org falla).
|
|
8
8
|
* - Idempotente por identidad Cognito.
|
|
9
|
-
* - `roleId`/`scope`/`scopeRef`: todos o ninguno; sin rol
|
|
9
|
+
* - `roleId`/`scope`/`scopeRef`: todos o ninguno; sin rol exige `suppressInvitation: true`
|
|
10
|
+
* y la invitación queda pendiente (`invitationPending`) hasta asignar el primer rol.
|
|
10
11
|
* - `createdBy` = cognitoSub del admin real (audit + grantedBy del assignment).
|
|
11
12
|
* - `customFields` = valores de los campos personalizados del tenant; si el correo ya tiene usuario, se fusionan.
|
|
12
13
|
*/
|
|
@@ -23,7 +23,8 @@ const hasAnyGrantField = (o) => o.roleId !== undefined || o.scope !== undefined
|
|
|
23
23
|
* Consumido por el alta de usuario orquestada de SureKeep F1 (retail-org → RBAC → RetailUser) vía api-invoker.
|
|
24
24
|
* - Usuario provisionado en estado INVITED (mitiga orphan si el paso siguiente en retail-org falla).
|
|
25
25
|
* - Idempotente por identidad Cognito.
|
|
26
|
-
* - `roleId`/`scope`/`scopeRef`: todos o ninguno; sin rol
|
|
26
|
+
* - `roleId`/`scope`/`scopeRef`: todos o ninguno; sin rol exige `suppressInvitation: true`
|
|
27
|
+
* y la invitación queda pendiente (`invitationPending`) hasta asignar el primer rol.
|
|
27
28
|
* - `createdBy` = cognitoSub del admin real (audit + grantedBy del assignment).
|
|
28
29
|
* - `customFields` = valores de los campos personalizados del tenant; si el correo ya tiene usuario, se fusionan.
|
|
29
30
|
*/
|
|
@@ -0,0 +1,30 @@
|
|
|
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.UpdateTenantUserEmailRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/** Body M2M que cambia el correo de un usuario del tenant; el correo se guarda en minúsculas. */
|
|
16
|
+
class UpdateTenantUserEmailRequest {
|
|
17
|
+
}
|
|
18
|
+
exports.UpdateTenantUserEmailRequest = UpdateTenantUserEmailRequest;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_transformer_1.Expose)(),
|
|
21
|
+
(0, class_transformer_1.Transform)(({ value }) => (typeof value === 'string' ? value.trim().toLowerCase() : value)),
|
|
22
|
+
(0, class_validator_1.IsEmail)(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], UpdateTenantUserEmailRequest.prototype, "email", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_transformer_1.Expose)(),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], UpdateTenantUserEmailRequest.prototype, "actedBy", void 0);
|
|
@@ -120,7 +120,8 @@ export declare enum Permission {
|
|
|
120
120
|
PLATFORM_INTEGRATION_KEY_ISSUE = "platform.integration.key.issue",
|
|
121
121
|
PLATFORM_INTEGRATION_KEY_REVOKE = "platform.integration.key.revoke",
|
|
122
122
|
TENANT_INTEGRATION_DIAGNOSTIC = "tenant.integration.diagnostic",
|
|
123
|
-
TENANT_API_USER_MANAGE = "tenant.api_user.manage"
|
|
123
|
+
TENANT_API_USER_MANAGE = "tenant.api_user.manage",
|
|
124
|
+
PLATFORM_RETAIL_INTEGRATION_ACTIVATE = "platform.retail_integration.activate"
|
|
124
125
|
}
|
|
125
126
|
/**
|
|
126
127
|
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
@@ -166,6 +166,8 @@ var Permission;
|
|
|
166
166
|
Permission["TENANT_INTEGRATION_DIAGNOSTIC"] = "tenant.integration.diagnostic";
|
|
167
167
|
// Alta, rotación de secreto y edición de IPs de usuarios de API; se exige además de tenant.user.create.
|
|
168
168
|
Permission["TENANT_API_USER_MANAGE"] = "tenant.api_user.manage";
|
|
169
|
+
// Activa la integración de un retailer externo (Zentral); scope PLATFORM.
|
|
170
|
+
Permission["PLATFORM_RETAIL_INTEGRATION_ACTIVATE"] = "platform.retail_integration.activate";
|
|
169
171
|
})(Permission || (exports.Permission = Permission = {}));
|
|
170
172
|
/**
|
|
171
173
|
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
@@ -286,6 +288,7 @@ exports.PERMISSION_BIT_ORDER = [
|
|
|
286
288
|
Permission.PLATFORM_INTEGRATION_KEY_REVOKE,
|
|
287
289
|
Permission.TENANT_INTEGRATION_DIAGNOSTIC,
|
|
288
290
|
Permission.TENANT_API_USER_MANAGE,
|
|
291
|
+
Permission.PLATFORM_RETAIL_INTEGRATION_ACTIVATE,
|
|
289
292
|
];
|
|
290
293
|
function djb2(input) {
|
|
291
294
|
let h = 5381;
|
|
@@ -73,6 +73,7 @@ export type { ListTenantUsersResponse } from './dtos/ListTenantUsersResponse';
|
|
|
73
73
|
export type { TenantUserListItemResponse } from './dtos/TenantUserListItemResponse';
|
|
74
74
|
export type { GetTenantUserResponse } from './dtos/GetTenantUserResponse';
|
|
75
75
|
export * from './dtos/UpdateTenantUserRequest';
|
|
76
|
+
export * from './dtos/UpdateTenantUserEmailRequest';
|
|
76
77
|
export * from './dtos/DeleteTenantUserRequest';
|
|
77
78
|
export * from './dtos/DisableTenantUserRequest';
|
|
78
79
|
export * from './dtos/EnableTenantUserRequest';
|
|
@@ -120,6 +120,7 @@ __exportStar(require("./dtos/UpdateIntegrationRequest"), exports);
|
|
|
120
120
|
__exportStar(require("./dtos/UpdateLevelEntityRequest"), exports);
|
|
121
121
|
__exportStar(require("./dtos/DeleteLevelEntityRequest"), exports);
|
|
122
122
|
__exportStar(require("./dtos/UpdateTenantUserRequest"), exports);
|
|
123
|
+
__exportStar(require("./dtos/UpdateTenantUserEmailRequest"), exports);
|
|
123
124
|
__exportStar(require("./dtos/DeleteTenantUserRequest"), exports);
|
|
124
125
|
__exportStar(require("./dtos/DisableTenantUserRequest"), exports);
|
|
125
126
|
__exportStar(require("./dtos/EnableTenantUserRequest"), exports);
|
|
@@ -60,6 +60,7 @@ export declare enum ProductSubtypeEnum {
|
|
|
60
60
|
SP_CASH_IN_CASH_IN_OXXO = "CASH_IN_OXXO",
|
|
61
61
|
SUREKEEP_BONUS_MX = "BONUS_MX",
|
|
62
62
|
SUREKEEP_SELLER_COMMISSION_MX = "SELLER_COMMISSION_MX",
|
|
63
|
+
REWARD_MX = "REWARD_MX",
|
|
63
64
|
STORE_PHONE = "PHONE",
|
|
64
65
|
REFUND_PCF_DICTAMEN_PROCEDE = "DICTAMEN_PROCEDE",
|
|
65
66
|
REFUND_PCF_AUTO_T2_SIN_2FA = "AUTO_T2_SIN_2FA",
|
|
@@ -77,6 +77,9 @@ var ProductSubtypeEnum;
|
|
|
77
77
|
ProductSubtypeEnum["SUREKEEP_BONUS_MX"] = "BONUS_MX";
|
|
78
78
|
// Comisión de vendedor de SureKeep abonada a la wallet.
|
|
79
79
|
ProductSubtypeEnum["SUREKEEP_SELLER_COMMISSION_MX"] = "SELLER_COMMISSION_MX";
|
|
80
|
+
//REWARDS
|
|
81
|
+
// Abono de recompensas de `rewards-business`.
|
|
82
|
+
ProductSubtypeEnum["REWARD_MX"] = "REWARD_MX";
|
|
80
83
|
//STORE
|
|
81
84
|
ProductSubtypeEnum["STORE_PHONE"] = "PHONE";
|
|
82
85
|
// REFUND_PCF
|
|
@@ -63,5 +63,7 @@ export declare enum ProductTypeEnum {
|
|
|
63
63
|
* Dispersión SPEI de liquidaciones de beneficios (money-transfer-connector).
|
|
64
64
|
* Producto del catálogo para la orden STP que sale con `source=BENEFITS_SETTLEMENT`.
|
|
65
65
|
*/
|
|
66
|
-
MONEY_TRANSFER_SA = "MONEY_TRANSFER_SA"
|
|
66
|
+
MONEY_TRANSFER_SA = "MONEY_TRANSFER_SA",
|
|
67
|
+
/** Abono de recompensas de `rewards-business`. */
|
|
68
|
+
REWARDS = "REWARDS"
|
|
67
69
|
}
|
|
@@ -68,4 +68,6 @@ var ProductTypeEnum;
|
|
|
68
68
|
* Producto del catálogo para la orden STP que sale con `source=BENEFITS_SETTLEMENT`.
|
|
69
69
|
*/
|
|
70
70
|
ProductTypeEnum["MONEY_TRANSFER_SA"] = "MONEY_TRANSFER_SA";
|
|
71
|
+
/** Abono de recompensas de `rewards-business`. */
|
|
72
|
+
ProductTypeEnum["REWARDS"] = "REWARDS";
|
|
71
73
|
})(ProductTypeEnum || (exports.ProductTypeEnum = ProductTypeEnum = {}));
|
|
@@ -34,3 +34,14 @@ export declare const RETAIL_EVENT_STOCK_MAX = 200;
|
|
|
34
34
|
export declare const RETAIL_ELIGIBLE_FINANCIERS_MAX = 50;
|
|
35
35
|
/** Decimal de los eventos del retailer: hasta 12 enteros y dos decimales, nunca negativo. */
|
|
36
36
|
export declare const RETAIL_EVENT_DECIMAL_PATTERN: RegExp;
|
|
37
|
+
/** Tope del `nextToken` opaco que devuelve Zentral. */
|
|
38
|
+
export declare const RETAIL_NEXT_TOKEN_MAX_LENGTH = 2048;
|
|
39
|
+
/** Id que asigna Zentral, como `externalSaleId`: no vacío, sin espacios y de a lo más 64. */
|
|
40
|
+
export declare const RETAIL_EXTERNAL_ID_PATTERN: RegExp;
|
|
41
|
+
/** Tope del `code` en el cuerpo de error de Zentral. */
|
|
42
|
+
export declare const RETAIL_ERROR_CODE_MAX_LENGTH = 64;
|
|
43
|
+
/** Rango de `lineIndex` en un error de línea de venta. */
|
|
44
|
+
export declare const RETAIL_LINE_INDEX_MIN = 0;
|
|
45
|
+
export declare const RETAIL_LINE_INDEX_MAX = 999;
|
|
46
|
+
/** Rango máximo de `GET /inventory/movements`: 7 días en milisegundos. */
|
|
47
|
+
export declare const RETAIL_MOVEMENTS_RANGE_MAX_MS: number;
|