@adtrackify/at-service-common 4.0.7 → 4.0.9

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 (69) hide show
  1. package/dist/cjs/__tests__/identity-cache/helpers.spec.d.ts +1 -0
  2. package/dist/cjs/__tests__/identity-cache/helpers.spec.js +594 -0
  3. package/dist/cjs/__tests__/identity-cache/helpers.spec.js.map +1 -0
  4. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.d.ts +1 -0
  5. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.js +556 -0
  6. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.js.map +1 -0
  7. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +23 -25
  8. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -1
  9. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +11 -12
  10. package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
  11. package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js +64 -21
  12. package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
  13. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js +1617 -14
  14. package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -1
  15. package/dist/cjs/__tests__/identity-cache/trait-merging-and-staleness.spec.js +711 -0
  16. package/dist/cjs/__tests__/identity-cache/trait-merging-and-staleness.spec.js.map +1 -1
  17. package/dist/cjs/helpers/identity-cache-helper.d.ts +9 -0
  18. package/dist/cjs/helpers/identity-cache-helper.js +54 -1
  19. package/dist/cjs/helpers/identity-cache-helper.js.map +1 -1
  20. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.d.ts +17 -4
  21. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js +35 -33
  22. package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -1
  23. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +4 -2
  24. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js +63 -8
  25. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -1
  26. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +1 -0
  27. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +97 -53
  28. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -1
  29. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.d.ts +1 -0
  30. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js +1 -0
  31. package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js.map +1 -1
  32. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.d.ts +16 -0
  33. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js +9 -1
  34. package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js.map +1 -1
  35. package/dist/esm/__tests__/identity-cache/helpers.spec.d.ts +1 -0
  36. package/dist/esm/__tests__/identity-cache/helpers.spec.js +592 -0
  37. package/dist/esm/__tests__/identity-cache/helpers.spec.js.map +1 -0
  38. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.d.ts +1 -0
  39. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.js +554 -0
  40. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.js.map +1 -0
  41. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +23 -25
  42. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -1
  43. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +11 -12
  44. package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
  45. package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js +65 -22
  46. package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
  47. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js +1617 -14
  48. package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -1
  49. package/dist/esm/__tests__/identity-cache/trait-merging-and-staleness.spec.js +712 -1
  50. package/dist/esm/__tests__/identity-cache/trait-merging-and-staleness.spec.js.map +1 -1
  51. package/dist/esm/helpers/identity-cache-helper.d.ts +9 -0
  52. package/dist/esm/helpers/identity-cache-helper.js +52 -1
  53. package/dist/esm/helpers/identity-cache-helper.js.map +1 -1
  54. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.d.ts +17 -4
  55. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js +33 -31
  56. package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -1
  57. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +4 -2
  58. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js +57 -2
  59. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -1
  60. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +1 -0
  61. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +98 -54
  62. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -1
  63. package/dist/esm/services/db/identity-cache-dynamodb-service/index.d.ts +1 -0
  64. package/dist/esm/services/db/identity-cache-dynamodb-service/index.js +1 -0
  65. package/dist/esm/services/db/identity-cache-dynamodb-service/index.js.map +1 -1
  66. package/dist/esm/services/db/identity-cache-dynamodb-service/types.d.ts +16 -0
  67. package/dist/esm/services/db/identity-cache-dynamodb-service/types.js +8 -0
  68. package/dist/esm/services/db/identity-cache-dynamodb-service/types.js.map +1 -1
  69. package/package.json +1 -1
