Files
Dashboard/docs/ZIELSYSTEM.md
T
dejanandClaude Opus 5 b8bf987d0e feat(dashboard): Analytics-Dashboard als Gestaltungsvorlage zur Übergabe
UI/UX-Prototyp der Analytics-Dashboards in HiveGrid, fachlich auf einen
SHK-/Handwerksbetrieb zugeschnitten. Ziel ist die Übergabe an die Entwicklung,
nicht der Produktivbetrieb.

Inhalt: sechs Seiten (Übersicht, Finanzen, Aufträge, Kunden, Team, Komponenten),
26 KPIs, neun Chart-Bausteine, Filtersystem mit seitenabhängiger Relevanz und ein
deterministischer Demo-Datensatz (420 Kunden, 1.900 Aufträge, Stichtag 30.07.2026).

Drei Quellen sind zusammengeführt: die fachliche Planung mit dem Branchenpartner
(Januar 2026), die Subframe-Komponentenbibliothek aus dem HiveGrid-Pitch und
IBM Carbon Data Visualization für die Diagrammregeln. Herkunft und bewusste
Abweichungen stehen in docs/HERKUNFT.md.

Dokumentation: README, HANDOVER (was echte Logik braucht), docs/DESIGN-SYSTEM,
KPI-KATALOG, DATENMODELL, NAVIGATION, HERKUNFT, ZIELSYSTEM (Einbauort in
HiveGrid Cloud) und LEITPLANKEN (welche Cloud-Screens als Vorbild taugen).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
2026-08-29 17:25:20 +02:00

216 lines
9.4 KiB
Markdown

