@adtrackify/at-service-common 4.0.5 → 4.0.7

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