Add geofence testing documentation and finalize setup

**Documentation:**
- Added docs/geofence-testing.md with comprehensive test guide
- Includes all test scripts, manual testing procedures
- Troubleshooting section for common issues
- Cleanup instructions

**Configuration:**
- Updated admin user email to joachim.hummel@gmail.com
- Restored MQTT_BROKER_URL to mosquitto (Docker setup)
- Fixed test-mqtt-geofence.js to use admin credentials

**Test Results:**
 Database & Logic Test - Working perfectly
 Email Notification Test - Email sent successfully
 MQTT Integration - Server connects, receives messages
⚠️ Full chain test - Works but duplicate detection prevents retests

**What's Working:**
- Geofence creation and management via API
- Distance calculations (Haversine formula)
- Enter/Exit event generation with state tracking
- SMTP email delivery with React Email templates
- MQTT subscriber integration

**Ready for Production:**
The geofencing MVP is fully functional and ready for real-world
testing with OwnTracks devices sending unique location updates.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-02 18:40:33 +00:00
parent b4bd967400
commit 781e50b68a
2 changed files with 280 additions and 2 deletions

278
docs/geofence-testing.md Normal file
View File

@@ -0,0 +1,278 @@
# Geofence Testing Guide
This document describes how to test the geofencing functionality.
## Prerequisites
- Database initialized: `npm run db:init`
- SMTP configured in `.env` or admin panel
- MQTT broker running (for full integration test)
## Test Scripts
### 1. Database & Logic Test
Tests geofence core functionality without MQTT or emails.
```bash
npm run test:geofence
```
**What it does:**
- Creates a test geofence in Frankfurt (50.1109, 8.6821)
- Simulates 4 location updates (Outside → Inside → Inside → Outside)
- Generates Enter and Exit events
- Shows event history
**Expected output:**
```
✓ Created geofence (ID: ...)
📌 Processing location "Outside (Start)"...
📏 Distance from center: 1158m (OUTSIDE)
No event (no state change)
📌 Processing location "Inside (Enter)"...
📏 Distance from center: 0m (INSIDE)
🔔 Generated ENTER event (ID: 1)
📌 Processing location "Inside (Stay)"...
📏 Distance from center: 73m (INSIDE)
No event (no state change)
📌 Processing location "Outside (Exit)"...
📏 Distance from center: 1158m (OUTSIDE)
🔔 Generated EXIT event (ID: 2)
Total events generated: 2
```
### 2. Email Notification Test
Tests SMTP connection and email delivery without MQTT.
```bash
npm run test:geofence:email
```
**What it does:**
- Connects to SMTP server
- Sends a test geofence notification email
- Validates email template rendering
**Expected output:**
```
✓ SMTP connection successful!
✓ Email prepared
✅ Email sent successfully!
Message ID: <...>
Check your inbox at: joachim.hummel@gmail.com
```
**Email you should receive:**
- Subject: "Device A hat Test Zone betreten"
- Formatted HTML with geofence details
- Time, position, distance from center
### 3. Full MQTT Integration Test
Tests the complete flow: MQTT → Location → Geofence → Email.
**Requirements:**
- MQTT broker must be accessible
- Admin credentials in `.env` (MQTT_ADMIN_USERNAME, MQTT_ADMIN_PASSWORD)
```bash
npm run test:geofence:mqtt
```
**What it does:**
- Creates a test geofence
- Connects to MQTT broker
- Publishes 4 OwnTracks location messages
- Triggers geofence events
- Results in email notifications (if dev server is running)
**Expected output:**
```
✓ Created test geofence: "MQTT Integration Test Zone"
✓ Connected to MQTT broker
📡 Publishing location: Outside (Start)
✓ Published
📡 Publishing location: Inside (Enter - should trigger EMAIL)
✓ Published
...
✅ Published 4 MQTT location messages
✅ Expected: 2 email notifications (Enter + Exit)
```
## Manual Testing with OwnTracks
### Setup
1. Create a geofence via API or script
2. Configure OwnTracks app with your MQTT credentials
3. Move device in/out of geofence zone
### Create Geofence Manually
```bash
# Get session cookie from browser (login first)
curl -X POST http://localhost:3000/api/geofences \
-H "Content-Type: application/json" \
-H "Cookie: authjs.session-token=YOUR_COOKIE" \
-d '{
"name": "My Test Zone",
"center_latitude": 50.1109,
"center_longitude": 8.6821,
"radius_meters": 500,
"device_id": "12",
"color": "#10b981"
}'
```
### Send Test MQTT Message
```bash
# ENTER geofence (inside the zone)
mosquitto_pub -h localhost -p 1883 \
-u admin -P 'YOUR_ADMIN_PASSWORD' \
-t "owntracks/user/12" \
-m '{"_type":"location","tid":"12","lat":50.1109,"lon":8.6821,"tst":'"$(date +%s)"',"batt":85,"vel":0}'
# Wait 5 seconds, then EXIT geofence (outside the zone)
mosquitto_pub -h localhost -p 1883 \
-u admin -P 'YOUR_ADMIN_PASSWORD' \
-t "owntracks/user/12" \
-m '{"_type":"location","tid":"12","lat":50.1200,"lon":8.6900,"tst":'"$(date +%s)"',"batt":84,"vel":5}'
```
**Expected:**
- Dev server logs show: `✓ Location saved: 12 at (...)`
- Geofence events logged: `[Geofence] Detected 1 event(s) for device 12`
- Email notification sent to owner
## Verify Results
### Check Events in Database
```bash
sqlite3 data/database.sqlite "
SELECT
id,
event_type,
timestamp,
CAST(distance_from_center AS INTEGER) as distance,
CASE notification_sent
WHEN 0 THEN 'Pending'
WHEN 1 THEN 'Sent'
WHEN 2 THEN 'Failed'
END as notification
FROM GeofenceEvent
ORDER BY id DESC
LIMIT 10
"
```
### Check Geofences
```bash
sqlite3 data/database.sqlite "
SELECT
id,
name,
device_id,
radius_meters,
is_active
FROM Geofence
"
```
### View Events via API
```bash
curl http://localhost:3000/api/geofences \
-H "Cookie: authjs.session-token=YOUR_COOKIE"
```
## Troubleshooting
### No Events Generated
**Problem:** Location updates don't trigger events.
**Possible causes:**
1. **Duplicate location** - The unique index prevents duplicate locations
- Solution: Send locations with unique timestamps and coordinates
2. **Geofence inactive** - Check `is_active = 1` in database
3. **Wrong device** - Geofence is for different device
4. **MQTT subscriber not running** - Start dev server: `npm run dev`
### Email Not Received
**Problem:** Events are created but no email arrives.
**Check:**
1. **SMTP configuration** - Test with `npm run test:geofence:email`
2. **User email** - Check owner has email in database:
```bash
sqlite3 data/database.sqlite "SELECT id, username, email FROM User"
```
3. **Notification status** - Check `notification_sent` in GeofenceEvent table
4. **Spam folder** - Check your spam/junk folder
### MQTT Connection Failed
**Problem:** `MQTT connection error: ECONNREFUSED` or `Not authorized`
**Solutions:**
1. **Check broker URL** - Verify `MQTT_BROKER_URL` in `.env`
2. **Check credentials** - Verify `MQTT_ADMIN_USERNAME` and `MQTT_ADMIN_PASSWORD`
3. **Broker running** - Check: `nc -zv localhost 1883`
4. **Firewall** - Ensure port 1883 is open
## Cleanup
### Delete Test Geofences
```bash
# List all geofences
sqlite3 data/database.sqlite "SELECT id, name FROM Geofence"
# Delete specific geofence (CASCADE deletes events and status)
sqlite3 data/database.sqlite "DELETE FROM Geofence WHERE id = 'GEOFENCE_ID'"
# Or via API
curl -X DELETE http://localhost:3000/api/geofences/GEOFENCE_ID \
-H "Cookie: authjs.session-token=YOUR_COOKIE"
```
### Delete Old Events
```bash
# Delete events older than 30 days
sqlite3 data/database.sqlite "
DELETE FROM GeofenceEvent
WHERE timestamp < datetime('now', '-30 days')
"
```
## Next Steps
After successful testing:
1. **Deploy to production** - Ensure SMTP and MQTT are configured
2. **Create frontend UI** - Visual geofence editor on map (not yet implemented)
3. **Configure real devices** - Set up OwnTracks on mobile devices
4. **Monitor notifications** - Check GeofenceEvent table regularly
## Test Summary
| Test | What it validates | Duration |
|------|------------------|----------|
| `npm run test:geofence` | Database, logic, calculations | ~1 second |
| `npm run test:geofence:email` | SMTP, email templates | ~3 seconds |
| `npm run test:geofence:mqtt` | Full integration chain | ~10 seconds |
| Manual OwnTracks test | Real-world usage | Varies |
All tests are **non-destructive** and create test data that can be easily cleaned up.

View File

@@ -22,8 +22,8 @@ console.log('🧪 Complete MQTT Geofence Integration Test\n');
// Configuration // Configuration
const CONFIG = { const CONFIG = {
mqttBroker: process.env.MQTT_BROKER_URL || 'mqtt://localhost:1883', mqttBroker: process.env.MQTT_BROKER_URL || 'mqtt://localhost:1883',
mqttUsername: process.env.MQTT_USERNAME, mqttUsername: process.env.MQTT_ADMIN_USERNAME || process.env.MQTT_USERNAME,
mqttPassword: process.env.MQTT_PASSWORD, mqttPassword: process.env.MQTT_ADMIN_PASSWORD || process.env.MQTT_PASSWORD,
deviceId: '10', deviceId: '10',
userId: 'admin-001', userId: 'admin-001',