From 9b24704f761d4a11c257baa80c90d7b0cf1cb5b9 Mon Sep 17 00:00:00 2001 From: Josepablo C Date: Fri, 9 Aug 2024 21:16:24 -0600 Subject: [PATCH] feat: Adding notifications endpoint --- scripts/playground.mongodb.js | 14 +++++ v1/README.md | 9 +++ v1/src/apps/private/index.js | 2 + v1/src/apps/private/notifications/routes.js | 9 +++ v1/src/apps/private/notifications/services.js | 57 +++++++++++++++++++ v1/src/apps/private/proposals/services.js | 4 +- v1/src/lib/Handlers/Proposals.handler.js | 29 +++++++++- v1/src/lib/Models/index.js | 3 + v1/src/lib/Models/notifications.model.js | 13 +++++ 9 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 scripts/playground.mongodb.js create mode 100644 v1/src/apps/private/notifications/routes.js create mode 100644 v1/src/apps/private/notifications/services.js create mode 100644 v1/src/lib/Models/notifications.model.js diff --git a/scripts/playground.mongodb.js b/scripts/playground.mongodb.js new file mode 100644 index 0000000..92ae89b --- /dev/null +++ b/scripts/playground.mongodb.js @@ -0,0 +1,14 @@ +// MongoDB Playground +// Use Ctrl+Space inside a snippet or a string literal to trigger completions. + +// The current database to use. +use('enrutaviaporte'); + +// Create a new document in the collection. +db.getCollection('notifications').insertOne({ + "owner" : ObjectId("65eeadb8ed616b897ca4c4cd"), + "title":"Notification title", + "description":"Notification description", + "tag":"category", + "deleted":false +}); diff --git a/v1/README.md b/v1/README.md index f57df7d..d7b9d11 100644 --- a/v1/README.md +++ b/v1/README.md @@ -391,6 +391,15 @@ This endpoint is part of /loads endpoint - `GET /loads/find?$sort[createdAt]=-1&load_status=Loading`: Get loads with status "Loading" sorted by createdAt. +### /notifications + + - `GET /` : Get list of latest notifications: + - `DELETE /:id` : Delete a single notification. + + In order to delete a list of notifications use the following query: + + `DELETE ?list[0]=66b6d50ce91a3a5b96686863&list[1]=66b6d50ce91a3a5b96686863&list[2]=66b6d50cf193e37bb1dd913d` + ### /proposals - `GET /find` : Find a list of elements with any of the following fields: diff --git a/v1/src/apps/private/index.js b/v1/src/apps/private/index.js index f81781f..4e26bf9 100644 --- a/v1/src/apps/private/index.js +++ b/v1/src/apps/private/index.js @@ -15,6 +15,7 @@ const loads = require('./loads/routes.js'); const proposals = require('./proposals/routes.js'); const users = require('./users/routes.js'); const vehicles = require('./vehicles/routes.js'); +const notifications = require('./notifications/routes.js'); router.use( jwtValidator.middleware ); router.use( context.middleware ); @@ -25,6 +26,7 @@ router.use('/branches', branches); router.use('/companies', companies); router.use('/load-attachments', loadAttachments ); router.use('/loads', loads); +router.use('/notifications', notifications); router.use('/proposals', proposals); router.use('/users', users); router.use('/vehicles', vehicles); diff --git a/v1/src/apps/private/notifications/routes.js b/v1/src/apps/private/notifications/routes.js new file mode 100644 index 0000000..07bc8f4 --- /dev/null +++ b/v1/src/apps/private/notifications/routes.js @@ -0,0 +1,9 @@ +'use strict'; +const router = require('express').Router(); +const services= require('./services.js'); + +router.get('/', services.getNotifications ); +router.delete('/', services.deleteNotifications ); +router.delete('/:id', services.deleteById ); + +module.exports = router; diff --git a/v1/src/apps/private/notifications/services.js b/v1/src/apps/private/notifications/services.js new file mode 100644 index 0000000..e81eeeb --- /dev/null +++ b/v1/src/apps/private/notifications/services.js @@ -0,0 +1,57 @@ +"use strict"; + +const Notifications = require( '../../../lib/Models/notifications.model' ); + +async function getNotifications(req, res, next) { + try{ + const userId = req.context.userId; + const list = await Notifications.find( { + owner : userId, + deleted : false + } ); + return res.send( list ); + }catch(error){ + console.error( error ); + return res.status( 500 ).send({ error }); + } +} + +async function deleteNotifications(req, res, next) { + try{ + const userId = req.context.userId; + const { list } = req.query; + + const ret = await Notifications.deleteMany({ + _id : list, + owner: userId + }); + + return res.send( { + msg : "Done" + } ); + }catch(error){ + console.error( error ); + return res.status( 500 ).send({ error }); + } +} + +async function deleteById(req, res, next) { + try{ + const userId = req.context.userId; + const notificationId = req.params.id; + + const ret = await Notifications.deleteOne( { + _id : notificationId, + owner: userId + } ); + + return res.send( { + msg : "Done" + } ); + }catch(error){ + console.error( error ); + return res.status( 500 ).send({ error }); + } +} + +module.exports = { getNotifications, deleteNotifications, deleteById }; diff --git a/v1/src/apps/private/proposals/services.js b/v1/src/apps/private/proposals/services.js index c8f500d..89fbfa3 100644 --- a/v1/src/apps/private/proposals/services.js +++ b/v1/src/apps/private/proposals/services.js @@ -3,7 +3,7 @@ const { getModel } = require( '../../../lib/Models' ); const { getPagination } = require( '../../../lib/Misc' ); const { GenericHandler } = require( '../../../lib/Handlers/Generic.handler' ); -const { onPatchEvent } = require('../../../lib/Handlers/Proposals.handler'); +const { onPostEvent, onPatchEvent } = require('../../../lib/Handlers/Proposals.handler'); const Model = getModel('proposals'); const populate_list = [ @@ -118,6 +118,8 @@ const postProposal = async(req, res) => { } const proposal = new Model( data ); await proposal.save(); + + await onPostEvent(proposal.id, data); return res.send( proposal ); }catch(error){ console.error( error ); diff --git a/v1/src/lib/Handlers/Proposals.handler.js b/v1/src/lib/Handlers/Proposals.handler.js index a8bfc44..169034b 100644 --- a/v1/src/lib/Handlers/Proposals.handler.js +++ b/v1/src/lib/Handlers/Proposals.handler.js @@ -6,9 +6,34 @@ const proposalsModel = getModel('proposals'); const loadsModel = getModel('loads'); const usersModel = getModel('users'); const companiesModel = getModel('companies'); +const notificationsModel = getModel('notifications'); + /** - * When the proposal is accepted then the load should be updated to have the + * When the proposal is created then the load owner should be notified + * @param {*} id + * @param {*} newProposalData + * @returns + */ +async function onPostEvent( id , newProposalData ){ + const proposal = await proposalsModel.findById( id ); + const load = await loadsModel.findById( proposal.load ); + const user = await usersModel.findById( load.posted_by ); + + const notification = new notificationsModel({ + "owner": user.id, + "title": "New proposal", + "description": `Your load ${load.shipment_code} has a new proposal!`, + "tag":"new_proposal", + "deleted":false + }); + + await notification.save(); +} + +/** + * When the proposal is accepted then the load should be updated to have the latest + * shipper, vehicle, etc. * @param {*} id * @param {*} newProposalData * @returns @@ -49,4 +74,4 @@ async function onPatchEvent( id , newProposalData ){ } } -module.exports = { onPatchEvent }; +module.exports = { onPostEvent, onPatchEvent }; diff --git a/v1/src/lib/Models/index.js b/v1/src/lib/Models/index.js index b4de87c..9b9df07 100644 --- a/v1/src/lib/Models/index.js +++ b/v1/src/lib/Models/index.js @@ -11,6 +11,7 @@ const mailer = require('./mailer.model.js'); const memberships = require('./memberships.model.js'); const meta_data = require('./meta-data.model.js'); const meta_groups = require('./meta-groups.model.js'); +const notifications = require('./notifications.model.js'); const news = require('./news.model.js'); const orders = require('./orders.model.js'); const product_categories = require('./product-categories.model.js'); @@ -47,6 +48,8 @@ function getModel( name ){ return meta_groups; case 'news': return news; + case 'notifications': + return notifications; case 'orders': return orders; case 'product_categories': diff --git a/v1/src/lib/Models/notifications.model.js b/v1/src/lib/Models/notifications.model.js new file mode 100644 index 0000000..21b2d04 --- /dev/null +++ b/v1/src/lib/Models/notifications.model.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); +const { Schema } = mongoose; + +const schema = new Schema({ + owner: { type: Schema.Types.ObjectId, ref: 'users' }, + title: { type: String, required : true }, + description: { type: String, required : true }, + tag: { type: String, require, required : true }, + createdAt: { type : Date, required : true, default : () => { return Date.now(); } }, + deleted: { type: Boolean, default: false, required : true } +}); + +module.exports = mongoose.model( "notifications", schema );