@@ -0,0 +1,554 @@
1
+ jest.mock('../../clients/index.js', () => ({
2
+ DynamoDbClient: {
3
+ safeGet: jest.fn(),
4
+ safePut: jest.fn(),
5
+ safeDelete: jest.fn(),
6
+ safeBatchGet: jest.fn(),
7
+ safeBatchWrite: jest.fn(),
8
+ safeQueryByGSI: jest.fn(),
9
+ batchWrite: jest.fn(),
10
+ },
11
+ }));
12
+ jest.mock('../../helpers/index.js', () => ({
13
+ Logger: {
14
+ debug: jest.fn(),
15
+ info: jest.fn(),
16
+ warn: jest.fn(),
17
+ error: jest.fn(),
18
+ },
19
+ }));
20
+ import { IdentityCacheDynamoDbDbService } from '../../services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js';
21
+ import { DynamoDbClient } from '../../clients/index.js';
22
+ import { Logger } from '../../helpers/index.js';
23
+ const mockedDynamoDbClient = DynamoDbClient;
24
+ const mockedLogger = Logger;
25
+ describe('IdentityCacheDynamoDbDbService.getIdentityFromCachePure()', () => {
26
+ const pixelId = 'pixel-test-123';
27
+ beforeEach(() => {
28
+ jest.clearAllMocks();
29
+ mockedDynamoDbClient.safeGet.mockReset();
30
+ mockedDynamoDbClient.safePut.mockReset();
31
+ mockedDynamoDbClient.safeBatchWrite.mockReset();
32
+ });
33
+ describe('cache hit by identity ID', () => {
34
+ it('should return cachedIdentity with lookupPath=identity_id and cacheHit=true', async () => {
35
+ const incomingIdentity = {
36
+ identityId: 'identity-123',
37
+ traits: { emails: ['test@email.com'] },
38
+ };
39
+ const cachedRecord = {
40
+ pk: `identity#${pixelId}#identity-123`,
41
+ pixelId,
42
+ identityId: 'identity-123',
43
+ response: {
44
+ identityId: 'identity-123',
45
+ traits: {
46
+ emails: ['test@email.com', 'cached@email.com'],
47
+ phones: ['555-1234'],
48
+ },
49
+ },
50
+ updatedAt: new Date().toISOString(),
51
+ };
52
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
53
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
54
+ expect(result.cacheHit).toBe(true);
55
+ expect(result.lookupPath).toBe('identity_id');
56
+ expect(result.cachedIdentity).toEqual(cachedRecord.response);
57
+ expect(result.discoveredIdentityId).toBeUndefined();
58
+ expect(mockedDynamoDbClient.safeGet).toHaveBeenCalledTimes(1);
59
+ expect(mockedDynamoDbClient.safeGet).toHaveBeenCalledWith(expect.any(String), 'pk', `identity#${pixelId}#identity-123`);
60
+ });
61
+ it('should return cachedIdentity with all traits preserved', async () => {
62
+ const incomingIdentity = {
63
+ identityId: 'full-traits-id',
64
+ traits: { emails: ['new@email.com'] },
65
+ };
66
+ const fullCachedIdentity = {
67
+ identityId: 'full-traits-id',
68
+ traits: {
69
+ emails: ['existing@email.com', 'another@email.com'],
70
+ phones: ['555-1111', '555-2222'],
71
+ addresses: [{ city: 'New York', zip: '10001' }],
72
+ userIds: ['user-1', 'user-2'],
73
+ shopifyYIds: ['shopify-y-1'],
74
+ click: { fbp: 'fb.1.123.456' },
75
+ ipAddress: '192.168.1.1',
76
+ userAgent: 'Mozilla/5.0...',
77
+ },
78
+ };
79
+ const cachedRecord = {
80
+ pk: `identity#${pixelId}#full-traits-id`,
81
+ pixelId,
82
+ identityId: 'full-traits-id',
83
+ response: fullCachedIdentity,
84
+ updatedAt: new Date().toISOString(),
85
+ };
86
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
87
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
88
+ expect(result.cacheHit).toBe(true);
89
+ expect(result.cachedIdentity).toEqual(fullCachedIdentity);
90
+ expect(result.cachedIdentity?.traits?.emails).toHaveLength(2);
91
+ expect(result.cachedIdentity?.traits?.phones).toHaveLength(2);
92
+ expect(result.cachedIdentity?.traits?.addresses).toHaveLength(1);
93
+ });
94
+ it('should NOT perform any merge logic', async () => {
95
+ const incomingIdentity = {
96
+ identityId: 'merge-test-id',
97
+ traits: {
98
+ emails: ['new-email@test.com'],
99
+ phones: ['999-0000'],
100
+ },
101
+ };
102
+ const cachedRecord = {
103
+ pk: `identity#${pixelId}#merge-test-id`,
104
+ pixelId,
105
+ identityId: 'merge-test-id',
106
+ response: {
107
+ identityId: 'merge-test-id',
108
+ traits: {
109
+ emails: ['old-email@test.com'],
110
+ phones: ['111-2222'],
111
+ },
112
+ },
113
+ updatedAt: new Date().toISOString(),
114
+ };
115
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
116
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
117
+ expect(result.cachedIdentity?.traits?.emails).toEqual(['old-email@test.com']);
118
+ expect(result.cachedIdentity?.traits?.phones).toEqual(['111-2222']);
119
+ expect(result.cachedIdentity?.traits?.emails).not.toContain('new-email@test.com');
120
+ });
121
+ it('should NOT perform staleness computation', async () => {
122
+ const incomingIdentity = {
123
+ identityId: 'stale-test-id',
124
+ traits: {
125
+ emails: ['new-email@test.com'],
126
+ },
127
+ };
128
+ const cachedRecord = {
129
+ pk: `identity#${pixelId}#stale-test-id`,
130
+ pixelId,
131
+ identityId: 'stale-test-id',
132
+ response: {
133
+ identityId: 'stale-test-id',
134
+ traits: {
135
+ emails: ['old-email@test.com'],
136
+ },
137
+ },
138
+ updatedAt: new Date().toISOString(),
139
+ };
140
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
141
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
142
+ expect(result).not.toHaveProperty('isCacheStale');
143
+ expect(result).not.toHaveProperty('staleTier');
144
+ expect(result).not.toHaveProperty('staleTracker');
145
+ expect(result).not.toHaveProperty('writeReason');
146
+ expect(result).not.toHaveProperty('skipNeptune');
147
+ });
148
+ });
149
+ describe('cache hit by email pointer', () => {
150
+ it('should return discoveredIdentityId with lookupPath=email_pointer and cacheHit=true', async () => {
151
+ const incomingIdentity = {
152
+ traits: { emails: ['lookup@email.com'] },
153
+ };
154
+ const emailPointerRecord = {
155
+ pk: `email#${pixelId}#lookup@email.com`,
156
+ pixelId,
157
+ identityId: 'discovered-identity-456',
158
+ updatedAt: new Date().toISOString(),
159
+ };
160
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(emailPointerRecord);
161
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
162
+ expect(result.cacheHit).toBe(true);
163
+ expect(result.lookupPath).toBe('email_pointer');
164
+ expect(result.discoveredIdentityId).toBe('discovered-identity-456');
165
+ expect(result.cachedIdentity).toBeUndefined();
166
+ });
167
+ it('should use first email in emails array for lookup', async () => {
168
+ const incomingIdentity = {
169
+ traits: { emails: ['first@email.com', 'second@email.com'] },
170
+ };
171
+ const emailPointerRecord = {
172
+ pk: `email#${pixelId}#first@email.com`,
173
+ pixelId,
174
+ identityId: 'pointer-identity-789',
175
+ updatedAt: new Date().toISOString(),
176
+ };
177
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(emailPointerRecord);
178
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
179
+ expect(result.discoveredIdentityId).toBe('pointer-identity-789');
180
+ expect(mockedDynamoDbClient.safeGet).toHaveBeenCalledWith(expect.any(String), 'pk', `email#${pixelId}#first@email.com`);
181
+ });
182
+ it('should NOT merge traits when returning email pointer discovery', async () => {
183
+ const incomingIdentity = {
184
+ traits: {
185
+ emails: ['discovery@email.com'],
186
+ phones: ['incoming-phone'],
187
+ },
188
+ };
189
+ const emailPointerRecord = {
190
+ pk: `email#${pixelId}#discovery@email.com`,
191
+ pixelId,
192
+ identityId: 'discovered-id',
193
+ updatedAt: new Date().toISOString(),
194
+ };
195
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(emailPointerRecord);
196
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
197
+ expect(result.cachedIdentity).toBeUndefined();
198
+ expect(result.discoveredIdentityId).toBe('discovered-id');
199
+ });
200
+ });
201
+ describe('cache miss', () => {
202
+ it('should return lookupPath=miss and cacheHit=false when identity not found', async () => {
203
+ const incomingIdentity = {
204
+ identityId: 'nonexistent-identity',
205
+ traits: { emails: ['test@email.com'] },
206
+ };
207
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
208
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
209
+ expect(result.cacheHit).toBe(false);
210
+ expect(result.lookupPath).toBe('identity_id');
211
+ expect(result.cachedIdentity).toBeUndefined();
212
+ expect(result.discoveredIdentityId).toBeUndefined();
213
+ });
214
+ it('should return lookupPath=miss and cacheHit=false when email pointer not found', async () => {
215
+ const incomingIdentity = {
216
+ traits: { emails: ['unknown@email.com'] },
217
+ };
218
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
219
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
220
+ expect(result.cacheHit).toBe(false);
221
+ expect(result.lookupPath).toBe('miss');
222
+ expect(result.cachedIdentity).toBeUndefined();
223
+ expect(result.discoveredIdentityId).toBeUndefined();
224
+ });
225
+ it('should return lookupPath=miss when cached record has no response field', async () => {
226
+ const incomingIdentity = {
227
+ identityId: 'no-response-identity',
228
+ traits: { emails: ['test@email.com'] },
229
+ };
230
+ const incompleteRecord = {
231
+ pk: `identity#${pixelId}#no-response-identity`,
232
+ pixelId,
233
+ identityId: 'no-response-identity',
234
+ updatedAt: new Date().toISOString(),
235
+ };
236
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(incompleteRecord);
237
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
238
+ expect(result.cacheHit).toBe(false);
239
+ expect(result.lookupPath).toBe('identity_id');
240
+ expect(result.cachedIdentity).toBeUndefined();
241
+ });
242
+ it('should return lookupPath=miss when no email provided for pointer lookup', async () => {
243
+ const incomingIdentity = {
244
+ traits: { phones: ['555-1234'] },
245
+ };
246
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
247
+ expect(result.cacheHit).toBe(false);
248
+ expect(result.lookupPath).toBe('miss');
249
+ expect(mockedDynamoDbClient.safeGet).not.toHaveBeenCalled();
250
+ });
251
+ });
252
+ describe('invalid input handling', () => {
253
+ it('should return cache miss for undefined pixelId', async () => {
254
+ const incomingIdentity = {
255
+ identityId: 'test-identity',
256
+ traits: { emails: ['test@email.com'] },
257
+ };
258
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(undefined, incomingIdentity);
259
+ expect(result.cacheHit).toBe(false);
260
+ expect(result.lookupPath).toBe('miss');
261
+ expect(mockedDynamoDbClient.safeGet).not.toHaveBeenCalled();
262
+ });
263
+ it('should return cache miss for empty pixelId', async () => {
264
+ const incomingIdentity = {
265
+ identityId: 'test-identity',
266
+ traits: { emails: ['test@email.com'] },
267
+ };
268
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure('', incomingIdentity);
269
+ expect(result.cacheHit).toBe(false);
270
+ expect(result.lookupPath).toBe('miss');
271
+ });
272
+ it('should return cache miss for undefined incomingIdentity', async () => {
273
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, undefined);
274
+ expect(result.cacheHit).toBe(false);
275
+ expect(result.lookupPath).toBe('miss');
276
+ });
277
+ it('should return cache miss for null incomingIdentity', async () => {
278
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, null);
279
+ expect(result.cacheHit).toBe(false);
280
+ expect(result.lookupPath).toBe('miss');
281
+ });
282
+ });
283
+ describe('error handling', () => {
284
+ it('should return cache miss when DynamoDB throws an error', async () => {
285
+ const incomingIdentity = {
286
+ identityId: 'error-test-identity',
287
+ traits: { emails: ['test@email.com'] },
288
+ };
289
+ mockedDynamoDbClient.safeGet.mockRejectedValueOnce(new Error('DynamoDB connection failed'));
290
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
291
+ expect(result.cacheHit).toBe(false);
292
+ expect(result.lookupPath).toBe('identity_id');
293
+ expect(result.cachedIdentity).toBeUndefined();
294
+ expect(mockedLogger.error).toHaveBeenCalledWith('IdentityCache - getItemByPk failed', expect.objectContaining({
295
+ error: expect.any(Error),
296
+ errorMessage: 'DynamoDB connection failed',
297
+ }));
298
+ });
299
+ it('should handle non-Error thrown values', async () => {
300
+ const incomingIdentity = {
301
+ identityId: 'string-error-identity',
302
+ traits: { emails: ['test@email.com'] },
303
+ };
304
+ mockedDynamoDbClient.safeGet.mockRejectedValueOnce('String error message');
305
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
306
+ expect(result.cacheHit).toBe(false);
307
+ expect(result.lookupPath).toBe('identity_id');
308
+ expect(mockedLogger.error).toHaveBeenCalledWith('IdentityCache - getItemByPk failed', expect.objectContaining({
309
+ errorMessage: 'String error message',
310
+ }));
311
+ });
312
+ });
313
+ describe('verification: no merge or staleness logic', () => {
314
+ it('should not call mergeIdentityTraits', async () => {
315
+ const incomingIdentity = {
316
+ identityId: 'verify-no-merge',
317
+ traits: { emails: ['incoming@email.com'] },
318
+ };
319
+ const cachedRecord = {
320
+ pk: `identity#${pixelId}#verify-no-merge`,
321
+ pixelId,
322
+ identityId: 'verify-no-merge',
323
+ response: {
324
+ identityId: 'verify-no-merge',
325
+ traits: { emails: ['cached@email.com'] },
326
+ },
327
+ updatedAt: new Date().toISOString(),
328
+ };
329
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
330
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
331
+ expect(result.cachedIdentity).toBe(cachedRecord.response);
332
+ expect(result.cachedIdentity?.traits?.emails).toEqual(['cached@email.com']);
333
+ });
334
+ it('should not call isIdentityCacheStale', async () => {
335
+ const incomingIdentity = {
336
+ identityId: 'verify-no-staleness',
337
+ traits: {
338
+ emails: ['new-email@test.com'],
339
+ },
340
+ };
341
+ const cachedRecord = {
342
+ pk: `identity#${pixelId}#verify-no-staleness`,
343
+ pixelId,
344
+ identityId: 'verify-no-staleness',
345
+ response: {
346
+ identityId: 'verify-no-staleness',
347
+ traits: { emails: ['old-email@test.com'] },
348
+ },
349
+ updatedAt: new Date().toISOString(),
350
+ };
351
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
352
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
353
+ expect(Object.keys(result)).toEqual(['cachedIdentity', 'lookupPath', 'cacheHit']);
354
+ });
355
+ it('result should only contain pure lookup properties', async () => {
356
+ const incomingIdentity = {
357
+ identityId: 'result-shape-test',
358
+ traits: { emails: ['test@email.com'] },
359
+ };
360
+ const cachedRecord = {
361
+ pk: `identity#${pixelId}#result-shape-test`,
362
+ pixelId,
363
+ identityId: 'result-shape-test',
364
+ response: {
365
+ identityId: 'result-shape-test',
366
+ traits: { emails: ['test@email.com'] },
367
+ },
368
+ updatedAt: new Date().toISOString(),
369
+ };
370
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
371
+ const result = await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
372
+ expect(result).toEqual({
373
+ cachedIdentity: cachedRecord.response,
374
+ lookupPath: 'identity_id',
375
+ cacheHit: true,
376
+ });
377
+ expect(result).not.toHaveProperty('resolvedIdentity');
378
+ expect(result).not.toHaveProperty('isCacheStale');
379
+ expect(result).not.toHaveProperty('staleTracker');
380
+ expect(result).not.toHaveProperty('staleTier');
381
+ expect(result).not.toHaveProperty('writeReason');
382
+ expect(result).not.toHaveProperty('skipNeptune');
383
+ expect(result).not.toHaveProperty('mergedIdentity');
384
+ });
385
+ });
386
+ describe('logging', () => {
387
+ it('should log debug on cache hit by identity ID', async () => {
388
+ const incomingIdentity = {
389
+ identityId: 'log-test-id',
390
+ traits: { emails: ['test@email.com'] },
391
+ };
392
+ const cachedRecord = {
393
+ pk: `identity#${pixelId}#log-test-id`,
394
+ pixelId,
395
+ identityId: 'log-test-id',
396
+ response: {
397
+ identityId: 'log-test-id',
398
+ traits: { emails: ['test@email.com'] },
399
+ },
400
+ updatedAt: new Date().toISOString(),
401
+ };
402
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(cachedRecord);
403
+ await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
404
+ expect(mockedLogger.debug).toHaveBeenCalledWith('IdentityCache - pure lookup hit', expect.objectContaining({
405
+ pixelId,
406
+ identityId: 'log-test-id',
407
+ }));
408
+ });
409
+ it('should log debug on cache miss', async () => {
410
+ const incomingIdentity = {
411
+ identityId: 'miss-log-test',
412
+ traits: { emails: ['test@email.com'] },
413
+ };
414
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
415
+ await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
416
+ expect(mockedLogger.debug).toHaveBeenCalledWith('IdentityCache - pure lookup miss', expect.objectContaining({
417
+ pixelId,
418
+ identityId: 'miss-log-test',
419
+ }));
420
+ });
421
+ it('should log debug on email pointer discovery', async () => {
422
+ const incomingIdentity = {
423
+ traits: { emails: ['email-pointer@test.com'] },
424
+ };
425
+ const emailPointerRecord = {
426
+ pk: `email#${pixelId}#email-pointer@test.com`,
427
+ pixelId,
428
+ identityId: 'discovered-from-pointer',
429
+ updatedAt: new Date().toISOString(),
430
+ };
431
+ mockedDynamoDbClient.safeGet.mockResolvedValueOnce(emailPointerRecord);
432
+ await IdentityCacheDynamoDbDbService.getIdentityFromCachePure(pixelId, incomingIdentity);
433
+ expect(mockedLogger.debug).toHaveBeenCalledWith('IdentityCache - pure email pointer discovery', expect.objectContaining({
434
+ pixelId,
435
+ discoveredIdentityId: 'discovered-from-pointer',
436
+ }));
437
+ });
438
+ });
439
+ });
440
+ describe('mergeAndComputeIdentityStaleness (pure function)', () => {
441
+ const { mergeAndComputeIdentityStaleness, IDENTITY_CACHE_STALENESS_TIER } = jest.requireActual('../../helpers/identity-cache-helper.js');
442
+ describe('merge behavior', () => {
443
+ it('should merge incoming traits with cached traits', () => {
444
+ const incomingIdentity = {
445
+ identityId: 'merge-test',
446
+ traits: {
447
+ emails: ['new@email.com'],
448
+ },
449
+ };
450
+ const cachedIdentity = {
451
+ identityId: 'merge-test',
452
+ traits: {
453
+ emails: ['cached@email.com'],
454
+ phones: ['555-1234'],
455
+ },
456
+ };
457
+ const result = mergeAndComputeIdentityStaleness(incomingIdentity, cachedIdentity);
458
+ expect(result.mergedIdentity.traits?.emails).toContain('new@email.com');
459
+ expect(result.mergedIdentity.traits?.emails).toContain('cached@email.com');
460
+ expect(result.mergedIdentity.traits?.phones).toContain('555-1234');
461
+ });
462
+ });
463
+ describe('staleness tier computation', () => {
464
+ it('should return NONE tier when no traits are stale', () => {
465
+ const incomingIdentity = {
466
+ identityId: 'same-test',
467
+ traits: { emails: ['same@email.com'] },
468
+ };
469
+ const cachedIdentity = {
470
+ identityId: 'same-test',
471
+ traits: { emails: ['same@email.com'] },
472
+ };
473
+ const result = mergeAndComputeIdentityStaleness(incomingIdentity, cachedIdentity);
474
+ expect(result.staleTier).toBe(IDENTITY_CACHE_STALENESS_TIER.NONE);
475
+ expect(result.isCacheStale).toBe(false);
476
+ });
477
+ it('should return VOLATILE_ONLY tier when incoming has new IP address (cached has none)', () => {
478
+ const incomingIdentity = {
479
+ identityId: 'volatile-test',
480
+ traits: {
481
+ emails: ['same@email.com'],
482
+ ipAddress: '192.168.1.100',
483
+ },
484
+ };
485
+ const cachedIdentity = {
486
+ identityId: 'volatile-test',
487
+ traits: {
488
+ emails: ['same@email.com'],
489
+ },
490
+ };
491
+ const result = mergeAndComputeIdentityStaleness(incomingIdentity, cachedIdentity);
492
+ expect(result.staleTier).toBe(IDENTITY_CACHE_STALENESS_TIER.VOLATILE_ONLY);
493
+ expect(result.isCacheStale).toBe(false);
494
+ });
495
+ it('should return ADDRESS_UPDATE tier when non-IP address is new', () => {
496
+ const incomingIdentity = {
497
+ identityId: 'address-test',
498
+ traits: {
499
+ emails: ['same@email.com'],
500
+ addresses: [{ firstName: 'John', city: 'New York' }],
501
+ },
502
+ };
503
+ const cachedIdentity = {
504
+ identityId: 'address-test',
505
+ traits: {
506
+ emails: ['same@email.com'],
507
+ addresses: [],
508
+ },
509
+ };
510
+ const result = mergeAndComputeIdentityStaleness(incomingIdentity, cachedIdentity);
511
+ expect(result.staleTier).toBe(IDENTITY_CACHE_STALENESS_TIER.ADDRESS_UPDATE);
512
+ expect(result.isCacheStale).toBe(true);
513
+ });
514
+ it('should return IDENTITY_STALE tier when email changes', () => {
515
+ const incomingIdentity = {
516
+ identityId: 'stale-test',
517
+ traits: {
518
+ emails: ['new@email.com'],
519
+ },
520
+ };
521
+ const cachedIdentity = {
522
+ identityId: 'stale-test',
523
+ traits: {
524
+ emails: ['old@email.com'],
525
+ },
526
+ };
527
+ const result = mergeAndComputeIdentityStaleness(incomingIdentity, cachedIdentity);
528
+ expect(result.staleTier).toBe(IDENTITY_CACHE_STALENESS_TIER.IDENTITY_STALE);
529
+ expect(result.isCacheStale).toBe(true);
530
+ });
531
+ });
532
+ describe('staleTraits extraction', () => {
533
+ it('should include changed trait names in staleTraits array', () => {
534
+ const incomingIdentity = {
535
+ identityId: 'traits-test',
536
+ traits: {
537
+ emails: ['new@email.com'],
538
+ phones: ['999-0000'],
539
+ },
540
+ };
541
+ const cachedIdentity = {
542
+ identityId: 'traits-test',
543
+ traits: {
544
+ emails: ['old@email.com'],
545
+ phones: ['111-2222'],
546
+ },
547
+ };
548
+ const result = mergeAndComputeIdentityStaleness(incomingIdentity, cachedIdentity);
549
+ expect(result.staleTraits).toContain('emails');
550
+ expect(result.staleTraits).toContain('phones');
551
+ });
552
+ });
553
+ });
554
+ //# sourceMappingURL=identity-cache-dynamodb-db-service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-cache-dynamodb-db-service.spec.js","sourceRoot":"","sources":["../../../../src/__tests__/identity-cache/identity-cache-dynamodb-db-service.spec.ts"],"names":[],"mappings":"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"}