# Übergabe an die Entwicklung > **Rangfolge:** Wo dieser Prototyp von HiveGrid Cloud abweicht, **gilt > HiveGrid**: Schrift, Schriftgrößen, Abstände, Farben, Control-Höhen, > App-Shell. Dass hier dieselbe Schrift und dieselbe Seitenleisten-Komponente > stecken, dient nur der Lesbarkeit neben der Software; es ist keine Vorlage, > an der sich die Software auszurichten hätte. Verbindlich sind aus diesem Repo > die Kennzahl-Definitionen, die Diagrammregeln, das Verhalten und die > Navigationsstruktur als Verabredung. Ausführlich: > [`docs/ZIELSYSTEM.md`](docs/ZIELSYSTEM.md) Abschnitt 0. > > **Der Einbau selbst steht in [`EINBAU.md`](EINBAU.md)**: Zielpfade, > Ticket-Docs im Format von `.planning/ticket-docs/`, i18n-Schlüssel. > > **Ebenfalls vor dem Einbau lesen:** > [`docs/SCOPE-ANALYTICS-DASHBOARD.md`](docs/SCOPE-ANALYTICS-DASHBOARD.md), > insbesondere Abschnitt 3a. Der Handlungsbedarf steht dort **absichtlich > doppelt**: auf dem Dashboard und auf der Analytics-Übersicht, weil das > Entfernen eine offene Produktfrage mitentschieden hätte. Das ist vor dem > Port aufzulösen und nicht zu übernehmen. Dieser Prototyp liefert **Gestaltung und Interaktion**, nicht die Anbindung. Was echt ist, was Attrappe ist und was beim Einbau zu tun bleibt: --- ## 1. Was fertig ist und übernommen werden kann | Bereich | Datei(en) | Zustand | |---|---|---| | Kennzahlen-Berechnung | `features/dashboard/data/calculations.ts` | **Reine Funktionen** über typisierten Eingangsdaten: direkt übernehmbar | | Chart-Theme | `features/dashboard/utils/chartTheme.ts` | Carbon-Tokens, Palette, Achsen-Props, Margins | | Formatierung | `features/dashboard/utils/formatters.ts` | Deutsche Zahlen-, Währungs- und Datumsformate | | Chart-Komponenten | `features/dashboard/components/charts/` | Vollständig, mit Leerzuständen und Tooltips | | Karten & Tabellen | `features/dashboard/components/cards/`, `tables/` | Vollständig | | Filtersystem | `features/dashboard/context/FilterContext.tsx`, `data/filtering.ts` | State und Relevanzlogik fertig | | Seitenaufbau | `features/dashboard/pages/` | **Reine Komponenten** `({ vm })`, kein Store-Zugriff, direkt übernehmbar | | View-Model-Builder | `features/dashboard/view-models/*.vm.ts` | Reine Funktionen `(daten, filter) → VMState<…>`; im Loader wiederverwendbar | | Seitenzustände | `components/layout/SeitenZustand.tsx` | idle · loading · empty · error ausgestaltet | --- ## 2. Was echte Logik braucht ### 2.1 Datenquelle austauschen Alles hängt an **einer** Stelle: `features/dashboard/data/seed.ts` exportiert `DATENSATZ` vom Typ `Datensatz`. Diesen Export durch echte Daten ersetzen, Loader, Server-Query oder Service, je nach Architektur. Alle Berechnungen und Komponenten arbeiten unverändert weiter. Feldzuordnung zu den HiveGrid-Entities steht in [`docs/DATENMODELL.md`](docs/DATENMODELL.md). **Achtung Zeitbezug:** `features/dashboard/utils/dateUtils.ts` definiert `HEUTE` als festen Stichtag (30.07.2026), damit der Prototyp reproduzierbar bleibt. Beim Einbau durch `new Date()` ersetzen, die Konstante wird an elf Stellen verwendet, alle über den Import. ### 2.2 Filter serverseitig anwenden Aktuell wird komplett clientseitig gefiltert (`data/filtering.ts`). Bei echten Datenmengen gehört das in die Query. Der State im `FilterContext` lässt sich dafür in URL-Parameter serialisieren; die Relevanzlogik (`FILTER_RELEVANZ`) bleibt clientseitig, weil sie nur die Anzeige steuert. ### 2.3 Aktionen ohne Wirkung Diese Elemente lösen bewusst nur einen Hinweis-Toast aus: | Element | Wo | Erwartetes Verhalten | |---|---|---| | Export (Seitenkopf) | `components/layout/PageHeader.tsx` | PDF-/CSV-Export der Ansicht | | Teilen | `components/layout/PageHeader.tsx` | Link mit eingefrorenen Filtern | | Aktualisieren | `components/layout/PageHeader.tsx` | Daten neu laden | | „Als Bild exportieren" | `components/cards/ChartCard.tsx` | PNG-Export des Charts | | Einträge in „Handlungsbedarf" | `components/cards/AlertList.tsx` | Absprung in die jeweilige Arbeitsliste, die Handlung je Zeile (`aktion`) beschreibt, was dort passieren soll | | Tabellenzeilen | `components/tables/DataTable.tsx` | Absprung auf den Datensatz | | Suche und Glocke (Kopfzeile) | `components/layout/AppShell.tsx` | Attrappe, gehört zur bestehenden Shell | ### 2.4 Was funktioniert und erhalten bleiben sollte - **Zeitraum-Umschaltung** rechnet alle Kennzahlen und Charts neu, inklusive Trendvergleich zur Vorperiode - **Mehrfachfilter** (Gewerk, Status, Quelle, Region, Mitarbeiter) mit entfernbaren Chips - **Seitenabhängige Filterrelevanz**: irrelevante Filter werden gar nicht erst angeboten - **Widgets ausblenden** über das ⋯-Menü jeder Karte, Wiedereinblenden über die Filterleiste, persistiert - **Tabellen** sortieren, durchsuchen, blättern - **Hover** auf Balken, Ringsegmenten, Trichterstufen und Verlaufspunkten - **Legenden im Ring** heben beim Klick das jeweilige Segment hervor - **Tastaturbedienung**: sichtbarer Fokus auf allen interaktiven Elementen, Escape schließt Dropdown und Karten-Menü Persistiert wird in `localStorage` unter `hivegrid.analytics.*`. In der echten Software gehört das an das Benutzerprofil. --- ## 3. Bewusste Entscheidungen **Recharts statt der Subframe-Chart-Komponenten.** Die Subframe-Wrapper (`ui/components/AreaChart` etc.) geben zu wenig Kontrolle über Achsen, Tooltips und Ringproportionen, um die Carbon-Regeln umzusetzen. Die übrige Oberfläche nutzt weiterhin die Subframe-Bibliothek und deren Design-Tokens. **Deterministische Dummy-Daten.** Fester Seed statt `Math.random()`: Die Zahlen bleiben über Reloads und Screenshots identisch, sonst ist keine Abstimmung über konkrete Werte möglich. **Team-Seite enthalten,** obwohl die Planung sie für v2 vorgesehen hatte. Auslastung ist im Handwerk die Kennzahl, nach der disponiert wird, ohne sie fehlt dem Dashboard der Bezug zum Tagesgeschäft. **Kein Dark Mode.** Die Carbon-Palette ist hier im Light Theme hinterlegt. Ein Dark Theme braucht die zweite Palettenvariante (in `@carbon/charts` enthalten) und eigene Kontrastprüfung: bewusst nicht angefangen, statt es halb zu machen. --- ## 4. Empfohlene Reihenfolge beim Einbau 1. `data/types.ts` gegen die echten Entity-Typen abgleichen 2. `data/seed.ts` durch die echte Datenquelle ersetzen 3. `HEUTE` in `utils/dateUtils.ts` auf `new Date()` umstellen 4. `view-models/index.ts` gegen `@hivegrid/view-models` tauschen, der Vertrag (`VMState`) ist wortgleich, es ist ein Import-Wechsel 5. Eine Seite vollständig durchziehen (Übersicht): Loader ruft `baueUebersichtVM()`, die Route rendert ``. Der Container unter `routes/` entfällt dabei, die Seite bleibt unverändert. Dabei zeigt sich, welche Felder in den echten Daten fehlen 6. Texte auf i18n-Keys ziehen, `data-ui-id` ergänzen, `mobile:`-Verhalten nachrüsten (siehe `docs/LEITPLANKEN.md`) 7. Filter serverseitig nachziehen, sobald die Datenmengen es erfordern 8. Export, Absprünge und Persistenz am Benutzerprofil ergänzen --- ## 5. Offene Punkte für die Fachabstimmung - **Auslastung** rechnet produktive Stunden gegen Vertragsstunden. Ob Rüst- und Fahrzeiten als produktiv zählen, ist eine betriebliche Festlegung, die Schwellen (70 % / 95 %) stehen in `components/charts/AuslastungsBalken.tsx`. - **Umsatz** ist hier Zahlungseingang, nicht Rechnungsstellung. Für die betriebswirtschaftliche Auswertung kann die andere Definition gewünscht sein; beide Varianten sind aus denselben Daten berechenbar. - **Deckungsbeitrag** basiert auf einer geschätzten Marge je Auftrag. Ob echte Kostendaten vorliegen, ist offen. - **Förderquote BAFA/KfW** ist als eigener Block angelegt, weil sie im Wärmepumpengeschäft entscheidend ist. Sie braucht ein Feld am Auftrag.