Documentation updates: - Add geofencing feature description with capabilities - Update database architecture ER diagram with Geofence, GeofenceEvent, and GeofenceStatus tables - Add complete schema documentation for all geofence tables and indexes - Update data flow diagram to show geofence monitoring pipeline - Update component overview with Geofence Monitor - Update Tech Stack versions: Next.js 16.0.7, React 19.2.1 - Add MQTT.js, Eclipse Mosquitto, Nodemailer, React Email to tech stack - Update dual-database architecture description - Add npm run db:init:geofence command documentation đ€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Location Tracker - Next.js Anwendung
Eine moderne Location-Tracking Anwendung basierend auf Next.js 14 mit MQTT/OwnTracks Integration, SQLite-Datenbank, Admin-Panel und Authentifizierung.
đ Inhaltsverzeichnis
- Features
- Tech Stack
- Installation
- Datenbank-Setup
- Verwendung
- Architektur
- API-Endpunkte
- Device Management
- Wartung
- Deployment
âš Features
Ăffentliche Features
- đșïž Interaktive Karte - Echtzeit-Standortverfolgung mit Leaflet.js
- đš Mehrere Kartenansichten - Standard, Satellit, Dark Mode
- đ Device-Filterung - Filtern nach GerĂ€t und Zeitraum
- â±ïž Flexible Zeitfilter:
- Quick Filters: 1h, 3h, 6h, 12h, 24h, All
- Custom Range: Benutzerdefinierter Zeitraum mit DateTime-Picker (z.B. 16.11.2025 16:00 - 17.11.2025 06:00)
- Kompakte UI - Custom Range nur sichtbar wenn aktiviert
- đ Auto-Refresh - Automatische Aktualisierung alle 5 Sekunden mit Pause/Resume Button
- đŻ Auto-Center - Karte zentriert automatisch auf neueste Position
- âžïž Pause/Resume - Toggle-Button zum Stoppen/Starten des Auto-Refresh
- đ± Responsive Design - Optimiert fĂŒr Desktop und Mobile
- đ Polylines - Bewegungspfade mit farbcodierter Darstellung
- đš Marker-Sortierung - Neueste Position immer im Vordergrund (z-index optimiert)
- đ Zoom-basierte Icon-Skalierung - Marker passen sich automatisch an Zoom-Level an
Admin-Panel (Login erforderlich)
- đ Authentifizierung - NextAuth.js v5 mit bcrypt-Hashing
- đ Dashboard - Ăbersicht ĂŒber GerĂ€te, Statistiken und Datenbankstatus
- â±ïž System Status - Live-Uptime, Memory Usage, Runtime Info
- đ± Device Management - GerĂ€te hinzufĂŒgen, bearbeiten, löschen
- đŻ Geofencing - Kreisförmige Geofences mit Enter/Exit-Benachrichtigungen:
- Geofences erstellen, bearbeiten und löschen
- Radius 50m bis 50km konfigurierbar
- Visualisierung auf der Karte mit Toggle-Button
- Event-Historie mit Enter/Exit-Ereignissen
- E-Mail und MQTT-Benachrichtigungen bei GrenzĂŒberschreitung
- đŸ Datenbank-Wartung:
- đ§č Cleanup alter Daten (7, 15, 30, 90 Tage)
- ⥠Datenbank-Optimierung (VACUUM)
- đ Detaillierte Statistiken
- đą Online/Offline Status - Echtzeit-Status (< 10 Min = Online)
- đ Telemetrie-Daten - Batterie, Geschwindigkeit, letzte Position (speed=0 wird korrekt behandelt)
đ Tech Stack
- Framework: Next.js 16.0.7 (App Router)
- Runtime: React 19.2.1
- Sprache: TypeScript 5.9
- Styling: Tailwind CSS v4
- Karten: Leaflet 1.9.4 + React-Leaflet 5.0
- Authentifizierung: NextAuth.js v5 (beta)
- Datenbank: SQLite (better-sqlite3)
- MQTT: MQTT.js v5 + Eclipse Mosquitto
- E-Mail: Nodemailer + React Email
- Passwort-Hashing: bcryptjs
- Datenquelle: MQTT Broker + lokale SQLite-Cache
Dual-Database Architektur
- database.sqlite - User, GerÀte, MQTT-Credentials, Geofences (kritische Daten)
- locations.sqlite - Location-Tracking (hohe Schreibrate, isoliert)
đŠ Installation
Voraussetzungen
- Node.js 18+
- npm oder yarn
Schritte
- Repository klonen
git clone https://github.com/yourusername/location-tracker-app.git
cd location-tracker-app
- Dependencies installieren
npm install
- Datenbank initialisieren
npm run db:init
Dies erstellt:
data/database.sqlite(User + Devices + MQTT + Geofences)data/locations.sqlite(Location-Tracking)- Standard Admin-User:
admin/admin123 - Standard Devices (ID 10, 11)
- Development Server starten
npm run dev
- Im Browser öffnen
- Karte: http://localhost:3000
- Login: http://localhost:3000/login
- Admin: http://localhost:3000/admin
- Devices: http://localhost:3000/admin/devices
đïž Datenbank-Setup
Initialisierung
Beide Datenbanken erstellen:
npm run db:init
Nur database.sqlite (User/Devices):
npm run db:init:app
Nur locations.sqlite (Tracking):
npm run db:init:locations
Nur Geofence-Tabellen:
npm run db:init:geofence
Datenbank zurĂŒcksetzen
Admin-User neu anlegen:
node scripts/reset-admin.js
Alte Locations löschen:
npm run db:cleanup # Ălter als 7 Tage
npm run db:cleanup:7d # Ălter als 7 Tage
npm run db:cleanup:30d # Ălter als 30 Tage
Duplikate entfernen (falls vorhanden):
node scripts/remove-duplicates.js
Schema
database.sqlite (User & Devices)
User Tabelle:
id TEXT PRIMARY KEY
username TEXT UNIQUE NOT NULL
email TEXT
passwordHash TEXT NOT NULL
role TEXT NOT NULL DEFAULT 'VIEWER' -- ADMIN oder VIEWER
parent_user_id TEXT -- FK zu User.id (Hierarchie)
createdAt TEXT DEFAULT (datetime('now'))
updatedAt TEXT DEFAULT (datetime('now'))
lastLoginAt TEXT
Device Tabelle:
id TEXT PRIMARY KEY
name TEXT NOT NULL
color TEXT NOT NULL
ownerId TEXT -- FK zu User.id
isActive INTEGER DEFAULT 1 -- 0 oder 1
description TEXT
icon TEXT
createdAt TEXT DEFAULT (datetime('now'))
updatedAt TEXT DEFAULT (datetime('now'))
MQTT Credentials Tabelle:
id INTEGER PRIMARY KEY AUTOINCREMENT
device_id TEXT NOT NULL UNIQUE -- FK zu Device.id
mqtt_username TEXT NOT NULL UNIQUE
mqtt_password_hash TEXT NOT NULL
enabled INTEGER DEFAULT 1 -- 0 oder 1
created_at TEXT DEFAULT (datetime('now'))
updated_at TEXT DEFAULT (datetime('now'))
MQTT ACL Rules Tabelle:
id INTEGER PRIMARY KEY AUTOINCREMENT
device_id TEXT NOT NULL -- FK zu Device.id
topic_pattern TEXT NOT NULL
permission TEXT NOT NULL -- 'read', 'write', 'readwrite'
created_at TEXT DEFAULT (datetime('now'))
MQTT Sync Status Tabelle:
id INTEGER PRIMARY KEY CHECK (id = 1) -- Singleton
pending_changes INTEGER DEFAULT 0
last_sync_at TEXT
last_sync_status TEXT
created_at TEXT DEFAULT (datetime('now'))
updated_at TEXT DEFAULT (datetime('now'))
Geofence Tabelle:
id TEXT PRIMARY KEY
name TEXT NOT NULL
description TEXT
shape_type TEXT NOT NULL DEFAULT 'circle' -- Only 'circle' for MVP
center_latitude REAL NOT NULL
center_longitude REAL NOT NULL
radius_meters INTEGER NOT NULL
owner_id TEXT NOT NULL -- FK zu User.id
device_id TEXT NOT NULL -- FK zu Device.id
is_active INTEGER DEFAULT 1 -- 0 oder 1
color TEXT DEFAULT '#3b82f6'
created_at TEXT DEFAULT (datetime('now'))
updated_at TEXT DEFAULT (datetime('now'))
GeofenceEvent Tabelle:
id INTEGER PRIMARY KEY AUTOINCREMENT
geofence_id TEXT NOT NULL -- FK zu Geofence.id
device_id TEXT NOT NULL -- FK zu Device.id
location_id INTEGER NOT NULL
event_type TEXT NOT NULL -- 'enter' oder 'exit'
latitude REAL NOT NULL
longitude REAL NOT NULL
distance_from_center REAL
notification_sent INTEGER DEFAULT 0 -- 0=not sent, 1=sent, 2=failed
notification_error TEXT
timestamp TEXT NOT NULL
created_at TEXT DEFAULT (datetime('now'))
GeofenceStatus Tabelle:
id INTEGER PRIMARY KEY AUTOINCREMENT
device_id TEXT NOT NULL -- FK zu Device.id
geofence_id TEXT NOT NULL -- FK zu Geofence.id
is_inside INTEGER NOT NULL DEFAULT 0 -- 0 oder 1
last_enter_time TEXT
last_exit_time TEXT
last_checked_at TEXT
created_at TEXT DEFAULT (datetime('now'))
updated_at TEXT DEFAULT (datetime('now'))
Indexes:
idx_user_usernameON User(username)idx_user_parentON User(parent_user_id)idx_device_ownerON Device(ownerId)idx_device_activeON Device(isActive)idx_mqtt_credentials_deviceON mqtt_credentials(device_id)idx_mqtt_credentials_usernameON mqtt_credentials(mqtt_username)idx_mqtt_acl_deviceON mqtt_acl_rules(device_id)idx_geofence_ownerON Geofence(owner_id)idx_geofence_deviceON Geofence(device_id)idx_geofence_activeON Geofence(is_active)idx_geofence_event_geofenceON GeofenceEvent(geofence_id)idx_geofence_event_deviceON GeofenceEvent(device_id)idx_geofence_event_timestampON GeofenceEvent(timestamp DESC)idx_geofence_event_notificationON GeofenceEvent(notification_sent)idx_geofence_event_compositeON GeofenceEvent(device_id, geofence_id, timestamp DESC)idx_geofence_status_deviceON GeofenceStatus(device_id)idx_geofence_status_geofenceON GeofenceStatus(geofence_id)idx_geofence_status_insideON GeofenceStatus(is_inside)
locations.sqlite (Tracking Data)
Location Tabelle:
id INTEGER PRIMARY KEY AUTOINCREMENT
latitude REAL NOT NULL -- -90 bis +90
longitude REAL NOT NULL -- -180 bis +180
timestamp TEXT NOT NULL -- ISO 8601 format
user_id INTEGER DEFAULT 0
first_name TEXT
last_name TEXT
username TEXT -- Device Tracker ID
marker_label TEXT
display_time TEXT -- Formatierte Zeit fĂŒr UI
chat_id INTEGER DEFAULT 0
battery INTEGER -- Batteriestand in %
speed REAL -- Geschwindigkeit in km/h
created_at TEXT DEFAULT (datetime('now'))
Indexes:
idx_location_timestampON Location(timestamp DESC)idx_location_usernameON Location(username)idx_location_user_idON Location(user_id)idx_location_compositeON Location(user_id, username, timestamp DESC)idx_location_uniqueUNIQUE ON Location(timestamp, username, latitude, longitude)
Constraints:
- Latitude: -90 bis +90
- Longitude: -180 bis +180
- UNIQUE: Kombination aus timestamp, username, latitude, longitude verhindert Duplikate
WAL Mode: Beide Datenbanken nutzen Write-Ahead Logging fĂŒr bessere Concurrency
đ Verwendung
Login
Standard-Zugangsdaten:
Benutzername: admin
Passwort: admin123
â ïž Wichtig: FĂŒr Production neuen User anlegen und Passwort Ă€ndern!
GerĂ€te hinzufĂŒgen
- Admin-Panel öffnen:
/admin/devices - "Add Device" klicken
- Device ID (muss mit OwnTracks
tidĂŒbereinstimmen) - Name und Farbe festlegen
- Speichern
Wichtig: Die Device ID muss mit der OwnTracks Tracker-ID ĂŒbereinstimmen!
OwnTracks konfigurieren
In der OwnTracks App:
- Tracker ID (tid): z.B.
12 - Topic: OwnTracks publishes automatically to
owntracks/<username>/<device_id>- Example:
owntracks/device_12_4397af93/12
- Example:
- MQTT Broker konfigurieren (siehe MQTT Setup)
Die App empfÀngt die Daten direkt vom MQTT Broker.
Zeitfilter verwenden
Die App bietet zwei Modi fĂŒr die Zeitfilterung:
Quick Filters (Schnellauswahl)
Vordefinierte ZeitrĂ€ume fĂŒr schnellen Zugriff:
- 1 Hour - Locations der letzten Stunde
- 3 Hours - Locations der letzten 3 Stunden
- 6 Hours - Locations der letzten 6 Stunden
- 12 Hours - Locations der letzten 12 Stunden
- 24 Hours - Locations der letzten 24 Stunden
- All - Alle verfĂŒgbaren Locations
Verwendung:
- Im Header unter "Time:" gewĂŒnschten Zeitraum auswĂ€hlen
- Die Karte aktualisiert sich automatisch
Custom Range (Benutzerdefiniert)
FĂŒr spezifische ZeitrĂ€ume, z.B. "Route von gestern Abend 18:00 bis heute Morgen 08:00":
Verwendung:
- Auf den "đ Custom" Button klicken
- Custom Range Felder erscheinen:
- From: Start-Datum und -Zeit wÀhlen (z.B. 16.11.2025 16:00)
- To: End-Datum und -Zeit wÀhlen (z.B. 17.11.2025 06:00)
- Die Route wird automatisch fĂŒr den gewĂ€hlten Zeitraum angezeigt
- Zum ZurĂŒckschalten: "đ Quick" Button klicken
Hinweis: Custom Range Controls sind nur sichtbar wenn aktiviert - spart Platz im Header!
đ Architektur
Datenfluss
flowchart TD
A[đ± OwnTracks App] -->|MQTT Publish| B[đ MQTT Broker]
B -->|Subscribe| C[đĄ Next.js MQTT Subscriber]
C -->|Store Locations| D[(đïž SQLite Cache<br/>locations.sqlite)]
C -->|Check Geofences| L[đŻ Geofence Monitor]
L -->|Store Events| K[(đŒ SQLite DB<br/>database.sqlite)]
E[đ„ïž Browser Client] -->|GET /api/locations<br/>alle 5 Sek| F[đĄ Next.js API Route]
D -->|Query Filtered Data| F
F -->|JSON Response| E
E -->|Render| G[đșïž React Leaflet Map]
E -->|Render Geofences| M[đ” Geofence Circles]
H[đ€ Admin User] -->|Login| I[đ NextAuth.js]
I -->|Authenticated| J[đ Admin Panel]
J -->|CRUD Operations| K
J -->|Manage Geofences| K
K -->|Query Events| J
style A fill:#4CAF50
style B fill:#FF9800
style C fill:#2196F3
style D fill:#FFC107
style F fill:#00BCD4
style G fill:#8BC34A
style I fill:#E91E63
style K fill:#FFC107
style L fill:#9C27B0
style M fill:#3F51B5
Komponenten-Ăbersicht
graph LR
subgraph "External Services"
A[OwnTracks App]
B[MQTT Broker]
end
subgraph "Next.js Application"
C[MQTT Subscriber]
I[Geofence Monitor]
D[Frontend<br/>React/Leaflet]
E[API Routes]
F[Auth Layer<br/>NextAuth.js]
end
subgraph "Data Layer"
G[locations.sqlite<br/>Tracking Data]
H[database.sqlite<br/>Users, Devices<br/>MQTT, Geofences]
end
A -->|MQTT| B
B -->|Subscribe| C
C -->|Write Locations| G
C -->|Trigger| I
I -->|Check & Store Events| H
D -->|HTTP| E
E -->|Read/Write| G
E -->|Read/Write| H
D -->|Auth| F
F -->|Validate| H
style A fill:#4CAF50,color:#fff
style B fill:#FF9800,color:#fff
style C fill:#2196F3,color:#fff
style I fill:#9C27B0,color:#fff
style D fill:#00BCD4,color:#000
style E fill:#00BCD4,color:#000
style F fill:#E91E63,color:#fff
style G fill:#FFC107,color:#000
style H fill:#FFC107,color:#000
Datenbank-Architektur
erDiagram
USER ||--o{ USER : "parent_user_id"
USER ||--o{ DEVICE : owns
USER ||--o{ GEOFENCE : owns
DEVICE ||--o{ LOCATION : tracks
DEVICE ||--o| MQTT_CREDENTIALS : has
DEVICE ||--o{ MQTT_ACL_RULES : has
DEVICE ||--o{ GEOFENCE : monitors
GEOFENCE ||--o{ GEOFENCE_EVENT : triggers
GEOFENCE ||--o{ GEOFENCE_STATUS : tracks
DEVICE ||--o{ GEOFENCE_EVENT : generates
DEVICE ||--o{ GEOFENCE_STATUS : has
USER {
string id PK
string username UK
string email
string passwordHash
string role
string parent_user_id FK
datetime createdAt
datetime lastLoginAt
}
DEVICE {
string id PK
string name
string color
string ownerId FK
boolean isActive
string description
datetime createdAt
}
MQTT_CREDENTIALS {
int id PK
string device_id FK_UK
string mqtt_username UK
string mqtt_password_hash
boolean enabled
datetime created_at
datetime updated_at
}
MQTT_ACL_RULES {
int id PK
string device_id FK
string topic_pattern
string permission
datetime created_at
}
MQTT_SYNC_STATUS {
int id PK
int pending_changes
datetime last_sync_at
string last_sync_status
datetime created_at
datetime updated_at
}
GEOFENCE {
string id PK
string name
string description
string shape_type
float center_latitude
float center_longitude
int radius_meters
string owner_id FK
string device_id FK
boolean is_active
string color
datetime created_at
datetime updated_at
}
GEOFENCE_EVENT {
int id PK
string geofence_id FK
string device_id FK
int location_id
string event_type
float latitude
float longitude
float distance_from_center
int notification_sent
string notification_error
datetime timestamp
datetime created_at
}
GEOFENCE_STATUS {
int id PK
string device_id FK
string geofence_id FK
boolean is_inside
datetime last_enter_time
datetime last_exit_time
datetime last_checked_at
datetime created_at
datetime updated_at
}
LOCATION {
int id PK
float latitude
float longitude
datetime timestamp
string username FK
int user_id
string display_time
int battery
float speed
int chat_id
}
Auto-Refresh Mechanismus
Die App verwendet einen Echtzeit-Ansatz:
- MQTT Subscriber empfÀngt OwnTracks Messages direkt vom Broker
- Locations werden sofort in SQLite gespeichert
- Frontend polling (alle 5 Sek.) â
/api/locations - API liest gefilterte Daten aus lokalem SQLite Cache
- Duplikate werden durch UNIQUE Index verhindert
Vorteile:
- Echtzeitdaten ohne Verzögerung
- Schnelle Antwortzeiten (direkter SQLite Zugriff)
- LÀngere ZeitrÀume abrufbar (24h+)
- Keine externen Dependencies
- Duplikate werden automatisch verhindert (UNIQUE Index)
Datenvalidierung & Normalisierung
Die App behandelt spezielle FĂ€lle bei speed/battery korrekt:
speed = 0 Behandlung:
- MQTT sendet
speed: 0(gĂŒltig - GerĂ€t steht still) - Wird mit
typeof === 'number'Check explizit als0gespeichert - Wird NICHT zu
nullkonvertiert (wichtig fĂŒr Telemetrie) - Popup zeigt "Speed: 0.0 km/h" an
Debug-Logging:
- Server-Logs zeigen MQTT Message-Verarbeitung
- Browser Console zeigt Daten-Flow (MapView, Popup)
- Hilfreich fĂŒr Troubleshooting
đĄ API-Endpunkte
Ăffentlich
GET /api/locations
- Location-Daten abrufen (aus SQLite Cache)
- Query-Parameter:
username- Device-Filter (z.B. "10", "11")- Zeitfilter (wÀhle eine Methode):
timeRangeHours- Quick Filter (1, 3, 6, 12, 24)startTime&endTime- Custom Range (ISO 8601 Format)
limit- Max. Anzahl (Standard: 1000)
Beispiele:
# Quick Filter: Letzte 3 Stunden
GET /api/locations?timeRangeHours=3
# Custom Range: Spezifischer Zeitraum
GET /api/locations?startTime=2025-11-16T16:00:00.000Z&endTime=2025-11-17T06:00:00.000Z
# Kombiniert: Device + Custom Range
GET /api/locations?username=10&startTime=2025-11-16T16:00:00.000Z&endTime=2025-11-17T06:00:00.000Z
GET /api/devices/public
- Ăffentliche Device-Liste (nur ID, Name, Color)
GeschĂŒtzt (Login erforderlich)
GET /api/devices
- Alle GerÀte mit Latest Location und Telemetrie
POST /api/devices
- Neues GerÀt erstellen
- Body:
{ id, name, color, description? }
PATCH /api/devices/:id
- GerÀt aktualisieren
- Body:
{ name?, color?, description? }
DELETE /api/devices/:id
- GerÀt löschen (soft delete)
POST /api/locations/cleanup
- Alte Locations löschen
- Body:
{ retentionHours }
POST /api/locations/optimize
- VACUUM + ANALYZE ausfĂŒhren
- Gibt freigegebenen Speicher zurĂŒck
GET /api/locations/stats
- Detaillierte DB-Statistiken
- GröĂe, Zeitraum, Locations pro Device
GET /api/system/status
- System-Status abrufen
- Returns: Uptime, Memory Usage, Node.js Version, Platform
- Auto-Refresh: Alle 10 Sekunden im Admin-Panel
đ± Device Management
Device-Karte zeigt:
- đą/â« Online/Offline Status
- Online = letzte Location < 10 Minuten
- Offline = letzte Location > 10 Minuten
- đ Last Seen - Zeitstempel letzter Location
- đ Batterie - Prozent (Rot bei < 20%)
- đ Geschwindigkeit - km/h (umgerechnet von m/s)
- đ Koordinaten - Lat/Lon mit 5 Dezimalen
Auto-Refresh
- Devices-Seite aktualisiert sich alle 10 Sekunden
- Online/Offline Status wird automatisch aktualisiert
đ§č Wartung
Datenbank aufrÀumen
Via Admin-Panel:
/adminâ Database Maintenance â Cleanup Buttons
Via CLI:
npm run db:cleanup # 7 Tage
npm run db:cleanup:30d # 30 Tage
Datenbank optimieren
Via Admin-Panel:
/adminâ Database Maintenance â Optimize Button
Via CLI:
# Manuell
node scripts/optimize-db.js
Was macht Optimize:
VACUUM- Speicherplatz freigebenANALYZE- Query-Statistiken aktualisieren
Logs prĂŒfen
# Development Server Logs
npm run dev
# Production Logs (PM2)
pm2 logs location-tracker-app
Zeitfilter debuggen
Bei Problemen mit der Zeitfilterung (z.B. alte Locations werden nicht ausgefiltert):
node scripts/test-time-filter.js
Das Script zeigt:
- Aktuelle Zeit (UTC und lokal)
- Letzte Locations in der Datenbank
- Welche Locations mit 1-Stunden-Filter angezeigt werden sollten
- Vergleich zwischen alter (SQLite datetime) und neuer (JavaScript) Methode
- Anzahl der gefilterten Locations
Verwendung:
- Script ausfĂŒhren um zu sehen, welche Locations in der DB sind
- ĂberprĂŒfen ob die Zeitfilterung korrekt funktioniert
- Bei Problemen: App neu starten nach Code-Updates
đ Deployment
Environment Variables
Erstelle .env.local:
# NextAuth
AUTH_SECRET=<generiere-mit-openssl-rand-base64-32>
NEXTAUTH_URL=https://your-domain.com
Secret generieren:
openssl rand -base64 32
Production Build
# Build
npm run build
# Start
npm run start
Mit PM2 (empfohlen)
# PM2 installieren
npm install -g pm2
# App starten
pm2 start npm --name "location-tracker-app" -- start
# Auto-Start bei Server-Neustart
pm2 startup
pm2 save
Nginx Reverse Proxy
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
đ Sicherheit
Production Checklist
AUTH_SECRETmit starkem Wert setzenNEXTAUTH_URLauf Production-Domain setzen- Admin-Passwort Àndern (nicht
admin123) - Ggf. weitere User anlegen mit VIEWER Rolle
- HTTPS aktivieren (Let's Encrypt)
- Firewall-Regeln prĂŒfen
- RegelmĂ€Ăige Backups einrichten
User-Rollen
- ADMIN - Voller Zugriff auf alle Admin-Funktionen
- VIEWER - Nur lesender Zugriff (geplant, noch nicht implementiert)
đ Projektstruktur
location-tracker-app/
âââ app/
â âââ api/
â â âââ auth/[...nextauth]/ # NextAuth API
â â âââ devices/ # Device CRUD
â â âââ locations/ # Location API + Sync/Cleanup/Stats
â â âââ system/status/ # System Status (Uptime, Memory)
â âââ admin/
â â âââ devices/ # Device Management
â â âââ page.tsx # Dashboard
â âââ login/ # Login-Seite
â âââ page.tsx # Ăffentliche Karte
â âââ layout.tsx # Root Layout
âââ components/
â âââ map/
â âââ MapView.tsx # Leaflet Map Component
âââ lib/
â âââ auth.ts # NextAuth Config
â âââ db.ts # SQLite Database Layer
âââ scripts/
â âââ init-database.js # Database.sqlite Setup
â âââ init-locations-db.js # Locations.sqlite Setup
â âââ reset-admin.js # Admin User Reset
â âââ remove-duplicates.js # Duplikate bereinigen
â âââ cleanup-old-locations.js # Alte Daten löschen
âââ data/
â âââ database.sqlite # User + Devices
â âââ locations.sqlite # Location Tracking
âââ types/
â âââ location.ts # TypeScript Interfaces
âââ middleware.ts # Route Protection
đ Changelog
Version 1.1.0 - November 2025
đ Neue Features
- Custom Date Range Filter
- Benutzerdefinierte ZeitrÀume mit DateTime-Picker (z.B. 16.11.2025 16:00 - 17.11.2025 06:00)
- Toggle-Button zwischen Quick Filters und Custom Range
- Kompakte UI - Custom Range nur sichtbar wenn aktiviert
- Backend-Support mit
startTimeundendTimeAPI-Parametern
đ Bug Fixes
- Zeitfilter-Bug behoben
- Alte Locations (z.B. 6+ Stunden alt) werden jetzt korrekt ausgefiltert
- JavaScript-basierte Zeitberechnung statt SQLite
datetime('now') - Verhindert Zeitversatz-Probleme
đ ïž Verbesserungen
- Zoom-basierte Icon-Skalierung fĂŒr bessere Sichtbarkeit
- Optimierte Zeitfilter-Logik in Datenbank-Queries
- Debug-Script
test-time-filter.jsfĂŒr Troubleshooting
đ Dokumentation
- README aktualisiert mit Custom Range Anleitung
- API-Endpunkte Dokumentation erweitert
- Wartungs-Abschnitt mit Debug-Script Information
đ Troubleshooting
"Invalid username or password"
Lösung:
node scripts/reset-admin.js
Datenbank-Dateien fehlen
Lösung:
npm run db:init
Duplikate in locations.sqlite
Lösung:
# Erst Duplikate entfernen
node scripts/remove-duplicates.js
# Dann UNIQUE Index hinzufĂŒgen
node scripts/init-locations-db.js
Map zeigt keine Daten
- MQTT Broker erreichbar?
mosquitto_sub -h localhost -p 1883 -t '#' - Locations in Datenbank?
/adminâ Database Statistics prĂŒfen - MQTT Subscriber lĂ€uft? Server-Logs prĂŒfen
"ENOENT: no such file or directory, open 'data/database.sqlite'"
Lösung:
mkdir -p data
npm run db:init
đ NPM Scripts
# Development
npm run dev # Dev Server starten
# Production
npm run build # Production Build
npm run start # Production Server
# Database
npm run db:init # Beide DBs initialisieren
npm run db:init:app # Nur database.sqlite
npm run db:init:locations # Nur locations.sqlite
npm run db:cleanup # Cleanup 7 Tage
npm run db:cleanup:7d # Cleanup 7 Tage
npm run db:cleanup:30d # Cleanup 30 Tage
# Linting
npm run lint # ESLint ausfĂŒhren
đ Lizenz
MIT License - Open Source
đ Open Source Lizenzen
Diese Anwendung verwendet folgende Open-Source-Software:
MIT License
- Next.js - Copyright (c) Vercel, Inc.
- React - Copyright (c) Meta Platforms, Inc.
- React-DOM - Copyright (c) Meta Platforms, Inc.
- Tailwind CSS - Copyright (c) Tailwind Labs, Inc.
- better-sqlite3 - Copyright (c) Joshua Wise
- bcryptjs - Copyright (c) Daniel Wirtz
Apache License 2.0
- TypeScript - Copyright (c) Microsoft Corporation
ISC License
- NextAuth.js - Copyright (c) NextAuth.js Contributors
BSD-2-Clause License
- Leaflet - Copyright (c) Vladimir Agafonkin
Hippocratic License 2.1
- React-Leaflet - Copyright (c) Paul Le Cam
VollstÀndige Lizenztexte:
Alle vollstÀndigen Lizenztexte der verwendeten Bibliotheken finden Sie in den jeweiligen GitHub-Repositories oder in der node_modules Directory nach Installation.
đ Credits
- Next.js 14 - React Framework
- Leaflet.js - Karten-Bibliothek
- NextAuth.js - Authentifizierung
- better-sqlite3 - SQLite fĂŒr Node.js
- Tailwind CSS - Utility-First CSS
- MQTT.js - MQTT Client fĂŒr Node.js
- OwnTracks - Location Tracking Apps
đ Support
Bei Fragen oder Problemen:
- Logs prĂŒfen (
npm run devOutput) - Browser Console öffnen (F12)
- Datenbank-Status in
/adminprĂŒfen - Issues im Repository erstellen