Cockpit-Daten-Domänen (Architektur)
Einheitliches Modell für alle Mess- und Analytics-Quellen im Cockpit — Mock-Daten werden nicht blind entfernt, sondern durch Resolver ersetzt, die später ohne UI-Bruch auf Live umstellen.
Prinzip pro Domäne
Live-Quelle (DB, Partner-API, Umami, …)
↓ wenn nicht verfügbar
Simulator (nur wo sinnvoll — Footfall, Parking, …)
↓ wenn Datenmodus „Aus“
Leer / „Keine Daten“ + Setup-Hinweis
Jede API-Antwort enthält:
source:live|simulator|unavailable(Website:configured)dataMode: globaler Cockpit-Modusmessage: erklärender Text für UI
Globaler Datenmodus
| Modus | Wirkung |
|---|---|
simulator | Domänen mit Simulator liefern Demo-Daten |
off | Kein Simulator — nur Live oder leer |
live | Kein Simulator-Fallback (nur echte Quellen) |
Priorität: COCKPIT_DATA_MODE (Env) → IntegrationConfig → Default.
API: GET/PATCH /api/system/data-mode — UI auf Footfall-Seite („Cockpit-Datenmodus“).
Pro Domäne (optional): In IntegrationConfig.config.domains können einzelne Domänen überschrieben werden (simulator | off | live). UI: Dropdown pro Domäne in DataSimulatorSettings. Effektiver Modus: getDomainMode() in jedem Resolver. Bei Env-Lock (COCKPIT_DATA_MODE) bleibt der globale Modus aus Env, Overrides aus der DB gelten weiterhin.
Wichtig: Wenn eine Live-Quelle liefert (z. B. Footfall-Partner, Parking-DB mit Zonen), hat Live immer Vorrang — unabhängig vom Toggle.
Domänen-Registry
| Domäne | Simulator | Live-Quelle | Status |
|---|---|---|---|
| footfall | Ja | FOOTFALL_API_* oder Simulator | Aktiv |
| parking | Ja | ParkingZone + OccupancyLog | Aktiv |
| website | Nein | Umami (umamiWebsiteId) | Aktiv |
| property | Nein (ableitet) | Footfall-Zonen → Flächen-Score | Teilweise |
| signage | Ja | SIGNAGE_API_* oder Companion-Umami | Aktiv |
| revenue | Ja | REVENUE_API_* (POS) | Aktiv |
| expenses | Ja | EXPENSES_API_* (ERP/Finance) | Aktiv |
| energy | Ja | ENERGY_API_* (Smart Meter) | Aktiv |
Code: apps/dashboard/src/lib/data-mode/domains.ts
Implementierung (Developer)
| Domäne | Resolver | API |
|---|---|---|
| Footfall | lib/analytics/footfall/resolve-footfall.ts | /api/analytics/footfall |
| Parking | lib/analytics/parking/resolve-parking.ts | /api/parking, /api/parking-zones, /api/centers/[centerId]/parking-zones |
Auth (Parking, seit Juni 2026): Lese- und Schreibzugriffe auf Parking-Daten und Parkzonen erfordern Center-Auth (Dashboard-Session, Center-Manager mit CM_BRIDGE_SECRET oder gültiger Bearer-Token). Öffentliche Besucher-Routen (Signage/Kiosk) nutzen weiterhin nur die für sie freigegebenen Endpunkte — nicht die Parkzonen-CRUD-APIs.
| Signage | lib/analytics/signage/resolve-signage.ts | /api/analytics/signage |
| Revenue | lib/analytics/revenue/resolve-revenue.ts | /api/analytics/revenue |
| Expenses | lib/analytics/expenses/resolve-expenses.ts | /api/analytics/expenses |
| Energy | lib/analytics/energy/resolve-energy.ts | /api/analytics/energy |
| Property Score | lib/analytics/property/space-footfall-insights.ts | /api/property/spaces |
| Website | lib/umami-api.ts + Center-Config | /api/analytics/website-stats |
Client-Hook (Footfall-KPIs): hooks/use-footfall-summary.ts
Website / Umami — bewusst ohne Simulator
Website-Traffic wird nicht simuliert:
- Center mit
umamiWebsiteId→ echte KPIs - Ohne Config → „Nicht verfügbar“ + CTA „Umami einrichten“
Das vermeidet irreführende Demo-Charts in Sales-Gesprächen. Für Demos: echtes Demo-Center mit Umami nutzen.
Property Footfall-Score
Kein separates Mock: footfallScore wird aus Footfall-Zonen abgeleitet (Zone-Matching anhand Flächenname/Etage). Quelle = dieselbe wie Footfall (Live/Simulator). Ohne Footfall-Daten: Score null, UI zeigt Hinweis.
Signage (Kiosk & Companion)
Auflösung in resolve-signage.ts:
- Signage-HTTP-API — Touchscreen-Interaktionen (Voll-Live)
- Companion-Umami — Teil-Live (Besucher/Pageviews), wenn API fehlt
- Simulator (globaler Datenmodus)
- Leer — bei Datenmodus „Aus“ nur Schritte 1–2, kein Simulator
Env (Dashboard-Server, z. B. Render mallos-dashboard)
| Variable | Zweck |
|---|---|
SIGNAGE_API_BASE_URL | Basis-URL des Signage-Services (ohne trailing slash) |
SIGNAGE_API_KEY | Optional, Bearer-Token |
SIGNAGE_API_TIMEOUT_MS | Timeout (Default 8000) |
UMAMI_PASSWORD | Für Companion-Umami (Website „Companion“) |
In Entwicklung ohne Env: Fallback http://localhost:3002/api. In Produktion ohne SIGNAGE_API_BASE_URL wird die Signage-API nicht abgefragt.
Companion-Umami: Button auf /dashboard/digital-signage/analytics → POST /api/umami-app-config/ensure — danach Reload der KPIs.
API-Antwort enthält integration, liveChannel (signage-api | companion-umami), liveDataAvailable.
UI: RealTimeAnalytics, SignageIntegrationStatusAlert, /dashboard/digital-signage/analytics
Revenue (Umsatz / POS)
Auflösung in resolve-revenue.ts:
- POS-HTTP-API (
REVENUE_PROVIDER=http,REVENUE_API_BASE_URL,REVENUE_API_KEY) — Adapter folgt mit Partner-Spec - Simulator — Mieterumsätze aus Shops in der DB (oder Demo-Shops)
- Leer
API: GET /api/analytics/revenue, GET /api/analytics/revenue/summary
Hook: hooks/use-revenue-summary.ts — HQ-Cockpit, Center-Manager Sales/Reports, Finance, Data-Business (RevenueStreamStatus), CM-App analytics.revenue
Expenses (Ausgaben / Budget)
Auflösung in resolve-expenses.ts:
- ERP-HTTP-API (
EXPENSES_PROVIDER=http,EXPENSES_API_BASE_URL,EXPENSES_API_KEY) - Simulator — Budget-Kategorien + Betriebskosten-Zeilen
- Leer
API: GET /api/analytics/expenses, GET /api/analytics/expenses/summary
Hook: hooks/use-expenses-summary.ts — Finance, Budget, Betriebskosten, Data-Business (ExpensesStreamStatus); Monatsgewinn = Revenue − Expenses auf /dashboard/finance
HQ-Cockpit: GET /api/cockpits/hq/summary — Portfolio-Auslastung (Property/Parking) + offene Issues; Hook use-hq-summary.ts
Energy (Verbrauch / Effizienz)
Auflösung in resolve-energy.ts:
- Smart-Meter-HTTP-API (
ENERGY_PROVIDER=http,ENERGY_API_BASE_URL,ENERGY_API_KEY) — Adapter folgt mit Partner-Spec - Simulator — Monatsverbrauch, Einsparung, Effizienz-Score
- Leer
API: GET /api/analytics/energy, GET /api/analytics/energy/summary
Hook: hooks/use-energy-summary.ts — HQ-Cockpit (Energieeffizienz-KPI), Data-Business (EnergyStreamStatus), CM-App analytics.energy
Roadmap
- Partner-API-Mapping (
fetchLive*) wenn Specs vorliegen (Footfall, Revenue, Expenses, Energy, …) - Data-Business — verbleibende Platzhalter-Streams (Feedback, Security) an echte Quellen
Verwandt
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /developer-guide/cockpit-data-domains