Add Geofence MVP feature implementation
Implemented complete MVP for geofencing functionality with database, backend logic, MQTT integration, and API endpoints. **Phase 1: Database & Core Logic** - scripts/init-geofence-db.js: Database initialization for Geofence tables - lib/types.ts: TypeScript types for Geofence, GeofenceEvent, GeofenceStatus - lib/geofence-engine.ts: Core geofencing logic (Haversine distance, state tracking) - lib/geofence-db.ts: Database layer with CRUD operations - package.json: Added db:init:geofence script **Phase 2: MQTT Integration & Email Notifications** - emails/geofence-enter.tsx: React Email template for enter events - emails/geofence-exit.tsx: React Email template for exit events - lib/email-renderer.ts: Added geofence email rendering functions - lib/geofence-notifications.ts: Notification service for geofence events - lib/mqtt-subscriber.ts: Integrated automatic geofence checking on location updates **Phase 3: Minimal API** - app/api/geofences/route.ts: GET (list) and POST (create) endpoints - app/api/geofences/[id]/route.ts: DELETE endpoint - All endpoints with authentication and ownership checks **MVP Simplifications:** - No zone limit enforcement (unlimited for all users) - No notification flags (always send Enter + Exit emails) - Device assignment required (no NULL device logic) - Circular geofences only **Features:** ✅ Automatic geofence detection on MQTT location updates ✅ Email notifications for enter/exit events ✅ State tracking to prevent duplicate events ✅ REST API for geofence management ✅ Non-blocking async processing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
// MQTT Subscriber Service für OwnTracks Location Updates
|
||||
import mqtt from 'mqtt';
|
||||
import { locationDb, Location } from './db';
|
||||
import { checkGeofences } from './geofence-engine';
|
||||
import { geofenceDb } from './geofence-db';
|
||||
import { sendGeofenceNotifications } from './geofence-notifications';
|
||||
|
||||
// OwnTracks Message Format
|
||||
interface OwnTracksMessage {
|
||||
@@ -139,6 +142,27 @@ class MQTTSubscriber {
|
||||
|
||||
if (saved) {
|
||||
console.log(`✓ Location saved: ${device} at (${payload.lat}, ${payload.lon})`);
|
||||
|
||||
// Geofence-Check asynchron ausführen (nicht blockieren)
|
||||
setImmediate(async () => {
|
||||
try {
|
||||
const events = await checkGeofences(saved, device, geofenceDb);
|
||||
|
||||
if (events.length > 0) {
|
||||
console.log(`[Geofence] Detected ${events.length} event(s) for device ${device}`);
|
||||
|
||||
// Events in Datenbank speichern
|
||||
const savedEvents = events.map((eventData) =>
|
||||
geofenceDb.createEvent(eventData)
|
||||
);
|
||||
|
||||
// Benachrichtigungen versenden (asynchron)
|
||||
await sendGeofenceNotifications(savedEvents);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Geofence] Check failed:', error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(`⚠ Duplicate location ignored: ${device}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user