# 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](#-features)
- [Tech Stack](#-tech-stack)
- [Installation](#-installation)
- [Datenbank-Setup](#-datenbank-setup)
- [Verwendung](#-verwendung)
- [Architektur](#-architektur)
- [API-Endpunkte](#-api-endpunkte)
- [Device Management](#-device-management)
- [Wartung](#-wartung)
- [Deployment](#-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
- đŸ **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 14 (App Router)
- **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)
- **Passwort-Hashing:** bcryptjs
- **Datenquelle:** MQTT Broker + lokale SQLite-Cache
### Dual-Database Architektur
- **database.sqlite** - User, GerÀte (kritische Daten)
- **locations.sqlite** - Location-Tracking (hohe Schreibrate, isoliert)
---
## đŠ Installation
### Voraussetzungen
- Node.js 18+
- npm oder yarn
### Schritte
1. **Repository klonen**
```bash
git clone https://github.com/yourusername/location-tracker-app.git
cd location-tracker-app
```
2. **Dependencies installieren**
```bash
npm install
```
3. **Datenbank initialisieren**
```bash
npm run db:init
```
Dies erstellt:
- `data/database.sqlite` (User + Devices)
- `data/locations.sqlite` (Location-Tracking)
- Standard Admin-User: `admin` / `admin123`
- Standard Devices (ID 10, 11)
4. **Development Server starten**
```bash
npm run dev
```
5. **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:**
```bash
npm run db:init
```
**Nur database.sqlite (User/Devices):**
```bash
npm run db:init:app
```
**Nur locations.sqlite (Tracking):**
```bash
npm run db:init:locations
```
### Datenbank zurĂŒcksetzen
**Admin-User neu anlegen:**
```bash
node scripts/reset-admin.js
```
**Alte Locations löschen:**
```bash
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):**
```bash
node scripts/remove-duplicates.js
```
### Schema
#### **database.sqlite** (User & Devices)
**User Tabelle:**
```sql
id TEXT PRIMARY KEY
username TEXT UNIQUE NOT NULL
email TEXT
passwordHash TEXT NOT NULL
role TEXT NOT NULL DEFAULT 'VIEWER' -- ADMIN oder VIEWER
createdAt TEXT DEFAULT (datetime('now'))
updatedAt TEXT DEFAULT (datetime('now'))
lastLoginAt TEXT
```
**Device Tabelle:**
```sql
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'))
```
**Indexes:**
- `idx_user_username` ON User(username)
- `idx_device_owner` ON Device(ownerId)
- `idx_device_active` ON Device(isActive)
---
#### **locations.sqlite** (Tracking Data)
**Location Tabelle:**
```sql
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_timestamp` ON Location(timestamp DESC)
- `idx_location_username` ON Location(username)
- `idx_location_user_id` ON Location(user_id)
- `idx_location_composite` ON Location(user_id, username, timestamp DESC)
- `idx_location_unique` UNIQUE 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
1. Admin-Panel öffnen: `/admin/devices`
2. "Add Device" klicken
3. Device ID (muss mit OwnTracks `tid` ĂŒbereinstimmen)
4. Name und Farbe festlegen
5. 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/user/12`
- 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:**
1. Im Header unter "Time:" gewĂŒnschten Zeitraum auswĂ€hlen
2. 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:**
1. Auf den **"đ
Custom"** Button klicken
2. 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)
3. Die Route wird automatisch fĂŒr den gewĂ€hlten Zeitraum angezeigt
4. Zum ZurĂŒckschalten: **"đ
Quick"** Button klicken
**Hinweis:** Custom Range Controls sind nur sichtbar wenn aktiviert - spart Platz im Header!
---
## đ Architektur
### Datenfluss
```mermaid
flowchart TD
A[đ± OwnTracks App] -->|MQTT Publish| B[đ MQTT Broker]
B -->|Subscribe| C[đĄ Next.js MQTT Subscriber]
C -->|Store Locations| D[(đïž SQLite Cache
locations.sqlite)]
E[đ„ïž Browser Client] -->|GET /api/locations
alle 5 Sek| F[đĄ Next.js API Route]
D -->|Query Filtered Data| F
F -->|JSON Response| E
E -->|Render| G[đșïž React Leaflet Map]
H[đ€ Admin User] -->|Login| I[đ NextAuth.js]
I -->|Authenticated| J[đ Admin Panel]
J -->|CRUD Operations| K[(đŒ SQLite DB
database.sqlite)]
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
```
### Komponenten-Ăbersicht
```mermaid
graph LR
subgraph "External Services"
A[OwnTracks App]
B[MQTT Broker]
end
subgraph "Next.js Application"
C[MQTT Subscriber]
D[Frontend
React/Leaflet]
E[API Routes]
F[Auth Layer
NextAuth.js]
end
subgraph "Data Layer"
G[locations.sqlite
Tracking Data]
H[database.sqlite
Users & Devices]
end
A -->|MQTT| B
B -->|Subscribe| C
C -->|Write| G
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 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
```mermaid
erDiagram
USER ||--o{ DEVICE : owns
DEVICE ||--o{ LOCATION : tracks
USER {
string id PK
string username UK
string email
string passwordHash
string role
datetime createdAt
datetime lastLoginAt
}
DEVICE {
string id PK
string name
string color
string ownerId FK
boolean isActive
string description
datetime createdAt
}
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**:
1. **MQTT Subscriber** empfÀngt OwnTracks Messages direkt vom Broker
2. **Locations** werden sofort in SQLite gespeichert
3. **Frontend polling** (alle 5 Sek.) â `/api/locations`
4. **API liest** gefilterte Daten aus lokalem SQLite Cache
5. **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 (kein n8n nötig)
- 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 als `0` gespeichert
- Wird NICHT zu `null` konvertiert (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:**
```bash
# 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:**
```bash
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:**
```bash
# Manuell
node scripts/optimize-db.js
```
**Was macht Optimize:**
- `VACUUM` - Speicherplatz freigeben
- `ANALYZE` - Query-Statistiken aktualisieren
### Logs prĂŒfen
```bash
# 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):
```bash
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:**
1. Script ausfĂŒhren um zu sehen, welche Locations in der DB sind
2. ĂberprĂŒfen ob die Zeitfilterung korrekt funktioniert
3. Bei Problemen: App neu starten nach Code-Updates
---
## đ Deployment
### Environment Variables
Erstelle `.env.local`:
```env
# NextAuth
AUTH_SECRET=
NEXTAUTH_URL=https://your-domain.com
```
**Secret generieren:**
```bash
openssl rand -base64 32
```
### Production Build
```bash
# Build
npm run build
# Start
npm run start
```
### Mit PM2 (empfohlen)
```bash
# 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
```nginx
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_SECRET` mit starkem Wert setzen
- [ ] `NEXTAUTH_URL` auf 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 `startTime` und `endTime` API-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.js` fĂŒ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:**
```bash
node scripts/reset-admin.js
```
### Datenbank-Dateien fehlen
**Lösung:**
```bash
npm run db:init
```
### Duplikate in locations.sqlite
**Lösung:**
```bash
# Erst Duplikate entfernen
node scripts/remove-duplicates.js
# Dann UNIQUE Index hinzufĂŒgen
node scripts/init-locations-db.js
```
### Map zeigt keine Daten
1. MQTT Broker erreichbar? `mosquitto_sub -h localhost -p 1883 -t '#'`
2. Locations in Datenbank? `/admin` â Database Statistics prĂŒfen
3. MQTT Subscriber lĂ€uft? Server-Logs prĂŒfen
### "ENOENT: no such file or directory, open 'data/database.sqlite'"
**Lösung:**
```bash
mkdir -p data
npm run db:init
```
---
## đ NPM Scripts
```bash
# 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](https://github.com/vercel/next.js) - Copyright (c) Vercel, Inc.
- [React](https://github.com/facebook/react) - Copyright (c) Meta Platforms, Inc.
- [React-DOM](https://github.com/facebook/react) - Copyright (c) Meta Platforms, Inc.
- [Tailwind CSS](https://github.com/tailwindlabs/tailwindcss) - Copyright (c) Tailwind Labs, Inc.
- [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) - Copyright (c) Joshua Wise
- [bcryptjs](https://github.com/dcodeIO/bcrypt.js) - Copyright (c) Daniel Wirtz
### Apache License 2.0
- [TypeScript](https://github.com/microsoft/TypeScript) - Copyright (c) Microsoft Corporation
### ISC License
- [NextAuth.js](https://github.com/nextauthjs/next-auth) - Copyright (c) NextAuth.js Contributors
### BSD-2-Clause License
- [Leaflet](https://github.com/Leaflet/Leaflet) - Copyright (c) Vladimir Agafonkin
### Hippocratic License 2.1
- [React-Leaflet](https://github.com/PaulLeCam/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:
1. Logs prĂŒfen (`npm run dev` Output)
2. Browser Console öffnen (F12)
3. Datenbank-Status in `/admin` prĂŒfen
4. Issues im Repository erstellen