Item request notifications
This commit is contained in:
@@ -5,6 +5,8 @@ const { authenticateToken, requireAdmin, optionalAuth } = require('../middleware
|
||||
const { uploadForumPostImages, uploadForumCommentImages } = require('../middleware/upload');
|
||||
const logger = require('../utils/logger');
|
||||
const emailServices = require('../services/email');
|
||||
const googleMapsService = require('../services/googleMapsService');
|
||||
const locationService = require('../services/locationService');
|
||||
const router = express.Router();
|
||||
|
||||
// Helper function to build nested comment tree
|
||||
@@ -238,7 +240,7 @@ router.get('/posts/:id', optionalAuth, async (req, res) => {
|
||||
// POST /api/forum/posts - Create new post
|
||||
router.post('/posts', authenticateToken, uploadForumPostImages, async (req, res) => {
|
||||
try {
|
||||
let { title, content, category, tags } = req.body;
|
||||
let { title, content, category, tags, zipCode } = req.body;
|
||||
|
||||
// Parse tags if they come as JSON string (from FormData)
|
||||
if (typeof tags === 'string') {
|
||||
@@ -252,12 +254,42 @@ router.post('/posts', authenticateToken, uploadForumPostImages, async (req, res)
|
||||
// Extract image filenames if uploaded
|
||||
const images = req.files ? req.files.map(file => file.filename) : [];
|
||||
|
||||
// Initialize location fields
|
||||
let latitude = null;
|
||||
let longitude = null;
|
||||
|
||||
// Geocode zip code for item requests
|
||||
if (category === 'item_request' && zipCode) {
|
||||
try {
|
||||
const geocodeResult = await googleMapsService.geocodeAddress(zipCode);
|
||||
latitude = geocodeResult.latitude;
|
||||
longitude = geocodeResult.longitude;
|
||||
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.info("Geocoded zip code for item request", {
|
||||
zipCode,
|
||||
latitude,
|
||||
longitude
|
||||
});
|
||||
} catch (error) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.error("Geocoding failed for item request", {
|
||||
error: error.message,
|
||||
zipCode
|
||||
});
|
||||
// Continue without coordinates - post will still be created
|
||||
}
|
||||
}
|
||||
|
||||
const post = await ForumPost.create({
|
||||
title,
|
||||
content,
|
||||
category,
|
||||
authorId: req.user.id,
|
||||
images
|
||||
images,
|
||||
zipCode: zipCode || null,
|
||||
latitude,
|
||||
longitude
|
||||
});
|
||||
|
||||
// Create tags if provided
|
||||
@@ -295,6 +327,71 @@ router.post('/posts', authenticateToken, uploadForumPostImages, async (req, res)
|
||||
});
|
||||
|
||||
res.status(201).json(postWithDetails);
|
||||
|
||||
// Send location-based notifications for item requests (asynchronously)
|
||||
if (category === 'item_request' && latitude && longitude) {
|
||||
(async () => {
|
||||
try {
|
||||
// Find all users within maximum radius (100 miles)
|
||||
const nearbyUsers = await locationService.findUsersInRadius(
|
||||
latitude,
|
||||
longitude,
|
||||
100
|
||||
);
|
||||
|
||||
const postAuthor = await User.findByPk(req.user.id);
|
||||
|
||||
let notificationsSent = 0;
|
||||
let usersChecked = 0;
|
||||
|
||||
for (const user of nearbyUsers) {
|
||||
// Don't notify the requester
|
||||
if (user.id !== req.user.id) {
|
||||
usersChecked++;
|
||||
|
||||
// Get user's notification preference
|
||||
const userProfile = await User.findByPk(user.id, {
|
||||
attributes: ['itemRequestNotificationRadius']
|
||||
});
|
||||
|
||||
const userPreferredRadius = userProfile?.itemRequestNotificationRadius || 10;
|
||||
|
||||
// Only notify if within user's preferred radius
|
||||
if (parseFloat(user.distance) <= userPreferredRadius) {
|
||||
try {
|
||||
await emailServices.forum.sendItemRequestNotification(
|
||||
user,
|
||||
postAuthor,
|
||||
post,
|
||||
user.distance
|
||||
);
|
||||
notificationsSent++;
|
||||
} catch (emailError) {
|
||||
logger.error("Failed to send item request notification", {
|
||||
error: emailError.message,
|
||||
recipientId: user.id,
|
||||
postId: post.id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Item request notifications sent", {
|
||||
postId: post.id,
|
||||
totalNearbyUsers: nearbyUsers.length,
|
||||
usersChecked,
|
||||
notificationsSent
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("Failed to process item request notifications", {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
postId: post.id
|
||||
});
|
||||
}
|
||||
})();
|
||||
}
|
||||
} catch (error) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.error("Forum post creation failed", {
|
||||
|
||||
Reference in New Issue
Block a user