Zum Hauptinhalt springen

Analytics-Integration

Wie v0- und Claude-gebaute Seiten auf das Cockpit-Analytics-System zugreifen – über MCP-Tools und ein wiederverwendbares Tracking-Snippet.

Überblick

Das Cockpit nutzt Umami als Analytics-Plattform. Alle MCP-Tool-Namen und Beispiel-Prompts: MCP-Tool-Referenz (Kategorie Analytics). Jedes Center kann eine eigene Umami-Website-ID und -URL hinterlegen (Center-Einstellungen im Dashboard → Analytics). Externe Seiten (v0-Builds, Claude-Seiten) können:

  1. Umami-Tracking einbettenV0AnalyticsSnippet
  2. Website-Analytics lesencockpit_analytics_website_stats, cockpit_analytics_umami_events, cockpit_analytics_umami_export, cockpit_analytics_website_insights
  3. Content-Performance lesencockpit_analytics_content_metrics, cockpit_analytics_content_performance, cockpit_analytics_content_performance_batch, cockpit_analytics_content_performance_insights
  4. Signage & Reportingcockpit_analytics_signage, cockpit_analytics_reporting, cockpit_analytics_trending, cockpit_analytics_companion_stats, cockpit_analytics_client_report, cockpit_analytics_client_report_bridge_insights
  5. Benutzerdefinierte Events erfassencockpit_analytics_track_event (Cockpit-DB, nicht Umami)

MCP-Tools (Umami & Analytics)

Alle Analytics-Tools laufen über mcp-cockpit-os und benötigen COCKPIT_AGENCYOS_API_KEY (Bearer). Das Dashboard akzeptiert zusätzlich Session-Cookies auf denselben API-Routen.

MCP-ToolUmami / QuelleInhalt
cockpit_analytics_website_statsUmamiVollständig: stats, Verlauf, Top-Seiten, Referrer, Geräte, Browser, OS, Länder, optional Events
cockpit_analytics_umami_eventsUmamiCustom Events (Rohliste)
cockpit_analytics_umami_exportUmamiMulti-Perioden 30 / 90 / 365 Tage
cockpit_analytics_website_insightsUmami + KIWebsite-Insights (Traffic, Bounce, Bot, …)
cockpit_analytics_content_metricsUmami + DBAggregierte Content-Views
cockpit_analytics_content_performanceUmami + DBEin Inhalt (news/offer/event/shop/job/hotpick)
cockpit_analytics_content_performance_batchUmami + DBBis 40 Inhalte
cockpit_analytics_content_performance_insightsUmami + KIKI-Tipps pro Inhalt
cockpit_analytics_signageSignage-API / Companion-UmamiStele/Kiosk-Analytics
cockpit_analytics_companion_statsUmami (systemweit)NOW!/Companion-Website
cockpit_analytics_reportingCockpit-DBAI-Nutzung, Suchen, Funnel
cockpit_analytics_trendingChatbot-DBBeliebte Shops/Angebote (kein Umami)
cockpit_analytics_client_reportCockpit (aggregiert)Kunden-Monatsbericht: Website, Social, Ads, Bewertungen, …
cockpit_analytics_client_report_bridge_insightsCockpit + KIOnline↔Center-Besuch (GET gespeichert / regenerate)
cockpit_analytics_track_eventCockpit-DBCustom Events schreiben (nicht Umami)

Zeiträume (period): 24h, 7d, 30d, 90d, 365d.

Entdecken: cockpit_mcp_discover_tools(query: "analytics").

cockpit_analytics_website_stats

Vollständige Umami-Website-Analytics für ein Center.

Parameter

ParameterTypStandardBeschreibung
centerIdUUIDCenter
period24h | 7d | 30d | 90d | 365d30dZeitraum
includeEventsbooleanfalseUmami Custom Events mitliefern
metricsLimit1–5015Max. Einträge pro Top-Liste

Antwort (Auszug)

{
"success": true,
"centerId": "…",
"stats": { "pageviews": 12340, "visitors": 3421, "visits": 4100, "bounces": 1100, "totaltime": 450000 },
"pageviewsSeries": { "pageviews": [], "sessions": [] },
"topPages": [{ "name": "/news/…", "value": 120 }],
"referrers": [], "devices": [], "browsers": [], "operatingSystems": [], "countries": [],
"derived": { "bounceRatePercent": 26.8, "avgTimePerVisitSeconds": 109, "pagesPerVisit": 3.0 }
}

