@fiado/type-kit 3.515.0 → 3.517.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 (138) hide show
  1. package/_test_/unit/group/groupOwnerFields.test.ts +32 -0
  2. package/_test_/unit/referral-business/groupOwnersByGroupIdsDtos.test.ts +46 -0
  3. package/_test_/unit/rewardsEligibility/backofficeBarrel.test.ts +16 -0
  4. package/_test_/unit/rewardsEligibility/campaignAndEventTypeDtos.test.ts +52 -0
  5. package/_test_/unit/rewardsEligibility/campaignConfigDecorators.test.ts +49 -0
  6. package/_test_/unit/rewardsEligibility/catalogDtos.test.ts +27 -0
  7. package/_test_/unit/rewardsEligibility/evaluationDtos.test.ts +53 -0
  8. package/_test_/unit/rewardsEligibility/events.test.ts +3 -3
  9. package/_test_/unit/rewardsEligibility/metricsDtos.test.ts +17 -0
  10. package/_test_/unit/rewardsEligibility/runDtos.test.ts +36 -0
  11. package/bin/group/dtos/GroupCreateRequest.d.ts +1 -0
  12. package/bin/group/dtos/GroupCreateRequest.js +5 -0
  13. package/bin/group/dtos/GroupResponse.d.ts +2 -0
  14. package/bin/referral-business/dtos/GroupOwnersByGroupIdsRequest.d.ts +4 -0
  15. package/bin/referral-business/dtos/GroupOwnersByGroupIdsRequest.js +25 -0
  16. package/bin/referral-business/dtos/GroupOwnersByGroupIdsResponse.d.ts +8 -0
  17. package/bin/referral-business/dtos/GroupOwnersByGroupIdsResponse.js +2 -0
  18. package/bin/referral-business/index.d.ts +2 -0
  19. package/bin/referral-business/index.js +2 -0
  20. package/bin/rewardsEligibility/constants/BackofficeLimits.d.ts +12 -0
  21. package/bin/rewardsEligibility/constants/BackofficeLimits.js +15 -0
  22. package/bin/rewardsEligibility/dtos/CampaignAlerts.js +20 -0
  23. package/bin/rewardsEligibility/dtos/CampaignQuota.d.ts +1 -1
  24. package/bin/rewardsEligibility/dtos/CampaignQuota.js +29 -0
  25. package/bin/rewardsEligibility/dtos/backoffice/ApproveRunRequest.d.ts +4 -0
  26. package/bin/rewardsEligibility/dtos/backoffice/ApproveRunRequest.js +27 -0
  27. package/bin/rewardsEligibility/dtos/backoffice/CampaignListResponse.d.ts +6 -0
  28. package/bin/rewardsEligibility/dtos/backoffice/CampaignListResponse.js +6 -0
  29. package/bin/rewardsEligibility/dtos/backoffice/CampaignRequest.d.ts +16 -0
  30. package/bin/rewardsEligibility/dtos/backoffice/CampaignRequest.js +72 -0
  31. package/bin/rewardsEligibility/dtos/backoffice/CampaignResponse.d.ts +23 -0
  32. package/bin/rewardsEligibility/dtos/backoffice/CampaignResponse.js +7 -0
  33. package/bin/rewardsEligibility/dtos/backoffice/CampaignStatusRequest.d.ts +5 -0
  34. package/bin/rewardsEligibility/dtos/backoffice/CampaignStatusRequest.js +24 -0
  35. package/bin/rewardsEligibility/dtos/backoffice/CampaignSummaryResponse.d.ts +28 -0
  36. package/bin/rewardsEligibility/dtos/backoffice/CampaignSummaryResponse.js +7 -0
  37. package/bin/rewardsEligibility/dtos/backoffice/CreateRunRequest.d.ts +11 -0
  38. package/bin/rewardsEligibility/dtos/backoffice/CreateRunRequest.js +45 -0
  39. package/bin/rewardsEligibility/dtos/backoffice/CreateRunResponse.d.ts +9 -0
  40. package/bin/rewardsEligibility/dtos/backoffice/CreateRunResponse.js +7 -0
  41. package/bin/rewardsEligibility/dtos/backoffice/EvaluationListResponse.d.ts +5 -0
  42. package/bin/rewardsEligibility/dtos/backoffice/EvaluationListResponse.js +6 -0
  43. package/bin/rewardsEligibility/dtos/backoffice/EvaluationRequest.d.ts +27 -0
  44. package/bin/rewardsEligibility/dtos/backoffice/EvaluationRequest.js +86 -0
  45. package/bin/rewardsEligibility/dtos/backoffice/EvaluationResponse.d.ts +26 -0
  46. package/bin/rewardsEligibility/dtos/backoffice/EvaluationResponse.js +6 -0
  47. package/bin/rewardsEligibility/dtos/backoffice/EvaluationStatusRequest.d.ts +5 -0
  48. package/bin/rewardsEligibility/dtos/backoffice/EvaluationStatusRequest.js +24 -0
  49. package/bin/rewardsEligibility/dtos/backoffice/EventTypeListResponse.d.ts +5 -0
  50. package/bin/rewardsEligibility/dtos/backoffice/EventTypeListResponse.js +6 -0
  51. package/bin/rewardsEligibility/dtos/backoffice/EventTypeRequest.d.ts +12 -0
  52. package/bin/rewardsEligibility/dtos/backoffice/EventTypeRequest.js +58 -0
  53. package/bin/rewardsEligibility/dtos/backoffice/EventTypeResponse.d.ts +12 -0
  54. package/bin/rewardsEligibility/dtos/backoffice/EventTypeResponse.js +6 -0
  55. package/bin/rewardsEligibility/dtos/backoffice/FailedConditionStatResponse.d.ts +8 -0
  56. package/bin/rewardsEligibility/dtos/backoffice/FailedConditionStatResponse.js +7 -0
  57. package/bin/rewardsEligibility/dtos/backoffice/InputTypeResponse.d.ts +6 -0
  58. package/bin/rewardsEligibility/dtos/backoffice/InputTypeResponse.js +7 -0
  59. package/bin/rewardsEligibility/dtos/backoffice/MetricsPointResponse.d.ts +14 -0
  60. package/bin/rewardsEligibility/dtos/backoffice/MetricsPointResponse.js +7 -0
  61. package/bin/rewardsEligibility/dtos/backoffice/MetricsQuery.d.ts +9 -0
  62. package/bin/rewardsEligibility/dtos/backoffice/MetricsQuery.js +7 -0
  63. package/bin/rewardsEligibility/dtos/backoffice/PopulationRunRequest.d.ts +5 -0
  64. package/bin/rewardsEligibility/dtos/backoffice/PopulationRunRequest.js +24 -0
  65. package/bin/rewardsEligibility/dtos/backoffice/PopulationSourceResponse.d.ts +11 -0
  66. package/bin/rewardsEligibility/dtos/backoffice/PopulationSourceResponse.js +7 -0
  67. package/bin/rewardsEligibility/dtos/backoffice/QuotaImpactResponse.d.ts +9 -0
  68. package/bin/rewardsEligibility/dtos/backoffice/QuotaImpactResponse.js +7 -0
  69. package/bin/rewardsEligibility/dtos/backoffice/QuotaUsageResponse.d.ts +10 -0
  70. package/bin/rewardsEligibility/dtos/backoffice/QuotaUsageResponse.js +7 -0
  71. package/bin/rewardsEligibility/dtos/backoffice/ResultTraceResponse.d.ts +34 -0
  72. package/bin/rewardsEligibility/dtos/backoffice/ResultTraceResponse.js +14 -0
  73. package/bin/rewardsEligibility/dtos/backoffice/RuleCatalogResponse.d.ts +28 -0
  74. package/bin/rewardsEligibility/dtos/backoffice/RuleCatalogResponse.js +13 -0
  75. package/bin/rewardsEligibility/dtos/backoffice/RunListResponse.d.ts +5 -0
  76. package/bin/rewardsEligibility/dtos/backoffice/RunListResponse.js +6 -0
  77. package/bin/rewardsEligibility/dtos/backoffice/RunResponse.d.ts +24 -0
  78. package/bin/rewardsEligibility/dtos/backoffice/RunResponse.js +7 -0
  79. package/bin/rewardsEligibility/dtos/backoffice/RunResultListResponse.d.ts +5 -0
  80. package/bin/rewardsEligibility/dtos/backoffice/RunResultListResponse.js +6 -0
  81. package/bin/rewardsEligibility/dtos/backoffice/RunResultResponse.d.ts +22 -0
  82. package/bin/rewardsEligibility/dtos/backoffice/RunResultResponse.js +7 -0
  83. package/bin/rewardsEligibility/dtos/backoffice/SimulateRequest.d.ts +8 -0
  84. package/bin/rewardsEligibility/dtos/backoffice/SimulateRequest.js +40 -0
  85. package/bin/rewardsEligibility/dtos/backoffice/SimulateResponse.d.ts +11 -0
  86. package/bin/rewardsEligibility/dtos/backoffice/SimulateResponse.js +6 -0
  87. package/bin/rewardsEligibility/enums/MetricsDimensionEnum.d.ts +8 -0
  88. package/bin/rewardsEligibility/enums/MetricsDimensionEnum.js +12 -0
  89. package/bin/rewardsEligibility/enums/RewardsEligibilityErrorCodeEnum.d.ts +46 -1
  90. package/bin/rewardsEligibility/enums/RewardsEligibilityErrorCodeEnum.js +46 -0
  91. package/bin/rewardsEligibility/enums/RuleValueTypeEnum.d.ts +9 -0
  92. package/bin/rewardsEligibility/enums/RuleValueTypeEnum.js +13 -0
  93. package/bin/rewardsEligibility/index.d.ts +34 -0
  94. package/bin/rewardsEligibility/index.js +35 -0
  95. package/package.json +1 -1
  96. package/src/group/dtos/GroupCreateRequest.ts +7 -1
  97. package/src/group/dtos/GroupResponse.ts +4 -0
  98. package/src/referral-business/dtos/GroupOwnersByGroupIdsRequest.ts +12 -0
  99. package/src/referral-business/dtos/GroupOwnersByGroupIdsResponse.ts +11 -0
  100. package/src/referral-business/index.ts +2 -0
  101. package/src/rewardsEligibility/constants/BackofficeLimits.ts +12 -0
  102. package/src/rewardsEligibility/dtos/CampaignAlerts.ts +9 -0
  103. package/src/rewardsEligibility/dtos/CampaignQuota.ts +13 -1
  104. package/src/rewardsEligibility/dtos/backoffice/ApproveRunRequest.ts +13 -0
  105. package/src/rewardsEligibility/dtos/backoffice/CampaignListResponse.ts +7 -0
  106. package/src/rewardsEligibility/dtos/backoffice/CampaignRequest.ts +53 -0
  107. package/src/rewardsEligibility/dtos/backoffice/CampaignResponse.ts +24 -0
  108. package/src/rewardsEligibility/dtos/backoffice/CampaignStatusRequest.ts +10 -0
  109. package/src/rewardsEligibility/dtos/backoffice/CampaignSummaryResponse.ts +26 -0
  110. package/src/rewardsEligibility/dtos/backoffice/CreateRunRequest.ts +30 -0
  111. package/src/rewardsEligibility/dtos/backoffice/CreateRunResponse.ts +10 -0
  112. package/src/rewardsEligibility/dtos/backoffice/EvaluationListResponse.ts +6 -0
  113. package/src/rewardsEligibility/dtos/backoffice/EvaluationRequest.ts +69 -0
  114. package/src/rewardsEligibility/dtos/backoffice/EvaluationResponse.ts +25 -0
  115. package/src/rewardsEligibility/dtos/backoffice/EvaluationStatusRequest.ts +10 -0
  116. package/src/rewardsEligibility/dtos/backoffice/EventTypeListResponse.ts +6 -0
  117. package/src/rewardsEligibility/dtos/backoffice/EventTypeRequest.ts +41 -0
  118. package/src/rewardsEligibility/dtos/backoffice/EventTypeResponse.ts +13 -0
  119. package/src/rewardsEligibility/dtos/backoffice/FailedConditionStatResponse.ts +8 -0
  120. package/src/rewardsEligibility/dtos/backoffice/InputTypeResponse.ts +7 -0
  121. package/src/rewardsEligibility/dtos/backoffice/MetricsPointResponse.ts +14 -0
  122. package/src/rewardsEligibility/dtos/backoffice/MetricsQuery.ts +10 -0
  123. package/src/rewardsEligibility/dtos/backoffice/PopulationRunRequest.ts +11 -0
  124. package/src/rewardsEligibility/dtos/backoffice/PopulationSourceResponse.ts +12 -0
  125. package/src/rewardsEligibility/dtos/backoffice/QuotaImpactResponse.ts +9 -0
  126. package/src/rewardsEligibility/dtos/backoffice/QuotaUsageResponse.ts +11 -0
  127. package/src/rewardsEligibility/dtos/backoffice/ResultTraceResponse.ts +34 -0
  128. package/src/rewardsEligibility/dtos/backoffice/RuleCatalogResponse.ts +28 -0
  129. package/src/rewardsEligibility/dtos/backoffice/RunListResponse.ts +6 -0
  130. package/src/rewardsEligibility/dtos/backoffice/RunResponse.ts +25 -0
  131. package/src/rewardsEligibility/dtos/backoffice/RunResultListResponse.ts +6 -0
  132. package/src/rewardsEligibility/dtos/backoffice/RunResultResponse.ts +23 -0
  133. package/src/rewardsEligibility/dtos/backoffice/SimulateRequest.ts +25 -0
  134. package/src/rewardsEligibility/dtos/backoffice/SimulateResponse.ts +12 -0
  135. package/src/rewardsEligibility/enums/MetricsDimensionEnum.ts +8 -0
  136. package/src/rewardsEligibility/enums/RewardsEligibilityErrorCodeEnum.ts +47 -0
  137. package/src/rewardsEligibility/enums/RuleValueTypeEnum.ts +9 -0
  138. package/src/rewardsEligibility/index.ts +36 -0
