@adtrackify/at-service-common 4.0.12 → 4.0.14

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 (71) hide show
  1. package/dist/cjs/__tests__/identity-cache/helpers.spec.js +37 -38
  2. package/dist/cjs/__tests__/identity-cache/helpers.spec.js.map +1 -1
  3. package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js +83 -344
  4. package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
  5. package/dist/cjs/__tests__/identity-cache/identity-client.spec.js +360 -0
  6. package/dist/cjs/__tests__/identity-cache/identity-client.spec.js.map +1 -0
  7. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js +335 -1261
  8. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -1
  9. package/dist/cjs/clients/internal-api/identity-client.d.ts +12 -2
  10. package/dist/cjs/clients/internal-api/identity-client.js +59 -13
  11. package/dist/cjs/clients/internal-api/identity-client.js.map +1 -1
  12. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +1 -7
  13. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js +0 -305
  14. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -1
  15. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +10 -9
  16. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +116 -321
  17. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -1
  18. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.d.ts +0 -1
  19. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js +0 -1
  20. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js.map +1 -1
  21. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.d.ts +9 -157
  22. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js +1 -15
  23. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js.map +1 -1
  24. package/dist/esm/__tests__/identity-cache/helpers.spec.js +26 -27
  25. package/dist/esm/__tests__/identity-cache/helpers.spec.js.map +1 -1
  26. package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js +83 -344
  27. package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
  28. package/dist/esm/__tests__/identity-cache/identity-client.spec.js +358 -0
  29. package/dist/esm/__tests__/identity-cache/identity-client.spec.js.map +1 -0
  30. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js +335 -1261
  31. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -1
  32. package/dist/esm/clients/internal-api/identity-client.d.ts +12 -2
  33. package/dist/esm/clients/internal-api/identity-client.js +60 -14
  34. package/dist/esm/clients/internal-api/identity-client.js.map +1 -1
  35. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +1 -7
  36. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js +1 -303
  37. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -1
  38. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +10 -9
  39. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +119 -321
  40. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -1
  41. package/dist/esm/services/db/identity-cache-dynamodb-service/index.d.ts +0 -1
  42. package/dist/esm/services/db/identity-cache-dynamodb-service/index.js +0 -1
  43. package/dist/esm/services/db/identity-cache-dynamodb-service/index.js.map +1 -1
  44. package/dist/esm/services/db/identity-cache-dynamodb-service/types.d.ts +9 -157
  45. package/dist/esm/services/db/identity-cache-dynamodb-service/types.js +0 -14
  46. package/dist/esm/services/db/identity-cache-dynamodb-service/types.js.map +1 -1
  47. package/package.json +2 -2
  48. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +0 -646
  49. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +0 -1
  50. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +0 -325
  51. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +0 -1
  52. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.d.ts +0 -1
  53. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +0 -1286
  54. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +0 -1
  55. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.d.ts +0 -26
  56. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js +0 -252
  57. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js.map +0 -1
  58. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +0 -1
  59. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +0 -644
  60. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +0 -1
  61. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +0 -1
  62. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +0 -323
  63. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +0 -1
  64. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.d.ts +0 -1
  65. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +0 -1284
  66. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +0 -1
  67. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.d.ts +0 -26
  68. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js +0 -235
  69. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js.map +0 -1
  70. /package/dist/cjs/__tests__/identity-cache/{identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts → identity-client.spec.d.ts} +0 -0
  71. /package/dist/{cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts → esm/__tests__/identity-cache/identity-client.spec.d.ts} +0 -0
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const at_tracking_event_types_1 = require("@adtrackify/at-tracking-event-types");
4
- const at_shared_utils_1 = require("@adtrackify/at-shared-utils");
5
- const identity_cache_dynamodb_service_1 = require("../../services/db/identity-cache-dynamodb-service");
6
- const mockInvokeFunction = jest.fn();
4
+ const mockLambdaInvoke = jest.fn();
7
5
  const mockBuildAndSendMessage = jest.fn();
8
6
  const mockSQSClientConstructor = jest.fn();