Voraussetzung: Analytics aktiv, umamiWebsiteId, Server UMAMI_PASSWORD.

Globale Content-Performance (Umami + KI)

Server-Module unter apps/dashboard/src/lib/analytics/ (Barrel: @/lib/analytics):

ModulZweck
center-umami-config.tsCenter-Analytics-Flags + umamiWebsiteId laden
content-url-paths.tsÖffentliche Detail-Pfade (News, Angebote, Events, Shops, Jobs)
content-umami-metrics.tsEinzelabruf + UmamiUrlMetricsCache (ein Umami-Call pro Center)
content-performance-service.tsSnapshot: Views, Engagement, Qualität
content-performance-ai.tsKI-Empfehlungen pro Inhalt (OPENAI_API_KEY)

HTTP (Session oder Agency-API-Key + Center-Zugriff)

RouteBeschreibung
GET /api/analytics/website-stats?centerId=&timeframe=Vollständige Umami-Website-Analytics
GET /api/analytics/umami-events?centerId=Umami Custom Events
GET /api/analytics/umami-export?centerId=Multi-Perioden-Export
GET /api/analytics/insights?centerId=KI-Website-Insights
GET /api/analytics/signage?centerId=Signage/Stele
GET /api/analytics/companion-statsCompanion-Umami (systemweit, nur API-Key)
GET /api/analytics/reporting?centerId=Center-Reporting
GET /api/analytics/client-report?centerId=&timeframe= oder &month=YYYY-MMKunden-Reporting (Website, Social, Bot, Signage)
POST /api/analytics/client-report/share-linkFreigabe-Link für das Centermanagement (scope: month | persistent)
GET /api/analytics/client-report/public/{token}?month=Öffentliches Kunden-Reporting (Token, kein Login)
GET/PATCH /api/analytics/client-report/notify-settingsGespeicherte Centermanagement-E-Mail(s), Feld emails: string[]
GET/PATCH /api/analytics/client-report/ads-budgetMonats-Werbebudget Meta/Google (metaAdsBudgetEur, googleAdsBudgetEur)
POST /api/analytics/client-report/notifyMonatsbericht manuell per E-Mail senden (emails oder email)
GET /api/analytics/trending?centerId=Chatbot-Trending
GET /api/analytics/content-performance?centerId=&kind=&id=Performance-Snapshot eines Inhalts
POST /api/analytics/content-performance/batchBody: { centerId, items: [{ kind, id }] } — Batch mit gemeinsamem Umami-Cache
POST /api/analytics/content-performance/insightsBody: { centerId, kind, id, context? } — KI-Insights inkl. Snapshot
GET /api/content/recent?centerId=Content-Übersicht: Views für News/Angebote/Events/Shops/Jobs/Hot Picks
GET /api/content/metrics?centerId=Aggregierte Views (Umami-Summen Detail-Pfade, 90 Tage)

Voraussetzungen: UMAMI_PASSWORD (Server), Center mit analyticsEnabled, Provider umami oder both, umamiWebsiteId. Optional umamiUrl pro Center.

Umami-Teams pro Organisation (automatisch)

  • Center mit organizationId → beim Analytics-Speichern wird ein Umami-Team der Organisation gefunden oder angelegt (organizations.umamiTeamId).
  • Team-Name = Organisationsname (z. B. „ILG“); bestehendes Team gleichen Namens wird verknüpft, nicht dupliziert.
  • Neue Umami-Websites landen im Team der Organisation.
  • Center ohne Organisation → Hauptbereich (kein teamId), wie bisher.
  • Bestehende umamiWebsiteId an Centers werden nicht verschoben oder überschrieben.

Einmalig bei manuell angelegten Teams (z. B. ILG): Den Cockpit-Umami-API-User (UMAMI_USERNAME, Standard admin) als Mitglied zum Team hinzufügen, damit Stats für bereits dort liegende Websites lesbar sind. Neu über die API angelegte Teams gehören dem API-User automatisch.

Code: apps/dashboard/src/lib/umami-organization-teams.ts, Migration 20260707140000_add_organization_umami_team_SAFE.sql.


kind: news | offer | event | shop | job | hotpick


Dashboard: KI-Insights (intern)

GET /api/analytics/insights?centerId={uuid}&timeframe=day|week|month

  • Session oder Agency-API-Key mit Center-Zugriff
  • Liest Umami Stats + Events, generiert 3–5 Insights via gpt-4o-mini (OPENAI_API_KEY)
  • UI: /dashboard/analytics → Teaser-Box im Tab Website + Tab KI-Insights
  • Fokus stakeholder / limit=2 für die Teaser-Box; jedes Insight optional mit clientMessage (Text fürs Centermanagement-Gespräch, im UI kopierbar)

