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:
- Umami-Tracking einbetten →
V0AnalyticsSnippet - Website-Analytics lesen →
cockpit_analytics_website_stats,cockpit_analytics_umami_events,cockpit_analytics_umami_export,cockpit_analytics_website_insights - Content-Performance lesen →
cockpit_analytics_content_metrics,cockpit_analytics_content_performance,cockpit_analytics_content_performance_batch,cockpit_analytics_content_performance_insights - Signage & Reporting →
cockpit_analytics_signage,cockpit_analytics_reporting,cockpit_analytics_trending,cockpit_analytics_companion_stats,cockpit_analytics_client_report,cockpit_analytics_client_report_bridge_insights - Benutzerdefinierte Events erfassen →
cockpit_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-Tool | Umami / Quelle | Inhalt |
|---|---|---|
cockpit_analytics_website_stats | Umami | Vollständig: stats, Verlauf, Top-Seiten, Referrer, Geräte, Browser, OS, Länder, optional Events |
cockpit_analytics_umami_events | Umami | Custom Events (Rohliste) |
cockpit_analytics_umami_export | Umami | Multi-Perioden 30 / 90 / 365 Tage |
cockpit_analytics_website_insights | Umami + KI | Website-Insights (Traffic, Bounce, Bot, …) |
cockpit_analytics_content_metrics | Umami + DB | Aggregierte Content-Views |
cockpit_analytics_content_performance | Umami + DB | Ein Inhalt (news/offer/event/shop/job/hotpick) |
cockpit_analytics_content_performance_batch | Umami + DB | Bis 40 Inhalte |
cockpit_analytics_content_performance_insights | Umami + KI | KI-Tipps pro Inhalt |
cockpit_analytics_signage | Signage-API / Companion-Umami | Stele/Kiosk-Analytics |
cockpit_analytics_companion_stats | Umami (systemweit) | NOW!/Companion-Website |
cockpit_analytics_reporting | Cockpit-DB | AI-Nutzung, Suchen, Funnel |
cockpit_analytics_trending | Chatbot-DB | Beliebte Shops/Angebote (kein Umami) |
cockpit_analytics_client_report | Cockpit (aggregiert) | Kunden-Monatsbericht: Website, Social, Ads, Bewertungen, … |
cockpit_analytics_client_report_bridge_insights | Cockpit + KI | Online↔Center-Besuch (GET gespeichert / regenerate) |
cockpit_analytics_track_event | Cockpit-DB | Custom 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
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
centerId | UUID | ✅ | Center |
period | 24h | 7d | 30d | 90d | 365d | 30d | Zeitraum |
includeEvents | boolean | false | Umami Custom Events mitliefern |
metricsLimit | 1–50 | 15 | Max. 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, ServerUMAMI_PASSWORD.
Globale Content-Performance (Umami + KI)
Server-Module unter apps/dashboard/src/lib/analytics/ (Barrel: @/lib/analytics):
| Modul | Zweck |
|---|---|
center-umami-config.ts | Center-Analytics-Flags + umamiWebsiteId laden |
content-url-paths.ts | Öffentliche Detail-Pfade (News, Angebote, Events, Shops, Jobs) |
content-umami-metrics.ts | Einzelabruf + UmamiUrlMetricsCache (ein Umami-Call pro Center) |
content-performance-service.ts | Snapshot: Views, Engagement, Qualität |
content-performance-ai.ts | KI-Empfehlungen pro Inhalt (OPENAI_API_KEY) |
HTTP (Session oder Agency-API-Key + Center-Zugriff)
| Route | Beschreibung |
|---|---|
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-stats | Companion-Umami (systemweit, nur API-Key) |
GET /api/analytics/reporting?centerId= | Center-Reporting |
GET /api/analytics/client-report?centerId=&timeframe= oder &month=YYYY-MM | Kunden-Reporting (Website, Social, Bot, Signage) |
POST /api/analytics/client-report/share-link | Freigabe-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-settings | Gespeicherte Centermanagement-E-Mail(s), Feld emails: string[] |
GET/PATCH /api/analytics/client-report/ads-budget | Monats-Werbebudget Meta/Google (metaAdsBudgetEur, googleAdsBudgetEur) |
POST /api/analytics/client-report/notify | Monatsbericht 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/batch | Body: { centerId, items: [{ kind, id }] } — Batch mit gemeinsamem Umami-Cache |
POST /api/analytics/content-performance/insights | Body: { 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
umamiWebsiteIdan 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=2für die Teaser-Box; jedes Insight optional mitclientMessage(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
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
centerId | string (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).
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
centerId | string (UUID) | ✅ | Center |
kind | news | offer | event | shop | job | hotpick | ✅ | Typ |
id | string (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.
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
centerId | string (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).
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
centerId | string (UUID) | ✅ | Center |
kind / id | wie oben | ✅ | Inhalt |
context | string | – | Zusatz für KI |
cockpit_analytics_track_event
Erfasst ein benutzerdefiniertes Nutzungs-Event. Events werden in der Datenbank gespeichert und erscheinen im monatlichen Reporting.
Parameter
| Parameter | Typ | Pflicht | Standard | Beschreibung |
|---|---|---|---|---|
centerId | string (UUID) | ✅ | – | UUID des Centers |
eventType | string | ✅ | – | Art des Events, z.B. "page_view", "offer_click" |
source | "website" | "kiosk" | "companion" | "app" | – | "website" | Quelle des Events |
metadata | object | – | – | Zusä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
| Prop | Typ | Pflicht | Beschreibung |
|---|---|---|---|
centerId | string | ✅ | UUID des Centers – wird für Multi-Tenant-Tracking genutzt |
umamiWebsiteId | string | – | Umami-Website-ID (wenn nicht angegeben, wird sie über die API geladen) |
umamiUrl | string | – | Basis-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.trackingvonpublic-visitor-surfaceund setztrespectDNT/trackingOptOut(Dashboard → Datenschutz) - Wartet auf Cookie-Consent (localStorage
cc_cookie, Kategorieanalytics) — v0 braucht einen eigenen Cookie-Banner oder kompatibles Opt-in - Respektiert Besucher-Opt-out (
localStorage cockpit-tracking-opt-out) und DNT (wennrespectDNTaktiv) - 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:
| Endpunkt | Methode | CORS | Beschreibung |
|---|---|---|---|
/api/analytics/website-stats | GET | ✅ | Umami-Traffic-Statistiken für ein Center |
/api/analytics/footfall | GET | – | Footfall (Live → Simulator → leer) |
/api/analytics/footfall/summary | GET | – | KPIs für Dashboard-Kacheln |
/api/system/data-mode | GET/PATCH | PATCH: SUPER_ADMIN | Globaler Datenmodus |
/api/analytics/usage-events | POST | ✅ | Benutzerdefinierte Events speichern |
/api/analytics/content-performance | GET | Session | Snapshot pro Inhalt (kind, id) |
/api/analytics/content-performance/batch | POST | Session | Mehrere Snapshots, ein Umami-Cache |
/api/analytics/content-performance/insights | POST | Session | KI + Snapshot |
/api/analytics/insights | GET | Session | Website-KI-Insights (Traffic-Tab) |
/api/content/metrics | GET | Session | Aggregierte Content-Metriken (Umami + DB) |
/api/content/recent | GET | Session | Zuletzt bearbeitete Inhalte + Umami-Views (Batch-Cache) |
/api/content/news/{id}/performance | GET/POST | Session | News 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 übercontent-url-paths.tsundcontent-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):
- Slug / Pfad: Die öffentliche URL weicht vom Cockpit-Slug ab (z. B. Shop:
ShopChain.slugwie/shops/al-carbon/stattShop.slugoder UUID). Das Matching nutzt Pfad-Varianten: trailing slash, optional/[centerSlug]/…, bei Shops zusätzlich Kette (extraSlugSegments). - Center:
analyticsEnabled,umamiWebsiteIdund Server-EnvUMAMI_PASSWORDmüssen zum gleichen Umami-Website-Eintrag passen wie in der Umami-UI für die Center-Domain. - Filialen: Performance-API unterstützt
ShopundShopLocation(gleichekind=shop, Kette-Slug ausShopChain).
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
| Check | Wo / wie |
|---|---|
| Analytics aktiv | Dashboard → Center → Analytics → aktiv, Provider umami oder both |
umamiWebsiteId gesetzt | Gleicher Tab oder GET Center-Stammdaten |
| Server | Render/Dashboard: UMAMI_PASSWORD gesetzt |
| KI-Insights | OPENAI_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)
| Check | Erwartung |
|---|---|
| Script lädt | DevTools → Network: …/script.js mit data-website-id=<umamiWebsiteId> |
| Cookie-Consent | Analytics-Kategorie akzeptieren — sonst kein Script |
| Pageviews | Umami-Dashboard oder cockpit_analytics_website_stats nach Traffic |
| Detail-URLs | Pfade 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
| Check | API / UI |
|---|---|
| Übersicht lädt schnell | /dashboard/content — max. ~12 s Umami-Timeout, dann DB-Fallback |
| Views in Tabelle | Spalte Views, ggf. „(Umami)“ |
| Einzelinhalt | News/Angebot/Event/Shop/Job-Detail → Performance-Karte |
| MCP | cockpit_analytics_content_metrics(centerId) |
| MCP Detail | cockpit_analytics_content_performance oder cockpit_analytics_content_performance_batch |
| MCP KI | cockpit_analytics_content_performance_insights(…) |
5. Custom Events (optional)
Website: trackEvent('offer_click', { offerId }) aus umami-analytics.tsx.
Server/MCP: cockpit_analytics_track_event → CenterUsageEvent (nicht automatisch in Umami Pageviews).
Verifikation: Event in DB/API Usage-Events; für Content-Views weiterhin normale Pageviews nötig.
6. Schnelltest per curl (lokal/staging, mit Session-Cookie oder API-Key)
# 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
- Seitenaufruf:
V0AnalyticsSnippetlädt das Umami-Script → Umami trackt Page Views direkt - Custom Events:
cockpit_analytics_track_eventschreibt in die Cockpit-DB (für Reporting) - Statistiken lesen:
cockpit_analytics_website_statsfragt 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