File size: 4,387 Bytes
9a92a42 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | import LocationHistory from "../model/locationHistory.model";
import User from "../model/user.model";
import { Request, Response } from "express";
// Helper to get current date in YYYY-MM-DD format
const getTodayDateString = (): string => {
const now = new Date();
return now.toISOString().split('T')[0];
};
// GET /location/users/latest
export const getAllUsersLatest = async (req: Request, res: Response) => {
try {
const users = await User.find({ isActive: true }).select('location lastActive username profilePhoto role');
return res.json(users.filter(u => u.location && u.location.coordinates && u.location.coordinates.length === 2));
} catch (err) {
console.error(err);
return res.status(500).json({ message: 'Server error' });
}
};
export const updateLocation = async (req: Request, res: Response) => {
try {
const userId = req.userId;
const { longitude, latitude } = req.body;
if (!longitude || !latitude) {
return res.status(400).json({ message: "Location missing" });
}
const today = getTodayDateString();
const coordinates: [number, number] = [longitude, latitude];
// 1) Update latest location in User model
await User.findByIdAndUpdate(userId, {
location: {
type: "Point",
coordinates
},
lastActive: new Date()
});
// 2) Upsert location history for today
await LocationHistory.findOneAndUpdate(
{ user: userId, date: today },
{
$push: {
locations: {
coordinates,
timestamp: new Date()
}
},
$set: {
lastLocation: {
type: "Point",
coordinates
}
}
},
{ upsert: true, new: true }
);
return res.json({ message: "Location updated" });
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Server error" });
}
};
// Get user's location history for a specific date
export const getLocationHistory = async (req: Request, res: Response) => {
try {
const userId = req.userId;
const { date } = req.query; // Expected format: YYYY-MM-DD
if (!date || typeof date !== 'string') {
return res.status(400).json({ message: "Date required (YYYY-MM-DD)" });
}
const history = await LocationHistory.findOne({ user: userId, date });
if (!history) {
return res.status(404).json({ message: "No location data for this date" });
}
return res.json({
date: history.date,
locations: history.locations,
totalPoints: history.locations.length
});
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Server error" });
}
};
// Get user's location history for a date range
export const getLocationHistoryRange = async (req: Request, res: Response) => {
try {
const userId = req.userId;
const { startDate, endDate } = req.query;
if (!startDate || !endDate || typeof startDate !== 'string' || typeof endDate !== 'string') {
return res.status(400).json({ message: "startDate and endDate required (YYYY-MM-DD)" });
}
const history = await LocationHistory.find({
user: userId,
date: { $gte: startDate, $lte: endDate }
}).sort({ date: 1 });
return res.json({
days: history.length,
history: history.map(h => ({
date: h.date,
locationCount: h.locations.length,
lastLocation: h.lastLocation
}))
});
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Server error" });
}
};
// Get nearby users based on their last known location
export const getNearbyUsers = async (req: Request, res: Response) => {
try {
const userId = req.userId;
const { maxDistance = 5000 } = req.query; // default 5km
const user = await User.findById(userId);
if (!user?.location) {
return res.status(400).json({ message: "User location not set" });
}
const nearbyUsers = await User.find({
_id: { $ne: userId },
location: {
$near: {
$geometry: user.location,
$maxDistance: Number(maxDistance)
}
}
}).limit(20).select('username profilePhoto location role');
return res.json({ nearbyUsers });
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Server error" });
}
}; |