diff --git a/controllers/aggregateMetric.js b/controllers/aggregateMetric.js new file mode 100644 index 0000000000000000000000000000000000000000..24711e0dde1c8e01c56a69fffadbedda298551a5 --- /dev/null +++ b/controllers/aggregateMetric.js @@ -0,0 +1,131 @@ +const pool = require("../config/db"); + +const handleGetAggregateMetrics = async (req, res) => { + try { + let { userId, startDate, endDate } = req.query; + + if (!startDate || !endDate) { + let now = new Date(); + startDate = new Date(); + startDate.setDate(now.getDate() - 30); + endDate = now; + } + + startDate = new Date(startDate).toISOString(); + endDate = new Date(endDate).toISOString(); + + let query, values; + + if (userId) { + // specific user + query = ` + SELECT + email AS user, + projectId, + COUNT(*) AS totalRequests, + COALESCE(SUM(linesOfCodeSuggested), 0) AS totalSuggested, + COALESCE(SUM(linesOfCodeAccepted), 0) AS totalAccepted, + COUNT(*) FILTER (WHERE requestType = 'completion') AS completionRequests, + COALESCE(SUM(linesOfCodeSuggested) FILTER (WHERE requestType = 'completion'), 0) AS completionSuggested, + COALESCE(SUM(linesOfCodeAccepted) FILTER (WHERE requestType = 'completion'), 0) AS completionAccepted, + COUNT(*) FILTER (WHERE requestType = 'explanation') AS explanationRequests, + COUNT(*) FILTER (WHERE requestType = 'documentation') AS documentationRequests, + COUNT(*) FILTER (WHERE requestType = 'testcase') AS testcaseRequests, + COALESCE(SUM(linesOfCodeSuggested) FILTER (WHERE requestType = 'testcase'), 0) AS testcaseSuggested + FROM usage_metrics + WHERE LOWER(email) = LOWER($1) + AND created_at BETWEEN $2 AND $3 + GROUP BY email, projectId + `; + values = [userId, startDate, endDate]; + } else { + // Q overall metrics (all users) + query = ` + SELECT + COUNT(*) AS totalRequests, + COALESCE(SUM(linesOfCodeSuggested), 0) AS totalSuggested, + COALESCE(SUM(linesOfCodeAccepted), 0) AS totalAccepted, + COUNT(*) FILTER (WHERE requestType = 'completion') AS completionRequests, + COALESCE(SUM(linesOfCodeSuggested) FILTER (WHERE requestType = 'completion'), 0) AS completionSuggested, + COALESCE(SUM(linesOfCodeAccepted) FILTER (WHERE requestType = 'completion'), 0) AS completionAccepted, + COUNT(*) FILTER (WHERE requestType = 'explanation') AS explanationRequests, + COUNT(*) FILTER (WHERE requestType = 'documentation') AS documentationRequests, + COUNT(*) FILTER (WHERE requestType = 'testcase') AS testcaseRequests, + COALESCE(SUM(linesOfCodeSuggested) FILTER (WHERE requestType = 'testcase'), 0) AS testcaseSuggested + FROM usage_metrics + WHERE created_at BETWEEN $1 AND $2 + `; + values = [startDate, endDate]; + } + + console.log("Executing Query:", query, "Values:", values); + + const result = await pool.query(query, values); + + if (result.rows.length === 0) { + return res.status(200).json({}); + } + + const metrics = result.rows[0]; + + if (userId) { + // Response for a specific user + const responseData = { + user: metrics.user, + projectId: metrics.projectid || "unknown", + totalRequests: parseInt(metrics.totalrequests) || 0, + totalSuggested: parseInt(metrics.totalsuggested) || 0, + totalAccepted: parseInt(metrics.totalaccepted) || 0, + breakdown: { + completion: { + totalRequests: parseInt(metrics.completionrequests) || 0, + totalSuggested: parseInt(metrics.completionsuggested) || 0, + totalAccepted: parseInt(metrics.completionaccepted) || 0 + }, + explanation: { + totalRequests: parseInt(metrics.explanationrequests) || 0 + }, + documentation: { + totalRequests: parseInt(metrics.documentationrequests) || 0 + }, + testcase: { + totalRequests: parseInt(metrics.testcaserequests) || 0, + totalSuggested: parseInt(metrics.testcasesuggested) || 0 + } + } + }; + return res.status(200).json(responseData); + } else { + // Response for overall metrics + const responseData = { + totalRequests: parseInt(metrics.totalrequests) || 0, + totalSuggested: parseInt(metrics.totalsuggested) || 0, + totalAccepted: parseInt(metrics.totalaccepted) || 0, + breakdown: { + completion: { + totalRequests: parseInt(metrics.completionrequests) || 0, + totalSuggested: parseInt(metrics.completionsuggested) || 0, + totalAccepted: parseInt(metrics.completionaccepted) || 0 + }, + explanation: { + totalRequests: parseInt(metrics.explanationrequests) || 0 + }, + documentation: { + totalRequests: parseInt(metrics.documentationrequests) || 0 + }, + testcase: { + totalRequests: parseInt(metrics.testcaserequests) || 0, + totalSuggested: parseInt(metrics.testcasesuggested) || 0 + } + } + }; + return res.status(200).json(responseData); + } + + } catch (error) { + console.error("Error fetching aggregate metrics:", error); + res.status(500).json({ error: "Internal Server Error" }); + } +}; + +module.exports = handleGetAggregateMetrics; diff --git a/controllers/usageMetric.js b/controllers/usageMetric.js index e067a6baab88f3996ee3efd5fc9a586aec512b11..d840eeade5d3228b62726454dfafa291d3f6ccba 100644 --- a/controllers/usageMetric.js +++ b/controllers/usageMetric.js @@ -1,51 +1,80 @@ -const pool = require('../config/db'); +const pool = require("../config/db"); - -exports.getUsageMetrics = async (req, res) => { - try { - const result = await pool.query(` +const handleGetUsageMetrics = async (req, res) => { + try { + const result = await pool.query(` SELECT id, email, projectId, requestType, linesOfCodeSuggested, linesOfCodeAccepted, created_at FROM usage_metrics ORDER BY created_at DESC; `); - res.status(200).json({ - success: true, - count: result.rows.length, - data: result.rows - }); - - } catch (error) { - console.error("Error fetching usage metrics:", error); - res.status(500).json({ success: false, message: "Internal Server Error", error: error.message }); - } + res.status(200).json({ + success: true, + count: result.rows.length, + data: result.rows, + }); + } catch (error) { + console.error("Error fetching usage metrics:", error); + res.status(500).json({ + success: false, + message: "Internal Server Error", + error: error.message, + }); + } }; +const handlePostrecordUsageMetric = async (req, res) => { + try { + const { + email, + projectId, + requestType, + linesOfCodeSuggested, + linesOfCodeAccepted, + } = req.body; -exports.recordUsageMetric = async (req, res) => { - try { - const { email, projectId, requestType, linesOfCodeSuggested, linesOfCodeAccepted } = req.body; - - if (!email || !projectId || !requestType || linesOfCodeSuggested === undefined || linesOfCodeAccepted === undefined) { - return res.status(400).json({ success: false, message: "All fields are required." }); - } + if ( + !email || + !projectId || + !requestType || + linesOfCodeSuggested === undefined || + linesOfCodeAccepted === undefined + ) { + return res + .status(400) + .json({ success: false, message: "All fields are required." }); + } - const query = ` + const query = ` INSERT INTO usage_metrics (email, projectId, requestType, linesOfCodeSuggested, linesOfCodeAccepted) VALUES ($1, $2, $3, $4, $5) RETURNING id; `; - const values = [email, projectId, requestType, linesOfCodeSuggested, linesOfCodeAccepted]; + const values = [ + email, + projectId, + requestType, + linesOfCodeSuggested, + linesOfCodeAccepted, + ]; - const result = await pool.query(query, values); + const result = await pool.query(query, values); - return res.status(201).json({ - success: true, - message: "Usage metric recorded successfully.", - data: { id: result.rows[0].id } - }); + return res.status(201).json({ + success: true, + message: "Usage metric recorded successfully.", + data: { id: result.rows[0].id }, + }); + } catch (error) { + console.error("Error saving usage metric:", error); + return res.status(500).json({ + success: false, + message: "Internal Server Error", + error: error.message, + }); + } +}; - } catch (error) { - console.error("Error saving usage metric:", error); - return res.status(500).json({ success: false, message: "Internal Server Error", error: error.message }); - } +module.exports = { + handleGetUsageMetrics, + handlePostrecordUsageMetric, }; diff --git a/index.js b/index.js index 61a10dbc68a759b6eb6a878081668bc4bf76ea4e..913c567bd416c27d2602b16183b3a4e31fd78e05 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,21 @@ -const express = require('express'); -const cors = require('cors'); -require('dotenv').config(); +require("dotenv").config(); +const express = require("express"); +const cors = require("cors"); const app = express(); +//Middlewares app.use(cors()); app.use(express.json()); -const usageMetricRoutes = require('./routes/usageMetric'); -app.use('/api', usageMetricRoutes); +//Routes +const usageMetricRoutes = require("./routes/usageMetric"); +const aggregateMetricRoutes = require("./routes/aggregateMetric"); -const PORT = process.env.PORT || 5000; +app.use("/api", usageMetricRoutes, aggregateMetricRoutes); + +//Server Configuration +const PORT = process.env.PORT || 8080; app.listen(PORT, () => { - console.log(`Server is running on port ${PORT}`); + console.log(`Server is running on port ${PORT}`); }); diff --git a/routes/aggregateMetric.js b/routes/aggregateMetric.js new file mode 100644 index 0000000000000000000000000000000000000000..fb7b563798d09da82a0dbd677933bb54bebc5046 --- /dev/null +++ b/routes/aggregateMetric.js @@ -0,0 +1,7 @@ +const express = require("express"); +const handleGetAggregateMetrics = require("../controllers/aggregateMetric"); +const aggregateMetricRoute = express.Router(); + +aggregateMetricRoute.get("/aggregateMetric", handleGetAggregateMetrics); + +module.exports = aggregateMetricRoute; diff --git a/routes/usageMetric.js b/routes/usageMetric.js index 5637ef5594dcb3e5c8fda43f7e699e36d9503532..a238dd87a5bee3e104257b498521c296ed3bfd19 100644 --- a/routes/usageMetric.js +++ b/routes/usageMetric.js @@ -1,39 +1,12 @@ -const express = require('express'); -const router = express.Router(); -const { getUsageMetrics, recordUsageMetric } = require('../controllers/usageMetric'); +const express = require("express"); +const { + handleGetUsageMetrics, + handlePostrecordUsageMetric, +} = require("../controllers/usageMetric"); -router.get('/usageMetrics', getUsageMetrics); -router.post('/usageMetrics', recordUsageMetric); +const usageMetricRoute = express.Router(); -module.exports = router; +usageMetricRoute.get("/usageMetrics", handleGetUsageMetrics); +usageMetricRoute.post("/usageMetrics", handlePostrecordUsageMetric); - - - - - - - - - - - - - - - - - - - - - - -// const express = require("express"); -// const { getAggregateMetrics } = require("../controllers/usageMetric"); - -// const router = express.Router(); - -// router.get("/aggregateMetric", getAggregateMetrics); - -// module.exports = router; +module.exports = usageMetricRoute;