Upload files to "/"

This commit is contained in:
2026-02-24 07:07:53 +00:00
commit 8dc1e80c62

588
DOKUMENTATION.md Normal file
View File

@@ -0,0 +1,588 @@
# SimmeProtect Projektdokumentation
**Projekt:** SimmeProtect GPS-Tracking & Fahrzeugschutz
**Entwickler:** JJ Banana
**Datum:** Februar 2026
---
## Inhaltsverzeichnis
1. [Projektbeschreibung](#1-projektbeschreibung)
2. [Systemarchitektur](#2-systemarchitektur)
3. [Backend](#3-backend)
- [Technologie-Stack](#31-technologie-stack)
- [Verzeichnisstruktur](#32-verzeichnisstruktur)
- [Datenbankschema](#33-datenbankschema)
- [API-Routen](#34-api-routen)
- [Authentifizierung & Sicherheit](#35-authentifizierung--sicherheit)
- [Echtzeit-Kommunikation](#36-echtzeit-kommunikation)
- [Alarme & Benachrichtigungen](#37-alarme--benachrichtigungen)
4. [Frontend](#4-frontend)
- [Technologie-Stack](#41-technologie-stack)
- [Verzeichnisstruktur](#42-verzeichnisstruktur)
- [Seiten & Features](#43-seiten--features)
- [Datenmodelle (TypeScript)](#44-datenmodelle-typescript)
5. [Zusammenspiel Frontend ↔ Backend](#5-zusammenspiel-frontend--backend)
6. [Entwicklung & Deployment](#6-entwicklung--deployment)
---
## 1. Projektbeschreibung
SimmeProtect ist ein vollständiges GPS-Tracking- und Fahrzeugschutzsystem. Das System erlaubt es Nutzern, ihre Fahrzeuge in Echtzeit zu überwachen, virtuelle Grenzen (Geofences) einzurichten, Alarme zu verwalten und Geräte direkt aus der Webanwendung heraus zu steuern.
Das Projekt besteht aus zwei Teilen:
- **Backend:** Ein REST-API- und WebSocket-Server in Go
- **Frontend:** Eine React-Webanwendung als Benutzeroberfläche
---
## 2. Systemarchitektur
```
┌─────────────────────────────────────────────────────────┐
│ Browser (User) │
│ React Frontend (TypeScript) │
└───────────────────┬────────────────┬────────────────────┘
│ REST API │ WebSocket
│ (HTTP/JSON) │ (Socket.IO)
┌───────────────────▼────────────────▼────────────────────┐
│ Go Backend (Gin) │
│ │
│ Handler → Service → Repository → Datenbank │
│ │
│ Middleware: JWT Auth, Rate Limiting, CORS, Logging │
└───────────────┬──────────────┬──────────────────────────┘
│ │
┌────────────▼───┐ ┌─────▼──────┐
│ PostgreSQL │ │ Redis │
│ + PostGIS │ │ (Cache, │
│ (Geodaten) │ │ Pub/Sub) │
└────────────────┘ └────────────┘
┌────────────┴───────────┐
│ GPS-Gerät (Tracker) │
│ IMEI + API-Key Auth │
└────────────────────────┘
```
Das Backend folgt einer **Clean Architecture**:
| Schicht | Verantwortung |
|---|---|
| **Handler** | HTTP-Anfragen annehmen, Eingaben validieren, Antwort senden |
| **Service** | Geschäftslogik (z.B. Alarm auslösen, Distanz berechnen) |
| **Repository** | Datenbankzugriffe (SQL-Queries) |
| **Domain** | Datenstrukturen und Repository-Interfaces |
---
## 3. Backend
### 3.1 Technologie-Stack
| Technologie | Version | Verwendungszweck |
|---|---|---|
| Go | 1.23 | Programmiersprache |
| Gin | 1.10.0 | Web-Framework (HTTP-Router) |
| PostgreSQL | | Hauptdatenbank |
| PostGIS | | Räumliche Datenbankfunktionen (Geofences, Distanzen) |
| Redis | | Caching, Pub/Sub für Echtzeit-Kommunikation |
| pgx | 5.7.1 | PostgreSQL-Treiber für Go |
| go-redis | 9.7.0 | Redis-Client für Go |
| golang-jwt | 5.2.1 | JSON Web Tokens (Authentifizierung) |
| go-webauthn | 0.11.2 | Passkey-/WebAuthn-Authentifizierung |
| bcrypt | | Passwort-Hashing |
| go-socket.io | 1.7.0 | Socket.IO-Server (WebSocket + Fallback) |
| go-mail | 0.5.1 | E-Mail-Benachrichtigungen (SMTP) |
| twilio-go | 1.23.5 | SMS-Benachrichtigungen |
| zerolog | 1.33.0 | Strukturiertes Logging |
| UUID (google) | 1.6.0 | Eindeutige IDs für alle Entitäten |
### 3.2 Verzeichnisstruktur
```
SimmeProtect-BackendV2/
├── cmd/
│ └── server/
│ └── main.go # Einstiegspunkt, Dependency Injection
├── internal/
│ ├── config/ # Umgebungsbasierte Konfiguration
│ ├── database/ # PostgreSQL- und Redis-Verbindungen
│ ├── domain/ # Datenstrukturen und Repository-Interfaces
│ │ ├── user.go
│ │ ├── device.go
│ │ ├── tracking.go
│ │ ├── geofence.go
│ │ ├── alarm.go
│ │ ├── driver.go
│ │ ├── trip.go
│ │ ├── command.go
│ │ ├── passkey.go
│ │ └── errors.go
│ ├── handler/ # HTTP-Handler (Gin)
│ ├── middleware/ # Auth, Rate-Limiting, CORS, Logging, Security
│ ├── repository/ # SQL-Implementierungen (pgx)
│ ├── service/ # Geschäftslogik
│ ├── router/
│ │ └── router.go # Alle Routen
│ └── websocket/
│ └── server.go # Socket.IO-Server
├── migrations/ # Datenbankmigrationen (SQL)
├── Makefile # Build & Run Befehle
└── CLAUDE.md
```
### 3.3 Datenbankschema
Die Datenbank nutzt **PostgreSQL mit der PostGIS-Extension** für geografische Daten.
**Haupttabellen:**
| Tabelle | Beschreibung | Wichtige Felder |
|---|---|---|
| `users` | Nutzerkonten | `email` (UNIQUE), `password_hash`, `role` |
| `devices` | GPS-Tracker | `imei` (UNIQUE), `api_key_hash`, `status`, `alarm_enabled` |
| `tracking_data` | GPS-Datenpunkte | `position` (GEOGRAPHY POINT), `speed`, `timestamp` |
| `geofences` | Virtuelle Grenzen | `geometry` (GEOGRAPHY), `type` (circle/polygon), `alert_on_enter`, `alert_on_exit` |
| `alarm_configs` | Alarmeinstellungen | `alarm_type`, `enabled`, `threshold_value` (JSONB) |
| `alarm_history` | Alarmereignisse | `alarm_type`, `severity`, `acknowledged` |
| `device_commands` | Befehlswarteschlange | `command_type`, `status` (pending/executed), `payload` (JSONB) |
| `drivers` | Fahrerprofil | `device_id`, `license_number`, `active` |
| `trips` | Fahrten | `start_time`, `end_time`, `distance_km`, `max_speed` |
| `passkey_credentials` | WebAuthn-Keys | `credential_id` (UNIQUE), `public_key`, `counter` |
**PostGIS-Besonderheiten:**
- `tracking_data.position` ist ein `GEOGRAPHY(POINT)` ermöglicht Distanzberechnungen in Metern
- `geofences.geometry` ist ein `GEOGRAPHY` ermöglicht `ST_Contains`-Abfragen (Punkt-in-Polygon)
- Index `GIST(position)` auf `tracking_data` für schnelle geografische Abfragen
**Datenbankindizes:**
- `devices(api_key_hash)` schnelle Gerät-Authentifizierung
- `tracking_data(device_id, timestamp DESC)` schnelle Historieabfragen
- `tracking_data GIST(position)` geografische Suchen
- `alarm_history(device_id, triggered_at DESC)` Alarmabfragen
### 3.4 API-Routen
**Öffentliche Routen (ohne Auth):**
| Methode | Pfad | Beschreibung |
|---|---|---|
| POST | `/api/auth/register` | Nutzer registrieren |
| POST | `/api/auth/login` | Einloggen, JWT erhalten |
| POST | `/api/auth/refresh-token` | JWT erneuern |
| POST | `/api/passkey/authenticate/options` | Passkey-Auth starten |
| POST | `/api/passkey/authenticate/verify` | Passkey-Auth verifizieren |
| GET | `/health` | Systemstatus |
**Gerät-authentifizierte Routen (IMEI + API-Key):**
| Methode | Pfad | Beschreibung |
|---|---|---|
| POST | `/api/tracking/data` | GPS-Datenpunkt senden |
| POST | `/api/alarms/trigger` | Alarm auslösen |
**Geschützte Routen (JWT erforderlich):**
*Geräte:*
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | `/api/devices` | Alle Geräte auflisten |
| POST | `/api/devices` | Gerät registrieren |
| GET | `/api/devices/:id` | Gerätedetails |
| PUT | `/api/devices/:id` | Gerät aktualisieren |
| DELETE | `/api/devices/:id` | Gerät löschen |
| POST | `/api/devices/:id/rotate-api-key` | API-Key rotieren |
| POST | `/api/devices/:id/shutdown` | Abschaltbefehl senden |
| POST | `/api/devices/:id/start` | Startbefehl senden |
| POST | `/api/devices/:id/alarm` | Alarm umschalten |
*Tracking:*
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | `/api/devices/:id/location` | Aktuelle Position |
| GET | `/api/devices/:id/history` | Positionshistorie (mit Zeitraum) |
| GET | `/api/devices/:id/stats` | Statistiken (Distanz, Geschwindigkeit) |
*Geofences:*
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | `/api/devices/:id/geofences` | Geofences auflisten |
| POST | `/api/devices/:id/geofences` | Geofence erstellen |
| PUT | `/api/geofences/:id` | Geofence aktualisieren |
| DELETE | `/api/geofences/:id` | Geofence löschen |
*Alarme:*
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | `/api/devices/:id/alarms` | Alarme auflisten |
| PUT | `/api/alarms/:id/settings` | Alarmeinstellungen |
| POST | `/api/alarms/:id/acknowledge` | Alarm bestätigen |
*Fahrer & Fahrten:*
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | `/api/devices/:id/drivers` | Fahrer auflisten |
| POST | `/api/devices/:id/drivers` | Fahrer anlegen |
| GET | `/api/devices/:id/drivers/:driverId/trips` | Fahrten eines Fahrers |
### 3.5 Authentifizierung & Sicherheit
Das System unterstützt zwei Authentifizierungsverfahren:
**JWT (JSON Web Token):**
- Nutzer erhalten nach Login einen Access Token (168h) und Refresh Token (720h)
- Token wird vom Frontend als `Authorization: Bearer <token>` mitgeschickt
- Auth-Middleware validiert und extrahiert Nutzer-ID, E-Mail und Rolle
- Bei abgelaufenem Token kann der Refresh Token genutzt werden
**WebAuthn / Passkeys (passwordless):**
- Nutzer können Passkeys (z.B. Face ID, Touch ID, Hardware-Key) registrieren
- Anmeldung ohne Passwort über kryptografische Herausforderungen
- Implementiert nach dem FIDO2-Standard mit go-webauthn
**Gerät-Authentifizierung (GPS-Tracker):**
- Geräte authentifizieren sich über IMEI + API-Key
- API-Key wird als SHA-256-Hash in der Datenbank gespeichert
- API-Key kann jederzeit rotiert werden
**Middleware-Sicherheitsschichten:**
| Middleware | Funktion |
|---|---|
| Auth | JWT-Token validieren |
| DeviceAuth | IMEI + API-Key validieren |
| RateLimiter | Max. Anfragen pro IP/Zeitfenster |
| CORS | Cross-Origin-Anfragen erlauben/blockieren |
| Security Headers | X-Frame-Options, XSS-Protection, HSTS |
| RequestID | Jede Anfrage erhält eine eindeutige ID für Tracing |
| Recovery | Panic-Handler verhindert Server-Absturz |
| Logger | Strukturiertes Logging aller Anfragen (zerolog) |
**Passwort-Sicherheit:**
- Passwörter werden mit bcrypt gehasht (nie im Klartext gespeichert)
### 3.6 Echtzeit-Kommunikation
Die Echtzeit-Kommunikation basiert auf drei Komponenten:
**Socket.IO-Server:**
- Clients verbinden sich per WebSocket (mit Long-Polling als Fallback)
- JWT-Token wird beim Verbinden übergeben und validiert
- Nutzer tritt automatisch dem Raum `user:{userID}` bei
- Geräte können einzeln abonniert werden (`subscribe:device`)
**Redis Pub/Sub:**
- Das Backend publisht GPS-Updates, Alarme und Gerätestatus in Redis-Kanäle
- Kanal-Muster: `tracking:*`, `alarm:*`, `device:*:status`
- Der Redis-Subscriber empfängt Nachrichten und leitet sie an Socket.IO-Räume weiter
**Events (Backend → Frontend):**
| Event | Inhalt |
|---|---|
| `location:update` | Neue GPS-Position mit lat/lng, Geschwindigkeit, Zündung |
| `alarm:triggered` | Neuer Alarm mit Typ, Schweregrad, Nachricht |
| `device:status` | Statusänderung (active/inactive) |
**Caching:**
- Letzte bekannte Position wird 10 Sekunden in Redis gecacht
- Geofence-Status (Fahrzeug inside/outside) wird 1 Stunde gecacht um doppelte Alarme zu verhindern
**Hintergrundprozesse:**
- **Monitoring Worker** (alle 60 Sekunden): Überprüft alle aktiven Geräte und markiert sie als offline wenn sie länger als X Minuten keine Daten gesendet haben
- **Cleanup Worker** (täglich): Löscht Tracking-Daten die älter als die konfigurierte Aufbewahrungszeit sind
### 3.7 Alarme & Benachrichtigungen
**Alarmtypen:**
- `GEOFENCE_ENTER` Fahrzeug betritt einen Geofence
- `GEOFENCE_EXIT` Fahrzeug verlässt einen Geofence
- `DEVICE_OFFLINE` Gerät sendet keine Daten mehr
- `SPEED_EXCEEDED` Geschwindigkeitsüberschreitung
- `BATTERY_LOW` Niedriger Batteriestand
- `VIBRATION` Vibration erkannt (möglicher Einbruch)
**Alarmschwergrade:** `LOW`, `MEDIUM`, `HIGH`
**Benachrichtigungskanäle:**
- **E-Mail:** Über SMTP (go-mail) für alle Alarmstufen
- **SMS:** Über Twilio nur bei hohem Schweregrad (HIGH), um Kosten zu sparen
---
## 4. Frontend
### 4.1 Technologie-Stack
| Technologie | Version | Verwendungszweck |
|---|---|---|
| React | 18.2.0 | UI-Framework |
| TypeScript | 4.9.5 | Typsicherheit |
| React Router | v6 | Client-seitiges Routing |
| React Query | 3.39.3 | Datenverwaltung & automatisches Caching |
| Material-UI (MUI) | 5.14.0 | UI-Komponentenbibliothek |
| Tailwind CSS | 3.3.6 | Utility-First CSS-Framework |
| Socket.io-client | 4.6.0 | WebSocket-Verbindung zum Backend |
| React Leaflet | 4.2.1 | Interaktive OpenStreetMap-Karte |
| Recharts | 2.10.0 | Diagramme & Statistiken |
| React Hook Form | 7.47.0 | Formularverwaltung mit Validierung |
| Axios | 1.6.0 | HTTP-Anfragen an die REST-API |
| date-fns | 2.30.0 | Datums- und Zeitformatierung |
| React Toastify | 9.1.3 | Toast-Benachrichtigungen |
### 4.2 Verzeichnisstruktur
```
src/
├── components/ # UI-Komponenten (nach Feature organisiert)
│ ├── auth/ # Login, Registrierung, ProtectedRoute
│ ├── layout/ # Header, Sidebar, Hauptlayout
│ ├── dashboard/ # Dashboard mit Statistiken
│ ├── vehicles/ # Fahrzeugliste, Fahrzeugdetails, Hinzufügen
│ ├── tracking/ # Live-Karte, Routenhistorie
│ ├── alerts/ # Alarmliste und -verwaltung
│ ├── geofence/ # Geofence-Erstellung und -verwaltung
│ └── devices/ # Geräteliste und Steuerung
├── contexts/
│ ├── AuthContext.tsx # Authentifizierungsstatus (global)
│ └── WebSocketContext.tsx # WebSocket-Verbindung (global)
├── hooks/
│ └── useAuth.ts # Eigener Hook für Auth-Zugriff
├── services/
│ └── api.ts # Alle API-Aufrufe (Axios)
├── types/
│ └── index.ts # TypeScript-Interfaces
├── styles/ # Globales CSS
├── App.tsx # Routing-Konfiguration
└── index.tsx # Einstiegspunkt mit React-Providern
```
### 4.3 Seiten & Features
**Login (`/login`) & Registrierung (`/register`)**
- Login mit E-Mail und Passwort
- Registrierung mit Vorname, Nachname, E-Mail und Passwort (mit Client-Validierung)
- JWT-Token wird im `localStorage` gespeichert
- Automatischer Re-Login beim Seitenaufruf wenn Token noch gültig
- Nicht eingeloggte Nutzer werden auf `/login` umgeleitet (ProtectedRoute)
**Dashboard (`/`)**
- Übersichtskacheln: Gesamtkilometer, aktive Fahrzeuge, offene Alarme
- Live-Karte mit aktuellen Fahrzeugpositionen
- Liste der neuesten Alarme
- Fahrzeugstatus-Überblick
**Fahrzeugliste (`/vehicles`)**
- Kachelansicht aller Fahrzeuge mit Suchfeld
- Fahrzeuge hinzufügen über Modal-Dialog (Name, Kennzeichen, Marke, Modell, Baujahr, Farbe)
**Fahrzeugdetails (`/vehicles/:id`)**
- Allgemeine Fahrzeugdaten (Marke, Modell, Kilometerstand)
- Gerätestatus mit IMEI und letzter Kommunikation
- Tabs für Tracking, Alarme und Statistiken
**Live-Tracking (`/tracking`)**
- Interaktive OpenStreetMap-Karte (React Leaflet)
- Fahrzeugmarker aktualisieren sich in Echtzeit über WebSocket
- Markerfarbe je nach Zündungsstatus: grün (an) / rot (aus)
- Anzeige von Geschwindigkeit, Kurs und Batteriestand
**Routenhistorie (`/tracking/history/:vehicleId`)**
- Vergangene Route als Linie auf der Karte
- Filterung nach Datum und Uhrzeit
- Berechnung der gefahrenen Distanz
**Alarme (`/alerts`)**
- Liste aller Alarme mit Filter nach Schweregrad
- Ungelesene / gelesene Alarme getrennt anzeigen
- Alarme per Klick als gelesen markieren
- Echtzeit-Toast-Benachrichtigung bei neuen kritischen Alarmen
**Geofence-Verwaltung (`/geofences`)**
- Kreis- und Polygon-Geofences direkt auf der Karte zeichnen
- Alarmregel: Alarm bei Einfahrt und/oder Ausfahrt
- Alle aktiven Geofences auf der Karte visualisiert
**Geräteverwaltung (`/devices`)**
- Liste aller Geräte mit Status und IMEI-Nummer
- Motor sperren / entsperren (Engine Lock)
- Gerätebefehle senden (Alarm, Shutdown, Start)
- Gerätehistorie mit Datumsfilter
**Header & Navigation:**
- Sidebar mit allen Hauptnavigationspunkten
- Verbindungsanzeige (grün = WebSocket verbunden, rot = getrennt)
- Benachrichtigungssymbol mit ungelesen Alarm-Zähler
- Nutzermenü mit Logout
### 4.4 Datenmodelle (TypeScript)
```typescript
// Nutzer
interface User {
id: string;
email: string;
firstName: string;
lastName: string;
role: string;
}
// Fahrzeug
interface Vehicle {
id: string;
name: string;
licensePlate: string;
brand: string;
model: string;
year: number;
color: string;
kilometers: number;
}
// GPS-Position
interface Position {
lat: number;
lng: number;
speed: number;
heading: number;
altitude: number;
battery: number;
ignition: boolean;
vibration: boolean;
}
// Alarm
interface Alert {
id: string;
type: string;
severity: 'info' | 'warning' | 'critical';
message: string;
vehicleId: string;
isRead: boolean;
createdAt: string;
}
// Geofence
interface Geofence {
id: string;
name: string;
type: 'circle' | 'polygon';
coordinates: number[][];
alertOnEnter: boolean;
alertOnExit: boolean;
}
// Standard-API-Antwort
interface ApiResponse<T> {
data: T;
message: string;
success: boolean;
}
```
---
## 5. Zusammenspiel Frontend ↔ Backend
**Normaler Datenfluss (REST API):**
```
Browser → Axios (mit JWT) → Gin-Router → Middleware → Handler → Service → Repository → PostgreSQL
Browser ← React Query (Cache) ← JSON-Antwort ← Handler ←──────────────────────────────
```
**Echtzeit-Datenfluss (WebSocket):**
```
GPS-Gerät → POST /api/tracking/data → TrackingService → Redis Publish (tracking:{id})
Redis Subscriber (Backend)
Socket.IO Broadcast → Browser
WebSocketContext → React State Update
Leaflet-Marker bewegt sich auf der Karte
```
**State Management im Frontend:**
| Zustandstyp | Technologie | Beispiel |
|---|---|---|
| Server-Daten | React Query | Fahrzeugliste, Alarmhistorie |
| Auth-Status | React Context | Eingeloggter Nutzer, JWT-Token |
| Live-Daten | React Context (WebSocket) | Aktuelle GPS-Positionen |
| UI-Zustand | React `useState` | Modal offen/zu, aktiver Tab |
---
## 6. Entwicklung & Deployment
### Backend starten
```bash
# Datenbank und Redis starten (Docker)
make docker-dev
# Datenbankmigrationen anwenden
make migrate-up-local
# Server starten
make dev
# Binary bauen
make build
# Tests ausführen
make test
```
### Frontend starten
```bash
# Abhängigkeiten installieren
npm install
# Entwicklungsserver starten (http://localhost:3001)
npm start
# Produktions-Build erstellen
npm run build
# Linting
npm run lint
# Code-Formatierung
npm run format
```
### Umgebungsvariablen
**Backend (`.env`):**
```env
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=simmeprotect
DB_USER=postgres
DB_PASSWORD=secret
REDIS_HOST=localhost
REDIS_PORT=6379
JWT_SECRET=supersecretkey
```
**Frontend (`.env`):**
```env
REACT_APP_API_URL=http://localhost:3000
REACT_APP_WS_URL=ws://localhost:3001
```