@@ -0,0 +1,32 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { GroupCreateRequest, GroupResponse, GroupStatus } from '../../../src/group';
5
+
6
+ const base = { id: 'TAXMA', name: 'Taxma', status: GroupStatus.ACTIVE };
7
+
8
+ describe('GroupCreateRequest.ownerDirectoryId', () => {
9
+ it('es opcional (la carga masiva por CSV no lo manda)', async () => {
10
+ expect(await validate(plainToInstance(GroupCreateRequest, base))).toEqual([]);
11
+ });
12
+ it('acepta un uuid v4', async () => {
13
+ const dto = plainToInstance(GroupCreateRequest, { ...base, ownerDirectoryId: 'b298ec6b-00b6-487b-b096-f4ac6ac8c91d' });
14
+ expect(await validate(dto)).toEqual([]);
15
+ });
16
+ it('rechaza lo que no es uuid v4', async () => {
17
+ const errors = await validate(plainToInstance(GroupCreateRequest, { ...base, ownerDirectoryId: 'no-es-uuid' }));
18
+ expect(errors[0].property).toBe('ownerDirectoryId');
19
+ expect(errors[0].constraints?.isUuid).toBeDefined();
20
+ });
21
+ });
22
+
23
+ describe('GroupResponse.owner', () => {
24
+ it('admite owner o null', () => {
25
+ const withOwner: Partial<GroupResponse> = {
26
+ owner: { agentId: 'AG-1', directoryId: 'DIR-1', name: null, email: null, status: 'ACTIVE' },
27
+ };
28
+ const withoutOwner: Partial<GroupResponse> = { owner: null };
29
+ expect(withOwner.owner?.agentId).toBe('AG-1');
30
+ expect(withoutOwner.owner).toBeNull();
31
+ });
32
+ });
@@ -0,0 +1,46 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ GroupOwnersByGroupIdsRequest,
6
+ GROUP_OWNERS_BY_GROUP_IDS_MAX_BATCH,
7
+ } from '../../../src/referral-business';
8
+ import type { GroupOwnerItem, GroupOwnersByGroupIdsResponse } from '../../../src/referral-business';
9
+
10
+ describe('GroupOwnersByGroupIdsRequest', () => {
11
+ it('el tope del lote es 100', () => {
12
+ expect(GROUP_OWNERS_BY_GROUP_IDS_MAX_BATCH).toBe(100);
13
+ });
14
+ it('acepta una lista de groupIds', async () => {
15
+ const dto = plainToInstance(GroupOwnersByGroupIdsRequest, { groupIds: ['FIADO', 'TAXMA'] });
16
+ expect(await validate(dto)).toEqual([]);
17
+ });
18
+ it('acepta la lista vacía', async () => {
19
+ const dto = plainToInstance(GroupOwnersByGroupIdsRequest, { groupIds: [] });
20
+ expect(await validate(dto)).toEqual([]);
21
+ });
22
+ it('rechaza 101 ids con arrayMaxSize', async () => {
23
+ const ids = Array.from({ length: 101 }, (_, i) => `G${i}`);
24
+ const errors = await validate(plainToInstance(GroupOwnersByGroupIdsRequest, { groupIds: ids }));
25
+ expect(errors[0].property).toBe('groupIds');
26
+ expect(errors[0].constraints?.arrayMaxSize).toBeDefined();
27
+ });
28
+ it('rechaza si groupIds no es arreglo', async () => {
29
+ const errors = await validate(plainToInstance(GroupOwnersByGroupIdsRequest, { groupIds: 'FIADO' }));
30
+ expect(errors[0].constraints?.isArray).toBeDefined();
31
+ });
32
+ it('rechaza elementos que no son string', async () => {
33
+ const errors = await validate(plainToInstance(GroupOwnersByGroupIdsRequest, { groupIds: [1] }));
34
+ expect(errors[0].constraints?.isString).toBeDefined();
35
+ });
36
+ });
37
+
38
+ describe('GroupOwnersByGroupIdsResponse', () => {
39
+ it('es un mapa groupId → GroupOwnerItem', () => {
40
+ const owner: GroupOwnerItem = {
41
+ agentId: 'AG-1', directoryId: 'DIR-1', name: 'MARIA DAVALOS', email: 'm@taxma.com', status: 'ACTIVE',
42
+ };
43
+ const res: GroupOwnersByGroupIdsResponse = { TAXMA: owner };
44
+ expect(res.TAXMA.directoryId).toBe('DIR-1');
45
+ });
46
+ });
@@ -0,0 +1,16 @@
1
+ import 'reflect-metadata';
2
+ import * as kit from '../../../src/rewardsEligibility';
3
+
4
+ describe('barrel rewardsEligibility incluye el backoffice', () => {
5
+ it.each([
6
+ 'CampaignRequest', 'CampaignStatusRequest', 'CampaignResponse', 'CampaignListResponse', 'QuotaUsageResponse', 'CampaignSummaryResponse',
7
+ 'EventTypeRequest', 'EventTypeResponse', 'EventTypeListResponse', 'EvaluationRequest', 'EvaluationStatusRequest', 'EvaluationResponse',
8
+ 'EvaluationListResponse', 'ResultTraceResponse', 'TraceGroupResponse', 'TraceConditionResponse', 'SimulateRequest', 'SimulateResponse',
9
+ 'RuleCatalogResponse', 'RuleCatalogSourceResponse', 'RuleCatalogFieldResponse', 'PopulationSourceResponse', 'InputTypeResponse',
10
+ 'CreateRunRequest', 'PopulationRunRequest', 'ApproveRunRequest', 'QuotaImpactResponse', 'RunResponse', 'RunListResponse',
11
+ 'RunResultResponse', 'RunResultListResponse', 'CreateRunResponse', 'MetricsPointResponse', 'FailedConditionStatResponse', 'MetricsQuery',
12
+ 'MetricsDimensionEnum', 'RuleValueTypeEnum', 'ELIGIBILITY_ID_PATTERN', 'EVENT_KEY_PATTERN', 'REQUEST_ID_PATTERN', 'MAX_QUOTAS_PER_CAMPAIGN',
13
+ ])('exporta %s', (name) => {
14
+ expect((kit as Record<string, object | string | number | RegExp>)[name]).toBeDefined();
15
+ });
16
+ });
@@ -0,0 +1,52 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { CampaignRequest } from '../../../src/rewardsEligibility/dtos/backoffice/CampaignRequest';
5
+ import { CampaignStatusRequest } from '../../../src/rewardsEligibility/dtos/backoffice/CampaignStatusRequest';
6
+ import { EventTypeRequest } from '../../../src/rewardsEligibility/dtos/backoffice/EventTypeRequest';
7
+
8
+ const parse = <T extends object>(cls: new () => T, value: object): T => plainToInstance(cls, value, { excludeExtraneousValues: true });
9
+ const valid = {
10
+ id: 'referidos-q4', name: 'Referidos Q4', objective: 'Que cada venta traiga una cuenta nueva.',
11
+ startsAt: '2026-10-15', endsAt: '2026-12-31',
12
+ quotas: [{ id: 'primeros-500', limit: 500, period: 'TOTAL' }, { id: 'semanal', limit: 100, period: 'WEEK' }],
13
+ onExhausted: 'PAUSE_CAMPAIGN', alerts: { thresholds: [0.8, 1] },
14
+ };
15
+
16
+ describe('CampaignRequest', () => {
17
+ it('un cuerpo válido pasa y conserva los cupos anidados', async () => {
18
+ const request = parse(CampaignRequest, { ...valid, hack: true });
19
+ expect(await validate(request)).toEqual([]);
20
+ expect(request.quotas).toHaveLength(2);
21
+ expect(request.quotas[0]).toMatchObject({ id: 'primeros-500', limit: 500, period: 'TOTAL' });
22
+ expect(Object.keys(request)).not.toContain('hack');
23
+ });
24
+ it.each([
25
+ ['id con #', { ...valid, id: 'a#b' }],
26
+ ['fecha mal formada', { ...valid, startsAt: '15/10/2026' }],
27
+ ['cupo inválido anidado', { ...valid, quotas: [{ id: 'x', limit: 0, period: 'TOTAL' }] }],
28
+ ['más de 9 cupos', { ...valid, quotas: Array.from({ length: 10 }, (_, i) => ({ id: `q${i}`, limit: 1, period: 'TOTAL' })) }],
29
+ ['onExhausted desconocido', { ...valid, onExhausted: 'DELETE' }],
30
+ ['sin alerts', { ...valid, alerts: undefined }],
31
+ ])('rechaza: %s', async (_name, value) => {
32
+ expect((await validate(parse(CampaignRequest, value))).length).toBeGreaterThan(0);
33
+ });
34
+ });
35
+
36
+ describe('CampaignStatusRequest / EventTypeRequest', () => {
37
+ it('status válido e inválido', async () => {
38
+ expect(await validate(parse(CampaignStatusRequest, { status: 'PAUSED' }))).toEqual([]);
39
+ expect((await validate(parse(CampaignStatusRequest, { status: 'BORRAR' }))).length).toBeGreaterThan(0);
40
+ });
41
+ it('un tipo de evento válido conserva sus fields (objetos sin clase) y rechaza eventKey en minúsculas', async () => {
42
+ const body = {
43
+ eventKey: 'PHONE_SALES_CODE_REDEEMED', name: 'Canje', description: 'd', emitter: 'phone-sales', status: 'ACTIVE',
44
+ fields: [{ key: 'saleId', type: 'ENTITY_REF', label: 'Venta', required: true }],
45
+ };
46
+ const ok = parse(EventTypeRequest, body);
47
+ expect(await validate(ok)).toEqual([]);
48
+ expect(ok.fields[0]).toMatchObject({ key: 'saleId', type: 'ENTITY_REF', label: 'Venta', required: true });
49
+ expect((await validate(parse(EventTypeRequest, { ...body, eventKey: 'phone' }))).length).toBeGreaterThan(0);
50
+ expect((await validate(parse(EventTypeRequest, { ...body, fields: 'x' }))).length).toBeGreaterThan(0);
51
+ });
52
+ });
@@ -0,0 +1,49 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { CampaignAlerts } from '../../../src/rewardsEligibility/dtos/CampaignAlerts';
5
+ import { CampaignQuota } from '../../../src/rewardsEligibility/dtos/CampaignQuota';
6
+ import { MetricsDimensionEnum } from '../../../src/rewardsEligibility/enums/MetricsDimensionEnum';
7
+ import { RewardsEligibilityErrorCodeEnum } from '../../../src/rewardsEligibility/enums/RewardsEligibilityErrorCodeEnum';
8
+ import { ELIGIBILITY_ID_PATTERN, EVENT_KEY_PATTERN, MAX_QUOTAS_PER_CAMPAIGN } from '../../../src/rewardsEligibility/constants/BackofficeLimits';
9
+
10
+ const parse = <T extends object>(cls: new () => T, value: object): T => plainToInstance(cls, value, { excludeExtraneousValues: true });
11
+
12
+ describe('CampaignQuota / CampaignAlerts validables', () => {
13
+ it('un cupo válido pasa y descarta campos extra', async () => {
14
+ const quota = parse(CampaignQuota, { id: 'primeros-500', limit: 500, period: 'TOTAL', extra: 1 });
15
+ expect(await validate(quota)).toEqual([]);
16
+ expect(Object.keys(quota).sort()).toEqual(['id', 'limit', 'period']);
17
+ });
18
+
19
+ it.each([
20
+ [{ id: 'con#almohadilla', limit: 5, period: 'TOTAL' }],
21
+ [{ id: 'ok', limit: 0, period: 'TOTAL' }],
22
+ [{ id: 'ok', limit: 1.5, period: 'TOTAL' }],
23
+ [{ id: 'ok', limit: 5, period: 'YEAR' }],
24
+ ])('un cupo inválido falla: %j', async (value) => {
25
+ expect((await validate(parse(CampaignQuota, value))).length).toBeGreaterThan(0);
26
+ });
27
+
28
+ it('umbrales de alerta: entre 0 y 1, hasta 5', async () => {
29
+ expect(await validate(parse(CampaignAlerts, { thresholds: [0.8, 1] }))).toEqual([]);
30
+ expect((await validate(parse(CampaignAlerts, { thresholds: [1.5] }))).length).toBeGreaterThan(0);
31
+ expect((await validate(parse(CampaignAlerts, { thresholds: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6] }))).length).toBeGreaterThan(0);
32
+ });
33
+ });
34
+
35
+ describe('constantes y enums del backoffice', () => {
36
+ it('patrones de id', () => {
37
+ expect(ELIGIBILITY_ID_PATTERN.test('referidos-q4')).toBe(true);
38
+ expect(ELIGIBILITY_ID_PATTERN.test('a#b')).toBe(false);
39
+ expect(ELIGIBILITY_ID_PATTERN.test('A:b')).toBe(false);
40
+ expect(EVENT_KEY_PATTERN.test('PHONE_SALES_CODE_REDEEMED')).toBe(true);
41
+ expect(EVENT_KEY_PATTERN.test('phone')).toBe(false);
42
+ expect(MAX_QUOTAS_PER_CAMPAIGN).toBe(9);
43
+ });
44
+ it('dimensiones y códigos', () => {
45
+ expect(Object.values(MetricsDimensionEnum)).toEqual(['CAMPAIGN', 'EVALUATION', 'PACKAGE', 'TRIGGER', 'ALL']);
46
+ expect(RewardsEligibilityErrorCodeEnum.EVALUATION_INVALID).toBe('EVALUATION_INVALID');
47
+ expect(RewardsEligibilityErrorCodeEnum.INPUT_INVALID).toBe('INPUT_INVALID');
48
+ });
49
+ });
@@ -0,0 +1,27 @@
1
+ import { RuleValueTypeEnum } from '../../../src/rewardsEligibility/enums/RuleValueTypeEnum';
2
+ import { InputFieldTypeEnum } from '../../../src/dynamicForm/enums/InputFieldTypeEnum';
3
+ import type { RuleCatalogResponse } from '../../../src/rewardsEligibility/dtos/backoffice/RuleCatalogResponse';
4
+ import type { PopulationSourceResponse } from '../../../src/rewardsEligibility/dtos/backoffice/PopulationSourceResponse';
5
+ import type { InputTypeResponse } from '../../../src/rewardsEligibility/dtos/backoffice/InputTypeResponse';
6
+
7
+ describe('DTOs de catálogos (forma)', () => {
8
+ it('un catálogo de reglas se puede armar con la forma pública', () => {
9
+ const catalog: RuleCatalogResponse = {
10
+ sources: [{
11
+ source: 'directory', label: 'Directorio', description: 'Datos del usuario',
12
+ fields: [{ field: 'accountAgeDays', label: 'Antigüedad', valueType: RuleValueTypeEnum.NUMBER, operators: ['GT', 'LTE'] }],
13
+ }],
14
+ operators: { GT: '>', LTE: '≤' },
15
+ };
16
+ expect(catalog.sources[0]?.fields[0]?.valueType).toBe('NUMBER');
17
+ });
18
+ it('una fuente de población y un tipo de input', () => {
19
+ const source: PopulationSourceResponse = {
20
+ source: 'TX_ACTIVE_IN_WINDOW', label: 'Con transacciones', description: 'd',
21
+ paramsSchema: [{ key: 'window', type: InputFieldTypeEnum.TEXT, label: 'Ventana', required: true }], provides: ['directoryId'],
22
+ };
23
+ const type: InputTypeResponse = { type: InputFieldTypeEnum.DIRECTORY, label: 'Usuario' };
24
+ expect(source.provides).toEqual(['directoryId']);
25
+ expect(type.type).toBe('DIRECTORY');
26
+ });
27
+ });
@@ -0,0 +1,53 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { EvaluationRequest } from '../../../src/rewardsEligibility/dtos/backoffice/EvaluationRequest';
5
+ import { EvaluationStatusRequest } from '../../../src/rewardsEligibility/dtos/backoffice/EvaluationStatusRequest';
6
+ import { SimulateRequest } from '../../../src/rewardsEligibility/dtos/backoffice/SimulateRequest';
7
+
8
+ const parse = <T extends object>(cls: new () => T, value: object): T => plainToInstance(cls, value, { excludeExtraneousValues: true });
9
+ const evaluation = {
10
+ id: 'phone-sales-referido', campaignId: 'referidos-q4', name: 'Premio', description: 'd',
11
+ inputs: [{ key: 'buyerDirectoryId', type: 'DIRECTORY', label: 'Comprador', required: true }],
12
+ rules: { match: 'ALL', groups: [{ match: 'ALL', conditions: [{ source: 'directory', subject: 'buyerDirectoryId', field: 'accountAgeDays', op: 'LTE', value: 7 }] }] },
13
+ beneficiaryInput: 'buyerDirectoryId',
14
+ reward: { packageId: 'paquete-referido', inputs: { topup: { accountNumberMatchesOperator: { const: true } } } },
15
+ grantPolicy: { mode: 'ONCE' },
16
+ triggers: [{ type: 'MANUAL', approval: 'AUTO' }],
17
+ };
18
+
19
+ describe('EvaluationRequest', () => {
20
+ it('válida: conserva rules, reward, grantPolicy y triggers anidados (objetos sin clase)', async () => {
21
+ const request = parse(EvaluationRequest, { ...evaluation, extra: 1 });
22
+ expect(await validate(request)).toEqual([]);
23
+ expect(request.rules).toEqual(evaluation.rules);
24
+ expect(request.reward).toEqual(evaluation.reward);
25
+ expect(request.grantPolicy).toEqual({ mode: 'ONCE' });
26
+ expect(request.triggers).toEqual(evaluation.triggers);
27
+ expect(Object.keys(request)).not.toContain('extra');
28
+ });
29
+ it.each([
30
+ ['id con :', { ...evaluation, id: 'a:b' }],
31
+ ['inputs no es arreglo', { ...evaluation, inputs: {} }],
32
+ ['rules no es objeto', { ...evaluation, rules: 'x' }],
33
+ ['triggers vacío', { ...evaluation, triggers: [] }],
34
+ ['sin beneficiaryInput', { ...evaluation, beneficiaryInput: '' }],
35
+ ])('rechaza: %s', async (_name, value) => {
36
+ expect((await validate(parse(EvaluationRequest, value))).length).toBeGreaterThan(0);
37
+ });
38
+ });
39
+
40
+ describe('EvaluationStatusRequest / SimulateRequest', () => {
41
+ it('status', async () => {
42
+ expect(await validate(parse(EvaluationStatusRequest, { status: 'ACTIVE' }))).toEqual([]);
43
+ expect((await validate(parse(EvaluationStatusRequest, { status: 'ENDED' }))).length).toBeGreaterThan(0);
44
+ });
45
+ it('simulate: evaluationId o borrador, con inputs', async () => {
46
+ expect(await validate(parse(SimulateRequest, { evaluationId: 'phone-sales-referido', inputs: { buyerDirectoryId: 'd-1' } }))).toEqual([]);
47
+ const draft = parse(SimulateRequest, { evaluation, inputs: { buyerDirectoryId: 'd-1' } });
48
+ expect(await validate(draft)).toEqual([]);
49
+ expect(draft.evaluation?.id).toBe('phone-sales-referido');
50
+ expect((await validate(parse(SimulateRequest, { evaluationId: 'x', inputs: { a: { nested: true } } }))).length).toBeGreaterThan(0);
51
+ expect((await validate(parse(SimulateRequest, { evaluationId: 'x' }))).length).toBeGreaterThan(0);
52
+ });
53
+ });
@@ -75,9 +75,9 @@ describe('enums de rewardsEligibility (valores que viajan por HTTP)', () => {
75
75
  );
76
76
  expect(Object.values(RunModeEnum).sort()).toEqual(['LIVE', 'SIMULATION']);
77
77
  expect(Object.values(TriggerTypeEnum).sort()).toEqual(['CRON', 'EVENT', 'MANUAL']);
78
- expect(Object.values(RewardsEligibilityErrorCodeEnum).sort()).toEqual(
79
- ['EVENT_TYPE_NOT_FOUND', 'INPUT_INVALID', 'RUN_NOT_FOUND'],
80
- );
78
+ const codes = Object.values(RewardsEligibilityErrorCodeEnum);
79
+ expect(codes).toEqual(expect.arrayContaining(['EVENT_TYPE_NOT_FOUND', 'INPUT_INVALID', 'RUN_NOT_FOUND']));
80
+ expect(codes).toHaveLength(30);
81
81
  });
