Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 43 additions & 15 deletions src/controllers/notificationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,69 @@ import { Request, Response } from "express";
import * as notificationService from '../services/notification.service';
import logger from "../config/loggingConfig";

export const createNotification = async (req: Request, res: Response) => {
export const getNotifications = async (req: Request, res: Response) => {
const authUser = req.currentUser;

// Check if authUser is defined
if (!authUser) {
logger.warn('No authenticated user found when trying to create notification.');
return res.status(401).json({ error: 'Unauthorized' });
}
const { reason } = req.body;
try {
const notification = await notificationService.addNotification(authUser?.pi_uid, reason);
return res.status(200).json({ message: "Notification created successfully", notification });
} catch (error) {
logger.error('Failed to create notification', error);
return res.status(500).json({ message: 'An error occurred while creating notification; please try again later' });
}
};

export const getNotifications = async (req: Request, res: Response) => {
const { pi_uid } = req.params;
const skip = req.query.skip ? Number(req.query.skip) : 0;
const limit = req.query.limit ? Number(req.query.limit) : 20;

const status = ['cleared', 'uncleared'].includes(req.query.status as string)
? (req.query.status as 'cleared' | 'uncleared') : undefined;

try {
const notifications = await notificationService.getNotifications(pi_uid, skip, limit, status);
const notifications = await notificationService.getNotifications(authUser.pi_uid, skip, limit, status);
return res.status(200).json(notifications);
} catch (error) {
logger.error('Failed to get notifications', error);
return res.status(500).json({ message: 'An error occurred while getting notifications; please try again later' });
}
};

export const getNotificationsCount = async (req: Request, res: Response) => {
try {
const authUser = req.currentUser;

if (!authUser) {
logger.warn('No authenticated user found when trying to get notification count.');
return res.status(401).json({ error: 'Unauthorized' });
}

const status = req.query.status as 'cleared'| 'uncleared' | undefined;

const count = await notificationService.countNotifications({
pi_uid: authUser.pi_uid,
status,
});

return res.status(200).json({ count });
} catch (error) {
logger.error('Failed to count notifications', error);
return res.status(500).json({ message: 'An error occurred while counting notifications; please try again later' });
}
};

export const createNotification = async (req: Request, res: Response) => {
const authUser = req.currentUser;

// Check if authUser is defined
if (!authUser) {
logger.warn('No authenticated user found when trying to create notification.');
return res.status(401).json({ error: 'Unauthorized' });
}
const { reason } = req.body;
try {
const notification = await notificationService.addNotification(authUser?.pi_uid, reason);
return res.status(200).json({ message: "Notification created successfully", notification });
} catch (error) {
logger.error('Failed to create notification', error);
return res.status(500).json({ message: 'An error occurred while creating notification; please try again later' });
}
};

export const updateNotification = async (req: Request, res: Response) => {
const { notification_id } = req.params;
try {
Expand Down
6 changes: 3 additions & 3 deletions src/models/misc/Toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ const toggleSchema = new Schema<IToggle>(
},
},
{
timestamps: true, // Automatically creates createdAt and updatedAt
timestamps: true, // Creates createdAt and updatedAt
toJSON: {
transform: function (doc, ret) {
delete ret._id;
delete ret.__v;
delete (ret as any)._id;
delete (ret as any).__v;
return ret;
}
}
Expand Down
79 changes: 56 additions & 23 deletions src/routes/notification.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,44 +69,77 @@ const notificationRoutes = Router();
* 500:
* description: Internal server error
*/
notificationRoutes.get("/:pi_uid", notificationController.getNotifications);
notificationRoutes.get("/", verifyToken, notificationController.getNotifications);

/**
* @swagger
* /api/v1/notifications/:
* post:
* tags:
* - Notification
* summary: Create a new notification *
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* reason:
* type: string
* example: This is a sample reason for notification.
* responses:
* 200:
* description: Successful response
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: Notification created successfully
* notification:
* $ref: '/api/docs/NotificationsSchema.yml#/components/schemas/Notification'
* 401:
* description: Unauthorized
* 500:
* description: Internal server error
*/
notificationRoutes.post("/", verifyToken, notificationController.createNotification);

/**
* @swagger
* /api/v1/notifications/:
* post:
* tags:
* - Notification
* summary: Create a new notification *
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* reason:
* type: string
* example: This is a sample reason for notification.
* /api/v1/notifications/count:
* get:
* tags:
* - Notification
* summary: Get the count of notifications filtered by status (cleared or uncleared)
* parameters:
* - in: query
* name: status
* schema:
* type: string
* enum: [cleared, uncleared]
* required: false
* description: Filter notifications by status
* responses:
* 200:
* description: Successful response
* description: Successful response with notification count
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: Notification created successfully
* notification:
* $ref: '/api/docs/NotificationsSchema.yml#/components/schemas/Notification'
* count:
* type: integer
* example: 5
* 401:
* description: Unauthorized
* 500:
* description: Internal server error
*/
notificationRoutes.post("/", verifyToken, notificationController.createNotification);
notificationRoutes.get("/count", verifyToken, notificationController.getNotificationsCount);

/**
* @swagger
Expand Down
21 changes: 21 additions & 0 deletions src/services/notification.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,25 @@ export const toggleNotificationStatus = async (notification_id: string): Promise
logger.error(`Failed to toggle notification status for ID ${ notification_id }: ${error.message}`);
throw error;
}
};

export const countNotifications = async ({
pi_uid,
status,
}: {
pi_uid: string;
status?: 'cleared' | 'uncleared';
}): Promise<number> => {
try {
const query: any = { pi_uid };

if (status === 'cleared') query.is_cleared = true;
if (status === 'uncleared') query.is_cleared = false;

const count = await Notification.countDocuments(query);
return count;
} catch (error: any) {
logger.error(`Failed to count notifications for piUID ${pi_uid}: ${error.message}`);
throw error;
}
};
2 changes: 1 addition & 1 deletion test/controllers/notificationController.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('notificationController', () => {
describe('getNotifications function', () => {
beforeEach(() => {
req = {
params: {
currentUser: {
pi_uid: '0a0a0a-0a0a-0a0a',
},
query : {
Expand Down