From 4e8033c7289eec55ef14d23e296d61ab3abae67b Mon Sep 17 00:00:00 2001
From: Adarsh Shetty <adarsh.int@niveussolutions.com>
Date: Thu, 20 Feb 2025 17:39:26 +0530
Subject: [PATCH] new changes

---
 controllers/aggregateMetric.js | 131 +++++++++++++++++++++++++++++++++
 controllers/usageMetric.js     |  97 +++++++++++++++---------
 index.js                       |  19 +++--
 routes/aggregateMetric.js      |   7 ++
 routes/usageMetric.js          |  45 +++--------
 5 files changed, 222 insertions(+), 77 deletions(-)
 create mode 100644 controllers/aggregateMetric.js
 create mode 100644 routes/aggregateMetric.js

diff --git a/controllers/aggregateMetric.js b/controllers/aggregateMetric.js
new file mode 100644
index 0000000..24711e0
--- /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 e067a6b..d840eea 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 61a10db..913c567 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 0000000..fb7b563
--- /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 5637ef5..a238dd8 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;
-- 
GitLab