# 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 ` 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 { 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 ```