@adtrackify/at-service-common 4.0.5 → 4.0.6

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 (79) hide show
  1. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +1 -0
  2. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +646 -0
  3. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +1 -0
  4. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +1 -0
  5. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +327 -0
  6. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -0
  7. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +250 -108
  8. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
  9. package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js +37 -36
  10. package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
  11. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.d.ts +1 -0
  12. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js +567 -0
  13. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -0
  14. package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.d.ts +3 -0
  15. package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.js +7 -0
  16. package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.js.map +1 -0
  17. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.d.ts +14 -0
  18. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js +251 -0
  19. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -0
  20. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +24 -0
  21. package/dist/cjs/services/db/{identity-cache-dynamodb-service.js → identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js} +221 -343
  22. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -0
  23. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +22 -0
  24. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +375 -0
  25. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -0
  26. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.d.ts +4 -0
  27. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js +21 -0
  28. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js.map +1 -0
  29. package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.d.ts +12 -0
  30. package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.js +32 -0
  31. package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.js.map +1 -0
  32. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.d.ts +205 -0
  33. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js +35 -0
  34. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js.map +1 -0
  35. package/dist/cjs/services/db/index.d.ts +4 -1
  36. package/dist/cjs/services/db/index.js +4 -1
  37. package/dist/cjs/services/db/index.js.map +1 -1
  38. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +1 -0
  39. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +644 -0
  40. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +1 -0
  41. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +1 -0
  42. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +325 -0
  43. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -0
  44. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +250 -108
  45. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
  46. package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js +37 -36
  47. package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
  48. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.d.ts +1 -0
  49. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js +565 -0
  50. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -0
  51. package/dist/esm/services/db/identity-cache-dynamodb-service/constants.d.ts +3 -0
  52. package/dist/esm/services/db/identity-cache-dynamodb-service/constants.js +4 -0
  53. package/dist/esm/services/db/identity-cache-dynamodb-service/constants.js.map +1 -0
  54. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.d.ts +14 -0
  55. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js +234 -0
  56. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -0
  57. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +24 -0
  58. package/dist/esm/services/db/{identity-cache-dynamodb-service.js → identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js} +199 -321
  59. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -0
  60. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +22 -0
  61. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +368 -0
  62. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -0
  63. package/dist/esm/services/db/identity-cache-dynamodb-service/index.d.ts +4 -0
  64. package/dist/esm/services/db/identity-cache-dynamodb-service/index.js +5 -0
  65. package/dist/esm/services/db/identity-cache-dynamodb-service/index.js.map +1 -0
  66. package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.d.ts +12 -0
  67. package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.js +24 -0
  68. package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.js.map +1 -0
  69. package/dist/esm/services/db/identity-cache-dynamodb-service/types.d.ts +205 -0
  70. package/dist/esm/services/db/identity-cache-dynamodb-service/types.js +32 -0
  71. package/dist/esm/services/db/identity-cache-dynamodb-service/types.js.map +1 -0
  72. package/dist/esm/services/db/index.d.ts +4 -1
  73. package/dist/esm/services/db/index.js +4 -1
  74. package/dist/esm/services/db/index.js.map +1 -1
  75. package/package.json +2 -1
  76. package/dist/cjs/services/db/identity-cache-dynamodb-service.d.ts +0 -44
  77. package/dist/cjs/services/db/identity-cache-dynamodb-service.js.map +0 -1
  78. package/dist/esm/services/db/identity-cache-dynamodb-service.d.ts +0 -44
  79. package/dist/esm/services/db/identity-cache-dynamodb-service.js.map +0 -1