9
7
  jest.mock('../../clients/index.js', () => ({
@@ -17,7 +15,7 @@ jest.mock('../../clients/index.js', () => ({
17
15
  batchWrite: jest.fn(),
18
16
  },
19
17
  LambdaInvokeClient: jest.fn().mockImplementation(() => ({
20
- invokeFunction: mockInvokeFunction,
18
+ invokeFunction: mockLambdaInvoke,
21
19
  })),
22
20
  SQSClient: jest.fn().mockImplementation((_region, _accountId, _queueName) => {
23
21
  mockSQSClientConstructor(_region, _accountId, _queueName);
@@ -35,15 +33,19 @@ jest.mock('../../helpers/index.js', () => ({
35
33
  error: jest.fn(),
36
34
  },
37
35
  }));
36
+ const mockGetIdentity = jest.fn();
37
+ jest.mock('../../clients/internal-api/identity-client.js', () => ({
38
+ IdentityClient: jest.fn().mockImplementation(() => ({
39
+ getIdentity: mockGetIdentity,
40
+ })),
41
+ }));
38
42
  const identity_gateway_service_js_1 = require("../../services/db/identity-cache-dynamodb-service/identity-gateway-service.js");
39
43
  const types_js_1 = require("../../services/db/identity-cache-dynamodb-service/types.js");
40
- const identity_cache_dynamodb_db_service_js_1 = require("../../services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js");
41
44
  const index_js_1 = require("../../clients/index.js");
42
45
  const mockedDynamoDbClient = index_js_1.DynamoDbClient;
43
46
  const _mockedSQSClient = index_js_1.SQSClient;
44
47
  describe('Identity Cache Three-Tier Routing', () => {
45
48
  const pixelId = 'pixel123';
46
- const lambdaArn = 'arn:aws:lambda:us-east-1:123456789:function:identity-private';
47
49
  beforeEach(() => {
48
50
  jest.clearAllMocks();
49
51
  mockedDynamoDbClient.safeGet.mockReset();
@@ -53,13 +55,14 @@ describe('Identity Cache Three-Tier Routing', () => {
53
55
  mockedDynamoDbClient.safeBatchWrite.mockReset();
54
56
  mockedDynamoDbClient.safeQueryByGSI.mockReset();
55
57
  mockedDynamoDbClient.batchWrite.mockReset();
56
- mockInvokeFunction.mockReset();
58
+ mockGetIdentity.mockReset();
57
59
  mockBuildAndSendMessage.mockReset();
58
60
  mockSQSClientConstructor.mockReset();
59
61
  _mockedSQSClient.mockClear();
60
- identity_gateway_service_js_1.IdentityGatewayService.lambdaInvokeClient = undefined;
62
+ identity_gateway_service_js_1.IdentityGatewayService.identityClient = undefined;
61
63
  identity_gateway_service_js_1.IdentityGatewayService.sqsClient = undefined;
62
64
  identity_gateway_service_js_1.IdentityGatewayService.sqsQueueUrl = undefined;
65
+ identity_gateway_service_js_1.IdentityGatewayService.configure({ identifyPrivateLambdaArn: 'arn:aws:lambda:us-east-1:123456789:function:identity-private' });
63
66
  });
64
67
  describe('TIER: VOLATILE_ONLY — Returns merged identity, NO Neptune, NO cache write', () => {
65
68
  it('should return merged identity without Neptune call when only ipAddress is stale', async () => {
@@ -84,10 +87,10 @@ describe('Identity Cache Three-Tier Routing', () => {
84
87
  updatedAt: new Date().toISOString(),
85
88
  };
86
89
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
87
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
90
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
88
91
  expect(result.identity).toBeDefined();
89
92
  expect(result.identity?.identityId).toBe('identity456');
90
- expect(mockInvokeFunction).not.toHaveBeenCalled();
93
+ expect(mockGetIdentity).not.toHaveBeenCalled();
91
94
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
92
95
  });
93
96
  it('should return merged identity without Neptune call when only userAgent is stale', async () => {
@@ -112,9 +115,9 @@ describe('Identity Cache Three-Tier Routing', () => {
112
115
  updatedAt: new Date().toISOString(),
113
116
  };
114
117
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
115
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
118
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
116
119
  expect(result.identity).toBeDefined();
117
- expect(mockInvokeFunction).not.toHaveBeenCalled();
120
+ expect(mockGetIdentity).not.toHaveBeenCalled();
118
121
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
119
122
  });
120
123
  it('should return merged identity without Neptune call when only IP-sourced addresses are stale', async () => {
@@ -139,117 +142,12 @@ describe('Identity Cache Three-Tier Routing', () => {
139
142
  updatedAt: new Date().toISOString(),
140
143
  };
141
144
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
142
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
145
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
143
146
  expect(result.identity).toBeDefined();
144
- expect(mockInvokeFunction).not.toHaveBeenCalled();
147
+ expect(mockGetIdentity).not.toHaveBeenCalled();
145
148
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
146
149
  });
147
150
  });
148
- describe('TIER: ADDRESS_UPDATE — Enqueues async update, NO Neptune call, NO sync cache write', () => {
149
- it('should enqueue async update but skip Neptune when new non-IP address is added', async () => {
150
- identity_gateway_service_js_1.IdentityGatewayService.configure({
151
- awsRegion: 'us-east-1',
152
- awsAccountId: '123456789',
153
- asyncUpdateQueueName: 'test-queue',
154
- });
155
- mockBuildAndSendMessage.mockResolvedValueOnce({ MessageId: 'test-msg-id' });
156
- const incomingIdentity = {
157
- identityId: 'identity456',
158
- traits: {
159
- emails: ['test@email.com'],
160
- addresses: [{ city: 'Boston', firstName: 'John', s: at_tracking_event_types_1.ADDRESS_INFO_SOURCE.INPUT }],
161
- },
162
- };
163
- const cachedResponse = {
164
- pk: `identity#${pixelId}#identity456`,
165
- pixelId,
166
- identityId: 'identity456',
167
- response: {
168
- identityId: 'identity456',
169
- traits: {
170
- emails: ['test@email.com'],
171
- addresses: [],
172
- },
173
- },
174
- updatedAt: new Date().toISOString(),
175
- };
176
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
177
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
178
- expect(result.identity).toBeDefined();
179
- expect(result.identity?.traits?.addresses).toHaveLength(1);
180
- expect(mockInvokeFunction).not.toHaveBeenCalled();
181
- expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
182
- expect(mockBuildAndSendMessage).toHaveBeenCalled();
183
- });
184
- it('should enqueue async update and skip Neptune when address with PII but no source is added', async () => {
185
- identity_gateway_service_js_1.IdentityGatewayService.configure({
186
- awsRegion: 'us-east-1',
187
- awsAccountId: '123456789',
188
- asyncUpdateQueueName: 'test-queue',
189
- });
190
- mockBuildAndSendMessage.mockResolvedValueOnce({ MessageId: 'test-msg-id' });
191
- const incomingIdentity = {
192
- identityId: 'identity456',
193
- traits: {
194
- emails: ['test@email.com'],
195
- addresses: [{ city: 'Miami', lastName: 'Smith' }],
196
- },
197
- };
198
- const cachedResponse = {
199
- pk: `identity#${pixelId}#identity456`,
200
- pixelId,
201
- identityId: 'identity456',
202
- response: {
203
- identityId: 'identity456',
204
- traits: {
205
- emails: ['test@email.com'],
206
- addresses: [],
207
- },
208
- },
209
- updatedAt: new Date().toISOString(),
210
- };
211
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
212
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
213
- expect(result.identity).toBeDefined();
214
- expect(mockInvokeFunction).not.toHaveBeenCalled();
215
- expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
216
- expect(mockBuildAndSendMessage).toHaveBeenCalled();
217
- });
218
- it('should return ADDRESS_UPDATE_ASYNC outcome in summary', async () => {
219
- identity_gateway_service_js_1.IdentityGatewayService.configure({
220
- awsRegion: 'us-east-1',
221
- awsAccountId: '123456789',
222
- asyncUpdateQueueName: 'test-queue',
223
- });
224
- mockBuildAndSendMessage.mockResolvedValueOnce({ MessageId: 'test-msg-id' });
225
- const incomingIdentity = {
226
- identityId: 'identity456',
227
- traits: {
228
- emails: ['test@email.com'],
229
- addresses: [{ city: 'Seattle', s: at_tracking_event_types_1.ADDRESS_INFO_SOURCE.INPUT }],
230
- },
231
- };
232
- const cachedResponse = {
233
- pk: `identity#${pixelId}#identity456`,
234
- pixelId,
235
- identityId: 'identity456',
236
- response: {
237
- identityId: 'identity456',
238
- traits: {
239
- emails: ['test@email.com'],
240
- addresses: [],
241
- },
242
- },
243
- updatedAt: new Date().toISOString(),
244
- };
245
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
246
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
247
- expect(result.summary.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.ADDRESS_UPDATE_ASYNC);
248
- expect(result.summary.didSkipNeptune).toBe(true);
249
- expect(result.summary.didWriteCache).toBe(false);
250
- expect(result.summary.didEnqueueAsync).toBe(true);
251
- });
252
- });
253
151
  describe('TIER: IDENTITY_STALE — Calls Neptune AND writes to cache', () => {
254
152
  it('should call Neptune and write to cache when emails are stale', async () => {
255
153
  const incomingIdentity = {
@@ -271,18 +169,13 @@ describe('Identity Cache Three-Tier Routing', () => {
271
169
  updatedAt: new Date().toISOString(),
272
170
  };
273
171
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
274
- mockInvokeFunction.mockResolvedValueOnce({
275
- statusCode: 200,
276
- body: JSON.stringify({
277
- identity: {
278
- identityId: 'identity456',
279
- traits: { emails: ['old@email.com', 'new@email.com', 'resolved@email.com'] },
280
- },
281
- }),
172
+ mockGetIdentity.mockResolvedValueOnce({
173
+ identityId: 'identity456',
174
+ traits: { emails: ['old@email.com', 'new@email.com', 'resolved@email.com'] },
282
175
  });
283
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
176
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
284
177
  expect(result.identity).toBeDefined();
285
- expect(mockInvokeFunction).toHaveBeenCalled();
178
+ expect(mockGetIdentity).toHaveBeenCalled();
286
179
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
287
180
  });
288
181
  it('should call Neptune and write to cache when phones are stale', async () => {
@@ -305,18 +198,13 @@ describe('Identity Cache Three-Tier Routing', () => {
305
198
  updatedAt: new Date().toISOString(),
306
199
  };
307
200
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
308
- mockInvokeFunction.mockResolvedValueOnce({
309
- statusCode: 200,
310
- body: JSON.stringify({
311
- identity: {
312
- identityId: 'identity456',
313
- traits: { phones: ['+1234567890', '+9876543210'] },
314
- },
315
- }),
201
+ mockGetIdentity.mockResolvedValueOnce({
202
+ identityId: 'identity456',
203
+ traits: { phones: ['+1234567890', '+9876543210'] },
316
204
  });
317
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
205
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
318
206
  expect(result.identity).toBeDefined();
319
- expect(mockInvokeFunction).toHaveBeenCalled();
207
+ expect(mockGetIdentity).toHaveBeenCalled();
320
208
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
321
209
  });
322
210
  it('should return NEPTUNE_WRITE_BACK outcome with staleTraits in summary', async () => {
@@ -337,20 +225,15 @@ describe('Identity Cache Three-Tier Routing', () => {
337
225
  updatedAt: new Date().toISOString(),
338
226
  };
339
227
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
340
- mockInvokeFunction.mockResolvedValueOnce({
341
- statusCode: 200,
342
- body: JSON.stringify({
343
- identity: {
344
- identityId: 'identity456',
345
- traits: { emails: ['old@email.com', 'new@email.com'] },
346
- },
347
- }),
228
+ mockGetIdentity.mockResolvedValueOnce({
229
+ identityId: 'identity456',
230
+ traits: { emails: ['old@email.com', 'new@email.com'] },
348
231
  });
349
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
350
- expect(result.summary.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_RESOLVED);
351
- expect(result.summary.staleTraits).toContain('emails');
352
- expect(result.summary.didCallNeptune).toBe(true);
353
- expect(result.summary.didWriteCache).toBe(false);
232
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
233
+ expect(result.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_RESOLVED);
234
+ expect(result.stalenessResult?.staleTraits).toContain('emails');
235
+ expect(result.didCallNeptune).toBe(true);
236
+ expect(result.didWriteCache).toBe(false);
354
237
  });
355
238
  });
356
239
  describe('CACHE_MISS — Calls Neptune AND writes to cache', () => {
@@ -360,18 +243,13 @@ describe('Identity Cache Three-Tier Routing', () => {
360
243
  traits: { emails: ['test@email.com'] },
361
244
  };
362
245
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
363
- mockInvokeFunction.mockResolvedValueOnce({
364
- statusCode: 200,
365
- body: JSON.stringify({
366
- identity: {
367
- identityId: 'identity456',
368
- traits: { emails: ['test@email.com'] },
369
- },
370
- }),
246
+ mockGetIdentity.mockResolvedValueOnce({
247
+ identityId: 'identity456',
248
+ traits: { emails: ['test@email.com'] },
371
249
  });
372
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
250
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
373
251
  expect(result.identity).toBeDefined();
374
- expect(mockInvokeFunction).toHaveBeenCalled();
252
+ expect(mockGetIdentity).toHaveBeenCalled();
375
253
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
376
254
  });
377
255
  it('should return NEPTUNE_WRITE_BACK outcome for cache miss', async () => {
@@ -380,19 +258,14 @@ describe('Identity Cache Three-Tier Routing', () => {
380
258
  traits: { emails: ['test@email.com'] },
381
259
  };
382
260
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
383
- mockInvokeFunction.mockResolvedValueOnce({
384
- statusCode: 200,
385
- body: JSON.stringify({
386
- identity: {
387
- identityId: 'identity456',
388
- traits: { emails: ['test@email.com'] },
389
- },
390
- }),
261
+ mockGetIdentity.mockResolvedValueOnce({
262
+ identityId: 'identity456',
263
+ traits: { emails: ['test@email.com'] },
391
264
  });
392
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
393
- expect(result.summary.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_RESOLVED);
394
- expect(result.summary.didCallNeptune).toBe(true);
395
- expect(result.summary.didWriteCache).toBe(false);
265
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
266
+ expect(result.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_RESOLVED);
267
+ expect(result.didCallNeptune).toBe(true);
268
+ expect(result.didWriteCache).toBe(false);
396
269
  });
397
270
  });
398
271
  describe('EMAIL_POINTER_DISCOVERY — Calls Neptune with discovered identityId', () => {
@@ -408,35 +281,28 @@ describe('Identity Cache Three-Tier Routing', () => {
408
281
  updatedAt: new Date().toISOString(),
409
282
  };
410
283
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(pointerRecord);
411
- mockInvokeFunction.mockResolvedValueOnce({
412
- statusCode: 200,
413
- body: JSON.stringify({
414
- identity: {
415
- identityId: 'discovered-id',
416
- traits: { emails: ['test@email.com', 'other@email.com'] },
417
- },
418
- }),
284
+ mockGetIdentity.mockResolvedValueOnce({
285
+ identityId: 'discovered-id',
286
+ traits: { emails: ['test@email.com', 'other@email.com'] },
419
287
  });
420
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
288
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
421
289
  expect(result.identity?.identityId).toBe('discovered-id');
422
- expect(mockInvokeFunction).toHaveBeenCalledWith(lambdaArn, expect.objectContaining({
423
- context: {
424
- identity: expect.objectContaining({
425
- traits: { emails: ['test@email.com'] },
426
- }),
427
- },
290
+ expect(mockGetIdentity).toHaveBeenCalledWith(pixelId, expect.objectContaining({
291
+ identity: expect.objectContaining({
292
+ identityId: 'discovered-id',
293
+ traits: expect.objectContaining({ emails: ['test@email.com'] }),
294
+ }),
428
295
  }));
429
296
  });
430
297
  });
431
298
  });
432
299
  describe('Identity Cache stripAddressTimestamps', () => {
433
300
  const pixelId = 'pixel123';
434
- const lambdaArn = 'arn:aws:lambda:us-east-1:123456789:function:identity-private';
435
301
  beforeEach(() => {
436
302
  jest.clearAllMocks();
437
303
  mockedDynamoDbClient.safeGet.mockReset();
438
304
  mockedDynamoDbClient.safeBatchWrite.mockReset();
439
- mockInvokeFunction.mockReset();
305
+ mockGetIdentity.mockReset();
440
306
  identity_gateway_service_js_1.IdentityGatewayService.lambdaInvokeClient = undefined;
441
307
  });
442
308
  it('should strip cra and upa from addresses during comparison', async () => {
@@ -475,9 +341,9 @@ describe('Identity Cache stripAddressTimestamps', () => {
475
341
  updatedAt: new Date().toISOString(),
476
342
  };
477
343
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
478
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
344
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
479
345
  expect(result.identity).toBeDefined();
480
- expect(mockInvokeFunction).not.toHaveBeenCalled();
346
+ expect(mockGetIdentity).not.toHaveBeenCalled();
481
347
  });
482
348
  it('should NOT mutate the original object when stripping timestamps', async () => {
483
349
  const originalAddress = {
@@ -514,7 +380,7 @@ describe('Identity Cache stripAddressTimestamps', () => {
514
380
  updatedAt: new Date().toISOString(),
515
381
  };
516
382
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
517
- await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
383
+ await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
518
384
  expect(incomingIdentity.traits?.addresses?.[0]).toHaveProperty('cra');
519
385
  expect(incomingIdentity.traits?.addresses?.[0]).toHaveProperty('upa');
520
386
  expect(cachedResponse.response.traits?.addresses?.[0]).toHaveProperty('cra');
@@ -540,9 +406,9 @@ describe('Identity Cache stripAddressTimestamps', () => {
540
406
  updatedAt: new Date().toISOString(),
541
407
  };
542
408
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
543
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
409
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
544
410
  expect(result.identity).toBeDefined();
545
- expect(mockInvokeFunction).not.toHaveBeenCalled();
411
+ expect(mockGetIdentity).not.toHaveBeenCalled();
546
412
  });
547
413
  it('should handle identity with empty addresses array', async () => {
548
414
  const incomingIdentity = {
@@ -566,9 +432,9 @@ describe('Identity Cache stripAddressTimestamps', () => {
566
432
  updatedAt: new Date().toISOString(),
567
433
  };
568
434
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
569
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
435
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
570
436
  expect(result.identity).toBeDefined();
571
- expect(mockInvokeFunction).not.toHaveBeenCalled();
437
+ expect(mockGetIdentity).not.toHaveBeenCalled();
572
438
  });
573
439
  it('should handle addresses without cra/upa (no-op)', async () => {
574
440
  const incomingIdentity = {
@@ -592,19 +458,18 @@ describe('Identity Cache stripAddressTimestamps', () => {
592
458
  updatedAt: new Date().toISOString(),
593
459
  };
594
460
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
595
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
461
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
596
462
  expect(result.identity).toBeDefined();
597
- expect(mockInvokeFunction).not.toHaveBeenCalled();
463
+ expect(mockGetIdentity).not.toHaveBeenCalled();
598
464
  });
599
465
  });
600
466
  describe('Identity Cache fastDeepEqual with Timestamp Stripping', () => {
601
467
  const pixelId = 'pixel123';
602
- const lambdaArn = 'arn:aws:lambda:us-east-1:123456789:function:identity-private';
603
468
  beforeEach(() => {
604
469
  jest.clearAllMocks();
605
470
  mockedDynamoDbClient.safeGet.mockReset();
606
471
  mockedDynamoDbClient.safeBatchWrite.mockReset();
607
- mockInvokeFunction.mockReset();
472
+ mockGetIdentity.mockReset();
608
473
  identity_gateway_service_js_1.IdentityGatewayService.lambdaInvokeClient = undefined;
609
474
  });
610
475
  it('should treat cached and merged as equal when they differ ONLY in cra/upa', async () => {
@@ -647,9 +512,9 @@ describe('Identity Cache fastDeepEqual with Timestamp Stripping', () => {
647
512
  updatedAt: new Date().toISOString(),
648
513
  };
649
514
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
650
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
515
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
651
516
  expect(result.identity).toBeDefined();
652
- expect(mockInvokeFunction).not.toHaveBeenCalled();
517
+ expect(mockGetIdentity).not.toHaveBeenCalled();
653
518
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
654
519
  });
655
520
  it('should treat cached and merged as NOT equal when address content differs (plus cra/upa)', async () => {
@@ -690,18 +555,17 @@ describe('Identity Cache fastDeepEqual with Timestamp Stripping', () => {
690
555
  updatedAt: new Date().toISOString(),
691
556
  };
692
557
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
693
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
558
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
694
559
  expect(result.identity).toBeDefined();
695
560
  });
696
561
  });
697
562
  describe('Identity Cache Logging Levels', () => {
698
563
  const pixelId = 'pixel123';
699
- const lambdaArn = 'arn:aws:lambda:us-east-1:123456789:function:identity-private';
700
564
  beforeEach(() => {
701
565
  jest.clearAllMocks();
702
566
  mockedDynamoDbClient.safeGet.mockReset();
703
567
  mockedDynamoDbClient.safeBatchWrite.mockReset();
704
- mockInvokeFunction.mockReset();
568
+ mockGetIdentity.mockReset();
705
569
  identity_gateway_service_js_1.IdentityGatewayService.lambdaInvokeClient = undefined;
706
570
  });
707
571
  it('should return fresh cache hit without calling Neptune or writing cache', async () => {
@@ -724,45 +588,11 @@ describe('Identity Cache Logging Levels', () => {
724
588
  updatedAt: new Date().toISOString(),
725
589
  };
726
590
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
727
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
728
- expect(result.summary.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.FRESH_CACHE_HIT);
729
- expect(mockInvokeFunction).not.toHaveBeenCalled();
591
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
592
+ expect(result.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.FRESH_CACHE_HIT);
593
+ expect(mockGetIdentity).not.toHaveBeenCalled();
730
594
  expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
731
595
  });
732
- it('should return ADDRESS_UPDATE_ASYNC outcome for address update path', async () => {
733
- identity_gateway_service_js_1.IdentityGatewayService.configure({
734
- awsRegion: 'us-east-1',
735
- awsAccountId: '123456789',
736
- asyncUpdateQueueName: 'test-queue',
737
- });
738
- mockBuildAndSendMessage.mockResolvedValueOnce({ MessageId: 'test-msg-id' });
739
- const incomingIdentity = {
740
- identityId: 'identity456',
741
- traits: {
742
- emails: ['test@email.com'],
743
- addresses: [{ city: 'New City', s: at_tracking_event_types_1.ADDRESS_INFO_SOURCE.INPUT }],
744
- },
745
- };
746
- const cachedResponse = {
747
- pk: `identity#${pixelId}#identity456`,
748
- pixelId,
749
- identityId: 'identity456',
750
- response: {
751
- identityId: 'identity456',
752
- traits: {
753
- emails: ['test@email.com'],
754
- addresses: [],
755
- },
756
- },
757
- updatedAt: new Date().toISOString(),
758
- };
759
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
760
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
761
- expect(result.summary.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.ADDRESS_UPDATE_ASYNC);
762
- expect(result.summary.didSkipNeptune).toBe(true);
763
- expect(result.summary.didWriteCache).toBe(false);
764
- expect(result.summary.didEnqueueAsync).toBe(true);
765
- });
766
596
  it('should return NEPTUNE_WRITE_BACK outcome with traitChanges for stale traits', async () => {
767
597
  const incomingIdentity = {
768
598
  identityId: 'identity456',
@@ -783,107 +613,16 @@ describe('Identity Cache Logging Levels', () => {
783
613
  updatedAt: new Date().toISOString(),
784
614
  };
785
615
  mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
786
- mockInvokeFunction.mockResolvedValueOnce({
787
- statusCode: 200,
788
- body: JSON.stringify({
789
- identity: {
790
- identityId: 'identity456',
791
- traits: { emails: ['old@email.com', 'new@email.com'] },
792
- },
793
- }),
794
- });
795
- const result = await identity_gateway_service_js_1.IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
796
- expect(result.summary.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_RESOLVED);
797
- expect(result.summary.staleTraits).toContain('emails');
798
- expect(result.summary.traitChanges).toBeDefined();
799
- expect(result.summary.didCallNeptune).toBe(true);
800
- expect(result.summary.didWriteCache).toBe(false);
801
- });
802
- });
803
- describe('getIdentityFromCache staleness tier results', () => {
804
- const pixelId = 'pixel123';
805
- beforeEach(() => {
806
- jest.clearAllMocks();
807
- mockedDynamoDbClient.safeGet.mockReset();
808
- });
809
- it('should return staleTier NONE when cached and incoming are deep equal', async () => {
810
- const incomingIdentity = {
811
- identityId: 'identity456',
812
- traits: {
813
- emails: ['test@email.com'],
814
- },
815
- };
816
- const cachedResponse = {
817
- pk: `identity#${pixelId}#identity456`,
818
- pixelId,
819
- identityId: 'identity456',
820
- response: {
821
- identityId: 'identity456',
822
- traits: {
823
- emails: ['test@email.com'],
824
- },
825
- },
826
- updatedAt: new Date().toISOString(),
827
- };
828
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
829
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getIdentityFromCache(pixelId, incomingIdentity);
830
- expect(result.staleTier).toBe(at_shared_utils_1.IDENTITY_CACHE_STALENESS_TIER.NONE);
831
- expect(result.isCacheStale).toBe(false);
832
- expect(result.skipNeptune).toBeUndefined();
833
- });
834
- it('should return staleTier ADDRESS_UPDATE and skipNeptune=true for new non-IP address', async () => {
835
- const incomingIdentity = {
836
- identityId: 'identity456',
837
- traits: {
838
- emails: ['test@email.com'],
839
- addresses: [{ city: 'New City', s: at_tracking_event_types_1.ADDRESS_INFO_SOURCE.INPUT }],
840
- },
841
- };
842
- const cachedResponse = {
843
- pk: `identity#${pixelId}#identity456`,
844
- pixelId,
845
- identityId: 'identity456',
846
- response: {
847
- identityId: 'identity456',
848
- traits: {
849
- emails: ['test@email.com'],
850
- addresses: [],
851
- },
852
- },
853
- updatedAt: new Date().toISOString(),
854
- };
855
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
856
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getIdentityFromCache(pixelId, incomingIdentity);
857
- expect(result.staleTier).toBe(at_shared_utils_1.IDENTITY_CACHE_STALENESS_TIER.ADDRESS_UPDATE);
858
- expect(result.isCacheStale).toBe(true);
859
- expect(result.skipNeptune).toBe(true);
860
- expect(result.writeReason).toBe(identity_cache_dynamodb_service_1.CACHE_WRITE_REASON.ADDRESS_UPDATE);
861
- });
862
- it('should return staleTier IDENTITY_STALE and skipNeptune=false for new email', async () => {
863
- const incomingIdentity = {
616
+ mockGetIdentity.mockResolvedValueOnce({
864
617
  identityId: 'identity456',
865
- traits: {
866
- emails: ['old@email.com', 'new@email.com'],
867
- },
868
- };
869
- const cachedResponse = {
870
- pk: `identity#${pixelId}#identity456`,
871
- pixelId,
872
- identityId: 'identity456',
873
- response: {
874
- identityId: 'identity456',
875
- traits: {
876
- emails: ['old@email.com'],
877
- },
878
- },
879
- updatedAt: new Date().toISOString(),
880
- };
881
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
882
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getIdentityFromCache(pixelId, incomingIdentity);
883
- expect(result.staleTier).toBe(at_shared_utils_1.IDENTITY_CACHE_STALENESS_TIER.IDENTITY_STALE);
884
- expect(result.isCacheStale).toBe(true);
885
- expect(result.skipNeptune).toBe(false);
886
- expect(result.writeReason).toBe(identity_cache_dynamodb_service_1.CACHE_WRITE_REASON.STALE_TRAITS);
618
+ traits: { emails: ['old@email.com', 'new@email.com'] },
619
+ });
620
+ const result = await identity_gateway_service_js_1.IdentityGatewayService.resolveIdentityWithCaching(pixelId, incomingIdentity);
621
+ expect(result.outcome).toBe(types_js_1.IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_RESOLVED);
622
+ expect(result.stalenessResult?.staleTraits).toContain('emails');
623
+ expect(result.traitChanges).toBeDefined();
624
+ expect(result.didCallNeptune).toBe(true);
625
+ expect(result.didWriteCache).toBe(false);
887
626
  });
888
627
  });
889
628
  //# sourceMappingURL=identity-cache-tier-routing.spec.js.map