spine-framework-cortex 0.1.18 → 0.1.19
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/CHANGELOG.md +4 -0
- package/functions/custom_funnel-signal.ts +26 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.1.19] — 2026-06-10
|
|
8
|
+
- Added `session_signals` link type + link creation in `upsertAnonymousSession()`
|
|
9
|
+
- Fixed scoring data path — flattened `scoring_components` to match `funnel_signal` schema (raw_score_rating, engagement_type, recency_window, etc.)
|
|
10
|
+
|
|
7
11
|
## [0.1.18] — 2026-06-10
|
|
8
12
|
- Fixed `custom_funnel-signal.ts` — added required `account_id` to anonymous_session insert (links to unidentified-visitors account)
|
|
9
13
|
|
|
@@ -47,13 +47,14 @@ export async function processSignal(
|
|
|
47
47
|
const payload = validation.data
|
|
48
48
|
|
|
49
49
|
// 2. RESOLVE IDs (read-only type/account lookups)
|
|
50
|
-
const [signalTypeId, sessionTypeId, queueTypeId, signalLinkTypeId, opportunityLinkTypeId, unidentifiedAccountId] =
|
|
50
|
+
const [signalTypeId, sessionTypeId, queueTypeId, signalLinkTypeId, opportunityLinkTypeId, sessionLinkTypeId, unidentifiedAccountId] =
|
|
51
51
|
await Promise.all([
|
|
52
52
|
resolveTypeId('funnel_signal'),
|
|
53
53
|
resolveTypeId('anonymous_session'),
|
|
54
54
|
resolveTypeId('opportunity_queue'),
|
|
55
55
|
resolveLinkTypeId('account_signals'),
|
|
56
56
|
resolveLinkTypeId('account_opportunities'),
|
|
57
|
+
resolveLinkTypeId('session_signals'),
|
|
57
58
|
resolveUnidentifiedAccountId(),
|
|
58
59
|
])
|
|
59
60
|
|
|
@@ -94,11 +95,17 @@ export async function processSignal(
|
|
|
94
95
|
action_description: payload.action_description || null,
|
|
95
96
|
url: payload.url || null,
|
|
96
97
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
// Scoring - flattened to match schema field names
|
|
99
|
+
raw_score_calculated: scoring.calculated,
|
|
100
|
+
raw_score_max_possible: scoring.max_possible,
|
|
101
|
+
raw_score_rating: scoring.rating,
|
|
102
|
+
engagement_type: engagement.type,
|
|
103
|
+
engagement_context: engagement.context,
|
|
104
|
+
engagement_session_depth: engagement.session_depth,
|
|
105
|
+
engagement_prior_session_count: engagement.prior_session_count || 0,
|
|
106
|
+
recency_divisor: recency.divisor,
|
|
107
|
+
recency_age_days: recency.age_days,
|
|
108
|
+
recency_window: recency.window,
|
|
102
109
|
attribution: {
|
|
103
110
|
immediate_referrer: payload.referrer || null,
|
|
104
111
|
first_touch_referrer_domain: referrerDomain,
|
|
@@ -144,7 +151,7 @@ export async function processSignal(
|
|
|
144
151
|
await createLink(signalLinkTypeId, 'account', payload.account_id, 'item', signalId)
|
|
145
152
|
}
|
|
146
153
|
} else if (payload.anonymous_id && sessionTypeId && unidentifiedAccountId) {
|
|
147
|
-
await upsertAnonymousSession(payload, sessionTypeId, unidentifiedAccountId, signalId, scoring, engagement, referrerDomain, referrerCategory, scoredAt)
|
|
154
|
+
await upsertAnonymousSession(payload, sessionTypeId, unidentifiedAccountId, signalId, scoring, engagement, referrerDomain, referrerCategory, scoredAt, sessionLinkTypeId)
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
// 7. EVALUATE QUEUE — if rating >= 4
|
|
@@ -287,7 +294,8 @@ async function updateAccountFunnel(
|
|
|
287
294
|
async function upsertAnonymousSession(
|
|
288
295
|
payload: SignalPayload, sessionTypeId: string, accountId: string, signalId: string,
|
|
289
296
|
scoring: { calculated: number; max_possible: number; rating: number },
|
|
290
|
-
engagement: any, referrerDomain: string, referrerCategory: string, now: string
|
|
297
|
+
engagement: any, referrerDomain: string, referrerCategory: string, now: string,
|
|
298
|
+
sessionLinkTypeId: string | null
|
|
291
299
|
): Promise<void> {
|
|
292
300
|
const { data: existing } = await adminDb
|
|
293
301
|
.from('items')
|
|
@@ -318,8 +326,12 @@ async function upsertAnonymousSession(
|
|
|
318
326
|
} : {}),
|
|
319
327
|
},
|
|
320
328
|
}).eq('id', existing.id)
|
|
329
|
+
// Link existing session to new signal
|
|
330
|
+
if (sessionLinkTypeId) {
|
|
331
|
+
await createLink(sessionLinkTypeId, 'item', existing.id, 'item', signalId)
|
|
332
|
+
}
|
|
321
333
|
} else {
|
|
322
|
-
await adminDb.from('items').insert({
|
|
334
|
+
const { data: newSession } = await adminDb.from('items').insert({
|
|
323
335
|
type_id: sessionTypeId,
|
|
324
336
|
account_id: accountId,
|
|
325
337
|
title: `Anonymous: ${payload.anonymous_id!.slice(0, 8)}`,
|
|
@@ -348,7 +360,11 @@ async function upsertAnonymousSession(
|
|
|
348
360
|
retention_retention_days: 90,
|
|
349
361
|
retention_purge_after: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString(),
|
|
350
362
|
},
|
|
351
|
-
})
|
|
363
|
+
}).select('id').single()
|
|
364
|
+
// Link new session to signal
|
|
365
|
+
if (sessionLinkTypeId && newSession) {
|
|
366
|
+
await createLink(sessionLinkTypeId, 'item', newSession.id, 'item', signalId)
|
|
367
|
+
}
|
|
352
368
|
}
|
|
353
369
|
}
|
|
354
370
|
|
package/package.json
CHANGED