Skip to main content

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-Modus
  • message: erklärender Text für UI

Globaler Datenmodus

ModusWirkung
simulatorDomänen mit Simulator liefern Demo-Daten
offKein Simulator — nur Live oder leer
liveKein 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äneSimulatorLive-QuelleStatus
footfallJaFOOTFALL_API_* oder SimulatorAktiv
parkingJaParkingZone + OccupancyLogAktiv
websiteNeinUmami (umamiWebsiteId)Aktiv
propertyNein (ableitet)Footfall-Zonen → Flächen-ScoreTeilweise
signageJaSIGNAGE_API_* oder Companion-UmamiAktiv
revenueJaREVENUE_API_* (POS)Aktiv
expensesJaEXPENSES_API_* (ERP/Finance)Aktiv
energyJaENERGY_API_* (Smart Meter)Aktiv

Code: apps/dashboard/src/lib/data-mode/domains.ts

Implementierung (Developer)

DomäneResolverAPI
Footfalllib/analytics/footfall/resolve-footfall.ts/api/analytics/footfall
Parkinglib/analytics/parking/resolve-parking.ts/api/parking
Signagelib/analytics/signage/resolve-signage.ts/api/analytics/signage
Revenuelib/analytics/revenue/resolve-revenue.ts/api/analytics/revenue
Expenseslib/analytics/expenses/resolve-expenses.ts/api/analytics/expenses
Energylib/analytics/energy/resolve-energy.ts/api/analytics/energy
Property Scorelib/analytics/property/space-footfall-insights.ts/api/property/spaces
Websitelib/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:

  1. Signage-HTTP-API — Touchscreen-Interaktionen (Voll-Live)
  2. Companion-Umami — Teil-Live (Besucher/Pageviews), wenn API fehlt
  3. Simulator (globaler Datenmodus)
  4. Leer — bei Datenmodus „Aus“ nur Schritte 1–2, kein Simulator

Env (Dashboard-Server, z. B. Render mallos-dashboard)

VariableZweck
SIGNAGE_API_BASE_URLBasis-URL des Signage-Services (ohne trailing slash)
SIGNAGE_API_KEYOptional, Bearer-Token
SIGNAGE_API_TIMEOUT_MSTimeout (Default 8000)
UMAMI_PASSWORDFü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/analyticsPOST /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:

  1. POS-HTTP-API (REVENUE_PROVIDER=http, REVENUE_API_BASE_URL, REVENUE_API_KEY) — Adapter folgt mit Partner-Spec
  2. Simulator — Mieterumsätze aus Shops in der DB (oder Demo-Shops)
  3. 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:

  1. ERP-HTTP-API (EXPENSES_PROVIDER=http, EXPENSES_API_BASE_URL, EXPENSES_API_KEY)
  2. Simulator — Budget-Kategorien + Betriebskosten-Zeilen
  3. 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:

  1. Smart-Meter-HTTP-API (ENERGY_PROVIDER=http, ENERGY_API_BASE_URL, ENERGY_API_KEY) — Adapter folgt mit Partner-Spec
  2. Simulator — Monatsverbrauch, Einsparung, Effizienz-Score
  3. 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

  1. Partner-API-Mapping (fetchLive*) wenn Specs vorliegen (Footfall, Revenue, Expenses, Energy, …)
  2. Data-Business — verbleibende Platzhalter-Streams (Feedback, Security) an echte Quellen

Verwandt

Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /en/developer-guide/cockpit-data-domains