Skip to content

Commit 73bb0f1

Browse files
committed
feat: adjusted for frontend visualisation
1 parent a75816e commit 73bb0f1

1 file changed

Lines changed: 23 additions & 27 deletions

File tree

src/routes/popularityEnhancedRoutes.js

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ const router = express.Router();
44
const PopularityEnhanced = require('../models/popularityEnhanced');
55
const EnhancedPopularityCache = require('../utilities/popularityEnhancedCache');
66

7-
/**
8-
* Enhanced Popularity Timeline Routes
9-
*/
7+
/** * Enhanced Popularity Timeline Routes */
108

119
// GET: Enhanced popularity timeline with role-based grouping
1210
router.get('/timeline', async (req, res) => {
1311
try {
14-
// Setting default for groupByRole to 'true' as this is the enhanced endpoint
1512
const { range, roles, start, end, groupByRole = 'true', includeLowVolume = 'true' } = req.query;
1613

17-
const cacheKey = `enhanced_timeline_${JSON.stringify({ range, roles, start, end, groupByRole, includeLowVolume })}`;
18-
14+
const cacheKey = `v2_enhanced_timeline_${JSON.stringify({ range, roles, start, end, groupByRole, includeLowVolume })}`;
1915
const cachedData = EnhancedPopularityCache.get(cacheKey);
2016
if (cachedData) {
2117
return res.json({
@@ -26,24 +22,23 @@ router.get('/timeline', async (req, res) => {
2622
});
2723
}
2824

29-
const match = { isActive: true }; // Enhanced role filtering with partial matching
25+
const match = { isActive: true };
3026

3127
if (roles && roles !== 'All Roles' && roles !== '["All Roles"]') {
3228
let parsedRoles;
3329
try {
34-
// Handle both JSON array and comma-separated string
3530
parsedRoles = JSON.parse(roles);
3631
} catch {
3732
parsedRoles = roles.split(',').map((r) => r.trim().replace(/"/g, ''));
3833
}
3934

4035
if (parsedRoles.length > 0 && !parsedRoles.includes('All Roles')) {
41-
// Create regex patterns for partial matching
4236
const rolePatterns = parsedRoles.map((role) => new RegExp(role, 'i'));
4337
match.role = { $in: rolePatterns };
4438
}
45-
} // Enhanced date range handling
39+
}
4640

41+
// Date range handling
4742
if (start && end) {
4843
const [startYear, startMonth] = start.split('-').map(Number);
4944
const [endYear, endMonth] = end.split('-').map(Number);
@@ -53,23 +48,26 @@ router.get('/timeline', async (req, res) => {
5348

5449
match.timestamp = { $gte: startDate, $lte: endDate };
5550
} else if (range) {
56-
const months = parseInt(range, 10) || 12;
51+
const months = parseInt(range, 10) || 6;
5752

58-
if (months <= 6) {
59-
const availableMonths = ['2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06'];
60-
const recentMonths = availableMonths.slice(-months);
61-
match.month = { $in: recentMonths };
62-
}
53+
// Dynamic date calculation relative to current date
54+
const startDate = new Date();
55+
// Subtract (months - 1) to include the current month in the count
56+
startDate.setMonth(startDate.getMonth() - (months - 1));
57+
58+
// Reset to first day of month to be inclusive
59+
startDate.setDate(1);
60+
startDate.setHours(0, 0, 0, 0);
61+
62+
match.timestamp = { $gte: startDate };
6363
}
6464

6565
if (includeLowVolume === 'false') {
6666
match.hitsCount = { $gte: 10 };
6767
}
6868

69-
let result; // We always run the role-based aggregation as this is the enhanced endpoint
70-
69+
let result;
7170
if (groupByRole === 'true') {
72-
// Role-based aggregation for timeline data (Supports the UX requirement for multiple lines)
7371
result = await PopularityEnhanced.aggregate([
7472
{ $match: match },
7573
{
@@ -140,7 +138,7 @@ router.get('/timeline', async (req, res) => {
140138
},
141139
},
142140
{ $sort: { 'summary.popularityScore': -1 } },
143-
]); // Sort each role's data by timestamp for correct line plotting order
141+
]);
144142

145143
result.forEach((roleGroup) => {
146144
roleGroup.data.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
@@ -150,7 +148,7 @@ router.get('/timeline', async (req, res) => {
150148
success: false,
151149
error: 'This endpoint only supports role-grouped aggregation (groupByRole=true)',
152150
});
153-
} // Cache the result
151+
}
154152

155153
EnhancedPopularityCache.set(cacheKey, result);
156154

@@ -183,7 +181,7 @@ router.get('/role-pairs', async (req, res) => {
183181
});
184182
}
185183

186-
const cacheKey = `role_pairs_${roles}_${start}_${end}`;
184+
const cacheKey = `v2_role_pairs_${roles}_${start}_${end}`;
187185
const cachedData = EnhancedPopularityCache.get(cacheKey);
188186
if (cachedData) return res.json({ success: true, data: cachedData, cached: true });
189187

@@ -199,7 +197,7 @@ router.get('/role-pairs', async (req, res) => {
199197
const match = {
200198
role: { $in: rolePatterns },
201199
isActive: true,
202-
}; // Date filtering
200+
};
203201

204202
if (start && end) {
205203
const [startYear, startMonth] = start.split('-').map(Number);
@@ -228,8 +226,8 @@ router.get('/role-pairs', async (req, res) => {
228226
roles: {
229227
$push: {
230228
role: '$_id.role',
231-
hitsCount: '$hitsCount',
232-
applicationsCount: '$applicationsCount',
229+
hitsCount: { $sum: '$hitsCount' },
230+
applicationsCount: { $sum: '$applicationsCount' },
233231
pairId: { $concat: ['$_id.role', '_', '$_id.month'] },
234232
},
235233
},
@@ -341,7 +339,6 @@ router.get('/roles-enhanced', async (req, res) => {
341339
popularityScore: 0,
342340
activityLevel: 'All',
343341
};
344-
345342
if (allRolesSummary.totalHits > 0) {
346343
allRolesSummary.conversionRate =
347344
allRolesSummary.totalApplications / allRolesSummary.totalHits;
@@ -352,7 +349,6 @@ router.get('/roles-enhanced', async (req, res) => {
352349
const enhancedRoles = [allRolesSummary, ...roles];
353350

354351
EnhancedPopularityCache.set(cacheKey, enhancedRoles, 15 * 60 * 1000); // 15 minutes
355-
356352
res.json({
357353
success: true,
358354
data: enhancedRoles,

0 commit comments

Comments
 (0)