Finalize metrics verification and backlog updates
This commit is contained in:
@@ -61,6 +61,7 @@ test("analytics dashboard renders filters, Convex metrics, and Rybbit error stat
|
||||
assert.doesNotMatch(pageSource, /DashboardPlaceholderPage/);
|
||||
assert.match(pageSource, /AnalyticsDashboard/);
|
||||
assert.match(componentSource, /api\.campaignMetrics\.getDashboard/);
|
||||
assert.match(componentSource, /\/api\/internal\/rybbit\/campaign/);
|
||||
assert.match(componentSource, /Kampagne/);
|
||||
assert.match(componentSource, /Nische/);
|
||||
assert.match(componentSource, /PLZ/);
|
||||
@@ -69,4 +70,6 @@ test("analytics dashboard renders filters, Convex metrics, and Rybbit error stat
|
||||
assert.match(componentSource, /Status/);
|
||||
assert.match(componentSource, /Zeitraum/);
|
||||
assert.match(componentSource, /Rybbit-Daten konnten nicht geladen werden/);
|
||||
assert.match(componentSource, /Audit-Öffnungen/);
|
||||
assert.match(componentSource, /CTA-Klicks/);
|
||||
});
|
||||
|
||||
@@ -192,6 +192,27 @@ test("toLeadFunnelCard maps blocked priority to deferred stage with blocker labe
|
||||
assert.equal(card.nextAction, "Zurückstellung prüfen");
|
||||
});
|
||||
|
||||
test("toLeadFunnelCard shows do-not-contact rechecks after the block window", () => {
|
||||
const card = toLeadFunnelCard({
|
||||
id: "lead-recheck",
|
||||
companyName: "Agentur Recheck",
|
||||
priority: "medium",
|
||||
contactStatus: "do_not_contact",
|
||||
blacklistStatus: "clear",
|
||||
outreach: {
|
||||
approvalStatus: "approved",
|
||||
sendStatus: "sent",
|
||||
responseStatus: "no_interest",
|
||||
salesStatus: "do_not_pursue",
|
||||
doNotContactUntil: Date.UTC(2026, 0, 1),
|
||||
},
|
||||
now: Date.UTC(2026, 0, 2),
|
||||
});
|
||||
|
||||
assert.equal(card.stageId, "deferred");
|
||||
assert.equal(card.nextAction, "Erneut prüfen");
|
||||
});
|
||||
|
||||
test("dashboard-model exposes stable lead label helpers for UI mapping", () => {
|
||||
assert.deepEqual(leadPriorityOptions, [
|
||||
"high",
|
||||
|
||||
@@ -32,3 +32,12 @@ test("manual sales status mutation updates lead suppression states", () => {
|
||||
assert.match(outreachSource, /not_interested[\s\S]*outreachPatch\.responseStatus\s*=\s*"no_interest"/);
|
||||
assert.match(outreachSource, /do_not_pursue[\s\S]*outreachPatch\.doNotContactUntil\s*=\s*now\s*\+\s*DO_NOT_CONTACT_RECHECK_MS/);
|
||||
});
|
||||
|
||||
test("lead funnel query exposes do-not-contact recheck dates", () => {
|
||||
const leadsSource = readFileSync(
|
||||
join(process.cwd(), "convex", "leads.ts"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
assert.match(leadsSource, /doNotContactUntil:\s*latestOutreach\.doNotContactUntil/);
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import test from "node:test";
|
||||
|
||||
import {
|
||||
buildRybbitEventsUrl,
|
||||
summarizeCampaignRybbitEvents,
|
||||
summarizeAuditRybbitEvents,
|
||||
type RybbitEvent,
|
||||
} from "../lib/rybbit-analytics";
|
||||
@@ -70,3 +71,19 @@ test("summarizeAuditRybbitEvents returns graceful empty metrics", () => {
|
||||
deviceTypes: [],
|
||||
});
|
||||
});
|
||||
|
||||
test("summarizeCampaignRybbitEvents aggregates public audit activity", () => {
|
||||
assert.deepEqual(
|
||||
summarizeCampaignRybbitEvents([
|
||||
{ type: "pageview", pathname: "/audit/a" },
|
||||
{ type: "pageview", pathname: "/dashboard" },
|
||||
{ type: "custom_event", event_name: "audit_cta_click", pathname: "/audit/a" },
|
||||
{ type: "outbound_link", pathname: "/audit/a" },
|
||||
]),
|
||||
{
|
||||
auditOpens: 1,
|
||||
ctaClicks: 1,
|
||||
outboundClicks: 1,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user