cockpit_analytics_content_metrics

Aggregierte Metriken für die Content-Übersicht (GET /api/content/metrics): Views (Umami Detail-Pfade + DB), Engagement, categoryBreakdown.

Parameter

ParameterTypPflichtBeschreibung
centerIdstring (UUID)UUID des Centers

Beispiel

cockpit_analytics_content_metrics(centerId: "f1a2b3c4-...")

cockpit_analytics_content_performance

Snapshot für einen Inhalt (Umami, DB, Qualität, Engagement).

ParameterTypPflichtBeschreibung
centerIdstring (UUID)Center
kindnews | offer | event | shop | job | hotpickTyp
idstring (UUID)Inhalt-ID

cockpit_analytics_content_performance_batch

Mehrere Snapshots in einem Request (max. 40 Items) — ein Umami-Call pro Center. Für Agents nach cockpit_center_context sinnvoller als viele Einzel-GETs.

ParameterTypPflichtBeschreibung
centerIdstring (UUID)Center
items{ kind, id }[]1–40 Einträge

Beispiel

cockpit_analytics_content_performance_batch(
centerId: "f1a2b3c4-...",
items: [
{ kind: "news", id: "…" },
{ kind: "offer", id: "…" }
]
)

Antwort (Auszug): data[] mit { kind, id, data?: snapshot } oder { error: "not_found"|"failed" }; meta.umamiBatch: true wenn Umami aktiv.

cockpit_analytics_content_performance_insights

KI-Empfehlungen zu einem Inhalt (POST, optional context).

ParameterTypPflichtBeschreibung
centerIdstring (UUID)Center
kind / idwie obenInhalt
contextstringZusatz für KI

cockpit_analytics_track_event

Erfasst ein benutzerdefiniertes Nutzungs-Event. Events werden in der Datenbank gespeichert und erscheinen im monatlichen Reporting.

Parameter

ParameterTypPflichtStandardBeschreibung
centerIdstring (UUID)UUID des Centers
eventTypestringArt des Events, z.B. "page_view", "offer_click"
source"website" | "kiosk" | "companion" | "app""website"Quelle des Events
metadataobjectZusätzliche Event-Daten (beliebig)

Beispiel

cockpit_analytics_track_event(
centerId: "f1a2b3c4-...",
eventType: "v0_page_load",
source: "website",
metadata: { page: "/angebote", referrer: "google" }
)

Tracking-Snippet für externe Seiten

V0AnalyticsSnippet

Eine React-Komponente (apps/center-website/components/analytics/v0-analytics-snippet.tsx) die das Umami-Tracking-Script in v0- oder Claude-gebaute Seiten einbettet.

Voraussetzungen

  • Next.js (App Router oder Pages Router) mit next/script
  • Das Center muss Analytics aktiviert und eine Umami-Website-ID hinterlegt haben

Props

