diff --git a/src/controllers/jobAnalytics/applicationTimeController.js b/src/controllers/jobAnalytics/applicationTimeController.js new file mode 100644 index 0000000000..c2d5b5cfe7 --- /dev/null +++ b/src/controllers/jobAnalytics/applicationTimeController.js @@ -0,0 +1,48 @@ +const ApplicationTimeModel = require('../../models/jobAnalytics/applicationTime'); + +const applicationTimeController = function () { + const getApplicationTimes = async (req, res) => { + try { + const { startDate, roles } = req.query; + + const query = {}; + + // add startDate to query + if (startDate) query.createdAt = { $gte: new Date(startDate) }; + + // add roles to query + if (roles) { + const roleList = roles.split(',').map((role) => role.trim()); + if (roleList.length > 0) query.role = { $in: roleList }; + } + + const applicationTimes = await ApplicationTimeModel.find(query); + + return res.status(200).json({ + data: applicationTimes, + count: applicationTimes.length, + }); + } catch (error) { + res.status(400).json({ error: 'failed to fetch application times. Please try again later.' }); + } + }; + + const getUniqueRoles = async (req, res) => { + try { + const uniqueRoles = await ApplicationTimeModel.distinct('role'); + return res.status(200).json({ + data: uniqueRoles, + count: uniqueRoles.length, + }); + } catch (error) { + res.status(400).json({ error: 'failed to fetch roles. Please try again later.' }); + } + }; + + return { + getApplicationTimes, + getUniqueRoles, + }; +}; + +module.exports = applicationTimeController; diff --git a/src/models/jobAnalytics/applicationTime.js b/src/models/jobAnalytics/applicationTime.js new file mode 100644 index 0000000000..45f717f294 --- /dev/null +++ b/src/models/jobAnalytics/applicationTime.js @@ -0,0 +1,60 @@ +const mongoose = require('mongoose'); + +const applicationTimeSchema = new mongoose.Schema( + { + location: { + country: { + type: String, + required: true, + }, + state: { + type: String, + required: true, + }, + }, + deviceType: { + type: String, + required: true, + }, + isOutlier: { + type: Boolean, + default: false, + }, + role: { + type: String, + required: true, + }, + userId: { + type: String, + required: true, + }, + jobId: { + type: String, + required: true, + }, + jobTitle: { + type: String, + required: true, + }, + clickedAt: { + type: Date, + }, + appliedAt: { + type: Date, + }, + timeTaken: { + type: Number, + }, + sessionId: { + type: String, + required: true, + }, + }, + { + timestamps: true, + }, +); + +const ApplicationTimeModel = mongoose.model('ApplicationTime', applicationTimeSchema); + +module.exports = ApplicationTimeModel; diff --git a/src/routes/jobAnalytics/applicationTimeRoutes.js b/src/routes/jobAnalytics/applicationTimeRoutes.js new file mode 100644 index 0000000000..944b289b87 --- /dev/null +++ b/src/routes/jobAnalytics/applicationTimeRoutes.js @@ -0,0 +1,10 @@ +const express = require('express'); +const applicationTimeController = + require('../../controllers/jobAnalytics/applicationTimeController')(); + +const router = express.Router(); + +router.route('/application-time').get(applicationTimeController.getApplicationTimes); +router.route('/application-time/roles').get(applicationTimeController.getUniqueRoles); + +module.exports = router; diff --git a/src/startup/routes.js b/src/startup/routes.js index 4cd7383c86..095b1bf151 100644 --- a/src/startup/routes.js +++ b/src/startup/routes.js @@ -225,6 +225,7 @@ const weeklySummariesFilterRouter = require('../routes/weeklySummariesFilterRout const jobAnalyticsRoutes = require('../routes/jobAnalytics'); const materialCostRouter = require('../routes/materialCostRouter')(); +const applicationTimeRoutes = require('../routes/jobAnalytics/applicationTimeRoutes'); // bm dashboard const bmLoginRouter = require('../routes/bmdashboard/bmLoginRouter')(); @@ -546,6 +547,7 @@ module.exports = function (app) { app.use('/api', taskCommentRouter); app.use('/api/popularity-enhanced', popularityEnhancedRoutes); app.use('/api', jobHitsAndApplicationsRoutes); + app.use('/api/analytics', applicationTimeRoutes); // bm dashboard app.use('/api/bm', bmLoginRouter);