Klarstellung, damit beim Port keine globalen Regeln aus diesem Repo in die Software wandern. Verbindlich ist aus diesem Repo nur das Analytics-Eigene und das Fachliche: Kennzahl-Definitionen, Diagrammregeln, Verhalten — und die Navigationsstruktur als Verabredung (zwei Einträge in der Seitenleiste, Analytics mit innerer Leiste). Nicht verbindlich ist alles Globale: Schrift, Schriftgrößen, Abstände, Farben, Radien, Control-Höhen, App-Shell, Kopfzeile, i18n, Formatierung. Das kommt ausschließlich aus HiveGrid. Dass dieser Prototyp dieselbe Schrift, dieselbe Seitenleisten-Komponente und dieselben Token benutzt, dient allein der Lesbarkeit neben der Software — es ist keine Vorlage, an der sich die Software auszurichten hätte. Weicht ein Wert hier von HiveGrid ab, ist der Wert hier falsch. Ebenso festgehalten, was Gerüst ist und wegfällt: AppShell, unsere Kopie der Seitenleiste, PageHeader, die Kopfzeile, die Routen unter app/ und die Dashboard-Platzhalterseite. Der Nachbau der inneren Leiste wird nicht portiert; in HiveGrid entsteht sie über das dortige SidebarIconsLayout. Vermerkt in ZIELSYSTEM.md (neuer Abschnitt 0 mit Zuständigkeitstabelle), im Kopf von HANDOVER.md und README.md, bei der Struktur in NAVIGATION.md, als Vorbemerkung zu den bewussten Abweichungen in LEITPLANKEN.md — und als Kommentarblock in AppShell.tsx und AnalyticsInnerNav.tsx, weil beim Port oft zuerst der Code gelesen wird. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
7.4 KiB
Ü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.mdAbschnitt 0.Ebenfalls vor dem Einbau lesen:
docs/SCOPE-ANALYTICS-DASHBOARD.md. Der Zuschnitt zwischen Analytics und Dashboard ist noch offen und betrifft die Übersichtsseite und den Handlungsbedarf.
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.
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
data/types.tsgegen die echten Entity-Typen abgleichendata/seed.tsdurch die echte Datenquelle ersetzenHEUTEinutils/dateUtils.tsaufnew Date()umstellenview-models/index.tsgegen@hivegrid/view-modelstauschen — der Vertrag (VMState) ist wortgleich, es ist ein Import-Wechsel- Eine Seite vollständig durchziehen (Übersicht): Loader ruft
baueUebersichtVM(), die Route rendert<UebersichtSeite vm={…} />. Der Container unterroutes/entfällt dabei, die Seite bleibt unverändert. Dabei zeigt sich, welche Felder in den echten Daten fehlen - Texte auf i18n-Keys ziehen,
data-ui-idergänzen,mobile:-Verhalten nachrüsten (siehedocs/LEITPLANKEN.md) - Filter serverseitig nachziehen, sobald die Datenmengen es erfordern
- 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.