82
82
  });
83
83
 
@@ -0,0 +1,17 @@
1
+ import { MetricsDimensionEnum } from '../../../src/rewardsEligibility/enums/MetricsDimensionEnum';
2
+ import type { FailedConditionStatResponse } from '../../../src/rewardsEligibility/dtos/backoffice/FailedConditionStatResponse';
3
+ import type { MetricsPointResponse } from '../../../src/rewardsEligibility/dtos/backoffice/MetricsPointResponse';
4
+ import type { MetricsQuery } from '../../../src/rewardsEligibility/dtos/backoffice/MetricsQuery';
5
+
6
+ describe('DTOs de métricas (forma)', () => {
7
+ it('un punto diario trae los 9 contadores del spec 5.7', () => {
8
+ const point: MetricsPointResponse = { date: '2026-10-08', evaluated: 3, match: 2, noMatch: 1, error: 0, alreadyGranted: 0, quotaExhausted: 0, excluded: 0, requested: 2, requestFailed: 0 };
9
+ expect(Object.keys(point)).toHaveLength(10);
10
+ });
11
+ it('ranking y query', () => {
12
+ const stat: FailedConditionStatResponse = { key: 'directory.accountAgeDays', label: 'Antigüedad de la cuenta', count: 7 };
13
+ const query: MetricsQuery = { dimension: MetricsDimensionEnum.CAMPAIGN, value: 'referidos-q4', from: '2026-10-01', to: '2026-10-08' };
14
+ expect(stat.count).toBe(7);
15
+ expect(query.dimension).toBe('CAMPAIGN');
16
+ });
17
+ });
@@ -0,0 +1,36 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { ApproveRunRequest } from '../../../src/rewardsEligibility/dtos/backoffice/ApproveRunRequest';
5
+ import { CreateRunRequest } from '../../../src/rewardsEligibility/dtos/backoffice/CreateRunRequest';
6
+
7
+ const parse = <T extends object>(cls: new () => T, value: object): T => plainToInstance(cls, value, { excludeExtraneousValues: true });
8
+
9
+ describe('CreateRunRequest', () => {
10
+ it('un sujeto: requestId, mode e inputs', async () => {
11
+ const request = parse(CreateRunRequest, { requestId: 'req-12345678', mode: 'LIVE', inputs: { buyerDirectoryId: 'd-1' }, x: 1 });
12
+ expect(await validate(request)).toEqual([]);
13
+ expect(request.inputs).toEqual({ buyerDirectoryId: 'd-1' });
14
+ });
15
+ it('población: params anidados se conservan', async () => {
16
+ const request = parse(CreateRunRequest, { requestId: 'req-12345678', mode: 'SIMULATION', population: { params: { window: '7d' } } });
17
+ expect(await validate(request)).toEqual([]);
18
+ expect(request.population?.params).toEqual({ window: '7d' });
19
+ });
20
+ it.each([
21
+ ['requestId corto', { requestId: 'a', mode: 'LIVE', inputs: {} }],
22
+ ['mode desconocido', { requestId: 'req-12345678', mode: 'DRY', inputs: {} }],
23
+ ['inputs con objeto anidado', { requestId: 'req-12345678', mode: 'LIVE', inputs: { a: { b: { c: 1 } } } }],
24
+ ])('rechaza: %s', async (_name, value) => {
25
+ expect((await validate(parse(CreateRunRequest, value))).length).toBeGreaterThan(0);
26
+ });
27
+ });
28
+
29
+ describe('ApproveRunRequest', () => {
30
+ it('excludeSubjectKeys es opcional y acotado', async () => {
31
+ expect(await validate(parse(ApproveRunRequest, {}))).toEqual([]);
32
+ expect(await validate(parse(ApproveRunRequest, { excludeSubjectKeys: ['a1b2c3d4e5f60718'] }))).toEqual([]);
33
+ expect((await validate(parse(ApproveRunRequest, { excludeSubjectKeys: [5] }))).length).toBeGreaterThan(0);
34
+ expect((await validate(parse(ApproveRunRequest, { excludeSubjectKeys: Array.from({ length: 1001 }, () => 'a1b2c3d4e5f60718') }))).length).toBeGreaterThan(0);
35
+ });
36
+ });
@@ -5,6 +5,7 @@ export declare class GroupCreateRequest {
5
5
  description: string;
6
6
  leaderEmail?: string | null;
7
7
  leaderDirectoryId?: string | null;
8
+ ownerDirectoryId?: string;
8
9
  status: GroupStatus;
9
10
  codeToRefer?: Array<string>;
10
11
  uniqueMainDirectory?: string;
@@ -44,6 +44,11 @@ __decorate([
44
44
  (0, class_transformer_1.Transform)(({ value }) => value ?? null),
45
45
  __metadata("design:type", String)
46
46
  ], GroupCreateRequest.prototype, "leaderDirectoryId", void 0);
47
+ __decorate([
48
+ (0, class_validator_1.IsOptional)(),
49
+ (0, class_validator_1.IsUUID)('4'),
50
+ __metadata("design:type", String)
51
+ ], GroupCreateRequest.prototype, "ownerDirectoryId", void 0);
47
52
  __decorate([
48
53
  (0, class_validator_1.IsEnum)(GroupStatus_1.GroupStatus),
49
54
  __metadata("design:type", String)
@@ -1,4 +1,5 @@
1
1
  import { GroupStatus } from "../enums/GroupStatus";
2
+ import type { GroupOwnerItem } from "../../referral-business/dtos/GroupOwnersByGroupIdsResponse";
2
3
  export declare class GroupResponse {
3
4
  id: string;
4
5
  name: string;
@@ -15,4 +16,5 @@ export declare class GroupResponse {
15
16
  imageUrl?: string | null;
16
17
  imageUrlSigned?: string | null;
17
18
  parentGroupId: string;
19
+ owner?: GroupOwnerItem | null;
18
20
  }
@@ -0,0 +1,4 @@
1
+ export declare const GROUP_OWNERS_BY_GROUP_IDS_MAX_BATCH = 100;
2
+ export declare class GroupOwnersByGroupIdsRequest {
3
+ groupIds: string[];
4
+ }
@@ -0,0 +1,25 @@
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.GroupOwnersByGroupIdsRequest = exports.GROUP_OWNERS_BY_GROUP_IDS_MAX_BATCH = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ // Tope de groupIds por request del endpoint batch de owners de grupo.
15
+ exports.GROUP_OWNERS_BY_GROUP_IDS_MAX_BATCH = 100;
16
+ // Body de POST /private/agents/owners/by-group-ids; la lista vacía es válida y responde {}.
17
+ class GroupOwnersByGroupIdsRequest {
18
+ }
19
+ exports.GroupOwnersByGroupIdsRequest = GroupOwnersByGroupIdsRequest;
20
+ __decorate([
21
+ (0, class_validator_1.IsArray)(),
22
+ (0, class_validator_1.ArrayMaxSize)(exports.GROUP_OWNERS_BY_GROUP_IDS_MAX_BATCH),
23
+ (0, class_validator_1.IsString)({ each: true }),
24
+ __metadata("design:type", Array)
25
+ ], GroupOwnersByGroupIdsRequest.prototype, "groupIds", void 0);
@@ -0,0 +1,8 @@
1
+ export interface GroupOwnerItem {
2
+ agentId: string;
3
+ directoryId: string;
4
+ name: string | null;
5
+ email: string | null;
6
+ status: string;
7
+ }
8
+ export type GroupOwnersByGroupIdsResponse = Record<string, GroupOwnerItem>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,5 @@
1
1
  export * from './enums/AgentRoleEnum';
2
2
  export * from './dtos/AgentsByDirectoryIdsRequest';
3
3
  export * from './dtos/AgentsByDirectoryIdsResponse';
4
+ export * from './dtos/GroupOwnersByGroupIdsRequest';
5
+ export * from './dtos/GroupOwnersByGroupIdsResponse';
@@ -19,3 +19,5 @@ __exportStar(require("./enums/AgentRoleEnum"), exports);
19
19
  //dtos
20
20
  __exportStar(require("./dtos/AgentsByDirectoryIdsRequest"), exports);
21
21
  __exportStar(require("./dtos/AgentsByDirectoryIdsResponse"), exports);
22
+ __exportStar(require("./dtos/GroupOwnersByGroupIdsRequest"), exports);
23
+ __exportStar(require("./dtos/GroupOwnersByGroupIdsResponse"), exports);
@@ -0,0 +1,12 @@
1
+ /** Id de campaña, evaluación (minúsculas, dígitos y guion; 2 a 64; sin `#` ni `:` porque entran en llaves compuestas y en la idempotencyKey). */
2
+ export declare const ELIGIBILITY_ID_PATTERN: RegExp;
3
+ /** `eventKey` de un tipo de evento: MAYÚSCULAS con guion bajo (ej. `PHONE_SALES_CODE_REDEEMED`). */
4
+ export declare const EVENT_KEY_PATTERN: RegExp;
5
+ /** Fecha de vigencia de una campaña (UTC, inclusiva). */
6
+ export declare const DATE_PATTERN: RegExp;
7
+ /** Id de solicitud que genera el backoffice al abrir el formulario de una corrida manual (llave de idempotencia). */
8
+ export declare const REQUEST_ID_PATTERN: RegExp;
9
+ /** Cupos por campaña que caben junto a las reservas de una transacción (100 − 90 − registro del lote). */
10
+ export declare const MAX_QUOTAS_PER_CAMPAIGN = 9;
11
+ /** Tope de `limit` de los listados paginados. */
12
+ export declare const LIST_PAGE_MAX = 100;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LIST_PAGE_MAX = exports.MAX_QUOTAS_PER_CAMPAIGN = exports.REQUEST_ID_PATTERN = exports.DATE_PATTERN = exports.EVENT_KEY_PATTERN = exports.ELIGIBILITY_ID_PATTERN = void 0;
4
+ /** Id de campaña, evaluación (minúsculas, dígitos y guion; 2 a 64; sin `#` ni `:` porque entran en llaves compuestas y en la idempotencyKey). */
5
+ exports.ELIGIBILITY_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$/;
6
+ /** `eventKey` de un tipo de evento: MAYÚSCULAS con guion bajo (ej. `PHONE_SALES_CODE_REDEEMED`). */
7
+ exports.EVENT_KEY_PATTERN = /^[A-Z][A-Z0-9_]{2,63}$/;
8
+ /** Fecha de vigencia de una campaña (UTC, inclusiva). */
9
+ exports.DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
10
+ /** Id de solicitud que genera el backoffice al abrir el formulario de una corrida manual (llave de idempotencia). */
11
+ exports.REQUEST_ID_PATTERN = /^[A-Za-z0-9_-]{8,64}$/;
12
+ /** Cupos por campaña que caben junto a las reservas de una transacción (100 − 90 − registro del lote). */
13
+ exports.MAX_QUOTAS_PER_CAMPAIGN = 9;
14
+ /** Tope de `limit` de los listados paginados. */
15
+ exports.LIST_PAGE_MAX = 100;
@@ -1,7 +1,27 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.CampaignAlerts = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
4
15
  /** Umbrales de consumo (0 a 1) que avisan a los operadores (spec B 5.6). */
5
16
  class CampaignAlerts {
6
17
  }
7
18
  exports.CampaignAlerts = CampaignAlerts;
19
+ __decorate([
20
+ (0, class_transformer_1.Expose)(),
21
+ (0, class_validator_1.IsArray)(),
22
+ (0, class_validator_1.ArrayMaxSize)(5),
23
+ (0, class_validator_1.IsNumber)({}, { each: true }),
24
+ (0, class_validator_1.Min)(0.01, { each: true }),
25
+ (0, class_validator_1.Max)(1, { each: true }),
26
+ __metadata("design:type", Array)
27
+ ], CampaignAlerts.prototype, "thresholds", void 0);
@@ -1,7 +1,7 @@
1
1
  import { QuotaPeriodEnum } from '../enums/QuotaPeriodEnum';
2
2
  /** Un cupo de campania: cantidad maxima de premios (no dinero) en un periodo (spec B 5.6). */
3
3
  export declare class CampaignQuota {
4
- /** Unico dentro de la campania (ej. `primeros-500`). Entra en la llave del consumo (`{id}#{periodo}`). */
4
+ /** Unico dentro de la campania (ej. `primeros-500`). Entra en la llave del consumo (`{id}#{periodo}`): sin `#`. */
5
5
  id: string;
6
6
  limit: number;
7
7
  period: QuotaPeriodEnum;
@@ -1,7 +1,36 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.CampaignQuota = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const QuotaPeriodEnum_1 = require("../enums/QuotaPeriodEnum");
4
16
  /** Un cupo de campania: cantidad maxima de premios (no dinero) en un periodo (spec B 5.6). */
5
17
  class CampaignQuota {
6
18
  }
7
19
  exports.CampaignQuota = CampaignQuota;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsString)(),
23
+ (0, class_validator_1.Matches)(/^[a-z0-9][a-z0-9-]{0,62}$/),
24
+ __metadata("design:type", String)
25
+ ], CampaignQuota.prototype, "id", void 0);
26
+ __decorate([
27
+ (0, class_transformer_1.Expose)(),
28
+ (0, class_validator_1.IsInt)(),
29
+ (0, class_validator_1.Min)(1),
30
+ __metadata("design:type", Number)
31
+ ], CampaignQuota.prototype, "limit", void 0);
32
+ __decorate([
33
+ (0, class_transformer_1.Expose)(),
34
+ (0, class_validator_1.IsEnum)(QuotaPeriodEnum_1.QuotaPeriodEnum),
35
+ __metadata("design:type", String)
36
+ ], CampaignQuota.prototype, "period", void 0);
@@ -0,0 +1,4 @@
1
+ /** `POST /runs/{id}/approve`: aprueba todo salvo los sujetos excluidos (`subjectKey`). */
2
+ export declare class ApproveRunRequest {
3
+ excludeSubjectKeys?: string[];
4
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ApproveRunRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /** `POST /runs/{id}/approve`: aprueba todo salvo los sujetos excluidos (`subjectKey`). */
16
+ class ApproveRunRequest {
17
+ }
18
+ exports.ApproveRunRequest = ApproveRunRequest;
19
+ __decorate([
20
+ (0, class_transformer_1.Expose)(),
21
+ (0, class_validator_1.IsOptional)(),
22
+ (0, class_validator_1.IsArray)(),
23
+ (0, class_validator_1.ArrayMaxSize)(1000),
24
+ (0, class_validator_1.IsString)({ each: true }),
25
+ (0, class_validator_1.Matches)(/^[A-Za-z0-9_-]{8,128}$/, { each: true }),
26
+ __metadata("design:type", Array)
27
+ ], ApproveRunRequest.prototype, "excludeSubjectKeys", void 0);
@@ -0,0 +1,6 @@
1
+ import { CampaignResponse } from './CampaignResponse';
2
+ export declare class CampaignListResponse {
3
+ items: CampaignResponse[];
4
+ /** Cursor opaco de la página siguiente; ausente en la última. */
5
+ nextCursor?: string;
6
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CampaignListResponse = void 0;
4
+ class CampaignListResponse {
5
+ }
6
+ exports.CampaignListResponse = CampaignListResponse;
@@ -0,0 +1,16 @@
1
+ import { QuotaExhaustedActionEnum } from '../../enums/QuotaExhaustedActionEnum';
2
+ import { CampaignAlerts } from '../CampaignAlerts';
3
+ import { CampaignQuota } from '../CampaignQuota';
4
+ /** Crear (POST) o reemplazar (PUT) una campaña. `status`, `pausedReason` y las fechas de auditoría las pone el servidor (el estado cambia con `POST /campaigns/{id}/status`). */
5
+ export declare class CampaignRequest {
6
+ id: string;
7
+ name: string;
8
+ /** Qué se quiere lograr (texto libre). */
9
+ objective: string;
10
+ /** `AAAA-MM-DD` (UTC, inclusiva). */
11
+ startsAt: string;
12
+ endsAt: string;
13
+ quotas: CampaignQuota[];
14
+ onExhausted: QuotaExhaustedActionEnum;
15
+ alerts: CampaignAlerts;
16
+ }