# Datenmodell Definiert in `features/dashboard/data/types.ts`, erzeugt in `data/seed.ts`. Die Struktur ist bewusst nah an den HiveGrid-Entities gehalten, damit beim Einbau nur die Datenquelle getauscht werden muss. --- ## Zuordnung zu HiveGrid | Prototyp | HiveGrid-Entity | Verfügbar | Anmerkung | |---|---|---|---| | `Rechnung` | **`Rechnung`** (Sub-Entity am Projekt) | v1 | Status dort `entwurf/gestellt/bezahlt/storniert`: **kein `ueberfaellig`**. Überfälligkeit wird aus `faellig_am` gegen heute abgeleitet, nicht als Status geführt | | `Auftrag` | **`Projekt`** in einer Pipeline mit `typ_hint = auftrag` | v1 | „Auftrag" ist nach **AD-20 keine eigene Entität**, sondern eine Pipeline-View auf den Projekt-Kern. Wert = `auftragsvolumen`, Status = `stage_id` und damit **pipeline-intern** | | `Kunde` | **`Kontakt`** mit `kontakt_status = kunde` | v1 | „Kunde" ist ein **Status am Kontakt**, keine Entität. Kontakt ist der Oberbegriff (Privatperson/Organisation); die Verknüpfung zum Projekt läuft über `ProjektKontakt` mit Rolle `auftraggeber` | | `Mitarbeiter` | `TenantUser` + `User` | v1 | | | `Zeiteintrag` |: | **v2** | **Zeiterfassung steht im v2-Backlog.** Damit hat die gesamte Team-Seite in v1 keine Datenquelle: siehe unten | > **Die Begriffe des Prototyps sind SHK-Fachsprache, nicht das Datenmodell der > Software.** „Auftrag" und „Kunde" existieren dort nicht als Entitäten. Das ist > kein Fehler des Prototyps, der Betrieb spricht so, und die Oberfläche soll so > sprechen. Beim Einbau ist es aber eine Übersetzungsleistung und keine > Eins-zu-eins-Zuordnung. ### Die Team-Seite hat in v1 keine Datenquelle Auslastung, Produktivquote, erfasste Stunden und Abwesenheiten beruhen alle auf `Zeiteintrag`. Zeiterfassung steht im ENTITY-MODEL ausdrücklich im **v2-Backlog**. Drei Wege: 1. Team-Seite als v2 einplanen und in v1 nicht ausliefern; 2. Stunden aus einem Drittsystem anbinden (der Betrieb erfasst sie ohnehin irgendwo): dann ist es eine Integrationsfrage, keine Modellfrage; 3. Zeiterfassung nach v1 ziehen, die größte Entscheidung von den dreien. Das ist eine Produktentscheidung, keine Gestaltungsfrage. Sie gehört vor den Einbau geklärt, weil sie eine von fünf Seiten betrifft. **Felder, die es so noch nicht gibt** und beim Einbau ergänzt werden müssen: | Feld | Wo | Wofür | |---|---|---| | `gewerk` | Auftrag, Mitarbeiter | Alle Gewerke-Auswertungen und der Gewerk-Filter | | `margeProzent` | Auftrag | Deckungsbeitrag | | `foerderung` / `foerderbetrag` | Auftrag | Förderquote BAFA/KfW | | `verlorenAb` | Auftrag | Ehrlicher Vertriebstrichter (siehe unten) | | `ueberAngebot` | Auftrag | Trennt Angebotsgeschäft von Direktaufträgen | | `wochenstunden` | Mitarbeiter | Auslastungsberechnung | | `zahlungsmoralTage` | Kunde | Auffällige Zahlungsmoral (auch aus Rechnungen ableitbar) | --- ## Statuswerte **Auftrag:** `anfrage` → `aufmass` → `angebot` → `beauftragt` → `in_arbeit` → `abgeschlossen`, dazu `verloren` als Endzustand. `verlorenAb` hält fest, welche Stufe ein verlorener Vorgang zuletzt erreicht hat. Ohne dieses Feld müsste der Trichter raten und würde die oberen Stufen systematisch zu klein zeigen. `ueberAngebot` trennt das Angebotsgeschäft (ab etwa 6.000 €) von Aufträgen, die direkt beauftragt werden: Wartung, Notdienst, E-Check. Trichter und Abschlussquote beziehen sich ausschließlich auf das Angebotsgeschäft. **Rechnung:** `entwurf` · `gestellt` · `bezahlt` · `ueberfaellig`. --- ## Gewerke und Leistungsarten | Gewerk | Leistungsarten | |---|---| | Heizung | Wärmepumpe, Gastherme, Heizkörper, Wartung | | Sanitär | Bad-Sanierung, Rohrleitungen, Armaturen, Notdienst | | Klima & Lüftung | Splitgerät, Lüftungsanlage, Kanalreinigung, Wartung | | Photovoltaik | PV-Anlage, Batteriespeicher, Wallbox, Wartung | | Elektro | Elektroinstallation, Zählerschrank, Smart Home, E-Check | Förderfähig (BAFA/KfW) sind Wärmepumpe, PV-Anlage, Batteriespeicher und Lüftungsanlage. --- ## Der Demo-Datensatz Erzeugt mit festem Seed (`mulberry32`, Seed `20260730`): die Zahlen bleiben über Reloads und Screenshots identisch. Bezugsdatum ist der **30.07.2026** (`HEUTE` in `utils/dateUtils.ts`). Fiktiver Betrieb: **Meister Krause GmbH**, Raum Rhein-Main, 24 Beschäftigte (3 Meister, 14 Monteure, 3 Auszubildende, 4 Büro). | Größe | Wert | |---|---| | Kunden | 420 | | Aufträge (24 Monate) | 1.900 | | Rechnungen | ~1.270 | | Zeiteinträge (12 Wochen) | ~1.500 | | Jahresumsatz | ~2,4 Mio. € | | Offene Forderungen | ~230 T€ | | Abschlussquote (Angebotsgeschäft) | ~38 % | | Ø Auslastung | ~73 % | **Eingebaute Effekte**, damit die Charts nicht künstlich flach aussehen: - **Saisonalität**: Heizung und Lüftung ziehen von September bis Februar an, der Hochsommer ist schwächer (`SAISON_INDEX`) - **Wachstum**, rund 12 % gegenüber dem Vorjahr - **Größenabhängige Abschlussquote**: Wartung und Notdienst werden fast immer ausgeführt, große Anlagen dagegen verglichen und häufiger verloren - **Zahlungsverhalten**, die Mehrheit zahlt nahe am Zahlungsziel (21 Tage), ein kleiner Rest wird zum Mahnfall; Forderungen älter als sieben Monate sind eingebracht oder ausgebucht und stehen nicht mehr in der offenen Liste - **Förderanträge**, nur bei Vorgängen der letzten rund 100 Tage offen; ein Bescheid dauert Wochen, nicht Jahre Diese Effekte sind fachlich begründet, nicht kosmetisch: Ein gleichverteilter Zufallsdatensatz erzeugt Charts, an denen sich keine Gestaltung prüfen lässt.