@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.
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +646 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +327 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +277 -131
- package/dist/cjs/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
- package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js +74 -80
- package/dist/cjs/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
- package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.d.ts +1 -0
- package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js +567 -0
- package/dist/cjs/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.d.ts +3 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.js +7 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/constants.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.d.ts +14 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js +251 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +24 -0
- package/dist/cjs/services/db/{identity-cache-dynamodb-service.js → identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js} +221 -343
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +22 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +375 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/index.d.ts +4 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js +21 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/index.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.d.ts +12 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.js +32 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/key-builders.js.map +1 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/types.d.ts +205 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js +35 -0
- package/dist/cjs/services/db/identity-cache-dynamodb-service/types.js.map +1 -0
- package/dist/cjs/services/db/index.d.ts +4 -1
- package/dist/cjs/services/db/index.js +4 -1
- package/dist/cjs/services/db/index.js.map +1 -1
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.d.ts +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js +644 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-db-service-v2-comparison.spec.js.map +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.d.ts +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js +325 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service-v2-comparison.spec.js.map +1 -0
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js +277 -131
- package/dist/esm/__tests__/identity-cache/identity-cache-dynamodb-service.spec.js.map +1 -1
- package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js +74 -80
- package/dist/esm/__tests__/identity-cache/identity-cache-tier-routing.spec.js.map +1 -1
- package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.d.ts +1 -0
- package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js +565 -0
- package/dist/esm/__tests__/identity-cache/identity-gateway-service.spec.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/constants.d.ts +3 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/constants.js +4 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/constants.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.d.ts +14 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js +234 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/helpers.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +24 -0
- package/dist/esm/services/db/{identity-cache-dynamodb-service.js → identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js} +199 -321
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.d.ts +22 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js +368 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/identity-gateway-service.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/index.d.ts +4 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/index.js +5 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/index.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.d.ts +12 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.js +24 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/key-builders.js.map +1 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/types.d.ts +205 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/types.js +32 -0
- package/dist/esm/services/db/identity-cache-dynamodb-service/types.js.map +1 -0
- package/dist/esm/services/db/index.d.ts +4 -1
- package/dist/esm/services/db/index.js +4 -1
- package/dist/esm/services/db/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/cjs/services/db/identity-cache-dynamodb-service.d.ts +0 -44
- package/dist/cjs/services/db/identity-cache-dynamodb-service.js.map +0 -1
- package/dist/esm/services/db/identity-cache-dynamodb-service.d.ts +0 -44
- package/dist/esm/services/db/identity-cache-dynamodb-service.js.map +0 -1
|
@@ -3,175 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const at_tracking_event_types_1 = require("@adtrackify/at-tracking-event-types");
|
|
6
|
+
exports.IdentityCacheDynamoDbDbService = void 0;
|
|
8
7
|
const at_shared_utils_1 = require("@adtrackify/at-shared-utils");
|
|
9
8
|
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
|
10
9
|
const luxon_1 = require("luxon");
|
|
11
|
-
const index_js_1 = require("
|
|
12
|
-
const index_js_2 = require("
|
|
13
|
-
const identity_cache_helper_js_1 = require("
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
CACHE_WRITE_REASON["STALE_TRAITS"] = "stale_traits";
|
|
21
|
-
CACHE_WRITE_REASON["EMAIL_POINTER_DISCOVERY"] = "email_pointer_discovery";
|
|
22
|
-
CACHE_WRITE_REASON["ADDRESS_UPDATE"] = "address_update";
|
|
23
|
-
})(CACHE_WRITE_REASON = exports.CACHE_WRITE_REASON || (exports.CACHE_WRITE_REASON = {}));
|
|
24
|
-
class IdentityCacheDynamoDbService {
|
|
25
|
-
static lambdaInvokeClient;
|
|
26
|
-
static getLambdaInvokeClient() {
|
|
27
|
-
if (!this.lambdaInvokeClient) {
|
|
28
|
-
this.lambdaInvokeClient = new index_js_1.LambdaInvokeClient();
|
|
29
|
-
}
|
|
30
|
-
return this.lambdaInvokeClient;
|
|
31
|
-
}
|
|
32
|
-
static getIdentityWithCaching = async (pixelId, incomingIdentity, identifyPrivateLambdaArn) => {
|
|
33
|
-
try {
|
|
34
|
-
if (!pixelId || !incomingIdentity) {
|
|
35
|
-
index_js_2.Logger.error('IdentityCache - missing required params', { pixelId, incomingIdentity });
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
const cacheResponse = await this.readFromCache(pixelId, incomingIdentity);
|
|
39
|
-
let resolvedIdentity = cacheResponse.resolvedIdentity;
|
|
40
|
-
const isCacheStale = cacheResponse.isCacheStale;
|
|
41
|
-
const cachedIdentity = cacheResponse.cachedIdentity;
|
|
42
|
-
const staleTracker = cacheResponse.staleTracker;
|
|
43
|
-
const writeReason = cacheResponse.writeReason;
|
|
44
|
-
const staleTier = cacheResponse.staleTier;
|
|
45
|
-
const skipNeptune = cacheResponse.skipNeptune;
|
|
46
|
-
if (resolvedIdentity && !isCacheStale) {
|
|
47
|
-
const tierLabel = staleTier === identity_cache_helper_js_1.IDENTITY_CACHE_STALENESS_TIER.VOLATILE_ONLY ? 'volatile_traits_only' : 'fresh';
|
|
48
|
-
index_js_2.Logger.debug(`IdentityCache - identity cache hit - ${tierLabel}`, {
|
|
49
|
-
pixelId,
|
|
50
|
-
identityId: resolvedIdentity.identityId,
|
|
51
|
-
staleTier,
|
|
52
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
53
|
-
incomingIdentity,
|
|
54
|
-
resolvedIdentity,
|
|
55
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
56
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
57
|
-
resolvedClick: resolvedIdentity?.traits?.click ?? null,
|
|
58
|
-
});
|
|
59
|
-
return resolvedIdentity;
|
|
60
|
-
}
|
|
61
|
-
if (resolvedIdentity && skipNeptune && writeReason === CACHE_WRITE_REASON.ADDRESS_UPDATE) {
|
|
62
|
-
const staleTraits = staleTracker ? this.extractStaleTraitNames(staleTracker) : [];
|
|
63
|
-
index_js_2.Logger.info('IdentityCache - identity cache write: address update only (skipping Neptune)', {
|
|
64
|
-
pixelId,
|
|
65
|
-
identityId: resolvedIdentity.identityId,
|
|
66
|
-
writeReason,
|
|
67
|
-
staleTier,
|
|
68
|
-
staleTraits,
|
|
69
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
70
|
-
incomingIdentity,
|
|
71
|
-
resolvedIdentity,
|
|
72
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
73
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
74
|
-
resolvedClick: resolvedIdentity?.traits?.click ?? null,
|
|
75
|
-
traitChanges: cachedIdentity ? this.computeTraitChanges(cachedIdentity, resolvedIdentity) : { reason: 'no cached identity' },
|
|
76
|
-
});
|
|
77
|
-
await this.safeWriteBackToCache(pixelId, resolvedIdentity, 'address update');
|
|
78
|
-
return resolvedIdentity;
|
|
79
|
-
}
|
|
80
|
-
const identityForNeptune = resolvedIdentity ?? incomingIdentity;
|
|
81
|
-
index_js_2.Logger.info('IdentityCache - identity cache stale - fetching from Neptune', {
|
|
82
|
-
pixelId,
|
|
83
|
-
identityId: identityForNeptune?.identityId,
|
|
84
|
-
staleTier,
|
|
85
|
-
writeReason,
|
|
86
|
-
staleTraits: staleTracker ? this.extractStaleTraitNames(staleTracker) : [],
|
|
87
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
88
|
-
incomingIdentity,
|
|
89
|
-
identityForNeptune,
|
|
90
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
91
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
92
|
-
hasDiscoveredIdentityId: !!resolvedIdentity?.identityId,
|
|
93
|
-
});
|
|
94
|
-
const neptuneIdentity = await this.resolveFromNeptune(pixelId, identityForNeptune, identifyPrivateLambdaArn);
|
|
95
|
-
if (neptuneIdentity) {
|
|
96
|
-
resolvedIdentity = neptuneIdentity;
|
|
97
|
-
const cachedForComparison = cachedIdentity ? this.stripAddressTimestamps(cachedIdentity) : undefined;
|
|
98
|
-
const neptuneForComparison = this.stripAddressTimestamps(neptuneIdentity);
|
|
99
|
-
const shouldWrite = !cachedForComparison || !(0, fast_deep_equal_1.default)(cachedForComparison, neptuneForComparison);
|
|
100
|
-
if (shouldWrite) {
|
|
101
|
-
const staleTraits = staleTracker ? this.extractStaleTraitNames(staleTracker) : [];
|
|
102
|
-
const isNewIdentity = writeReason === CACHE_WRITE_REASON.CACHE_MISS || writeReason === CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY;
|
|
103
|
-
const writeType = isNewIdentity ? 'new_identity' : 'stale_traits_update';
|
|
104
|
-
index_js_2.Logger.info(`IdentityCache - identity cache write: ${writeType}`, {
|
|
105
|
-
pixelId,
|
|
106
|
-
identityId: neptuneIdentity.identityId,
|
|
107
|
-
writeReason,
|
|
108
|
-
staleTier,
|
|
109
|
-
staleTraits,
|
|
110
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
111
|
-
incomingIdentity,
|
|
112
|
-
neptuneIdentity,
|
|
113
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
114
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
115
|
-
neptuneClick: neptuneIdentity?.traits?.click ?? null,
|
|
116
|
-
traitChanges: cachedIdentity
|
|
117
|
-
? this.computeTraitChanges(cachedIdentity, neptuneIdentity)
|
|
118
|
-
: { reason: 'no cached identity' },
|
|
119
|
-
});
|
|
120
|
-
await this.safeWriteBackToCache(pixelId, resolvedIdentity, 'neptune write-back');
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
index_js_2.Logger.info('IdentityCache - identity cache skip write - Neptune matches cached', {
|
|
124
|
-
pixelId,
|
|
125
|
-
identityId: neptuneIdentity.identityId,
|
|
126
|
-
staleTier,
|
|
127
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
128
|
-
incomingIdentity,
|
|
129
|
-
neptuneIdentity,
|
|
130
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
131
|
-
cachedClick: cachedIdentity?.traits?.click ?? null,
|
|
132
|
-
neptuneClick: neptuneIdentity?.traits?.click ?? null,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
index_js_2.Logger.error('IdentityCache - Neptune resolution failed', {
|
|
138
|
-
pixelId,
|
|
139
|
-
staleTier,
|
|
140
|
-
writeReason,
|
|
141
|
-
cachedIdentity: cachedIdentity ?? null,
|
|
142
|
-
incomingIdentity,
|
|
143
|
-
identityForNeptune,
|
|
144
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
if (!resolvedIdentity) {
|
|
148
|
-
index_js_2.Logger.error('IdentityCache - no identity found, using incoming', {
|
|
149
|
-
pixelId,
|
|
150
|
-
incomingIdentity,
|
|
151
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
152
|
-
});
|
|
153
|
-
resolvedIdentity = incomingIdentity;
|
|
154
|
-
}
|
|
155
|
-
return resolvedIdentity;
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
index_js_2.Logger.error('IdentityCache - getIdentityWithCaching failed', {
|
|
159
|
-
error,
|
|
160
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
161
|
-
pixelId,
|
|
162
|
-
incomingIdentity,
|
|
163
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
164
|
-
});
|
|
165
|
-
return undefined;
|
|
166
|
-
}
|
|
167
|
-
};
|
|
10
|
+
const index_js_1 = require("../../../clients/index.js");
|
|
11
|
+
const index_js_2 = require("../../../helpers/index.js");
|
|
12
|
+
const identity_cache_helper_js_1 = require("../../../helpers/identity-cache-helper.js");
|
|
13
|
+
const constants_js_1 = require("./constants.js");
|
|
14
|
+
const key_builders_js_1 = require("./key-builders.js");
|
|
15
|
+
const types_js_1 = require("./types.js");
|
|
16
|
+
const helpers_js_1 = require("./helpers.js");
|
|
17
|
+
const types_js_2 = require("./types.js");
|
|
18
|
+
class IdentityCacheDynamoDbDbService {
|
|
168
19
|
static getIdentityFromCache = async (pixelId, incomingIdentity) => {
|
|
169
20
|
try {
|
|
170
21
|
if (!pixelId || !incomingIdentity) {
|
|
171
|
-
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: CACHE_WRITE_REASON.CACHE_MISS };
|
|
22
|
+
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.CACHE_MISS };
|
|
172
23
|
}
|
|
173
24
|
if (incomingIdentity.identityId) {
|
|
174
|
-
const pk = (0,
|
|
25
|
+
const pk = (0, key_builders_js_1.buildIdentityPk)(pixelId, incomingIdentity.identityId);
|
|
175
26
|
index_js_2.Logger.debug('IdentityCache - lookup by identityId', { pixelId, pk, incomingIdentity });
|
|
176
27
|
const cachedIdentityResponse = await this.getItemByPk(pk);
|
|
177
28
|
if (!cachedIdentityResponse) {
|
|
@@ -181,7 +32,16 @@ class IdentityCacheDynamoDbService {
|
|
|
181
32
|
incomingIdentity,
|
|
182
33
|
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
183
34
|
});
|
|
184
|
-
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: CACHE_WRITE_REASON.CACHE_MISS };
|
|
35
|
+
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.CACHE_MISS };
|
|
36
|
+
}
|
|
37
|
+
if (!cachedIdentityResponse?.response) {
|
|
38
|
+
index_js_2.Logger.debug('IdentityCache - found cached identity but no response', {
|
|
39
|
+
pixelId,
|
|
40
|
+
identityId: incomingIdentity.identityId,
|
|
41
|
+
incomingIdentity,
|
|
42
|
+
cachedIdentityResponse,
|
|
43
|
+
});
|
|
44
|
+
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.CACHE_MISS };
|
|
185
45
|
}
|
|
186
46
|
index_js_2.Logger.debug('IdentityCache - found cached identity', {
|
|
187
47
|
pixelId,
|
|
@@ -192,8 +52,8 @@ class IdentityCacheDynamoDbService {
|
|
|
192
52
|
const mergedTraits = (0, at_shared_utils_1.mergeIdentityTraits)(incomingIdentity.traits, cachedIdentityResponse.response.traits);
|
|
193
53
|
const mergedIdentity = { ...incomingIdentity, traits: mergedTraits };
|
|
194
54
|
const identityStaleCacheTracker = (0, identity_cache_helper_js_1.isIdentityCacheStale)(cachedIdentityResponse.response, mergedIdentity);
|
|
195
|
-
const cachedForComparison =
|
|
196
|
-
const mergedForComparison =
|
|
55
|
+
const cachedForComparison = (0, helpers_js_1.stripAddressTimestamps)(cachedIdentityResponse.response);
|
|
56
|
+
const mergedForComparison = (0, helpers_js_1.stripAddressTimestamps)(mergedIdentity);
|
|
197
57
|
const isDeepEqual = (0, fast_deep_equal_1.default)(cachedForComparison, mergedForComparison);
|
|
198
58
|
const staleTier = identityStaleCacheTracker.staleTier;
|
|
199
59
|
let isCacheStale = identityStaleCacheTracker.isCacheStale;
|
|
@@ -230,10 +90,10 @@ class IdentityCacheDynamoDbService {
|
|
|
230
90
|
let writeReason;
|
|
231
91
|
if (isCacheStale) {
|
|
232
92
|
if (isAddressUpdateOnly) {
|
|
233
|
-
writeReason = CACHE_WRITE_REASON.ADDRESS_UPDATE;
|
|
93
|
+
writeReason = types_js_1.CACHE_WRITE_REASON.ADDRESS_UPDATE;
|
|
234
94
|
}
|
|
235
95
|
else {
|
|
236
|
-
writeReason = CACHE_WRITE_REASON.STALE_TRAITS;
|
|
96
|
+
writeReason = types_js_1.CACHE_WRITE_REASON.STALE_TRAITS;
|
|
237
97
|
}
|
|
238
98
|
}
|
|
239
99
|
if (isCacheStale) {
|
|
@@ -272,9 +132,33 @@ class IdentityCacheDynamoDbService {
|
|
|
272
132
|
...incomingIdentity,
|
|
273
133
|
identityId: discoveredIdentityId,
|
|
274
134
|
};
|
|
275
|
-
return { resolvedIdentity: identityWithDiscoveredId, isCacheStale: true, writeReason: CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY };
|
|
135
|
+
return { resolvedIdentity: identityWithDiscoveredId, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY };
|
|
136
|
+
}
|
|
137
|
+
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.CACHE_MISS };
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
index_js_2.Logger.error('IdentityCache - getIdentityFromCache failed', {
|
|
141
|
+
error,
|
|
142
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
143
|
+
pixelId,
|
|
144
|
+
incomingIdentity,
|
|
145
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
146
|
+
});
|
|
147
|
+
return { resolvedIdentity: undefined, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.CACHE_MISS };
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
static getIdentityFromCacheV2 = async (pixelId, incomingIdentity) => {
|
|
151
|
+
const state = (0, helpers_js_1.createIdentityCacheLookupState)(pixelId, incomingIdentity);
|
|
152
|
+
try {
|
|
153
|
+
if (!pixelId || !incomingIdentity) {
|
|
154
|
+
state.isCacheStale = true;
|
|
155
|
+
state.writeReason = types_js_1.CACHE_WRITE_REASON.CACHE_MISS;
|
|
156
|
+
return (0, helpers_js_1.createCacheMissLookupResult)(state, types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.INVALID_INPUT);
|
|
157
|
+
}
|
|
158
|
+
if (incomingIdentity.identityId) {
|
|
159
|
+
return await this.resolveCacheByIdentityIdV2(state);
|
|
276
160
|
}
|
|
277
|
-
return
|
|
161
|
+
return await this.resolveCacheByEmailPointerV2(state);
|
|
278
162
|
}
|
|
279
163
|
catch (error) {
|
|
280
164
|
index_js_2.Logger.error('IdentityCache - getIdentityFromCache failed', {
|
|
@@ -284,16 +168,159 @@ class IdentityCacheDynamoDbService {
|
|
|
284
168
|
incomingIdentity,
|
|
285
169
|
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
286
170
|
});
|
|
287
|
-
|
|
171
|
+
state.isCacheStale = true;
|
|
172
|
+
state.writeReason = types_js_1.CACHE_WRITE_REASON.CACHE_MISS;
|
|
173
|
+
return (0, helpers_js_1.createCacheMissLookupResult)(state, types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.FAILED, {
|
|
174
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
static resolveCacheByIdentityIdV2 = async (state) => {
|
|
179
|
+
const incomingIdentity = state.incomingIdentity;
|
|
180
|
+
const identityId = incomingIdentity.identityId;
|
|
181
|
+
state.didLookupByIdentityId = true;
|
|
182
|
+
const pk = (0, key_builders_js_1.buildIdentityPk)(state.pixelId, identityId);
|
|
183
|
+
index_js_2.Logger.debug('IdentityCache - lookup by identityId', { pixelId: state.pixelId, pk, incomingIdentity });
|
|
184
|
+
const cachedIdentityResponse = await this.getItemByPk(pk);
|
|
185
|
+
if (!cachedIdentityResponse) {
|
|
186
|
+
index_js_2.Logger.debug('IdentityCache - identity cache miss - no cached identity found', {
|
|
187
|
+
pixelId: state.pixelId,
|
|
188
|
+
identityId,
|
|
189
|
+
incomingIdentity,
|
|
190
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
191
|
+
});
|
|
192
|
+
state.isCacheStale = true;
|
|
193
|
+
state.writeReason = types_js_1.CACHE_WRITE_REASON.CACHE_MISS;
|
|
194
|
+
return (0, helpers_js_1.createCacheMissLookupResult)(state, types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_MISS);
|
|
195
|
+
}
|
|
196
|
+
state.cachedIdentityResponse = cachedIdentityResponse;
|
|
197
|
+
if (!cachedIdentityResponse?.response) {
|
|
198
|
+
index_js_2.Logger.debug('IdentityCache - found cached identity but no response', {
|
|
199
|
+
pixelId: state.pixelId,
|
|
200
|
+
identityId,
|
|
201
|
+
incomingIdentity,
|
|
202
|
+
cachedIdentityResponse,
|
|
203
|
+
});
|
|
204
|
+
state.isCacheStale = true;
|
|
205
|
+
state.writeReason = types_js_1.CACHE_WRITE_REASON.CACHE_MISS;
|
|
206
|
+
return (0, helpers_js_1.createCacheMissLookupResult)(state, types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_MISS_NO_RESPONSE);
|
|
288
207
|
}
|
|
208
|
+
this.applyPrimaryCacheHitState(state, cachedIdentityResponse);
|
|
209
|
+
return this.createPrimaryCacheLookupResult(state);
|
|
210
|
+
};
|
|
211
|
+
static applyPrimaryCacheHitState(state, cachedIdentityResponse) {
|
|
212
|
+
const incomingIdentity = state.incomingIdentity;
|
|
213
|
+
const identityId = incomingIdentity.identityId;
|
|
214
|
+
index_js_2.Logger.debug('IdentityCache - found cached identity', {
|
|
215
|
+
pixelId: state.pixelId,
|
|
216
|
+
identityId,
|
|
217
|
+
cachedIdentity: cachedIdentityResponse.response,
|
|
218
|
+
cachedClick: cachedIdentityResponse.response?.traits?.click ?? null,
|
|
219
|
+
});
|
|
220
|
+
state.cachedIdentity = cachedIdentityResponse.response;
|
|
221
|
+
const mergedTraits = (0, at_shared_utils_1.mergeIdentityTraits)(incomingIdentity.traits, cachedIdentityResponse.response.traits);
|
|
222
|
+
state.mergedIdentity = { ...incomingIdentity, traits: mergedTraits };
|
|
223
|
+
state.resolvedIdentity = state.mergedIdentity;
|
|
224
|
+
state.identityStaleCacheTracker = (0, identity_cache_helper_js_1.isIdentityCacheStale)(cachedIdentityResponse.response, state.mergedIdentity);
|
|
225
|
+
const cachedForComparison = (0, helpers_js_1.stripAddressTimestamps)(cachedIdentityResponse.response);
|
|
226
|
+
const mergedForComparison = (0, helpers_js_1.stripAddressTimestamps)(state.mergedIdentity);
|
|
227
|
+
state.isDeepEqual = (0, fast_deep_equal_1.default)(cachedForComparison, mergedForComparison);
|
|
228
|
+
state.staleTier = state.identityStaleCacheTracker.staleTier;
|
|
229
|
+
state.isCacheStale = state.identityStaleCacheTracker.isCacheStale;
|
|
230
|
+
if (state.isDeepEqual) {
|
|
231
|
+
index_js_2.Logger.debug('IdentityCache - deep equal (after stripping timestamps)', {
|
|
232
|
+
pixelId: state.pixelId,
|
|
233
|
+
identityId,
|
|
234
|
+
staleTier: state.staleTier,
|
|
235
|
+
});
|
|
236
|
+
state.isCacheStale = false;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
index_js_2.Logger.debug('IdentityCache - not deep equal', {
|
|
240
|
+
pixelId: state.pixelId,
|
|
241
|
+
identityId,
|
|
242
|
+
staleTier: state.staleTier,
|
|
243
|
+
identityStaleCacheTracker: state.identityStaleCacheTracker,
|
|
244
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
245
|
+
cachedClick: cachedIdentityResponse.response?.traits?.click ?? null,
|
|
246
|
+
mergedClick: state.mergedIdentity?.traits?.click ?? null,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const isVolatileOnly = state.staleTier === identity_cache_helper_js_1.IDENTITY_CACHE_STALENESS_TIER.VOLATILE_ONLY;
|
|
250
|
+
const isAddressUpdateOnly = state.staleTier === identity_cache_helper_js_1.IDENTITY_CACHE_STALENESS_TIER.ADDRESS_UPDATE;
|
|
251
|
+
const skipNeptune = isVolatileOnly || isAddressUpdateOnly;
|
|
252
|
+
if (isVolatileOnly && !state.isDeepEqual) {
|
|
253
|
+
index_js_2.Logger.debug('IdentityCache - volatile only - treating as cache hit', {
|
|
254
|
+
pixelId: state.pixelId,
|
|
255
|
+
identityId,
|
|
256
|
+
staleTier: state.staleTier,
|
|
257
|
+
});
|
|
258
|
+
state.isCacheStale = false;
|
|
259
|
+
}
|
|
260
|
+
if (state.isCacheStale) {
|
|
261
|
+
state.writeReason = isAddressUpdateOnly ? types_js_1.CACHE_WRITE_REASON.ADDRESS_UPDATE : types_js_1.CACHE_WRITE_REASON.STALE_TRAITS;
|
|
262
|
+
state.skipNeptune = skipNeptune;
|
|
263
|
+
state.staleTraits = (0, helpers_js_1.extractStaleTraitNames)(state.identityStaleCacheTracker);
|
|
264
|
+
index_js_2.Logger.debug('IdentityCache - stale detected', {
|
|
265
|
+
pixelId: state.pixelId,
|
|
266
|
+
identityId,
|
|
267
|
+
isCacheStale: state.isCacheStale,
|
|
268
|
+
isDeepEqual: state.isDeepEqual,
|
|
269
|
+
staleTier: state.staleTier,
|
|
270
|
+
skipNeptune: state.skipNeptune,
|
|
271
|
+
writeReason: state.writeReason,
|
|
272
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
273
|
+
cachedClick: cachedIdentityResponse.response?.traits?.click ?? null,
|
|
274
|
+
mergedClick: state.mergedIdentity?.traits?.click ?? null,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
static createPrimaryCacheLookupResult(state) {
|
|
279
|
+
const cacheResult = {
|
|
280
|
+
resolvedIdentity: state.mergedIdentity,
|
|
281
|
+
isCacheStale: state.isCacheStale,
|
|
282
|
+
cachedIdentity: state.cachedIdentity,
|
|
283
|
+
staleTracker: state.isCacheStale ? state.identityStaleCacheTracker : undefined,
|
|
284
|
+
writeReason: state.writeReason,
|
|
285
|
+
staleTier: state.staleTier,
|
|
286
|
+
skipNeptune: state.isCacheStale ? state.skipNeptune : undefined,
|
|
287
|
+
};
|
|
288
|
+
return (0, helpers_js_1.createIdentityCacheLookupResultFromState)(state, cacheResult, {
|
|
289
|
+
outcome: state.isCacheStale ? types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_STALE : types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.PRIMARY_CACHE_HIT,
|
|
290
|
+
skipNeptune: state.isCacheStale ? state.skipNeptune : undefined,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
static resolveCacheByEmailPointerV2 = async (state) => {
|
|
294
|
+
const incomingIdentity = state.incomingIdentity;
|
|
295
|
+
state.didLookupByEmail = !!incomingIdentity.traits?.emails?.[0];
|
|
296
|
+
state.discoveredIdentityId = await this.getIdentityIdFromEmailLookup(state.pixelId, incomingIdentity);
|
|
297
|
+
if (state.discoveredIdentityId) {
|
|
298
|
+
index_js_2.Logger.debug('IdentityCache - identityId from email pointer', {
|
|
299
|
+
pixelId: state.pixelId,
|
|
300
|
+
discoveredIdentityId: state.discoveredIdentityId,
|
|
301
|
+
incomingIdentity,
|
|
302
|
+
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
303
|
+
});
|
|
304
|
+
const identityWithDiscoveredId = {
|
|
305
|
+
...incomingIdentity,
|
|
306
|
+
identityId: state.discoveredIdentityId,
|
|
307
|
+
};
|
|
308
|
+
state.resolvedIdentity = identityWithDiscoveredId;
|
|
309
|
+
state.isCacheStale = true;
|
|
310
|
+
state.writeReason = types_js_1.CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY;
|
|
311
|
+
return (0, helpers_js_1.createIdentityCacheLookupResultFromState)(state, { resolvedIdentity: identityWithDiscoveredId, isCacheStale: true, writeReason: types_js_1.CACHE_WRITE_REASON.EMAIL_POINTER_DISCOVERY }, { outcome: types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.EMAIL_POINTER_DISCOVERY });
|
|
312
|
+
}
|
|
313
|
+
state.isCacheStale = true;
|
|
314
|
+
state.writeReason = types_js_1.CACHE_WRITE_REASON.CACHE_MISS;
|
|
315
|
+
return (0, helpers_js_1.createCacheMissLookupResult)(state, types_js_2.IDENTITY_CACHE_LOOKUP_OUTCOME.EMAIL_POINTER_MISS);
|
|
289
316
|
};
|
|
290
317
|
static getIdentityMap = async (pixelId, identityId) => {
|
|
291
318
|
try {
|
|
292
319
|
if (!pixelId || !identityId) {
|
|
293
320
|
return undefined;
|
|
294
321
|
}
|
|
295
|
-
const pk = (0,
|
|
296
|
-
const result = (await index_js_1.DynamoDbClient.safeGet(
|
|
322
|
+
const pk = (0, key_builders_js_1.buildIdentityMapPk)(pixelId, identityId);
|
|
323
|
+
const result = (await index_js_1.DynamoDbClient.safeGet(constants_js_1.IDENTITY_CACHE_TABLE_NAME, 'pk', pk));
|
|
297
324
|
return result ?? undefined;
|
|
298
325
|
}
|
|
299
326
|
catch (error) {
|
|
@@ -311,8 +338,8 @@ class IdentityCacheDynamoDbService {
|
|
|
311
338
|
if (!pixelId || !identityId) {
|
|
312
339
|
return false;
|
|
313
340
|
}
|
|
314
|
-
const pk = (0,
|
|
315
|
-
const result = await index_js_1.DynamoDbClient.safeGet(
|
|
341
|
+
const pk = (0, key_builders_js_1.buildForcePurgePk)(pixelId, identityId);
|
|
342
|
+
const result = await index_js_1.DynamoDbClient.safeGet(constants_js_1.IDENTITY_CACHE_TABLE_NAME, 'pk', pk);
|
|
316
343
|
return result !== null;
|
|
317
344
|
}
|
|
318
345
|
catch (error) {
|
|
@@ -333,7 +360,7 @@ class IdentityCacheDynamoDbService {
|
|
|
333
360
|
const items = [];
|
|
334
361
|
const now = new Date().toISOString();
|
|
335
362
|
items.push({
|
|
336
|
-
pk: (0,
|
|
363
|
+
pk: (0, key_builders_js_1.buildIdentityPk)(pixelId, response.identityId),
|
|
337
364
|
response,
|
|
338
365
|
updatedAt: now,
|
|
339
366
|
pixelId,
|
|
@@ -344,7 +371,7 @@ class IdentityCacheDynamoDbService {
|
|
|
344
371
|
for (const email of emails) {
|
|
345
372
|
if (email) {
|
|
346
373
|
const pointerRecord = {
|
|
347
|
-
pk: (0,
|
|
374
|
+
pk: (0, key_builders_js_1.buildEmailPk)(pixelId, email),
|
|
348
375
|
updatedAt: now,
|
|
349
376
|
pixelId,
|
|
350
377
|
identityId: response.identityId,
|
|
@@ -353,7 +380,7 @@ class IdentityCacheDynamoDbService {
|
|
|
353
380
|
items.push(pointerRecord);
|
|
354
381
|
}
|
|
355
382
|
}
|
|
356
|
-
await index_js_1.DynamoDbClient.safeBatchWrite(
|
|
383
|
+
await index_js_1.DynamoDbClient.safeBatchWrite(constants_js_1.IDENTITY_CACHE_TABLE_NAME, items);
|
|
357
384
|
index_js_2.Logger.debug('IdentityCache - cache written', { pixelId, identityId: response.identityId, itemCount: items.length });
|
|
358
385
|
}
|
|
359
386
|
catch (error) {
|
|
@@ -370,13 +397,13 @@ class IdentityCacheDynamoDbService {
|
|
|
370
397
|
return;
|
|
371
398
|
}
|
|
372
399
|
const item = {
|
|
373
|
-
pk: (0,
|
|
400
|
+
pk: (0, key_builders_js_1.buildIdentityMapPk)(pixelId, identityId),
|
|
374
401
|
pixelId,
|
|
375
402
|
identityId,
|
|
376
403
|
linkedIdentities,
|
|
377
404
|
updatedAt: new Date().toISOString(),
|
|
378
405
|
};
|
|
379
|
-
await index_js_1.DynamoDbClient.safePut(
|
|
406
|
+
await index_js_1.DynamoDbClient.safePut(constants_js_1.IDENTITY_CACHE_TABLE_NAME, item);
|
|
380
407
|
index_js_2.Logger.debug('IdentityCache - identity map written', { pixelId, identityId, linkedIdentities });
|
|
381
408
|
}
|
|
382
409
|
catch (error) {
|
|
@@ -388,7 +415,7 @@ class IdentityCacheDynamoDbService {
|
|
|
388
415
|
});
|
|
389
416
|
}
|
|
390
417
|
};
|
|
391
|
-
static setForcePurgeFlag = async (pixelId, identityId, ttlSeconds = FORCE_PURGE_TTL_SECONDS) => {
|
|
418
|
+
static setForcePurgeFlag = async (pixelId, identityId, ttlSeconds = constants_js_1.FORCE_PURGE_TTL_SECONDS) => {
|
|
392
419
|
try {
|
|
393
420
|
if (!pixelId || !identityId) {
|
|
394
421
|
return;
|
|
@@ -396,13 +423,13 @@ class IdentityCacheDynamoDbService {
|
|
|
396
423
|
const now = new Date().toISOString();
|
|
397
424
|
const ttl = luxon_1.DateTime.utc().plus({ seconds: ttlSeconds }).toSeconds();
|
|
398
425
|
const item = {
|
|
399
|
-
pk: (0,
|
|
426
|
+
pk: (0, key_builders_js_1.buildForcePurgePk)(pixelId, identityId),
|
|
400
427
|
pixelId,
|
|
401
428
|
identityId,
|
|
402
429
|
createdAt: now,
|
|
403
430
|
ttl: Math.floor(ttl),
|
|
404
431
|
};
|
|
405
|
-
await index_js_1.DynamoDbClient.safePut(
|
|
432
|
+
await index_js_1.DynamoDbClient.safePut(constants_js_1.IDENTITY_CACHE_TABLE_NAME, item);
|
|
406
433
|
index_js_2.Logger.debug('IdentityCache - force purge flag set', { pixelId, identityId, ttlSeconds });
|
|
407
434
|
}
|
|
408
435
|
catch (error) {
|
|
@@ -437,12 +464,12 @@ class IdentityCacheDynamoDbService {
|
|
|
437
464
|
}
|
|
438
465
|
if (incomingIdentity?.traits?.emails) {
|
|
439
466
|
for (const email of incomingIdentity.traits.emails) {
|
|
440
|
-
deleteKeys.push({ pk: (0,
|
|
467
|
+
deleteKeys.push({ pk: (0, key_builders_js_1.buildEmailPk)(pixelId, email) });
|
|
441
468
|
}
|
|
442
469
|
}
|
|
443
470
|
if (resolvedIdentity?.traits?.emails) {
|
|
444
471
|
for (const email of resolvedIdentity.traits.emails) {
|
|
445
|
-
deleteKeys.push({ pk: (0,
|
|
472
|
+
deleteKeys.push({ pk: (0, key_builders_js_1.buildEmailPk)(pixelId, email) });
|
|
446
473
|
}
|
|
447
474
|
}
|
|
448
475
|
const uniqueKeys = Array.from(new Set(deleteKeys.map((k) => k.pk))).map((pk) => ({ pk }));
|
|
@@ -464,8 +491,8 @@ class IdentityCacheDynamoDbService {
|
|
|
464
491
|
if (!pixelId || !identityId) {
|
|
465
492
|
return;
|
|
466
493
|
}
|
|
467
|
-
const pk = (0,
|
|
468
|
-
await index_js_1.DynamoDbClient.safeDelete(
|
|
494
|
+
const pk = (0, key_builders_js_1.buildIdentityMapPk)(pixelId, identityId);
|
|
495
|
+
await index_js_1.DynamoDbClient.safeDelete(constants_js_1.IDENTITY_CACHE_TABLE_NAME, 'pk', pk);
|
|
469
496
|
index_js_2.Logger.debug('IdentityCache - identity map deleted', { pixelId, identityId });
|
|
470
497
|
}
|
|
471
498
|
catch (error) {
|
|
@@ -482,8 +509,8 @@ class IdentityCacheDynamoDbService {
|
|
|
482
509
|
if (!pixelId || !identityId) {
|
|
483
510
|
return;
|
|
484
511
|
}
|
|
485
|
-
const pk = (0,
|
|
486
|
-
await index_js_1.DynamoDbClient.safeDelete(
|
|
512
|
+
const pk = (0, key_builders_js_1.buildForcePurgePk)(pixelId, identityId);
|
|
513
|
+
await index_js_1.DynamoDbClient.safeDelete(constants_js_1.IDENTITY_CACHE_TABLE_NAME, 'pk', pk);
|
|
487
514
|
index_js_2.Logger.debug('IdentityCache - force purge flag deleted', { pixelId, identityId });
|
|
488
515
|
}
|
|
489
516
|
catch (error) {
|
|
@@ -495,50 +522,6 @@ class IdentityCacheDynamoDbService {
|
|
|
495
522
|
});
|
|
496
523
|
}
|
|
497
524
|
};
|
|
498
|
-
static readFromCache = async (pixelId, incomingIdentity) => {
|
|
499
|
-
return await this.getIdentityFromCache(pixelId, incomingIdentity);
|
|
500
|
-
};
|
|
501
|
-
static resolveFromNeptune = async (pixelId, incomingIdentity, identifyPrivateLambdaArn) => {
|
|
502
|
-
try {
|
|
503
|
-
const client = this.getLambdaInvokeClient();
|
|
504
|
-
const response = await client.invokeFunction(identifyPrivateLambdaArn, {
|
|
505
|
-
pixelId,
|
|
506
|
-
context: { identity: incomingIdentity },
|
|
507
|
-
});
|
|
508
|
-
if (response?.statusCode === 200 && response?.body) {
|
|
509
|
-
const identifyResponse = JSON.parse(response.body);
|
|
510
|
-
return identifyResponse?.identity;
|
|
511
|
-
}
|
|
512
|
-
return incomingIdentity;
|
|
513
|
-
}
|
|
514
|
-
catch (error) {
|
|
515
|
-
index_js_2.Logger.error('IdentityCache - Neptune resolution failed', {
|
|
516
|
-
error,
|
|
517
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
518
|
-
pixelId,
|
|
519
|
-
incomingIdentity,
|
|
520
|
-
incomingClick: incomingIdentity?.traits?.click ?? null,
|
|
521
|
-
});
|
|
522
|
-
return undefined;
|
|
523
|
-
}
|
|
524
|
-
};
|
|
525
|
-
static writeBackToCache = async (pixelId, resolvedIdentity) => {
|
|
526
|
-
await this.updateIdentityCache(pixelId, resolvedIdentity);
|
|
527
|
-
};
|
|
528
|
-
static safeWriteBackToCache = async (pixelId, resolvedIdentity, context) => {
|
|
529
|
-
try {
|
|
530
|
-
await this.writeBackToCache(pixelId, resolvedIdentity);
|
|
531
|
-
}
|
|
532
|
-
catch (writeError) {
|
|
533
|
-
index_js_2.Logger.error(`IdentityCache - write back failed (${context})`, {
|
|
534
|
-
error: writeError,
|
|
535
|
-
errorMessage: writeError instanceof Error ? writeError.message : String(writeError),
|
|
536
|
-
pixelId,
|
|
537
|
-
identityId: resolvedIdentity?.identityId,
|
|
538
|
-
resolvedClick: resolvedIdentity?.traits?.click ?? null,
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
525
|
static getIdentityIdFromEmailLookup = async (pixelId, incomingIdentity) => {
|
|
543
526
|
try {
|
|
544
527
|
if (!pixelId || !incomingIdentity) {
|
|
@@ -548,9 +531,9 @@ class IdentityCacheDynamoDbService {
|
|
|
548
531
|
if (!firstEmail) {
|
|
549
532
|
return undefined;
|
|
550
533
|
}
|
|
551
|
-
const pk = (0,
|
|
534
|
+
const pk = (0, key_builders_js_1.buildEmailPk)(pixelId, firstEmail);
|
|
552
535
|
index_js_2.Logger.debug('IdentityCache - email secondary lookup', { pixelId, pk, email: firstEmail });
|
|
553
|
-
const result = (await index_js_1.DynamoDbClient.safeGet(
|
|
536
|
+
const result = (await index_js_1.DynamoDbClient.safeGet(constants_js_1.IDENTITY_CACHE_TABLE_NAME, 'pk', pk));
|
|
554
537
|
if (!result) {
|
|
555
538
|
return undefined;
|
|
556
539
|
}
|
|
@@ -569,7 +552,7 @@ class IdentityCacheDynamoDbService {
|
|
|
569
552
|
};
|
|
570
553
|
static getItemByPk = async (pk) => {
|
|
571
554
|
try {
|
|
572
|
-
const result = (await index_js_1.DynamoDbClient.safeGet(
|
|
555
|
+
const result = (await index_js_1.DynamoDbClient.safeGet(constants_js_1.IDENTITY_CACHE_TABLE_NAME, 'pk', pk));
|
|
573
556
|
return result ?? undefined;
|
|
574
557
|
}
|
|
575
558
|
catch (error) {
|
|
@@ -583,7 +566,7 @@ class IdentityCacheDynamoDbService {
|
|
|
583
566
|
};
|
|
584
567
|
static queryByGsi1 = async (identityId) => {
|
|
585
568
|
try {
|
|
586
|
-
const results = await index_js_1.DynamoDbClient.safeQueryByGSI(
|
|
569
|
+
const results = await index_js_1.DynamoDbClient.safeQueryByGSI(constants_js_1.IDENTITY_CACHE_TABLE_NAME, constants_js_1.IDENTITY_CACHE_GSI1_NAME, 'gsi1pk', identityId);
|
|
587
570
|
return (results ?? []);
|
|
588
571
|
}
|
|
589
572
|
catch (error) {
|
|
@@ -606,7 +589,7 @@ class IdentityCacheDynamoDbService {
|
|
|
606
589
|
DeleteRequest: { Key: { pk: key.pk } },
|
|
607
590
|
}));
|
|
608
591
|
await index_js_1.DynamoDbClient.batchWrite({
|
|
609
|
-
RequestItems: { [
|
|
592
|
+
RequestItems: { [constants_js_1.IDENTITY_CACHE_TABLE_NAME]: deleteRequests },
|
|
610
593
|
});
|
|
611
594
|
}
|
|
612
595
|
catch (error) {
|
|
@@ -625,111 +608,6 @@ class IdentityCacheDynamoDbService {
|
|
|
625
608
|
}
|
|
626
609
|
return chunks;
|
|
627
610
|
}
|
|
628
|
-
static stripAddressTimestamps(identity) {
|
|
629
|
-
if (!identity?.traits?.addresses?.length) {
|
|
630
|
-
return identity;
|
|
631
|
-
}
|
|
632
|
-
const strippedAddresses = identity.traits.addresses.map((addr) => {
|
|
633
|
-
if (!addr)
|
|
634
|
-
return addr;
|
|
635
|
-
const { cra, upa, ...rest } = addr;
|
|
636
|
-
return rest;
|
|
637
|
-
});
|
|
638
|
-
return {
|
|
639
|
-
...identity,
|
|
640
|
-
traits: {
|
|
641
|
-
...identity.traits,
|
|
642
|
-
addresses: strippedAddresses,
|
|
643
|
-
},
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
static extractStaleTraitNames(tracker) {
|
|
647
|
-
const staleTraits = [];
|
|
648
|
-
if (tracker.isIdentityIdStale)
|
|
649
|
-
staleTraits.push('identityId');
|
|
650
|
-
if (tracker.isUserIdsStale)
|
|
651
|
-
staleTraits.push('userIds');
|
|
652
|
-
if (tracker.isIdsStale)
|
|
653
|
-
staleTraits.push('ids');
|
|
654
|
-
if (tracker.isEmailsStale)
|
|
655
|
-
staleTraits.push('emails');
|
|
656
|
-
if (tracker.isPhonesStale)
|
|
657
|
-
staleTraits.push('phones');
|
|
658
|
-
if (tracker.isShopifyYIdsStale)
|
|
659
|
-
staleTraits.push('shopifyYIds');
|
|
660
|
-
if (tracker.isGendersStale)
|
|
661
|
-
staleTraits.push('genders');
|
|
662
|
-
if (tracker.isDobsStale)
|
|
663
|
-
staleTraits.push('dobs');
|
|
664
|
-
if (tracker.isAddressesStale)
|
|
665
|
-
staleTraits.push('addresses');
|
|
666
|
-
if (tracker.isClickInfosStale)
|
|
667
|
-
staleTraits.push('clickInfos');
|
|
668
|
-
if (tracker.isIpAddressStale)
|
|
669
|
-
staleTraits.push('ipAddress');
|
|
670
|
-
if (tracker.isUserAgentStale)
|
|
671
|
-
staleTraits.push('userAgent');
|
|
672
|
-
if (tracker.isThirdPartyContactsStale)
|
|
673
|
-
staleTraits.push('thirdPartyContacts');
|
|
674
|
-
return staleTraits;
|
|
675
|
-
}
|
|
676
|
-
static computeTraitChanges(cachedIdentity, resolvedIdentity) {
|
|
677
|
-
const changes = {};
|
|
678
|
-
const cachedTraits = cachedIdentity.traits ?? {};
|
|
679
|
-
const resolvedTraits = resolvedIdentity.traits ?? {};
|
|
680
|
-
const arrayTraits = [
|
|
681
|
-
'emails',
|
|
682
|
-
'phones',
|
|
683
|
-
'userIds',
|
|
684
|
-
'shopifyYIds',
|
|
685
|
-
'shopifyCustomerIds',
|
|
686
|
-
'klaviyoIds',
|
|
687
|
-
'genders',
|
|
688
|
-
'dobs',
|
|
689
|
-
'ids',
|
|
690
|
-
];
|
|
691
|
-
for (const trait of arrayTraits) {
|
|
692
|
-
const cachedValue = cachedTraits[trait];
|
|
693
|
-
const resolvedValue = resolvedTraits[trait];
|
|
694
|
-
if (!(0, fast_deep_equal_1.default)(cachedValue, resolvedValue)) {
|
|
695
|
-
changes[trait] = {
|
|
696
|
-
cached: cachedValue ?? [],
|
|
697
|
-
resolved: resolvedValue ?? [],
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
if (!(0, fast_deep_equal_1.default)(cachedTraits.addresses, resolvedTraits.addresses)) {
|
|
702
|
-
changes.addresses = {
|
|
703
|
-
cached: cachedTraits.addresses ?? [],
|
|
704
|
-
resolved: resolvedTraits.addresses ?? [],
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
if (!(0, fast_deep_equal_1.default)(cachedTraits.click, resolvedTraits.click)) {
|
|
708
|
-
changes.click = {
|
|
709
|
-
cached: cachedTraits.click ?? {},
|
|
710
|
-
resolved: resolvedTraits.click ?? {},
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
if (cachedTraits.ipAddress !== resolvedTraits.ipAddress) {
|
|
714
|
-
changes.ipAddress = {
|
|
715
|
-
cached: cachedTraits.ipAddress,
|
|
716
|
-
resolved: resolvedTraits.ipAddress,
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
if (cachedTraits.userAgent !== resolvedTraits.userAgent) {
|
|
720
|
-
changes.userAgent = {
|
|
721
|
-
cached: cachedTraits.userAgent,
|
|
722
|
-
resolved: resolvedTraits.userAgent,
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
if (cachedIdentity.identityId !== resolvedIdentity.identityId) {
|
|
726
|
-
changes.identityId = {
|
|
727
|
-
cached: cachedIdentity.identityId,
|
|
728
|
-
resolved: resolvedIdentity.identityId,
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
return changes;
|
|
732
|
-
}
|
|
733
611
|
}
|
|
734
|
-
exports.
|
|
735
|
-
//# sourceMappingURL=identity-cache-dynamodb-service.js.map
|
|
612
|
+
exports.IdentityCacheDynamoDbDbService = IdentityCacheDynamoDbDbService;
|
|
613
|
+
//# sourceMappingURL=identity-cache-dynamodb-db-service.js.map
|