feat: add attributable page analytics
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
resolveAnalyticsOwnerLabel,
|
||||
resolveAnalyticsOwnerSegment,
|
||||
resolveAnalyticsPlan,
|
||||
sendMindSpaceAnalyticsEvent,
|
||||
} from '../mindspace-analytics.mjs';
|
||||
import {
|
||||
@@ -43,6 +44,7 @@ export async function bootstrapPortalIntegrationServices({
|
||||
resolveAnalyticsOwnerSegment,
|
||||
resolveAnalyticsOwnerLabelFn =
|
||||
resolveAnalyticsOwnerLabel,
|
||||
resolveAnalyticsPlanFn = resolveAnalyticsPlan,
|
||||
sendMindSpaceAnalyticsEventFn =
|
||||
sendMindSpaceAnalyticsEvent,
|
||||
sendMindSpaceRybbitEventFn =
|
||||
@@ -155,6 +157,8 @@ export async function bootstrapPortalIntegrationServices({
|
||||
ownerLabel: resolveAnalyticsOwnerLabelFn(
|
||||
pageOwner,
|
||||
),
|
||||
planType: resolveAnalyticsPlanFn(pageOwner),
|
||||
generatedAt: new Date().toISOString(),
|
||||
pageId: artifact.relativePath,
|
||||
publicationId: sessionId,
|
||||
agentRunId: sessionId,
|
||||
|
||||
@@ -148,6 +148,10 @@ function createSetup(overrides = {}) {
|
||||
calls.push(['owner-label', user]);
|
||||
return 'label';
|
||||
},
|
||||
resolveAnalyticsPlanFn(user) {
|
||||
calls.push(['plan-type', user]);
|
||||
return 'pro';
|
||||
},
|
||||
sendMindSpaceAnalyticsEventFn(event) {
|
||||
calls.push(['analytics', event]);
|
||||
return Promise.resolve();
|
||||
@@ -349,12 +353,18 @@ test('preserves generated-page analytics projection', async () => {
|
||||
ownerId: 'user-1',
|
||||
ownerSegment: 'segment',
|
||||
ownerLabel: 'label',
|
||||
planType: 'pro',
|
||||
generatedAt: analyticsCall[1].generatedAt,
|
||||
pageId: 'public/page.html',
|
||||
publicationId: 'session-1',
|
||||
agentRunId: 'session-1',
|
||||
channel: 'wechat_mp',
|
||||
url: 'https://example/page',
|
||||
});
|
||||
assert.match(
|
||||
analyticsCall[1].generatedAt,
|
||||
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,
|
||||
);
|
||||
const rybbitCall = setup.calls.find(
|
||||
([name]) => name === 'rybbit',
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import {
|
||||
resolveAnalyticsOwnerLabel,
|
||||
resolveAnalyticsOwnerSegment,
|
||||
resolveAnalyticsPlan,
|
||||
sendMindSpaceAnalyticsEvent,
|
||||
} from '../mindspace-analytics.mjs';
|
||||
import {
|
||||
@@ -96,6 +97,7 @@ export function attachPortalSessionRoutes(
|
||||
resolveAnalyticsOwnerSegment,
|
||||
resolveAnalyticsOwnerLabelFn =
|
||||
resolveAnalyticsOwnerLabel,
|
||||
resolveAnalyticsPlanFn = resolveAnalyticsPlan,
|
||||
syncPublicHtmlAfterFinishFn = syncPublicHtmlAfterFinish,
|
||||
resolveMindSpaceRuntimeConfigFn =
|
||||
resolveMindSpaceRuntimeConfig,
|
||||
@@ -432,6 +434,8 @@ export function attachPortalSessionRoutes(
|
||||
resolveAnalyticsOwnerSegmentFn(req.currentUser),
|
||||
ownerLabel:
|
||||
resolveAnalyticsOwnerLabelFn(req.currentUser),
|
||||
planType: resolveAnalyticsPlanFn(req.currentUser),
|
||||
generatedAt: new Date().toISOString(),
|
||||
pageId: relativePath,
|
||||
publicationId: sessionId,
|
||||
agentRunId: sessionId,
|
||||
|
||||
@@ -165,6 +165,7 @@ function createDependencies(overrides = {}) {
|
||||
sendMindSpaceAnalyticsEventFn: async () => {},
|
||||
resolveAnalyticsOwnerSegmentFn: () => 'segment',
|
||||
resolveAnalyticsOwnerLabelFn: () => 'label',
|
||||
resolveAnalyticsPlanFn: () => 'pro',
|
||||
syncPublicHtmlAfterFinishFn: async () => ({
|
||||
publicHtmlRelativePaths: [],
|
||||
}),
|
||||
@@ -524,6 +525,11 @@ test('stream hook uses current session id for contracts and analytics', async ()
|
||||
assert.equal(calls[1].kind, 'materialize');
|
||||
assert.equal(calls[2].input.publicationId, 'session-1');
|
||||
assert.equal(calls[2].input.agentRunId, 'session-1');
|
||||
assert.equal(calls[2].input.planType, 'pro');
|
||||
assert.match(
|
||||
calls[2].input.generatedAt,
|
||||
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,
|
||||
);
|
||||
});
|
||||
|
||||
test('Finish hook preserves refresh, sync, delivery readiness, memory, and lock lifecycle', async () => {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
injectMindSpaceAnalytics,
|
||||
resolveAnalyticsOwnerLabel,
|
||||
resolveAnalyticsOwnerSegment,
|
||||
resolveAnalyticsPlan,
|
||||
} from '../mindspace-analytics.mjs';
|
||||
import {
|
||||
injectMindSpaceRybbit,
|
||||
@@ -303,6 +304,8 @@ export function createPortalWorkspacePublicationDelivery({
|
||||
ownerLabel: resolveAnalyticsOwnerLabel(
|
||||
pageOwner ?? {},
|
||||
),
|
||||
planType: resolveAnalyticsPlan(pageOwner ?? {}),
|
||||
generatedAt: pageDataContext?.generatedAt ?? '',
|
||||
pageId:
|
||||
pageDataContext?.pageId ?? '',
|
||||
publicationId:
|
||||
|
||||
Reference in New Issue
Block a user