import assert from "node:assert/strict"; import test from "node:test"; import { dashboardKpis, dashboardNavigation, groupLeadFunnelCards, leadFunnelStages, pipelineStages, toLeadFunnelCard, reviewQueue, } from "../lib/dashboard-model"; type NavigationItem = { label: string; href: string }; type PipelineStage = { title: string; count: number }; type ReviewQueueItem = { title: string }; test("dashboardNavigation contains the expected sidebar routes in order", () => { assert.deepEqual( dashboardNavigation.map((item: NavigationItem) => [item.label, item.href]), [ ["Übersicht", "/dashboard"], ["Kampagnen", "/dashboard/campaigns"], ["Leads", "/dashboard/leads"], ["Audits", "/dashboard/audits"], ["Review", "/dashboard/outreach"], ["Analytics", "/dashboard/analytics"], ["Sperrliste", "/dashboard/blacklist"], ["Einstellungen", "/dashboard/settings"], ], ); }); test("pipelineStages keep the first-screen workflow focused on pipeline overview", () => { assert.deepEqual( pipelineStages.map((stage: PipelineStage) => stage.title), ["Kampagnen", "Lead-Recherche", "Audit-Freigabe", "Outreach"], ); assert.equal( pipelineStages.every((stage: PipelineStage) => stage.count >= 0), true, ); }); test("leadFunnelStages expose the agreed German funnel columns", () => { assert.deepEqual( leadFunnelStages.map((stage) => stage.title), [ "Kontakt fehlt", "Audit bereit", "Freigabe offen", "Kontaktiert", "Follow-up", "Zurückgestellt", ], ); }); test("toLeadFunnelCard exposes scan data and derives missing contact next action", () => { const card = toLeadFunnelCard({ id: "lead-1", companyName: "Malerbetrieb Klein", niche: "Maler", city: "Freiburg", postalCode: "79098", priority: "high", contactStatus: "missing_contact", blacklistStatus: "clear", }); assert.equal(card.stageId, "missing_contact"); assert.equal(card.company, "Malerbetrieb Klein"); assert.equal(card.niche, "Maler"); assert.equal(card.location, "79098 Freiburg"); assert.equal(card.priorityLabel, "Hoch"); assert.equal(card.contactStatusLabel, "Kontakt fehlt"); assert.equal(card.nextAction, "Kontaktquelle recherchieren"); }); test("groupLeadFunnelCards derives review, follow-up, and deferred columns without schema migration", () => { const groups = groupLeadFunnelCards([ { id: "lead-review", companyName: "Physio am Park", city: "Freiburg", priority: "medium", contactStatus: "outreach_ready", blacklistStatus: "clear", outreach: { approvalStatus: "draft", sendStatus: "not_sent", responseStatus: "none", salesStatus: "follow_up_planned", }, }, { id: "lead-follow-up", companyName: "Tischlerei Weber", city: "Emmendingen", priority: "medium", contactStatus: "contacted", blacklistStatus: "clear", outreach: { approvalStatus: "approved", sendStatus: "sent", responseStatus: "follow_up_needed", salesStatus: "follow_up_planned", }, }, { id: "lead-replied", companyName: "Salon Licht", city: "Freiburg", priority: "low", contactStatus: "replied", blacklistStatus: "clear", }, { id: "lead-defer", companyName: "Cafe Morgen", city: "Basel", priority: "defer", contactStatus: "new", blacklistStatus: "clear", }, ]); assert.deepEqual( groups.map((group) => [group.stage.id, group.cards.map((card) => card.id)]), [ ["missing_contact", []], ["audit_ready", []], ["review_open", ["lead-review"]], ["contacted", ["lead-replied"]], ["follow_up", ["lead-follow-up"]], ["deferred", ["lead-defer"]], ], ); }); test("dashboardKpis and reviewQueue expose the above-the-fold dashboard summary", () => { assert.equal(dashboardKpis.length, 4); assert.equal(reviewQueue.length, 3); assert.equal( reviewQueue.some((item: ReviewQueueItem) => item.title.includes("Audit-Freigabe"), ), true, ); });