Location Tracking: - POST /api/location/update — driver GPS update - GET /api/location/:load_id — get driver location for load - Migration 007: vehicle_locations table with spatial indexes Bulk WhatsApp Parser: - UI for pasting multiple messages at once - Batch parse via /api/parse-whatsapp - Review parsed results with confidence scores - Select and save all valid loads to database - One-click import from WhatsApp to loads Deployment: - DEPLOYMENT.md: full deployment guide - Environment configuration - Docker + Docker Compose setup - Coolify deployment steps - Post-deployment checklist - Troubleshooting guide - Architecture diagram
68 lines
2 KiB
JavaScript
68 lines
2 KiB
JavaScript
// POST /api/location/update — driver updates their GPS location
|
|
// GET /api/location/:load_id — get driver location for a load (shipper views this)
|
|
|
|
const express = require('express');
|
|
const router = express.Router();
|
|
const supabase = require('../services/supabase');
|
|
const { asyncHandler } = require('../middleware/security');
|
|
|
|
function requirePortalAuth(req, res, next) {
|
|
if (!req.session.portalUser) {
|
|
return res.status(401).json({ error: 'Authentication required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
// POST /api/location/update
|
|
router.post('/update', requirePortalAuth, asyncHandler(async (req, res) => {
|
|
const { lat, lng, accuracy, heading, speed } = req.body;
|
|
const driverId = req.session.portalUser?.driver_id;
|
|
|
|
if (!lat || !lng) {
|
|
return res.status(400).json({ error: 'lat and lng are required' });
|
|
}
|
|
|
|
if (!driverId) {
|
|
return res.status(400).json({ error: 'Driver profile not found' });
|
|
}
|
|
|
|
await supabase.from('vehicles').update({
|
|
current_lat: parseFloat(lat),
|
|
current_lng: parseFloat(lng),
|
|
updated_at: new Date().toISOString(),
|
|
}).eq('id', driverId);
|
|
|
|
// Also store in location history
|
|
await supabase.from('vehicle_locations').insert({
|
|
vehicle_id: driverId,
|
|
lat: parseFloat(lat),
|
|
lng: parseFloat(lng),
|
|
accuracy: accuracy || null,
|
|
heading: heading || null,
|
|
speed: speed || null,
|
|
});
|
|
|
|
res.json({ success: true });
|
|
}));
|
|
|
|
// GET /api/location/:load_id — get assigned driver's location
|
|
router.get('/:load_id', requirePortalAuth, asyncHandler(async (req, res) => {
|
|
const { data: load } = await supabase
|
|
.from('loads')
|
|
.select('accepted_bid_id, vehicles(current_lat, current_lng, driver_name, updated_at)')
|
|
.eq('id', req.params.load_id)
|
|
.single();
|
|
|
|
if (!load?.vehicles) {
|
|
return res.json({ error: 'No driver assigned or location not available' });
|
|
}
|
|
|
|
res.json({
|
|
driver_name: load.vehicles.driver_name,
|
|
lat: load.vehicles.current_lat,
|
|
lng: load.vehicles.current_lng,
|
|
last_updated: load.vehicles.updated_at,
|
|
});
|
|
}));
|
|
|
|
module.exports = router;
|