Wiki source code of Fuhrpark (Fleet Manager)

Version 13.1 by Patrizia Gurschka on 2026/09/10 08:23

Hide last authors
Patrizia Gurschka 10.1 1 |(((
Patrizia Gurschka 11.1 2 = **đźš— Fuhrpark (Fleet Manager)** =
Dimitri Rupp 5.1 3
Patrizia Gurschka 10.1 4 |(((
Patrizia Gurschka 13.1 5 {{info}}
Patrizia Gurschka 10.1 6 **Zweck: **Webbasierte Verwaltung des Firmenfuhrparks — Fahrzeug-/Fahrerstammdaten, Kostenkalkulation, Kilometerauswertung, Ersatzbeschaffungs-Planung (Handlungsbedarf) und monatliche Abrechnung.
Patrizia Gurschka 13.1 7 **Zielgruppe: **Fuhrpark-/Controlling-Team, Line Manager, IT-Betrieb.
Dimitri Rupp 1.1 8
Patrizia Gurschka 13.1 9 {{/info}}
10
11
Patrizia Gurschka 10.1 12 )))
13
14
15 )))|(((
16 |(((
Patrizia Gurschka 7.3 17 **Auf dieser Seite**
18
Patrizia Gurschka 10.1 19 * [[đźš— Fuhrpark (Fleet Manager)>>path:#top]]
20 ** [[Ăśberblick>>path:#ueberblick]]
21 ** [[Architektur>>path:#architektur]]
22 ** [[Technologiestack>>path:#technologiestack]]
23 ** [[Hauptfunktionen>>path:#hauptfunktionen]]
24 *** [[1. Stammdaten-Import>>path:#hf1]]
25 *** [[2. Fahrzeug-/Fahrer-Zuordnung>>path:#hf2]]
26 *** [[3. Kilometer-Erfassung>>path:#hf3]]
27 *** [[4. Kalkulation>>path:#hf4]]
28 *** [[5. Handlungsbedarf>>path:#hf5]]
29 *** [[6. Export & Abrechnung>>path:#hf6]]
30 ** [[Nachvollziehbarkeit & Fehlerbehandlung>>path:#orch]]
31 ** [[Cronjobs & Konfiguration>>path:#konfiguration]]
32 ** [[Sicherheit>>path:#sicherheit]]
33 *** [[Authentifizierung>>path:#auth]]
34 *** [[Datenschutz>>path:#datenschutz]]
35 ** [[Besondere Geschäftslogik>>path:#geschaeftslogik]]
36 ** [[Offene Punkte / zu verifizieren>>path:#offene-punkte]]
37 ** [[Server / Umgebung>>path:#server]]
38 )))
Patrizia Gurschka 7.3 39
Patrizia Gurschka 10.1 40
41 )))
Dimitri Rupp 1.1 42
43
44
Patrizia Gurschka 10.1 45 = Ăśberblick =
Dimitri Rupp 1.1 46
Patrizia Gurschka 10.1 47 Fuhrpark ist eine FastAPI-Backend- + React-Frontend-Anwendung (migriert von einer Streamlit-Monolith-Anwendung). Die Lösung besteht aus:
Dimitri Rupp 1.1 48
Patrizia Gurschka 10.1 49 * Frontend: React 18 · Vite · React Query · Axios-Client (nginx-Reverse-Proxy)
50 * Backend: FastAPI · SQLite (WAL-Modus) · JWT-Authentifizierung
51 * Datenquellen: RIMO/SQL-Server (Fahrer-Stammdaten) · Microsoft Fabric (SharePoint, KM-Formular-Mails) · GPS-AT/Tesla-APIs (Kilometerstände)
52 * Orchestrierung: eigenständige Cron-Skripte auf dem Server, unabhängig vom Docker-Container
Dimitri Rupp 1.1 53
Patrizia Gurschka 10.1 54 = Architektur =
Dimitri Rupp 1.1 55
Patrizia Gurschka 10.1 56 [[image:1789018507266-361.png]]
Dimitri Rupp 1.1 57
Patrizia Gurschka 10.1 58 //Frontend, Backend und Datenbank laufen im Docker-Compose-Stack; die Cron-Skripte laufen direkt auf dem Host und schreiben in dieselbe fleet.db.//
Dimitri Rupp 1.1 59
Patrizia Gurschka 10.1 60 = Technologiestack =
Dimitri Rupp 1.1 61
Patrizia Gurschka 10.1 62 **Frontend: **React 18 · Vite · React Router · React Query (TanStack Query) · Axios
Dimitri Rupp 1.1 63
Patrizia Gurschka 10.1 64 **Backend: **FastAPI (Python) · SQLite · Pandas · python-jose (JWT) · passlib/bcrypt · pyodbc
Dimitri Rupp 1.1 65
Patrizia Gurschka 10.1 66 **Externe APIs: **RIMO/SQL-Server (ai.sdmperson, rimo.sdmtool) · Microsoft Fabric (SharePoint, KM-Formular-Mails) · GPS-AT- und Tesla-API
Dimitri Rupp 1.1 67
Patrizia Gurschka 10.1 68 = Hauptfunktionen =
Dimitri Rupp 1.1 69
Patrizia Gurschka 10.1 70 ~1. Stammdaten-Import
Dimitri Rupp 1.1 71
Patrizia Gurschka 10.1 72 Fahrzeuge werden initial aus RIMO importiert und danach in der App gepflegt (Rückschreiben nach RIMO ist geplant, aktuell nicht implementiert). Fahrer werden täglich um 4:00 Uhr gegen RIMO (ai.sdmperson) abgeglichen — Neuanlage bei unbekannter Personalnummer, sonst Aktualisierung von Stammdaten, Kostenstelle und Line Manager. Externe Fahrer können zusätzlich manuell angelegt werden; Stammdaten interner (RIMO-importierter) Fahrer sind schreibgeschützt.
Dimitri Rupp 1.1 73
Patrizia Gurschka 10.1 74 2. Fahrzeug-/Fahrer-Zuordnung
Dimitri Rupp 1.1 75
Patrizia Gurschka 10.1 76 Fahrer und Line Manager können einem Fahrzeug direkt zugewiesen werden (Line Manager wird bei Fahrer-Auswahl automatisch ergänzt, bleibt aber überschreibbar). Befristete Zuordnungen kehren nach Ablauf automatisch zum vorherigen Fahrer zurück. Jede Zuordnungs- sowie Line-Manager-/Kostenstellen-Änderung wird vollständig und zeitlich abgegrenzt protokolliert (vehicle_assignment_history, driver_attribute_history) — sowohl bei manueller Änderung als auch beim täglichen RIMO-Sync.
Dimitri Rupp 1.1 77
Patrizia Gurschka 10.1 78 3. Kilometer-Erfassung
Dimitri Rupp 1.1 79
Patrizia Gurschka 10.1 80 Kilometerstände werden automatisiert importiert: GPS-AT täglich, Tesla wöchentlich, jeweils zum Monatsende. Für Fahrzeuge ohne automatische Anbindung wird 3 Tage vor Monatsende täglich eine Erinnerungsmail verschickt, bis ein Wert in der SharePoint-Liste eingetragen ist. Das KM-Dashboard berücksichtigt bei der Auswertung ausschließlich den Zeitraum, in dem die jeweilige Zuordnung tatsächlich bestand — auch bei unterjährigem Fahrer- oder Line-Manager-Wechsel.
Dimitri Rupp 1.1 81
Patrizia Gurschka 10.1 82 4. Kalkulation
Dimitri Rupp 1.1 83
Patrizia Gurschka 10.1 84 Pro Fahrzeug wird eine Kostenkalkulation aus Anschaffungskosten, laufenden Kosten und Verbrauch/Energiepreisen erstellt (Kosten pro Monat/Jahr/Kilometer). Beim Anlegen werden Default-Parameter aus „Kalkulationsparameter“ nach Fahrzeugtyp übernommen; individuelle Felder werden ergänzt und per „Aktualisieren“ neu berechnet. Änderungen an Kalkulationsparametern wirken sich auf alle Fahrzeuge des jeweiligen Typs aus (Rollen admin/demo/controlling).
Dimitri Rupp 1.1 85
Patrizia Gurschka 10.1 86 5. Handlungsbedarf
Dimitri Rupp 1.1 87
Patrizia Gurschka 10.1 88 Hochrechnungen werden bei jedem KM-Stand-Import neu berechnet. Ein bestelltes Fahrzeug wird über das Häkchen „Bestellt“ markiert, erst danach anlegbar. Nach Anlage steht „Geliefert“ zur Verfügung; sobald gesetzt, entfällt das Fahrzeug automatisch aus der Handlungsbedarfsliste. Ein gesetztes „Deactivation Date“ deaktiviert und archiviert ein Fahrzeug automatisch zum entsprechenden Datum.
Dimitri Rupp 1.1 89
Patrizia Gurschka 10.1 90 6. Export & Abrechnung
Dimitri Rupp 1.1 91
Patrizia Gurschka 10.1 92 Monatliche Abrechnungen und Kostenstellen-Umbuchungen werden auf Klick erstellt und als CSV exportiert. Die vollständige Fahrzeugliste (inkl. kompletter Kalkulationsaufschlüsselung) sowie gefahrene Kilometer können als Excel-Datei heruntergeladen werden.
Dimitri Rupp 1.1 93
Patrizia Gurschka 10.1 94 = Nachvollziehbarkeit & Fehlerbehandlung =
Dimitri Rupp 1.1 95
Patrizia Gurschka 10.1 96 Ändert sich der Line Manager eines Fahrers — manuell oder über den täglichen Cron-Sync — wird nicht nur drivers.user_id aktualisiert, sondern auch jede betroffene vehicle_assignment_history-Zeile korrekt geschlossen und neu angelegt. Ohne diesen Schritt bliebe ein Fahrzeug fälschlich sowohl beim alten als auch beim neuen Line Manager sichtbar (historisch aufgetretener Fehler, mittlerweile behoben und mit einem Reparatur-Skript für Altfälle nachgezogen).
Dimitri Rupp 1.1 97
Patrizia Gurschka 12.1 98 [[image:1789018507268-395.png||height="336" width="979"]]
Dimitri Rupp 1.1 99
Patrizia Gurschka 10.1 100 //Ablauf bei einem Line-Manager-Wechsel, inkl. Absicherung gegen doppelte Sichtbarkeit.//
Dimitri Rupp 1.1 101
Patrizia Gurschka 10.1 102 = Cronjobs & Konfiguration =
Dimitri Rupp 1.1 103
Patrizia Gurschka 10.1 104 |**Bereich**|**Details**
105 |Täglicher Fahrer-Sync|1_import_users_drivers.py, 4:00 Uhr — Fahrer-Stammdaten, Line Manager, Kostenstelle gegen RIMO (ai.sdmperson) abgleichen
106 |KM-Import gpsat|import_km.py gpsat, täglich 4:00 Uhr, jeweils zum Monatsende
107 |KM-Import Tesla|import_km.py tesla, montags 4:00 Uhr, jeweils zum Monatsende
108 |SharePoint-Erinnerung|3 Tage vor Monatsende täglich, wenn kein KM-Stand in der SharePoint-Liste vorhanden ist
109 |Docker Compose|Services backend (FastAPI) + frontend (nginx + React-Build)
110 |Datenbank|SQLite, WAL-Modus, data/fleet.db (Projekt-Root, nicht in Git)
111 |Reparatur-Skript|repair_stale_line_manager_assignments.py — einmalig, bei Altlasten vor dem Line-Manager-Fix
Dimitri Rupp 1.1 112
113
114
Patrizia Gurschka 10.1 115 = Sicherheit =
Dimitri Rupp 1.1 116
Patrizia Gurschka 10.1 117 Authentifizierung
Dimitri Rupp 1.1 118
Patrizia Gurschka 10.1 119 * JWT (python-jose), OAuth2-Password-Flow, 8-Stunden-Tokens
120 * Rollen: admin, demo, controlling, Benutzer (Line Manager/Fahrer)
121 * Zugriff auf Fahrzeug-Zuweisungshistorie und rohe KM-Ablesungen ist admin/demo vorbehalten — serverseitig abgesichert (403), nicht nur im Frontend versteckt
Dimitri Rupp 1.1 122
Patrizia Gurschka 10.1 123 Datenschutz
Dimitri Rupp 1.1 124
Patrizia Gurschka 10.1 125 Sichtbarkeit von Fahrzeugen und Fahrern für normale Nutzer richtet sich ausschließlich nach der Line-Manager-Zuordnung. Passwörter sowie SQL-Server-/Fabric-Zugangsdaten liegen in nicht versionierten .env-Dateien (Docker-.env für Secrets der App, backend/.env für die Cron-Skripte).
Dimitri Rupp 1.1 126
Patrizia Gurschka 10.1 127 = Besondere Geschäftslogik =
Dimitri Rupp 1.1 128
Patrizia Gurschka 10.1 129 * **Zeitzonen-Korrektur: **sync_vehicle_assignment() vergleicht mit datetime('now','localtime') statt datetime('now') — SQLite liefert sonst UTC, während alle gespeicherten Zeitstempel lokale Zeit sind. Ohne die Korrektur blieb eine gerade beendete Zuordnung bis zu 1–2 Stunden fälschlich „aktiv“.
130 * **Import-Marker: **Historienzeilen aus der einmaligen Erstbefüllung (changed_by='import') zeigen in der Zuordnungs-Anzeige bewusst kein Startdatum („– 20.04.2026“ statt „28.02.2026 – 20.04.2026“), da dieses Datum nur den Zeitpunkt des Imports, nicht den echten historischen Beginn widerspiegelt.
131 * **Odometer vs. Jahreskilometer: **vehicles.current_km speichert die im laufenden Kalenderjahr gefahrenen Kilometer (Vergleichswert zu „Max. KM/Jahr“), nicht den tatsächlichen Tacho-Stand. Für die Anzeige des echten Kilometerstands wird stattdessen die letzte Ablesung aus der KM-Historie herangezogen (latest_odometer_km).
132 * **Zuordnungsende “heute“: **Wird als Enddatum das aktuelle Datum gewählt, wird als Enddatum bewusst der Vortag (23:59:59) gespeichert — damit gilt die Zuordnung ab exakt Mitternacht des gewählten Tages als beendet, ohne Sekundenpräzision oder Sonderfall im Code.
Dimitri Rupp 1.1 133
Patrizia Gurschka 10.1 134 |(((
135 **⚠️  Offene Punkte / zu verifizieren**
Dimitri Rupp 1.1 136
Patrizia Gurschka 10.1 137 * Flottenweite Reaktivierung in apply_due_deactivations(): Die automatische Reaktivierung („kein Deactivation Date mehr“) wirkt aktuell auf ALLE Fahrzeuge mit deactivation_date=NULL, nicht nur auf das gerade bearbeitete — kann manuell archivierte Fahrzeuge versehentlich mit reaktivieren. Fix identifiziert (Reaktivierung auf die eine Fahrzeug-ID scopen), Umsetzung noch ausständig.
138 * Genaues Schema von rimo.sdmtool (Spaltennamen name/last_update) ist aus einer Beschreibung ĂĽbernommen, nicht 1:1 gegen die echte Tabelle verifiziert.
139 * Kein bestätigtes automatisches Backup der Produktivdatenbank gefunden — falls vorhanden, läuft es außerhalb des Anwendungscodes; sollte auf dem Server verifiziert werden.
140 * Exakte SharePoint-/Fabric-Spaltennamen (SP_LIST_ITEMS_URL u. Ă„.) sollten einmalig gegen die reale Liste geprĂĽft werden.
141 )))
142
143
144
145 = Server / Umgebung =
146
Patrizia Gurschka 7.2 147 Die App läuft auf 192.168.208.2, per Docker Compose (Services backend + frontend), und liegt unter /mnt/data/fleet-manager/fuhrpark.
Dimitri Rupp 1.1 148
Patrizia Gurschka 7.2 149 **Deployment bei Codeänderungen** (manuell auf dem Server auszuführen):
Dimitri Rupp 1.1 150
Patrizia Gurschka 10.1 151 sudo -u www-data git pull
Dimitri Rupp 1.1 152
Patrizia Gurschka 10.1 153 docker compose up -d ~-~-build
Dimitri Rupp 1.1 154
155
Patrizia Gurschka 10.1 156 **Cronjobs: **sudo -u www-data crontab -e, Logs unter /mnt/data/fleet-manager/fuhrpark/logs.
Dimitri Rupp 1.1 157
Patrizia Gurschka 10.1 158 Erreichbar unter http:~/~/fleetmanager.spl-tele.com:8501 — mit VPN und im SPL-TELE-Netzwerk.