Files
cannaiq/backend/dist/routes/analytics.js
2025-11-28 19:45:44 -07:00

122 lines
4.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const middleware_1 = require("../auth/middleware");
const migrate_1 = require("../db/migrate");
const router = (0, express_1.Router)();
router.use(middleware_1.authMiddleware);
// Get analytics overview
router.get('/overview', async (req, res) => {
try {
const { days = 30 } = req.query;
// Total clicks
const clicksResult = await migrate_1.pool.query(`
SELECT COUNT(*) as total_clicks
FROM clicks
WHERE clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
`);
// Unique products clicked
const uniqueProductsResult = await migrate_1.pool.query(`
SELECT COUNT(DISTINCT product_id) as unique_products
FROM clicks
WHERE clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
`);
// Clicks by day
const clicksByDayResult = await migrate_1.pool.query(`
SELECT DATE(clicked_at) as date, COUNT(*) as clicks
FROM clicks
WHERE clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
GROUP BY DATE(clicked_at)
ORDER BY date DESC
`);
// Top products
const topProductsResult = await migrate_1.pool.query(`
SELECT p.id, p.name, p.price, COUNT(c.id) as click_count
FROM clicks c
JOIN products p ON c.product_id = p.id
WHERE c.clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
GROUP BY p.id, p.name, p.price
ORDER BY click_count DESC
LIMIT 10
`);
res.json({
overview: {
total_clicks: parseInt(clicksResult.rows[0].total_clicks),
unique_products: parseInt(uniqueProductsResult.rows[0].unique_products)
},
clicks_by_day: clicksByDayResult.rows,
top_products: topProductsResult.rows
});
}
catch (error) {
console.error('Error fetching analytics:', error);
res.status(500).json({ error: 'Failed to fetch analytics' });
}
});
// Get product analytics
router.get('/products/:id', async (req, res) => {
try {
const { id } = req.params;
const { days = 30 } = req.query;
// Total clicks for this product
const totalResult = await migrate_1.pool.query(`
SELECT COUNT(*) as total_clicks
FROM clicks
WHERE product_id = $1
AND clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
`, [id]);
// Clicks by day
const byDayResult = await migrate_1.pool.query(`
SELECT DATE(clicked_at) as date, COUNT(*) as clicks
FROM clicks
WHERE product_id = $1
AND clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
GROUP BY DATE(clicked_at)
ORDER BY date DESC
`, [id]);
res.json({
product_id: parseInt(id),
total_clicks: parseInt(totalResult.rows[0].total_clicks),
clicks_by_day: byDayResult.rows
});
}
catch (error) {
console.error('Error fetching product analytics:', error);
res.status(500).json({ error: 'Failed to fetch product analytics' });
}
});
// Get campaign analytics
router.get('/campaigns/:id', async (req, res) => {
try {
const { id } = req.params;
const { days = 30 } = req.query;
// Total clicks for this campaign
const totalResult = await migrate_1.pool.query(`
SELECT COUNT(*) as total_clicks
FROM clicks
WHERE campaign_id = $1
AND clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
`, [id]);
// Clicks by product in this campaign
const byProductResult = await migrate_1.pool.query(`
SELECT p.id, p.name, COUNT(c.id) as clicks
FROM clicks c
JOIN products p ON c.product_id = p.id
WHERE c.campaign_id = $1
AND c.clicked_at >= NOW() - INTERVAL '${parseInt(days)} days'
GROUP BY p.id, p.name
ORDER BY clicks DESC
`, [id]);
res.json({
campaign_id: parseInt(id),
total_clicks: parseInt(totalResult.rows[0].total_clicks),
clicks_by_product: byProductResult.rows
});
}
catch (error) {
console.error('Error fetching campaign analytics:', error);
res.status(500).json({ error: 'Failed to fetch campaign analytics' });
}
});
exports.default = router;