Re_Backend/src/controllers/notification.controller.ts

216 lines
6.0 KiB
TypeScript

import { Request, Response } from 'express';
import mongoose from 'mongoose';
import { NotificationModel as Notification } from '../models/mongoose/Notification.schema';
import logger from '../utils/logger';
import { notificationMongoService as notificationService } from '../services/notification.service';
export class NotificationController {
/**
* Get user's notifications with pagination
*/
async getUserNotifications(req: Request, res: Response): Promise<void> {
try {
const userId = (req as any).user?.userId;
const { page = 1, limit = 20, unreadOnly = false } = req.query;
if (!userId) {
res.status(401).json({ success: false, message: 'Unauthorized' });
return;
}
const where: any = { userId };
if (unreadOnly === 'true') {
where.isRead = false;
}
const offset = (Number(page) - 1) * Number(limit);
const rows = await Notification.find(where)
.sort({ createdAt: -1 })
.limit(Number(limit))
.skip(offset);
const count = await Notification.countDocuments(where);
res.json({
success: true,
data: {
notifications: rows,
pagination: {
page: Number(page),
limit: Number(limit),
total: count,
totalPages: Math.ceil(count / Number(limit))
},
unreadCount: unreadOnly === 'true' ? count : await Notification.countDocuments({ userId, isRead: false })
}
});
} catch (error: any) {
logger.error('[Notification Controller] Error fetching notifications:', error);
res.status(500).json({ success: false, message: error.message });
}
}
/**
* Get unread notification count
*/
async getUnreadCount(req: Request, res: Response): Promise<void> {
try {
const userId = (req as any).user?.userId;
if (!userId) {
res.status(401).json({ success: false, message: 'Unauthorized' });
return;
}
const count = await Notification.countDocuments({
userId, isRead: false
});
res.json({
success: true,
data: { unreadCount: count }
});
} catch (error: any) {
logger.error('[Notification Controller] Error fetching unread count:', error);
res.status(500).json({ success: false, message: error.message });
}
}
/**
* Mark notification as read
*/
async markAsRead(req: Request, res: Response): Promise<void> {
try {
const userId = (req as any).user?.userId;
const { notificationId } = req.params;
if (!userId) {
res.status(401).json({ success: false, message: 'Unauthorized' });
return;
}
if (!mongoose.Types.ObjectId.isValid(notificationId)) {
res.status(400).json({ success: false, message: 'Invalid notification ID' });
return;
}
const notification = await Notification.findOne({
_id: notificationId, userId
});
if (!notification) {
res.status(404).json({ success: false, message: 'Notification not found' });
return;
}
notification.isRead = true;
notification.metadata = notification.metadata || {};
notification.metadata.readAt = new Date();
await notification.save();
res.json({
success: true,
message: 'Notification marked as read',
data: { notification }
});
} catch (error: any) {
logger.error('[Notification Controller] Error marking notification as read:', error);
res.status(500).json({ success: false, message: error.message });
}
}
/**
* Mark all notifications as read
*/
async markAllAsRead(req: Request, res: Response): Promise<void> {
try {
const userId = (req as any).user?.userId;
if (!userId) {
res.status(401).json({ success: false, message: 'Unauthorized' });
return;
}
await Notification.updateMany(
{ userId, isRead: false },
{ $set: { isRead: true } }
);
res.json({
success: true,
message: 'All notifications marked as read'
});
} catch (error: any) {
logger.error('[Notification Controller] Error marking all as read:', error);
res.status(500).json({ success: false, message: error.message });
}
}
/**
* Delete notification
*/
async deleteNotification(req: Request, res: Response): Promise<void> {
try {
const userId = (req as any).user?.userId;
const { notificationId } = req.params;
if (!userId) {
res.status(401).json({ success: false, message: 'Unauthorized' });
return;
}
if (!mongoose.Types.ObjectId.isValid(notificationId)) {
res.status(400).json({ success: false, message: 'Invalid notification ID' });
return;
}
const result = await Notification.deleteOne({
_id: notificationId, userId
});
const deleted = result.deletedCount;
if (deleted === 0) {
res.status(404).json({ success: false, message: 'Notification not found' });
return;
}
res.json({
success: true,
message: 'Notification deleted'
});
} catch (error: any) {
logger.error('[Notification Controller] Error deleting notification:', error);
res.status(500).json({ success: false, message: error.message });
}
}
/**
* Get user's push notification subscriptions
*/
async getUserSubscriptions(req: Request, res: Response): Promise<void> {
try {
const userId = (req as any).user?.userId;
if (!userId) {
res.status(401).json({ success: false, message: 'Unauthorized' });
return;
}
const subscriptions = await notificationService.getUserSubscriptions(userId);
res.json({
success: true,
data: {
subscriptions,
count: subscriptions.length
}
});
} catch (error: any) {
logger.error('[Notification Controller] Error fetching subscriptions:', error);
res.status(500).json({ success: false, message: error.message });
}
}
}