@@ -0,0 +1,565 @@
1
+ const mockInvokeFunction = jest.fn();
2
+ const mockBuildAndSendMessage = jest.fn();
3
+ const mockSQSClientConstructor = jest.fn();
4
+ jest.mock('../../clients/index.js', () => ({
5
+ DynamoDbClient: {
6
+ safeGet: jest.fn(),
7
+ safePut: jest.fn(),
8
+ safeDelete: jest.fn(),
9
+ safeBatchGet: jest.fn(),
10
+ safeBatchWrite: jest.fn(),
11
+ safeQueryByGSI: jest.fn(),
12
+ batchWrite: jest.fn(),
13
+ },
14
+ LambdaInvokeClient: jest.fn().mockImplementation(() => ({
15
+ invokeFunction: mockInvokeFunction,
16
+ })),
17
+ SQSClient: jest.fn().mockImplementation((_region, _accountId, _queueName) => {
18
+ mockSQSClientConstructor(_region, _accountId, _queueName);
19
+ return {
20
+ buildAndSendMessage: mockBuildAndSendMessage,
21
+ queueUrl: `https://sqs.${_region}.amazonaws.com/${_accountId}/${_queueName}`,
22
+ };
23
+ }),
24
+ }));
25
+ jest.mock('../../helpers/index.js', () => ({
26
+ Logger: {
27
+ debug: jest.fn(),
28
+ info: jest.fn(),
29
+ warn: jest.fn(),
30
+ error: jest.fn(),
31
+ },
32
+ }));
33
+ import { IdentityGatewayService, } from '../../services/db/identity-cache-dynamodb-service/identity-gateway-service.js';
34
+ import { IDENTITY_CACHE_WITH_CACHING_OUTCOME, } from '../../services/db/identity-cache-dynamodb-service/types.js';
35
+ import { DynamoDbClient, SQSClient } from '../../clients/index.js';
36
+ import { Logger } from '../../helpers/index.js';
37
+ const mockedDynamoDbClient = DynamoDbClient;
38
+ const mockedLogger = Logger;
39
+ const mockedSQSClient = SQSClient;
40
+ describe('IdentityGatewayService new features', () => {
41
+ const pixelId = 'pixel123';
42
+ const lambdaArn = 'arn:aws:lambda:us-east-1:123456789:function:identity-private';
43
+ beforeEach(() => {
44
+ jest.clearAllMocks();
45
+ mockedDynamoDbClient.safeGet.mockReset();
46
+ mockedDynamoDbClient.safePut.mockReset();
47
+ mockedDynamoDbClient.safeDelete.mockReset();
48
+ mockedDynamoDbClient.safeBatchGet.mockReset();
49
+ mockedDynamoDbClient.safeBatchWrite.mockReset();
50
+ mockedDynamoDbClient.safeQueryByGSI.mockReset();
51
+ mockedDynamoDbClient.batchWrite.mockReset();
52
+ mockInvokeFunction.mockReset();
53
+ mockBuildAndSendMessage.mockReset();
54
+ mockSQSClientConstructor.mockReset();
55
+ mockedSQSClient.mockClear();
56
+ IdentityGatewayService.lambdaInvokeClient = undefined;
57
+ IdentityGatewayService.sqsClient = undefined;
58
+ IdentityGatewayService.sqsQueueUrl = undefined;
59
+ });
60
+ describe('configure()', () => {
61
+ it('should configure with direct queue URL', () => {
62
+ const options = {
63
+ asyncUpdateQueueUrl: 'https://sqs.us-east-1.amazonaws.com/123456789/test-queue',
64
+ };
65
+ IdentityGatewayService.configure(options);
66
+ expect(IdentityGatewayService.sqsQueueUrl).toBe(options.asyncUpdateQueueUrl);
67
+ });
68
+ it('should configure with region/accountId/queueName', () => {
69
+ const options = {
70
+ awsRegion: 'us-east-1',
71
+ awsAccountId: '123456789',
72
+ asyncUpdateQueueName: 'identity-async-queue',
73
+ };
74
+ IdentityGatewayService.configure(options);
75
+ expect(mockSQSClientConstructor).toHaveBeenCalledWith('us-east-1', '123456789', 'identity-async-queue');
76
+ expect(IdentityGatewayService.sqsClient).toBeDefined();
77
+ expect(IdentityGatewayService.sqsQueueUrl).toBeDefined();
78
+ });
79
+ it('should fallback to environment variable for queue name', () => {
80
+ const originalEnv = process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME;
81
+ process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME = 'env-queue-name';
82
+ try {
83
+ const options = {
84
+ awsRegion: 'us-west-2',
85
+ awsAccountId: '987654321',
86
+ };
87
+ IdentityGatewayService.configure(options);
88
+ expect(mockSQSClientConstructor).toHaveBeenCalledWith('us-west-2', '987654321', 'env-queue-name');
89
+ }
90
+ finally {
91
+ if (originalEnv !== undefined) {
92
+ process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME = originalEnv;
93
+ }
94
+ else {
95
+ delete process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME;
96
+ }
97
+ }
98
+ });
99
+ it('should not configure SQS when region/accountId provided but no queue name', () => {
100
+ const originalEnv = process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME;
101
+ delete process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME;
102
+ try {
103
+ const options = {
104
+ awsRegion: 'us-east-1',
105
+ awsAccountId: '123456789',
106
+ };
107
+ IdentityGatewayService.configure(options);
108
+ expect(mockSQSClientConstructor).not.toHaveBeenCalled();
109
+ expect(IdentityGatewayService.sqsClient).toBeUndefined();
110
+ }
111
+ finally {
112
+ if (originalEnv !== undefined) {
113
+ process.env.IDENTIFY_ASYNC_UPDATE_QUEUE_NAME = originalEnv;
114
+ }
115
+ }
116
+ });
117
+ it('should not configure SQS when only region provided', () => {
118
+ const options = {
119
+ awsRegion: 'us-east-1',
120
+ };
121
+ IdentityGatewayService.configure(options);
122
+ expect(mockSQSClientConstructor).not.toHaveBeenCalled();
123
+ expect(IdentityGatewayService.sqsClient).toBeUndefined();
124
+ });
125
+ });
126
+ describe('enqueueAsyncIdentityUpdate()', () => {
127
+ const testIdentity = {
128
+ identityId: 'identity456',
129
+ traits: { emails: ['test@email.com'] },
130
+ };
131
+ const testContext = {
132
+ identity: testIdentity,
133
+ };
134
+ it('should return error result when SQS client is not configured', async () => {
135
+ const result = await IdentityGatewayService.enqueueAsyncIdentityUpdate({
136
+ pixelId,
137
+ identity: testIdentity,
138
+ context: testContext,
139
+ reason: 'test reason',
140
+ eventId: 'event123',
141
+ });
142
+ expect(result.success).toBe(false);
143
+ expect(result.error).toBe('SQS client not configured');
144
+ expect(result.messageId).toBeUndefined();
145
+ expect(mockedLogger.warn).toHaveBeenCalledWith('IdentityGateway - enqueueAsyncIdentityUpdate: SQS client not configured', expect.objectContaining({
146
+ pixelId,
147
+ identityId: testIdentity.identityId,
148
+ reason: 'test reason',
149
+ eventId: 'event123',
150
+ }));
151
+ });
152
+ it('should successfully enqueue message when SQS client is configured', async () => {
153
+ IdentityGatewayService.configure({
154
+ awsRegion: 'us-east-1',
155
+ awsAccountId: '123456789',
156
+ asyncUpdateQueueName: 'test-queue',
157
+ });
158
+ mockBuildAndSendMessage.mockResolvedValueOnce({
159
+ MessageId: 'sqs-message-id-123',
160
+ });
161
+ const result = await IdentityGatewayService.enqueueAsyncIdentityUpdate({
162
+ pixelId,
163
+ identity: testIdentity,
164
+ context: testContext,
165
+ reason: 'stale cache traits',
166
+ eventId: 'event456',
167
+ });
168
+ expect(result.success).toBe(true);
169
+ expect(result.messageId).toBe('sqs-message-id-123');
170
+ expect(result.error).toBeUndefined();
171
+ expect(mockBuildAndSendMessage).toHaveBeenCalledWith('identify.updateAsync', expect.objectContaining({
172
+ pixelId,
173
+ incomingIdentityId: testIdentity.identityId,
174
+ context: testContext,
175
+ }));
176
+ expect(mockedLogger.debug).toHaveBeenCalledWith('IdentityGateway - enqueueAsyncIdentityUpdate: message sent', expect.objectContaining({
177
+ pixelId,
178
+ identityId: testIdentity.identityId,
179
+ reason: 'stale cache traits',
180
+ eventId: 'event456',
181
+ sqsMessageId: 'sqs-message-id-123',
182
+ }));
183
+ });
184
+ it('should fail open with logging when SQS send fails', async () => {
185
+ IdentityGatewayService.configure({
186
+ awsRegion: 'us-east-1',
187
+ awsAccountId: '123456789',
188
+ asyncUpdateQueueName: 'test-queue',
189
+ });
190
+ mockBuildAndSendMessage.mockRejectedValueOnce(new Error('SQS send failed'));
191
+ const result = await IdentityGatewayService.enqueueAsyncIdentityUpdate({
192
+ pixelId,
193
+ identity: testIdentity,
194
+ context: testContext,
195
+ reason: 'test reason',
196
+ eventId: 'event789',
197
+ });
198
+ expect(result.success).toBe(false);
199
+ expect(result.error).toBe('SQS send failed');
200
+ expect(result.messageId).toBeUndefined();
201
+ expect(mockedLogger.warn).toHaveBeenCalledWith('IdentityGateway - enqueueAsyncIdentityUpdate: failed to enqueue (failing open)', expect.objectContaining({
202
+ error: expect.any(Error),
203
+ errorMessage: 'SQS send failed',
204
+ pixelId,
205
+ identityId: testIdentity.identityId,
206
+ reason: 'test reason',
207
+ eventId: 'event789',
208
+ }));
209
+ });
210
+ it('should build message shape matching IdentifyAsyncUpdateMessage interface', async () => {
211
+ IdentityGatewayService.configure({
212
+ awsRegion: 'us-east-1',
213
+ awsAccountId: '123456789',
214
+ asyncUpdateQueueName: 'test-queue',
215
+ });
216
+ mockBuildAndSendMessage.mockResolvedValueOnce({ MessageId: 'test-id' });
217
+ const identity = {
218
+ identityId: 'id-xyz',
219
+ traits: { emails: ['user@example.com'], userIds: ['user-1'] },
220
+ };
221
+ const context = { identity };
222
+ await IdentityGatewayService.enqueueAsyncIdentityUpdate({
223
+ pixelId: 'pixel-abc',
224
+ identity,
225
+ context,
226
+ reason: 'test',
227
+ });
228
+ const messageArg = mockBuildAndSendMessage.mock.calls[0][1];
229
+ expect(messageArg).toEqual({
230
+ pixelId: 'pixel-abc',
231
+ incomingIdentityId: 'id-xyz',
232
+ context,
233
+ });
234
+ });
235
+ it('should return error when identity has no identityId', async () => {
236
+ IdentityGatewayService.configure({
237
+ awsRegion: 'us-east-1',
238
+ awsAccountId: '123456789',
239
+ asyncUpdateQueueName: 'test-queue',
240
+ });
241
+ const identityWithoutId = {
242
+ traits: { emails: ['anon@example.com'] },
243
+ };
244
+ const context = { identity: identityWithoutId };
245
+ const result = await IdentityGatewayService.enqueueAsyncIdentityUpdate({
246
+ pixelId,
247
+ identity: identityWithoutId,
248
+ context,
249
+ reason: 'anonymous identity',
250
+ });
251
+ expect(result.success).toBe(false);
252
+ expect(result.error).toBe('Missing required pixelId or identityId');
253
+ expect(mockBuildAndSendMessage).not.toHaveBeenCalled();
254
+ });
255
+ it('should handle optional eventId parameter', async () => {
256
+ IdentityGatewayService.configure({
257
+ awsRegion: 'us-east-1',
258
+ awsAccountId: '123456789',
259
+ asyncUpdateQueueName: 'test-queue',
260
+ });
261
+ mockBuildAndSendMessage.mockResolvedValueOnce({ MessageId: 'test-id' });
262
+ await IdentityGatewayService.enqueueAsyncIdentityUpdate({
263
+ pixelId,
264
+ identity: testIdentity,
265
+ context: testContext,
266
+ reason: 'test',
267
+ });
268
+ expect(mockedLogger.debug).toHaveBeenCalledWith('IdentityGateway - enqueueAsyncIdentityUpdate: message sent', expect.objectContaining({
269
+ eventId: undefined,
270
+ }));
271
+ });
272
+ });
273
+ describe('getIdentityWithCachingV2() with skipCacheWrite option', () => {
274
+ const incomingIdentity = {
275
+ identityId: 'identity456',
276
+ traits: { emails: ['test@email.com'] },
277
+ };
278
+ describe('default behavior (no options)', () => {
279
+ it('should write to cache when Neptune returns new identity', async () => {
280
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
281
+ mockInvokeFunction.mockResolvedValueOnce({
282
+ statusCode: 200,
283
+ body: JSON.stringify({
284
+ identity: {
285
+ identityId: 'resolved-identity',
286
+ traits: { emails: ['test@email.com', 'resolved@email.com'] },
287
+ },
288
+ }),
289
+ });
290
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn);
291
+ expect(result.summary.didWriteCache).toBe(true);
292
+ expect(mockedDynamoDbClient.safeBatchWrite).toHaveBeenCalled();
293
+ });
294
+ });
295
+ describe('skipCacheWrite: false', () => {
296
+ it('should write to cache (same as default)', async () => {
297
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
298
+ mockInvokeFunction.mockResolvedValueOnce({
299
+ statusCode: 200,
300
+ body: JSON.stringify({
301
+ identity: {
302
+ identityId: 'resolved-identity',
303
+ traits: { emails: ['test@email.com'] },
304
+ },
305
+ }),
306
+ });
307
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn, { skipCacheWrite: false });
308
+ expect(result.summary.didWriteCache).toBe(true);
309
+ expect(mockedDynamoDbClient.safeBatchWrite).toHaveBeenCalled();
310
+ });
311
+ });
312
+ describe('skipCacheWrite: true', () => {
313
+ it('should NOT write to cache on Neptune write-back path', async () => {
314
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
315
+ mockInvokeFunction.mockResolvedValueOnce({
316
+ statusCode: 200,
317
+ body: JSON.stringify({
318
+ identity: {
319
+ identityId: 'resolved-identity',
320
+ traits: { emails: ['test@email.com', 'resolved@email.com'] },
321
+ },
322
+ }),
323
+ });
324
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn, { skipCacheWrite: true });
325
+ expect(result.identity?.identityId).toBe('resolved-identity');
326
+ expect(result.summary.didWriteCache).toBe(false);
327
+ expect(result.summary.outcome).toBe(IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_WRITE_BACK);
328
+ expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
329
+ });
330
+ it('should NOT write to cache on address update path', async () => {
331
+ const cachedResponse = {
332
+ pk: `identity#${pixelId}#identity456`,
333
+ pixelId,
334
+ identityId: 'identity456',
335
+ response: {
336
+ identityId: 'identity456',
337
+ traits: {
338
+ emails: ['test@email.com'],
339
+ addresses: [{ city: 'Old City', upa: 1704067200000 }],
340
+ },
341
+ },
342
+ updatedAt: new Date().toISOString(),
343
+ };
344
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
345
+ const identityWithNewAddress = {
346
+ identityId: 'identity456',
347
+ traits: {
348
+ emails: ['test@email.com'],
349
+ addresses: [{ city: 'New City', upa: 1717200000000 }],
350
+ },
351
+ };
352
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, identityWithNewAddress, lambdaArn, { skipCacheWrite: true });
353
+ if (result.summary.outcome === IDENTITY_CACHE_WITH_CACHING_OUTCOME.ADDRESS_UPDATE_WRITE) {
354
+ expect(result.summary.didWriteCache).toBe(false);
355
+ expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
356
+ }
357
+ });
358
+ it('should still return resolved identity when skipCacheWrite is true', async () => {
359
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
360
+ mockInvokeFunction.mockResolvedValueOnce({
361
+ statusCode: 200,
362
+ body: JSON.stringify({
363
+ identity: {
364
+ identityId: 'neptune-resolved-id',
365
+ traits: { emails: ['test@email.com', 'new@email.com'] },
366
+ },
367
+ }),
368
+ });
369
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn, { skipCacheWrite: true });
370
+ expect(result.identity).toBeDefined();
371
+ expect(result.identity?.identityId).toBe('neptune-resolved-id');
372
+ expect(result.identity?.traits?.emails).toContain('new@email.com');
373
+ });
374
+ it('should return fresh cache hit without writing (skipCacheWrite irrelevant for hits)', async () => {
375
+ const cachedResponse = {
376
+ pk: `identity#${pixelId}#identity456`,
377
+ pixelId,
378
+ identityId: 'identity456',
379
+ response: {
380
+ identityId: 'identity456',
381
+ traits: { emails: ['test@email.com'] },
382
+ },
383
+ updatedAt: new Date().toISOString(),
384
+ };
385
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
386
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, incomingIdentity, lambdaArn, { skipCacheWrite: true });
387
+ expect(result.summary.outcome).toBe(IDENTITY_CACHE_WITH_CACHING_OUTCOME.FRESH_CACHE_HIT);
388
+ expect(result.summary.didWriteCache).toBe(false);
389
+ expect(mockInvokeFunction).not.toHaveBeenCalled();
390
+ expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
391
+ });
392
+ });
393
+ describe('address update path with skipCacheWrite', () => {
394
+ it('should write cache when skipCacheWrite is false and address update triggers write', async () => {
395
+ const cachedResponse = {
396
+ pk: `identity#${pixelId}#identity456`,
397
+ pixelId,
398
+ identityId: 'identity456',
399
+ response: {
400
+ identityId: 'identity456',
401
+ traits: {
402
+ emails: ['test@email.com'],
403
+ addresses: [{ city: 'Old City', upa: 1704067200000 }],
404
+ },
405
+ },
406
+ updatedAt: new Date().toISOString(),
407
+ };
408
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
409
+ const identityWithNewAddress = {
410
+ identityId: 'identity456',
411
+ traits: {
412
+ emails: ['test@email.com'],
413
+ addresses: [{ city: 'New City', upa: 1717200000000 }],
414
+ },
415
+ };
416
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, identityWithNewAddress, lambdaArn, { skipCacheWrite: false });
417
+ if (result.summary.outcome === IDENTITY_CACHE_WITH_CACHING_OUTCOME.ADDRESS_UPDATE_WRITE) {
418
+ expect(result.summary.didWriteCache).toBe(true);
419
+ expect(mockedDynamoDbClient.safeBatchWrite).toHaveBeenCalled();
420
+ }
421
+ });
422
+ });
423
+ });
424
+ describe('edge cases', () => {
425
+ it('should return invalid input when pixelId is undefined', async () => {
426
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(undefined, { identityId: 'test' }, lambdaArn);
427
+ expect(result.identity).toBeUndefined();
428
+ expect(result.summary.outcome).toBe(IDENTITY_CACHE_WITH_CACHING_OUTCOME.INVALID_INPUT);
429
+ expect(result.summary.didReadCache).toBe(false);
430
+ expect(result.summary.didWriteCache).toBe(false);
431
+ });
432
+ it('should return invalid input when incomingIdentity is null', async () => {
433
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, null, lambdaArn);
434
+ expect(result.identity).toBeUndefined();
435
+ expect(result.summary.outcome).toBe(IDENTITY_CACHE_WITH_CACHING_OUTCOME.INVALID_INPUT);
436
+ });
437
+ it('should return invalid input when both pixelId and identity are missing', async () => {
438
+ const result = await IdentityGatewayService.getIdentityWithCachingV2('', undefined, lambdaArn);
439
+ expect(result.identity).toBeUndefined();
440
+ expect(result.summary.outcome).toBe(IDENTITY_CACHE_WITH_CACHING_OUTCOME.INVALID_INPUT);
441
+ });
442
+ it('should gracefully fallback when cache read fails (fail-open pattern)', async () => {
443
+ mockedDynamoDbClient.safeGet.mockRejectedValueOnce(new Error('Unexpected DynamoDB error'));
444
+ mockInvokeFunction.mockResolvedValueOnce({
445
+ statusCode: 200,
446
+ body: JSON.stringify({
447
+ identity: {
448
+ identityId: 'neptune-resolved',
449
+ traits: { emails: ['test@email.com'] },
450
+ },
451
+ }),
452
+ });
453
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, { identityId: 'test-id', traits: { emails: ['test@email.com'] } }, lambdaArn);
454
+ expect(result.identity).toBeDefined();
455
+ expect(result.identity?.identityId).toBe('neptune-resolved');
456
+ expect(result.summary.didReadCache).toBe(true);
457
+ expect(result.summary.didCallNeptune).toBe(true);
458
+ });
459
+ it('should reject identity with undefined identityId in enqueue', async () => {
460
+ IdentityGatewayService.configure({
461
+ awsRegion: 'us-east-1',
462
+ awsAccountId: '123456789',
463
+ asyncUpdateQueueName: 'test-queue',
464
+ });
465
+ const identity = { traits: { emails: ['test@email.com'] } };
466
+ const context = { identity };
467
+ const result = await IdentityGatewayService.enqueueAsyncIdentityUpdate({
468
+ pixelId,
469
+ identity,
470
+ context,
471
+ reason: 'anonymous user',
472
+ });
473
+ expect(result.success).toBe(false);
474
+ expect(result.error).toBe('Missing required pixelId or identityId');
475
+ expect(mockBuildAndSendMessage).not.toHaveBeenCalled();
476
+ expect(mockedLogger.warn).toHaveBeenCalledWith('IdentityGateway - enqueueAsyncIdentityUpdate: missing required params', expect.objectContaining({
477
+ pixelId,
478
+ identityId: undefined,
479
+ }));
480
+ });
481
+ });
482
+ describe('safeWriteBackToCache behavior with skipCacheWrite', () => {
483
+ it('should not call safeWriteBackToCache when skipCacheWrite is true and Neptune returns new identity', async () => {
484
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
485
+ mockInvokeFunction.mockResolvedValueOnce({
486
+ statusCode: 200,
487
+ body: JSON.stringify({
488
+ identity: {
489
+ identityId: 'new-resolved-identity',
490
+ traits: { emails: ['test@email.com'] },
491
+ },
492
+ }),
493
+ });
494
+ await IdentityGatewayService.getIdentityWithCachingV2(pixelId, { identityId: 'original-id', traits: { emails: ['test@email.com'] } }, lambdaArn, { skipCacheWrite: true });
495
+ expect(mockedDynamoDbClient.safeBatchWrite).not.toHaveBeenCalled();
496
+ });
497
+ it('should call safeWriteBackToCache when skipCacheWrite is false and Neptune returns new identity', async () => {
498
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
499
+ mockInvokeFunction.mockResolvedValueOnce({
500
+ statusCode: 200,
501
+ body: JSON.stringify({
502
+ identity: {
503
+ identityId: 'new-resolved-identity',
504
+ traits: { emails: ['test@email.com'] },
505
+ },
506
+ }),
507
+ });
508
+ await IdentityGatewayService.getIdentityWithCachingV2(pixelId, { identityId: 'original-id', traits: { emails: ['test@email.com'] } }, lambdaArn, { skipCacheWrite: false });
509
+ expect(mockedDynamoDbClient.safeBatchWrite).toHaveBeenCalled();
510
+ });
511
+ });
512
+ describe('summary fields consistency', () => {
513
+ it('should include all required summary fields in getIdentityWithCachingV2 result', async () => {
514
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
515
+ mockInvokeFunction.mockResolvedValueOnce({
516
+ statusCode: 200,
517
+ body: JSON.stringify({
518
+ identity: {
519
+ identityId: 'resolved-id',
520
+ traits: { emails: ['test@email.com'] },
521
+ },
522
+ }),
523
+ });
524
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, { identityId: 'incoming-id', traits: { emails: ['test@email.com'] } }, lambdaArn, { skipCacheWrite: true });
525
+ expect(result.summary).toEqual(expect.objectContaining({
526
+ outcome: expect.any(String),
527
+ pixelId,
528
+ identityId: 'resolved-id',
529
+ didReadCache: true,
530
+ didCallNeptune: true,
531
+ didWriteCache: false,
532
+ didSkipNeptune: false,
533
+ didFallbackToIncoming: false,
534
+ staleTraits: expect.any(Array),
535
+ }));
536
+ });
537
+ it('should include traitChanges in summary when identity changes', async () => {
538
+ const cachedResponse = {
539
+ pk: `identity#${pixelId}#identity456`,
540
+ pixelId,
541
+ identityId: 'identity456',
542
+ response: {
543
+ identityId: 'identity456',
544
+ traits: { emails: ['old@email.com'] },
545
+ },
546
+ updatedAt: new Date().toISOString(),
547
+ };
548
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedResponse);
549
+ mockInvokeFunction.mockResolvedValueOnce({
550
+ statusCode: 200,
551
+ body: JSON.stringify({
552
+ identity: {
553
+ identityId: 'identity456',
554
+ traits: { emails: ['old@email.com', 'new@email.com'] },
555
+ },
556
+ }),
557
+ });
558
+ const result = await IdentityGatewayService.getIdentityWithCachingV2(pixelId, { identityId: 'identity456', traits: { emails: ['old@email.com', 'new@email.com'] } }, lambdaArn);
559
+ if (result.summary.outcome === IDENTITY_CACHE_WITH_CACHING_OUTCOME.NEPTUNE_WRITE_BACK) {
560
+ expect(result.summary.traitChanges).toBeDefined();
561
+ }
562
+ });
563
+ });
564
+ });
565
+ //# sourceMappingURL=identity-gateway-service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-gateway-service.spec.js","sourceRoot":"","sources":["../../../../src/__tests__/identity-cache/identity-gateway-service.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const IDENTITY_CACHE_TABLE_NAME: string;
2
+ export declare const IDENTITY_CACHE_GSI1_NAME: string;
3
+ export declare const FORCE_PURGE_TTL_SECONDS: number;
@@ -0,0 +1,4 @@
1
+ export const IDENTITY_CACHE_TABLE_NAME = process.env.IDENTITY_CACHE_TABLE_V2 ?? '';
2
+ export const IDENTITY_CACHE_GSI1_NAME = process.env.IDENTITY_CACHE_GSI1 ?? 'gsi1pk-index';
3
+ export const FORCE_PURGE_TTL_SECONDS = 60 * 60 * 24 * 30;
4
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../src/services/db/identity-cache-dynamodb-service/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC;AACnF,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,cAAc,CAAC;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { EventIdentity } from '@adtrackify/at-tracking-event-types';
2
+ import { IdentityCacheStaleTracker } from '../../../helpers/identity-cache-helper.js';
3
+ import { IdentityCacheTraitChanges, IdentityCacheLookupResult, IdentityCacheLookupState, IdentityCacheLookupStateSummaryInput, IdentityCacheLookupSummary, IdentityCacheLookupSummaryInput, IdentityCacheWithCachingResult, IdentityCacheWithCachingState, IdentityCacheWithCachingStateSummaryInput, IdentityCacheWithCachingSummary, IdentityCacheWithCachingSummaryInput } from './types.js';
4
+ export declare function createIdentityCacheLookupState(pixelId: string, incomingIdentity: EventIdentity): IdentityCacheLookupState;
5
+ export declare function createIdentityCacheLookupSummary({ outcome, pixelId, identityId, didLookupByIdentityId, didLookupByEmail, isDeepEqual, isCacheStale, staleTier, staleTraits, writeReason, skipNeptune, cachedIdentity, incomingIdentity, mergedIdentity, resolvedIdentity, discoveredIdentityId, errorMessage, }: IdentityCacheLookupSummaryInput): IdentityCacheLookupSummary;
6
+ export declare function createIdentityCacheLookupResult(cacheResult: IdentityCacheLookupResult['cacheResult'], summaryInput: IdentityCacheLookupSummaryInput): IdentityCacheLookupResult;
7
+ export declare function createIdentityCacheLookupResultFromState(state: IdentityCacheLookupState, cacheResult: IdentityCacheLookupResult['cacheResult'], summaryInput: IdentityCacheLookupStateSummaryInput): IdentityCacheLookupResult;
8
+ export declare function createCacheMissLookupResult(state: IdentityCacheLookupState, outcome: IdentityCacheLookupStateSummaryInput['outcome'], summaryOverrides?: Partial<IdentityCacheLookupStateSummaryInput>): IdentityCacheLookupResult;
9
+ export declare function createIdentityCacheWithCachingSummary({ outcome, pixelId, identityId, writeReason, staleTier, staleTraits, didReadCache, didCallNeptune, didWriteCache, didSkipNeptune, didFallbackToIncoming, cachedIdentity, incomingIdentity, identityForNeptune, resolvedIdentity, neptuneIdentity, traitChanges, hasDiscoveredIdentityId, lookupSummary, errorMessage, }: IdentityCacheWithCachingSummaryInput): IdentityCacheWithCachingSummary;
10
+ export declare function createIdentityCacheWithCachingResult(identity: EventIdentity | undefined, summaryInput: IdentityCacheWithCachingSummaryInput): IdentityCacheWithCachingResult;
11
+ export declare function createIdentityCacheWithCachingResultFromState(state: IdentityCacheWithCachingState, identity: EventIdentity | undefined, summaryInput: IdentityCacheWithCachingStateSummaryInput): IdentityCacheWithCachingResult;
12
+ export declare function stripAddressTimestamps(identity: EventIdentity): EventIdentity;
13
+ export declare function extractStaleTraitNames(tracker: IdentityCacheStaleTracker): string[];
14
+ export declare function computeTraitChanges(cachedIdentity: EventIdentity, resolvedIdentity: EventIdentity): IdentityCacheTraitChanges;