Zum Hauptinhalt springen

Footfall-API: Live-Anbindung & Simulator

Das Dashboard lädt Footfall zentral über GET /api/analytics/footfall?centerId=<uuid>.
Die Auflösung folgt der Reihenfolge Live → Simulator → leer — ohne verstreute Hardcoded-Mocks.

Datenmodus (global)

ModusVerhalten
liveNur echte Partner-/Sensor-Daten (wenn Env konfiguriert)
simulatorDeterministische Demo-Zahlen (Center + Datum als Seed)
offKeine simulierten Daten — leere Zustände wenn Live fehlt

Priorität: COCKPIT_DATA_MODE (Env) → IntegrationConfig (service: cockpit-data-mode) → Default (simulator, wenn keine Live-Footfall-Env).

  • API: GET /api/system/data-mode, PATCH nur SUPER_ADMIN
  • UI: Karte „Daten-Simulator“ auf /dashboard/analytics/footfall
  • KPIs: GET /api/analytics/footfall/summary?centerId=<uuid> (Admin-Dashboard-Kacheln)
# Optional: Env-Override (sperrt UI-Toggle)
COCKPIT_DATA_MODE=simulator # live | simulator | off

Bereits im Code

BausteinPfad
Typen (inkl. Zonen)apps/dashboard/src/lib/analytics/footfall/types.ts
Zentrale Auflösungresolve-footfall.tsresolveFootfallData, getFootfallKpis
Simulatorsimulator.tsbuildSimulatedFootfallPayload
Datenmodusapps/dashboard/src/lib/data-mode/
Env + Live-Stubintegration.tsfetchLiveFootfall
Partner → Payloadmap-partner-response.ts
API-Routenfootfall/route.ts, footfall/summary/route.ts
UIFootfallIntegrationStatusAlert, DataSimulatorSettings, DataSourceBadge, footfall-charts.tsx

Legacy mock-footfall-data.ts bleibt nur für Tests — nicht für Produktion.

Env Footfall-Partner (Server, optional)

FOOTFALL_PROVIDER=none # später: http
FOOTFALL_API_BASE_URL= # Basis-URL des Anbieters
FOOTFALL_API_KEY= # API-Key / Token
FOOTFALL_API_TIMEOUT_MS=15000

Die Route setzt integration in der JSON-Antwort (Provider, ob URL/Key gesetzt, Hinweistext).

API-Antwort

{
"success": true,
"source": "simulator",
"dataMode": "simulator",
"liveDataAvailable": false,
"data": { "summary": { ... }, "centers": [ ... ], "hourlyToday": [ ... ], "weeklyTrend": [ ... ], "monthlyTrend": [ ... ], "zones": [ ... ], "weekdayHeatmap": [ ... ] }
}

source: live | simulator | unavailable

Wenn die API-Spec da ist

  1. Response-Typ in PartnerFootfallRawResponse (map-partner-response.ts) anpassen.
  2. fetchLiveFootfallHttp in integration.ts — implementiert: GET {FOOTFALL_API_BASE_URL}/centers/{centerId}/footfall?date=today, Mapping über mapPartnerFootfallToPayload.
  3. Route liefert automatisch source: "live", liveDataAvailable: true (Vorrang vor Simulator).

Zonen (Bereiche)

FootfallApiPayload.zones ist optional:

{ zoneId, name, visitors, dwellMinutes?, conversionPercent? }

Der Simulator liefert Beispiel-Zonen; Live-Partner kann eigene Zonen mappen.

Optional in FootfallApiPayload (Simulator liefert alle Felder für das primäre Center):

FeldBeschreibung
weeklyTrend7 Tage: { date, label, visitors }
monthlyTrend12 Monate: { date, label, visitors }
weekdayHeatmap7×14 Gitter: Wochentag × Stunde (08:0021:00)
zonesBereiche mit visitors, optional dwellMinutes, conversionPercent

UI: Reiter Übersicht, Trends und Heatmap auf /dashboard/analytics/footfall (footfall-charts.tsx).

Center-Mapping (später, DB)

Expand-only Vorschlag (noch nicht migriert):

  • ShoppingCenter.footfallProvider (nullable)
  • ShoppingCenter.footfallExternalId (nullable)

Bis dahin: globales Env oder Mapping in integration.ts.

Consumer (alle über dieselbe Auflösung)

ConsumerPfad / API
Footfall-Dashboard/dashboard/analytics/footfallGET /api/analytics/footfall
Analytics-Übersicht, Admin-KachelnGET /api/analytics/footfall/summary
Center-Manager AppsGET /api/center-manager/apps
Center-Manager Daten & ConfigGET /api/center-manager/data, GET /api/center-manager/config
Reports, Sales, HQ-Cockpit, AI-AssistentClient-Hook useFootfallSummary/summary
Data-Business-CockpitFootfallStreamStatus

Umschalten: PATCH /api/system/data-mode oder Toggle auf der Footfall-Seite. Live-Partner (FOOTFALL_API_*) hat immer Vorrang.

Verwandt

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