PropTypPflichtBeschreibung
centerIdstringUUID des Centers – wird für Multi-Tenant-Tracking genutzt
umamiWebsiteIdstringUmami-Website-ID (wenn nicht angegeben, wird sie über die API geladen)
umamiUrlstringBasis-URL der Umami-Instanz (Standard: https://analytics.cockpit-os.de)

Verwendung

Einfachste Variante (Config wird automatisch geladen):

import { V0AnalyticsSnippet } from '@/components/analytics/v0-analytics-snippet'

export default function Layout({ children }) {
return (
<>
<V0AnalyticsSnippet centerId="f1a2b3c4-uuid-des-centers" />
{children}
</>
)
}

Mit expliziten Werten (kein API-Call nötig):

<V0AnalyticsSnippet
centerId="f1a2b3c4-uuid-des-centers"
umamiWebsiteId="abc123-umami-website-id"
umamiUrl="https://analytics.cockpit-os.de"
/>

Verhalten

  • Lädt data.tracking von public-visitor-surface und setzt respectDNT / trackingOptOut (Dashboard → Datenschutz)
  • Wartet auf Cookie-Consent (localStorage cc_cookie, Kategorie analytics) — v0 braucht einen eigenen Cookie-Banner oder kompatibles Opt-in
  • Respektiert Besucher-Opt-out (localStorage cockpit-tracking-opt-out) und DNT (wenn respectDNT aktiv)
  • Dev ohne Consent nur mit NEXT_PUBLIC_UMAMI_DEV_WITHOUT_CONSENT=1 (Center-Website; v0 optional)
  • Wenn keine Website-ID oder Analytics deaktiviert: rendert nichts (kein Fehler)

API-Endpunkte

Die MCP-Tools und das Snippet nutzen diese Dashboard-API-Routen:

EndpunktMethodeCORSBeschreibung
/api/analytics/website-statsGETUmami-Traffic-Statistiken für ein Center
/api/analytics/footfallGETFootfall (Live → Simulator → leer)
/api/analytics/footfall/summaryGETKPIs für Dashboard-Kacheln
/api/system/data-modeGET/PATCHPATCH: SUPER_ADMINGlobaler Datenmodus
/api/analytics/usage-eventsPOSTBenutzerdefinierte Events speichern
/api/analytics/content-performanceGETSessionSnapshot pro Inhalt (kind, id)
/api/analytics/content-performance/batchPOSTSessionMehrere Snapshots, ein Umami-Cache
/api/analytics/content-performance/insightsPOSTSessionKI + Snapshot
/api/analytics/insightsGETSessionWebsite-KI-Insights (Traffic-Tab)
/api/content/metricsGETSessionAggregierte Content-Metriken (Umami + DB)
/api/content/recentGETSessionZuletzt bearbeitete Inhalte + Umami-Views (Batch-Cache)
/api/content/news/{id}/performanceGET/POSTSessionNews SEO (POST = OpenAI)

Öffentlich (v0, ohne Session): GET /api/agencyos/v1/public/visitor-surface?centerId=data.tracking für V0AnalyticsSnippet.

Alle Dashboard-Endpunkte: centerId als Query (GET) bzw. im Body (POST). MCP nutzt COCKPIT_AGENCYOS_API_KEY als Bearer.

Content-Übersicht (/dashboard/content)

  • GET /api/content/metrics: Views aus Umami Detail-Pfaden (90 Tage) für News/Angebote/Events/Shops/Jobs; Hot Picks/Jobs-Engagement aus DB.
  • GET /api/content/recent: Ein Umami Top-URL-Call pro Center; Matching über content-url-paths.ts und content-umami-match-opts.ts (Center-Slug-Prefix, Shop-Kette, trailing slash — kein N× Path-Stats).
  • Detailseiten: ContentPerformanceCard + globale APIs oben (News, Angebote, Events, Jobs, Shops, Shop-Filialen).

Content-Detail: Umami zeigt Aufrufe, Cockpit zeigt 0

Gilt für News, Angebote, Events, Jobs, Hot Picks, Shops und Shop-Filialen (Tab Analytics bzw. ContentPerformanceCard).

Typische Ursachen (Stand 2026-05):

  1. Slug / Pfad: Die öffentliche URL weicht vom Cockpit-Slug ab (z. B. Shop: ShopChain.slug wie /shops/al-carbon/ statt Shop.slug oder UUID). Das Matching nutzt Pfad-Varianten: trailing slash, optional /[centerSlug]/…, bei Shops zusätzlich Kette (extraSlugSegments).
  2. Center: analyticsEnabled, umamiWebsiteId und Server-Env UMAMI_PASSWORD müssen zum gleichen Umami-Website-Eintrag passen wie in der Umami-UI für die Center-Domain.
  3. Filialen: Performance-API unterstützt Shop und ShopLocation (gleiche kind=shop, Kette-Slug aus ShopChain).

Nach Deploy: Tab Analytics neu laden; bei Treffer erscheint Umami-URL (z. B. /shops/al-carbon/).

Code: loadContentRecord lädt center.slug für alle Content-Typen; Listen nutzen shopListItemForUmamiMatch / listItemWithCenterSlug in GET /api/content/recent.

Verifikation (Checkliste)

1. Cockpit-Konfiguration

CheckWo / wie
Analytics aktivDashboard → Center → Analytics → aktiv, Provider umami oder both
umamiWebsiteId gesetztGleicher Tab oder GET Center-Stammdaten
ServerRender/Dashboard: UMAMI_PASSWORD gesetzt
KI-InsightsOPENAI_API_KEY (optional, sonst Fallback-Texte)

MCP: cockpit_get_center_website_config oder cockpit_public_visitor_surface → Feld data.tracking / analyticsConfig.

2. Center-Website (Standard-Layout)

CheckErwartung
Script lädtDevTools → Network: …/script.js mit data-website-id=<umamiWebsiteId>
Cookie-ConsentAnalytics-Kategorie akzeptieren — sonst kein Script
PageviewsUmami-Dashboard oder cockpit_analytics_website_stats nach Traffic
Detail-URLsPfade wie /aktuelles/news/{slug}, /angebote/{slug} — siehe content-url-paths.ts

Pfad-Abweichung (z. B. nur /nachrichten/…): Pfade in apps/dashboard/src/lib/analytics/content-url-paths.ts ergänzen, kein Template-Zwang wenn URLs bereits so geroutet sind.

3. Externe / v0-Seite (ohne app/[slug]/layout)

import { V0AnalyticsSnippet } from '@/components/analytics/v0-analytics-snippet'
// Im Root-Layout:
<V0AnalyticsSnippet centerId="<center-uuid>" />

Verifikation: cockpit_public_visitor_surface(centerId)data.tracking.umamiWebsiteId nicht leer; nach Consent dasselbe script.js wie oben.

4. Content-Performance im Dashboard

CheckAPI / UI
Übersicht lädt schnell/dashboard/content — max. ~12 s Umami-Timeout, dann DB-Fallback
Views in TabelleSpalte Views, ggf. „(Umami)“
EinzelinhaltNews/Angebot/Event/Shop/Job-Detail → Performance-Karte
MCPcockpit_analytics_content_metrics(centerId)
MCP Detailcockpit_analytics_content_performance oder cockpit_analytics_content_performance_batch
MCP KIcockpit_analytics_content_performance_insights(…)

5. Custom Events (optional)

Website: trackEvent('offer_click', { offerId }) aus umami-analytics.tsx.
Server/MCP: cockpit_analytics_track_eventCenterUsageEvent (nicht automatisch in Umami Pageviews).

Verifikation: Event in DB/API Usage-Events; für Content-Views weiterhin normale Pageviews nötig.

# Aggregat (MCP-gleich)
curl -s -H "Authorization: Bearer $COCKPIT_AGENCYOS_API_KEY" \
"https://dashboard.cockpit-os.de/api/content/metrics?centerId=<UUID>"

# Snapshot News
curl -s -H "Authorization: Bearer $COCKPIT_AGENCYOS_API_KEY" \
"https://dashboard.cockpit-os.de/api/analytics/content-performance?centerId=<UUID>&kind=news&id=<NEWS_UUID>"

dataSources.umamiEnabled: true und views > 0 in metrics = Umami-Pfad-Matching funktioniert (bei Traffic).


Footfall (Besucherströme)

Dashboard: /dashboard/analytics/footfall

API: GET /api/analytics/footfall?centerId=<uuid> (ohne centerId: Portfolio bis 12 Center)

Antwort: success, source (live | simulator | unavailable), dataMode, liveDataAvailable, data mit summary, centers[], hourlyToday[], optional zones[].

Auflösung: Live-Partner (fetchLiveFootfall) → bei Modus simulator deterministische Demo-Daten → bei off leere Kennzahlen. Kein verstreutes Mock mehr in der Route.

Zentrale Lib: resolve-footfall.ts, simulator.ts, data-mode/. Live-Anbindung: Footfall-API & Simulator.

Env: COCKPIT_DATA_MODE, FOOTFALL_PROVIDER, FOOTFALL_API_BASE_URL, FOOTFALL_API_KEY. UI-Toggle auf der Footfall-Seite (außer Env-Lock).


Architektur

Externe Seite (v0/Claude)

├─► V0AnalyticsSnippet ──► Umami Script (direkt zum Umami-Server)
│ └─ Center-Config-API (/api/centers/{id}/public-config)

└─► cockpit_analytics_* (MCP-Tools)

├─► /api/analytics/website-stats ──► Umami API
├─► /api/content/metrics ──► Umami (Top-URLs) + Prisma
├─► /api/analytics/content-performance ──► Umami + Prisma
└─► /api/analytics/usage-events ──► Prisma (CenterUsageEvent)

Datenfluss Tracking

  1. Seitenaufruf: V0AnalyticsSnippet lädt das Umami-Script → Umami trackt Page Views direkt
  2. Custom Events: cockpit_analytics_track_event schreibt in die Cockpit-DB (für Reporting)
  3. Statistiken lesen: cockpit_analytics_website_stats fragt Umami über die server-seitige API ab

Verwandte Dokumentation

Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /developer-guide/analytics-integration