diff --git a/.dependencygraph/setting.json b/.dependencygraph/setting.json new file mode 100644 index 0000000..9834404 --- /dev/null +++ b/.dependencygraph/setting.json @@ -0,0 +1,13 @@ +{ + "entryFilePath": "index.js", + "alias": false, + "resolveExtensions": [ + ".js", + ".jsx", + ".ts", + ".tsx", + ".vue", + ".scss", + ".less" + ] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 23ff2c2..4781473 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,4 @@ dist .yarn/install-state.gz .pnp.* .clinic/ +features.md \ No newline at end of file diff --git a/controllers/metricsController.js b/controllers/metricsController.js index f173318..0c0d847 100644 --- a/controllers/metricsController.js +++ b/controllers/metricsController.js @@ -1,4 +1,6 @@ +const Metrics = require('../models/metrics'); const client = require('prom-client'); +const jwt = require('jsonwebtoken'); // Create a Registry to register metrics const register = new client.Registry(); @@ -25,9 +27,113 @@ const trackRequests = (req, res, next) => { }; // Metrics endpoint handler +/* const getMetrics = async (req, res) => { res.set('Content-Type', register.contentType); res.send(await register.metrics()); }; +*/ -module.exports = { trackRequests, getMetrics }; +const getMetrics = async (req, res) => { + try { + // Get the Authorization header + const authHeader = req.headers['authorization']; + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return res.status(401).json({ error: 'Unauthorized: No token provided' }); + } + + // Extract the token + const token = authHeader.split(' ')[1]; + + // Verify and decode the token + const decoded = jwt.verify(token, process.env.JWT_SECRET); + const userId = decoded.userId; // Ensure your JWT payload contains a `userId` + + if (!userId) { + return res.status(400).json({ error: 'Invalid token: userId missing' }); + } + + // Set content type and retrieve metrics + res.set('Content-Type', register.contentType); + const metricsText = await register.metrics(); + const metrics = parseMetrics(metricsText); // Helper function to parse metrics. + + // Save metrics to the database + await Metrics.saveMetricsToDatabase(userId, metrics); + + // Send the metrics as a response + res.set('Content-Type', register.contentType); + res.send(metricsText); + } catch (error) { + console.error("Error in getMetrics:", error); + res.status(500).send({ error: "Failed to process metrics" }); + } +}; + +function parseMetrics(metricsText) { + const lines = metricsText.split("\n"); + const metrics = []; + + lines.forEach(line => { + // Look for metric lines that follow the format: 'metric_name value' + if (!line.startsWith("#") && line.trim() !== "") { + const [metricName, metricValue] = line.split(/\s+/); + if (metricName && metricValue) { + metrics.push({ metricName, metricValue }); + } + } + }); + + return metrics; +} + + +const createMetric = async (req, res) => { + const { userId, metricName, metricValue } = req.body; + try { + const metric = await Metrics.create({ userId, metricName, metricValue }); + res.status(201).json(metric); + } catch (error) { + res.status(500).json({ error: 'Failed to create metric' }); + } +}; + +const getMetricsByUser = async (req, res) => { + const { userId } = req.params; + try { + const metrics = await Metrics.findByUserId(userId); + res.status(200).json(metrics); + } catch (error) { + res.status(500).json({ error: 'Failed to fetch metrics' }); + } +}; + +const updateMetric = async (req, res) => { + const { id } = req.params; + const { metricName, metricValue } = req.body; + try { + const metric = await Metrics.update(id, { metricName, metricValue }); + res.status(200).json(metric); + } catch (error) { + res.status(500).json({ error: 'Failed to update metric' }); + } +}; + +const deleteMetric = async (req, res) => { + const { id } = req.params; + try { + await Metrics.delete(id); + res.status(200).json({ message: 'Metric deleted successfully' }); + } catch (error) { + res.status(500).json({ error: 'Failed to delete metric' }); + } +}; + +module.exports = { + trackRequests, + getMetrics, + createMetric, + getMetricsByUser, + updateMetric, + deleteMetric, +}; diff --git a/models/metrics.js b/models/metrics.js new file mode 100644 index 0000000..7c28d70 --- /dev/null +++ b/models/metrics.js @@ -0,0 +1,42 @@ +const pool = require('../config/db'); + +class Metrics { + static async create({ userId, metricName, metricValue }) { + const result = await pool.query( + 'INSERT INTO metrics (user_id, metric_name, metric_value) VALUES ($1, $2, $3) RETURNING *', + [userId, metricName, metricValue] + ); + return result.rows[0]; + } + + static async findByUserId(userId) { + const result = await pool.query('SELECT * FROM metrics WHERE user_id = $1', [userId]); + return result.rows; + } + + static async update(id, { metricName, metricValue }) { + const result = await pool.query( + 'UPDATE metrics SET metric_name = $1, metric_value = $2, updated_at = NOW() WHERE id = $3 RETURNING *', + [metricName, metricValue, id] + ); + return result.rows[0]; + } + + static async delete(id) { + await pool.query('DELETE FROM metrics WHERE id = $1', [id]); + } + + static async saveMetricsToDatabase(userId, metrics) { + for (const metric of metrics) { + const { metricName, metricValue } = metric; + + // Use your database library to insert data, e.g., with PostgreSQL: + await pool.query( + "INSERT INTO metrics (user_id, metric_name, metric_value) VALUES ($1, $2, $3)", + [userId, metricName, metricValue] + ); + } + } +} + +module.exports = Metrics; diff --git a/routes/metricsRoutes.js b/routes/metricsRoutes.js index 0b2f2ed..58c748a 100644 --- a/routes/metricsRoutes.js +++ b/routes/metricsRoutes.js @@ -1,9 +1,13 @@ const express = require('express'); -const { getMetrics } = require('../controllers/metricsController'); - const router = express.Router(); +const metricsController = require('../controllers/metricsController'); +const authenticateToken = require('../middleware/auth'); // Metrics endpoint -router.get('/', getMetrics); +router.get('/', authenticateToken, metricsController.getMetrics); +router.post('/', authenticateToken, metricsController.createMetric); +router.get('/user/:userId', authenticateToken, metricsController.getMetricsByUser); +router.put('/:id', authenticateToken, metricsController.updateMetric); +router.delete('/:id', authenticateToken, metricsController.deleteMetric); module.exports = router;