# Zielsystem: HiveGrid Cloud
Wohin dieser Prototyp eingebaut wird, was dort heute schon steht und was beim
Einbau konkret anzupassen ist.
Repo: `HiveGrid-Cloud` (Gitea `git.tool-ctrl.de/toolctrl-labs/HiveGrid-Cloud`).
pnpm-Monorepo, React Router 7, Prisma/Postgres, mandantenfähig mit RLS.
`apps/web` (Tenant- und Admin-App), dazu `api`, `worker`, `desktop`,
`hocuspocus`, `portal-domain-controller` und rund 40 Pakete unter `packages/`.
Größenordnung: 678 Route-Dateien, davon 575 im Core-Manifest.
---
## 1. Der Platz dieses Prototyps
Das Ziel ist der Tenant-Dashboard-Screen unter `…/<tenant>/dashboard`.
Dort liegt bereits eine Implementierung:
| Datei | Was drin steht |
|---|---|
| `apps/web/app/components/screens/dashboard/DashboardPage.tsx` | Widget-Grid, 495 Zeilen |
| `…/DashboardEditPanel.tsx` | Edit-Modus (Widget-Filter/Zeitraum) |
| `…/DashboardDrilldownDialog.tsx` | Drilldown je Kachel |
| `…/DashboardMonthlySeriesChart.tsx`, `…/DashboardStageDistributionChart.tsx` | die zwei vorhandenen Diagramme |
| `apps/web/app/routes/app.$tenant/dashboard.tsx` | Loader, SSE-Stream, Export |
Fachlich ist das die Phase **P11** (Modul M20): drei feste Rollen-Layouts
(**GF · Büro · Monteur**) aus einer Widget-Registry, live über SSE, plus das
Komfort-Delta aus **P30** (Edit-Modus, Drilldown, CSV-/Report-Export,
Realtime-Opt-out).
**Wichtig:** Dieser Stand ist ausdrücklich **Interim-UI nach AD-28** — der Dev
baut aus `~/ui` gegen ein stabiles View-Model, damit das Ticket nicht auf den
finalen Screen wartet. Der Kommentarkopf von `DashboardPage.tsx` sagt es
wörtlich: *„Final Subframe optics = tracked design-nachzug (D-DASH / VD-P30)."*
Genau diese Lücke füllt dieser Prototyp. Der Einbau ist der geplante Nachzug,
kein Umbau gegen den Strom.
---
## 2. Gemeinsame Basis — und wo sie auseinanderläuft
| | Prototyp | HiveGrid Cloud |
|---|---|---|
| Subframe-Projekt | `f023064a5ca0` | `f023064a5ca0` — **dasselbe** |
| Bibliothek | `ui/`, 86 Komponenten | `apps/web/app/ui/`, Alias `~/ui/*`, 92 Komponenten |
| Überschneidung | 82 Komponenten gleich benannt | dieselben 82 |
| Diagramme | Recharts ^2.15.4 | Recharts ^2.15.3 — **dieselbe Bibliothek** |
| Framework | Next.js 16 | React Router 7 |
Die vier Namensunterschiede: `DialogFullscreen` → `FullscreenDialog`,
`DrawerRight` → `Drawer`, `AddressDialog` und `BannerOffline` existieren dort
nicht. Cloud hat zusätzlich `BulkActionBar`, `ConfirmDialog`, `DropdownMenu`,
`ModalBlank`, `ResultDialog`, `BannerPermanent`, `ChatSprechblase`.
Dass Komponentenbibliothek **und** Chart-Bibliothek übereinstimmen, ist der
Grund, warum der Einbau realistisch ein Port ist und keine Neuimplementierung.
---
## 3. Was beim Einbau konkret anders wird
### 3.1 Daten kommen als View-Model-Prop
Der Prototyp importiert `DATENSATZ` direkt. In der Cloud gilt das Muster
`<XPage vm={} actions={} />`: Die Route besitzt Loader, SSE und Actions, die
Screen-Komponente ist rein und bekommt alles als Prop. Kein `useLoaderData`
in der Komponente.
```ts
export type DashboardPageVM = VMState<DashboardPageData>;
type VMState<T> =
| { status: "idle" }
| { status: "loading"; data?: T }
| { status: "ready"; data: T }
| { status: "empty" }
| { status: "error"; data?: T; error: { messageKey: string; code?: string } };
```
Fünf Zustände statt einem. Der Prototyp kennt nur „Daten da"; `loading`,
`empty` und `error` sind je Seite zu ergänzen. Die Chart-Leerzustände
(`ChartLeer`) decken davon nur einen Teil ab.
`DashboardPageData` führt außerdem `activeRole`, `layout`, `generatedAt`,
`streamUrl`, `canCustomize`, `liveUpdatesEnabled`, `layoutSource` und
`catalog` — das Dashboard ist dort rollen- und berechtigungsabhängig, was der
Prototyp nicht abbildet.
### 3.2 Kein eigenes App-Chrome
`AppShell.tsx` aus diesem Prototyp fällt beim Einbau **weg**. Die Cloud-Routen
laufen bereits in der echten App-Shell mit Sidebar, Tenant-Layout und
Breadcrumb (`SubframeAppShell.tsx`, `AppSidebar.tsx`). Screen-Komponenten
dürfen dort ausdrücklich **kein** `~/ui/layouts/DefaultPageLayout` rendern —
das bringt eine eigene Beispiel-Sidebar mit und erzeugt eine doppelte
Navigation. Stattdessen gilt `PageShell` / `PageHeader` / `PageBody` aus
`components/screens/shared/PageShell.tsx`.
Unsere Seitenköpfe und die Filterleiste bleiben, die Rahmen-Navigation nicht.
### 3.3 Texte über i18n
Alle statischen Texte laufen über `react-i18next` (`t("app.dashboard.…")`).
Dieser Prototyp hat deutsche Strings fest im JSX. Das ist beim Einbau
mechanische Arbeit, aber flächendeckend — es betrifft jede Karte, jede
Achsenbeschriftung und jeden Leerzustand.
Die deutschen **Bezeichner im Code** (`umsatz`, `auftraege`) bleiben davon
unberührt und passen zur Cloud, deren UI ebenfalls deutsch ist (EN-Locale erst
in P30).
### 3.4 Barrierefreiheit der Diagramme
In der Cloud sind Charts konsequent `aria-hidden="true"`, und die umgebende
Karte liefert eine Textzusammenfassung plus Datentabelle für Screenreader.
Dieser Prototyp hat das **nicht**. Beim Einbau ist es Pflicht — das Repo fährt
ein a11y-Lint-Baseline-Gate und axe-Tests je Primitive.
### 3.5 Stabile Oberflächen-IDs
Jede relevante Fläche trägt ein `data-ui-id` (`ui.dashboard.widget.…`), erfasst
in `docs/ui-inventory/surfaces.json`. Tests und Agenten adressieren darüber.
Unsere Widget-IDs aus dem `WidgetContext` sind der natürliche Anknüpfungspunkt,
müssen aber auf das dortige Namensschema umgestellt werden.
### 3.6 Spacing passt bereits
`.planning/INTERIM-UI-DESIGN-STANDARDS.md` schreibt fest: Page-Padding **24**,
Card **16**, Grid-Gap **16**, Section-Gap **24**, Field-Gap **16**,
Control-Höhe Medium **36**, Input-Radius **4**. Das deckt sich mit dem
8-px-System in [DESIGN-SYSTEM.md](DESIGN-SYSTEM.md) Abschnitt 5 — hier ist
nichts anzupassen.
---
## 4. Was dieser Prototyp dem Zielsystem voraushat
Nicht alles fließt nur in eine Richtung. Drei Dinge fehlen dort heute:
**Ein gemeinsames Chart-Theme.** Die beiden vorhandenen Diagramme setzen
Farben direkt im JSX (`fill="#334155"`, `fill="#cbd5e1"`), jedes mit eigenem
Gitter (`strokeDasharray="3 3"`), eigener Achsenbreite und eigenem
Balkenradius. Es gibt keine geteilte Palette, keine Kategorien-Obergrenze und
keine feste Farbzuordnung. `features/dashboard/utils/chartTheme.ts` ist genau
das, was dort fehlt — und der Teil, der sich am ehesten unabhängig vom Rest
übernehmen lässt.
**Ausformulierte Diagramm-Regeln.** [DESIGN-SYSTEM.md](DESIGN-SYSTEM.md) hat in
der Cloud keine Entsprechung. Die Standards dort regeln Layout, Controls und
Zustände sehr genau, Datenvisualisierung dagegen gar nicht.
**Fachliche Kennzahl-Definitionen.** [KPI-KATALOG.md](KPI-KATALOG.md) mit
Zeitbezug und Berechnung je KPI ist im Zielsystem so nicht vorhanden; die
Widget-Registry beschreibt Kacheln, nicht deren betriebswirtschaftliche
Definition.
---
## 5. Wer entwirft was — der Rest ist noch nicht fertig designt
HiveGrid Cloud ist nach dem **Designer-First-Prinzip** organisiert
(`.planning/DESIGNER-FIRST-PLAYBOOK.md`). Der Ablauf ist verbindlich:
1. Dev/Planung stellt je Phase einen **Designer-Brief** bereit —
*was* das Modul tut und *welche UI-Elemente* vorkommen müssen, **kein Layout**.
2. Der Designer entwirft die Screens in Subframe und darf Spec und UI/UX
**überschreiben** — Anordnung und Layout sind eine Design-Entscheidung.
3. Das **Delta** (geänderte Spec-Punkte, neue UX-Entscheidungen, Subframe-Link)
wird in den Brief eingetragen.
4. Der Dev setzt um und zieht Spec und Doku nach.
Es gibt 31 solcher Briefs (`.planning/designer-briefs/P01…P34.md`) — Auth, CRM,
Lead-Inbox, Projekt-Pipelines, Automation-Flow-Editor, Form-Builder, Plantafel,
Kalender, Telefonie, HR, Billing, Customer-Portal, Help-Center. Für einen
großen Teil davon steht der Delta-Block **noch leer**: Der finale Screen ist
noch nicht entworfen, die Route läuft bis dahin auf Interim-UI.
**Für die Einordnung dieses Prototyps heißt das dreierlei:**
- Das Dashboard ist **ein Baustein unter vielen**, nicht die Leitgestaltung der
Anwendung. Es fügt sich in eine App-Shell und ein Design-System ein, die
bereits stehen.
- Was hier an Anordnung und Raster festgelegt ist, ist ein **Vorschlag**. Die
Layout-Hoheit liegt beim Designer — der Brief zu P11 sagt ausdrücklich
„Anordnung = Davids freie Hand". Verbindlich zu übergeben sind die
**Kennzahl-Definitionen, die Chart-Regeln und das Verhalten**, nicht die
Pixelanordnung.
- Andere Bereiche der Anwendung sehen heute noch nicht final aus, weil sie
entweder auf Interim-UI laufen oder noch beim Designer liegen. Ein Vergleich
„unser Dashboard gegen den aktuellen Screen X" misst deshalb nicht
zwangsläufig gegen den Zielzustand.
---
## 6. Wenn du dir das Zielsystem selbst ansehen willst
```sh
corepack enable && pnpm install
pnpm dev:services # Postgres + Redis
pnpm dev:services:reset # Wegwerf-DB inkl. Migrationen und Demo-Daten
pnpm dev:local
```
Tenant-App auf `http://app.localhost:3000`. Die lokalen Demo-Zugänge (Tenant
„HiveGrid Demo SHK") stehen im README von HiveGrid Cloud unter „App starten" —
sie werden hier bewusst nicht wiederholt. Die Demo-Daten sind zunächst
ausgeblendet und erscheinen über **„Demo-Daten anzeigen"** oder `?demo=show`.
Der Weg zum Dashboard ist nach dem Login die erste Seite der Tenant-App.
Für einen schnellen Überblick ohne Setup:
`docs/ui-inventory/surface-map.md` listet alle stabilen Oberflächen mit ihren
Quelldateien, `docs/route-inventory.md` die Größenordnung des Routenbestands.