Klarstellung aus der Abstimmung: Der Prototyp wurde bisher als 'das Dashboard'
bezeichnet, tatsächlich sind es zwei Features mit unterschiedlichem Zweck.
Analytics beantwortet 'warum ist das so' — mehrerer Seiten, seitenübergreifender
Zeitraum- und Dimensionsfilter, fachlich geschnitten. Das Dashboard beantwortet
'wie ist meine Lage' — Begrüßungsbildschirm, rollenbezogen, Widgets. Es zeigt die
wichtigsten Charts aus Analytics, ist aber nicht darauf beschränkt: HR-Anträge
('2 neue Anträge'), Aufgaben und Termine gehören ebenfalls dorthin.
Die Software sieht das bereits vor. DashboardWidgetDomain kennt 'hr',
DashboardWidgetKind kennt 'list', und der Designer-Brief P11 nennt HR-Anträge
wörtlich im Büro-Dashboard. Neu ist nicht der Scope der Software, sondern das
Verhältnis zu diesem Prototyp.
Drei Stellen bekommen dadurch einen anderen Zuschnitt: die Seite 'Übersicht'
überschneidet sich mit dem Dashboard, der Handlungsbedarf ist eher ein
Dashboard-Element, und Charts brauchen als Widgets einen eigenen Zeitraum, weil
das Dashboard keinen globalen Filter hat.
Sechs offene Punkte sind in docs/SCOPE-ANALYTICS-DASHBOARD.md Abschnitt 5
festgehalten. Nichts davon ist entschieden, am Code ist nichts geändert.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
134 lines
6.8 KiB
Markdown
134 lines
6.8 KiB
Markdown
# Übergabe an die Entwicklung
|
|
|
|
> **Vor dem Einbau lesen:**
|
|
> [`docs/SCOPE-ANALYTICS-DASHBOARD.md`](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`](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 `<UebersichtSeite vm={…} />`. 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.
|