From c3c92b47f1499669c2d15e5998ae7429061076b4 Mon Sep 17 00:00:00 2001 From: Anton Roslund Date: Sun, 30 Mar 2025 16:17:26 +0200 Subject: [PATCH] Move stats api to separate file --- src/index.js | 78 ++++-------------------------------------------- src/stats.js | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 73 deletions(-) create mode 100644 src/stats.js diff --git a/src/index.js b/src/index.js index f9f07f6..74fb67b 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,8 @@ const commandLineArgs = require("command-line-args"); const commandLineUsage = require("command-line-usage"); const cors = require('cors'); +const statsRoutes = require('./stats.js'); + // create prisma db client const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); @@ -87,6 +89,9 @@ app.get('/', async (req, res) => { res.sendFile(path.join(__dirname, 'public/index.html')); }); +// stats API in separate file +app.use('/api/v1/stats', statsRoutes); + app.get('/api', async (req, res) => { const links = [ @@ -650,42 +655,6 @@ app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { } }); -app.get('/api/v1/stats/hardware-models', async (req, res) => { - try { - - // get nodes from db - const results = await prisma.node.groupBy({ - by: ['hardware_model'], - orderBy: { - _count: { - hardware_model: 'desc', - }, - }, - _count: { - hardware_model: true, - }, - }); - - const hardwareModelStats = results.map((result) => { - return { - count: result._count.hardware_model, - hardware_model: result.hardware_model, - hardware_model_name: HardwareModel.valuesById[result.hardware_model] ?? "UNKNOWN", - }; - }); - - res.json({ - hardware_model_stats: hardwareModelStats, - }); - - } catch(err) { - console.error(err); - res.status(500).json({ - message: "Something went wrong, try again later.", - }); - } -}); - app.get('/api/v1/text-messages', async (req, res) => { try { @@ -812,43 +781,6 @@ app.get('/api/v1/waypoints', async (req, res) => { } }); -app.get('/api/v1/messages-per-hour', async (req, res) => { - try { - const hours = 168; - const now = new Date(); - const startTime = new Date(now.getTime() - hours * 60 * 60 * 1000); - - const messages = await prisma.textMessage.findMany({ - where: { created_at: { gte: startTime } }, - select: { packet_id: true, created_at: true }, - distinct: ['packet_id'], // Ensures only unique packet_id entries are counted - orderBy: { created_at: 'asc' } - }); - - // Pre-fill `uniqueCounts` with zeros for all hours - const uniqueCounts = Object.fromEntries( - Array.from({ length: hours }, (_, i) => { - const hourTime = new Date(now.getTime() - (hours - i) * 60 * 60 * 1000); - const hourString = hourTime.toISOString().slice(0, 13); // YYYY-MM-DD HH - return [hourString, 0]; - }) - ); - - // Populate actual message counts - messages.forEach(({ created_at }) => { - const hourString = created_at.toISOString().slice(0, 13); // YYYY-MM-DD HH - uniqueCounts[hourString]++; - }); - - // Convert to final result format - const result = Object.entries(uniqueCounts).map(([hour, count]) => ({ hour, count })); - - res.json(result); - } catch (error) { - console.error('Error fetching messages:', error); - res.status(500).json({ error: 'Internal Server Error' }); - } -}); // start express server const listener = app.listen(port, () => { diff --git a/src/stats.js b/src/stats.js new file mode 100644 index 0000000..97c1770 --- /dev/null +++ b/src/stats.js @@ -0,0 +1,83 @@ +const express = require('express'); +const router = express.Router(); + +// create prisma db client +const { PrismaClient } = require("@prisma/client"); +const prisma = new PrismaClient(); + + +router.get('/hardware-models', async (req, res) => { + try { + + // get nodes from db + const results = await prisma.node.groupBy({ + by: ['hardware_model'], + orderBy: { + _count: { + hardware_model: 'desc', + }, + }, + _count: { + hardware_model: true, + }, + }); + + const hardwareModelStats = results.map((result) => { + return { + count: result._count.hardware_model, + hardware_model: result.hardware_model, + hardware_model_name: HardwareModel.valuesById[result.hardware_model] ?? "UNKNOWN", + }; + }); + + res.json({ + hardware_model_stats: hardwareModelStats, + }); + + } catch(err) { + console.error(err); + res.status(500).json({ + message: "Something went wrong, try again later.", + }); + } +}); + +router.get('/messages-per-hour', async (req, res) => { + try { + const hours = 168; + const now = new Date(); + const startTime = new Date(now.getTime() - hours * 60 * 60 * 1000); + + const messages = await prisma.textMessage.findMany({ + where: { created_at: { gte: startTime } }, + select: { packet_id: true, created_at: true }, + distinct: ['packet_id'], // Ensures only unique packet_id entries are counted + orderBy: { created_at: 'asc' } + }); + + // Pre-fill `uniqueCounts` with zeros for all hours + const uniqueCounts = Object.fromEntries( + Array.from({ length: hours }, (_, i) => { + const hourTime = new Date(now.getTime() - (hours - i) * 60 * 60 * 1000); + const hourString = hourTime.toISOString().slice(0, 13); // YYYY-MM-DD HH + return [hourString, 0]; + }) + ); + + // Populate actual message counts + messages.forEach(({ created_at }) => { + const hourString = created_at.toISOString().slice(0, 13); // YYYY-MM-DD HH + uniqueCounts[hourString]++; + }); + + // Convert to final result format + const result = Object.entries(uniqueCounts).map(([hour, count]) => ({ hour, count })); + + res.json(result); + } catch (error) { + console.error('Error fetching messages:', error); + res.status(500).json({ error: 'Internal Server Error' }); + } +}); + +module.exports = router; \ No newline at end of file