mongodb
Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
This commit is contained in:
@@ -1,22 +1,57 @@
|
||||
import express from 'express';
|
||||
import { readJSON } from '../utils/fileUtils.js';
|
||||
import { PATHS } from '../config/constants.js';
|
||||
import { getFavorites, getNotifiedArticles, getRedisClient } from '../services/redis.js';
|
||||
import { getFavorites, getNotifiedArticles, getDB, getWorkers, clearAllArticles } from '../services/mongodb.js';
|
||||
import { basicAuthMiddleware } from '../middlewares/auth.js';
|
||||
import { adminAuthMiddleware } from '../middlewares/adminAuth.js';
|
||||
import { broadcast } from '../services/websocket.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Obtener estadísticas
|
||||
router.get('/stats', async (req, res) => {
|
||||
// Obtener estadísticas (requiere autenticación obligatoria)
|
||||
router.get('/stats', basicAuthMiddleware, async (req, res) => {
|
||||
try {
|
||||
const workers = readJSON(PATHS.WORKERS, { items: [] });
|
||||
const favorites = await getFavorites();
|
||||
const notifiedArticles = await getNotifiedArticles();
|
||||
const db = getDB();
|
||||
if (!db) {
|
||||
return res.status(500).json({ error: 'MongoDB no está disponible' });
|
||||
}
|
||||
|
||||
// Obtener usuario autenticado (requerido)
|
||||
const user = req.user;
|
||||
const isAdmin = user.role === 'admin';
|
||||
|
||||
let totalWorkers = 0;
|
||||
let activeWorkers = 0;
|
||||
let favorites = [];
|
||||
let notifiedArticles = [];
|
||||
|
||||
if (isAdmin) {
|
||||
// Admin: estadísticas globales de todos los usuarios
|
||||
const workersCollection = db.collection('workers');
|
||||
const allWorkers = await workersCollection.find({}).toArray();
|
||||
|
||||
for (const userWorkers of allWorkers) {
|
||||
const items = userWorkers.items || [];
|
||||
const disabled = userWorkers.disabled || [];
|
||||
totalWorkers += items.length;
|
||||
activeWorkers += items.filter(w => !disabled.includes(w.name) && !disabled.includes(w.id)).length;
|
||||
}
|
||||
|
||||
favorites = await getFavorites(null); // Todos los favoritos
|
||||
notifiedArticles = await getNotifiedArticles(); // Todos los artículos
|
||||
} else {
|
||||
// Usuario normal: solo sus estadísticas
|
||||
const workers = await getWorkers(user.username);
|
||||
const items = workers.items || [];
|
||||
const disabled = workers.disabled || [];
|
||||
totalWorkers = items.length;
|
||||
activeWorkers = items.filter(w => !disabled.includes(w.name) && !disabled.includes(w.id)).length;
|
||||
|
||||
favorites = await getFavorites(user.username); // Solo sus favoritos
|
||||
notifiedArticles = await getNotifiedArticles({ username: user.username }); // Solo sus artículos
|
||||
}
|
||||
|
||||
const stats = {
|
||||
totalWorkers: workers.items?.length || 0,
|
||||
activeWorkers: (workers.items || []).filter(w => !workers.disabled?.includes(w.name)).length,
|
||||
totalWorkers,
|
||||
activeWorkers,
|
||||
totalFavorites: favorites.length,
|
||||
totalNotified: notifiedArticles.length,
|
||||
platforms: {
|
||||
@@ -27,34 +62,21 @@ router.get('/stats', async (req, res) => {
|
||||
|
||||
res.json(stats);
|
||||
} catch (error) {
|
||||
console.error('Error obteniendo estadísticas:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Limpiar toda la caché de Redis (requiere autenticación)
|
||||
router.delete('/cache', basicAuthMiddleware, async (req, res) => {
|
||||
// Limpiar toda la caché de MongoDB (requiere autenticación de administrador)
|
||||
router.delete('/cache', basicAuthMiddleware, adminAuthMiddleware, async (req, res) => {
|
||||
try {
|
||||
const redisClient = getRedisClient();
|
||||
if (!redisClient) {
|
||||
return res.status(500).json({ error: 'Redis no está disponible' });
|
||||
const db = getDB();
|
||||
if (!db) {
|
||||
return res.status(500).json({ error: 'MongoDB no está disponible' });
|
||||
}
|
||||
|
||||
// Obtener todas las claves que empiezan con 'notified:'
|
||||
const keys = await redisClient.keys('notified:*');
|
||||
|
||||
if (!keys || keys.length === 0) {
|
||||
return res.json({
|
||||
success: true,
|
||||
message: 'Cache ya está vacío',
|
||||
count: 0
|
||||
});
|
||||
}
|
||||
|
||||
// Eliminar todas las claves
|
||||
const count = keys.length;
|
||||
for (const key of keys) {
|
||||
await redisClient.del(key);
|
||||
}
|
||||
// Eliminar todos los artículos
|
||||
const count = await clearAllArticles();
|
||||
|
||||
// Notificar a los clientes WebSocket
|
||||
broadcast({
|
||||
@@ -62,17 +84,55 @@ router.delete('/cache', basicAuthMiddleware, async (req, res) => {
|
||||
data: { count, timestamp: Date.now() }
|
||||
});
|
||||
|
||||
// También notificar actualización de artículos (ahora está vacío)
|
||||
broadcast({ type: 'articles_updated', data: [] });
|
||||
|
||||
// También actualizar favoritos (debería estar vacío ahora)
|
||||
const favorites = await getFavorites();
|
||||
broadcast({ type: 'favorites_updated', data: favorites });
|
||||
const favorites = await getFavorites(null);
|
||||
broadcast({ type: 'favorites_updated', data: favorites, username: null });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Cache limpiado: ${count} artículos eliminados`,
|
||||
message: `Todos los artículos eliminados: ${count} artículos borrados`,
|
||||
count
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error limpiando cache de Redis:', error);
|
||||
console.error('Error limpiando cache de MongoDB:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Endpoint específico para borrar artículos (alias de /cache para claridad)
|
||||
router.delete('/articles', basicAuthMiddleware, adminAuthMiddleware, async (req, res) => {
|
||||
try {
|
||||
const db = getDB();
|
||||
if (!db) {
|
||||
return res.status(500).json({ error: 'MongoDB no está disponible' });
|
||||
}
|
||||
|
||||
// Eliminar todos los artículos
|
||||
const count = await clearAllArticles();
|
||||
|
||||
// Notificar a los clientes WebSocket
|
||||
broadcast({
|
||||
type: 'articles_cleared',
|
||||
data: { count, timestamp: Date.now() }
|
||||
});
|
||||
|
||||
// También notificar actualización de artículos (ahora está vacío)
|
||||
broadcast({ type: 'articles_updated', data: [] });
|
||||
|
||||
// También actualizar favoritos (debería estar vacío ahora)
|
||||
const favorites = await getFavorites(null);
|
||||
broadcast({ type: 'favorites_updated', data: favorites, username: null });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Todos los artículos eliminados: ${count} artículos borrados`,
|
||||
count
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error borrando artículos:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user