Die Uebergabe geht an einen Dev, der den Einbau mit einem Coding-Agenten macht. Dafuer reicht "hier ist das Repo" nicht. Vier neue Artefakte, alle gegen das Zielsystem geprueft, nicht aus dem Gedaechtnis geschrieben. **EINBAU.md** ist der Einstieg. Der wichtigste Satz darin steht ganz oben: Das Dashboard in HiveGrid ist kein leeres Blatt. Route, Widget-Registry, Rollen-Layouts, Drilldown, Export, Live-Updates und Layout-Speicherung sind gebaut. Wer dort eine neue Seite anlegt, wirft funktionierende Software weg. Das ist nicht meine Einschaetzung: Der Brief P30 im Zielsystem sagt woertlich "Delta-Phase, kein Neubau ... Dashboard/Widget-Registry voll gebaut". Analytics dagegen gibt es noch nicht und wird nach dem Muster von leads.analytics.tsx neu gebaut. Dazu eine Tabelle, welche Datei wohin wandert, und eine zweite, was ausdruecklich nicht mitwandert und warum. **docs/port/TICKET-ANALYTICS.md und TICKET-DASHBOARD.md** sind im Format von .planning/ticket-docs/ geschrieben, mit Header-Tabelle, Abhaengigkeiten, Definition of Done, Technischen Bausteinen, Quellen und Dev-Nachzug. Sie koennen dorthin kopiert werden; dann greift der bestehende Ablauf, statt dass wir einen zweiten danebenstellen. **docs/port/i18n-*.json plus TEXTE.md.** pnpm run verify:i18n ist in HiveGrid ein Gate: keine hartkodierten Strings. Dieser Prototyp ist zu 100 % hartkodiertes Deutsch. 185 Texte mit Schluesselvorschlag und Fundstelle, dazu derselbe Inhalt als einfuegbarer Baum. Erzeugt von scripts/i18n-inventar.py (npm run i18n:inventar), damit das Inventar nicht auseinanderlaeuft, wenn sich am Prototyp noch etwas aendert. Dabei gefunden: app.dashboard.widgets.* enthaelt bereits 17 Widgets, darunter genau fuenf, die dieser Prototyp gestaltet (receivables, orderIntake, daysToPayment, winRate, stageDistribution) und genau die drei, die er als reserviert markiert (myTasks, scheduleToday, hrRequests). Neue Schluessel dafuer waeren Dubletten; die acht sind in TEXTE.md einzeln aufgefuehrt. Die Anrede stimmt ebenfalls schon ueberein, HiveGrid duzt. **CLAUDE.md** als Einstiegspunkt, den Claude Code beim Oeffnen des Repos von selbst liest: was dieses Repo ist, die drei Dinge, an denen ein Einbau sonst scheitert, und wo was steht. Jeder in den Dokumenten genannte Pfad wurde in beiden Repos nachgeprueft. Ein Fehler dabei gefunden und behoben: der Designer-Brief heisst P11-suche-dashboard.md, nicht P11.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
148 lines
7.7 KiB
Markdown
148 lines
7.7 KiB
Markdown
# Ü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 `<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.
|