// routes/scanStatus.js const express = require('express'); const router = express.Router(); const db = require('../db/knex'); const photoIngestQueue = require('../api_v1/scanner/photoIngestQueue'); const photoScanProgress = require('../api_v1/scanner/photoScanProgress'); const activityScanProgress = require('../api_v1/scanner/activityScanProgress'); const activityIngestQueue = require('../api_v1/scanner/activityIngestQueue'); router.get('/photos', async (req, res) => { res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate'); res.setHeader('Pragma', 'no-cache'); res.setHeader('Expires', '0'); try { const status = await photoScanProgress.getGlobalPhotoScanStatus(db); res.json(status); } catch (err) { console.error('[scanStatus/photos] Errore:', err.message); res.status(500).json({ ok: false, error: 'Impossibile leggere lo stato della coda foto' }); } }); router.get('/activities', async (req, res) => { res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate'); res.setHeader('Pragma', 'no-cache'); res.setHeader('Expires', '0'); try { const status = await activityScanProgress.getGlobalActivityScanStatus(db); res.json(status); } catch (err) { console.error('[scanStatus/activities] Errore:', err.message); res.status(500).json({ ok: false, error: 'Impossibile leggere lo stato della coda attività' }); } }); // Conteggio dei job ancora in attesa o in elaborazione. // Questa route legge le code senza modificarle e non interferisce con i worker. router.get('/worker-queues', async (req, res) => { res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate'); try { const activityIngestQueue = require('../api_v1/scanner/activityIngestQueue'); const [faceCounts, geocodeCounts, photoCounts, activityCounts] = await Promise.all([ db('face_scan_jobs') .select('status') .count({ count: '*' }) .groupBy('status'), db('geocode_jobs') .select('status') .count({ count: '*' }) .groupBy('status'), photoIngestQueue.getPhotoIngestQueueCounts(db), activityIngestQueue.getActivityIngestQueueCounts(db) ]); const countStatus = (rows, statuses) => rows.reduce((total, row) => statuses.includes(row.status) ? total + Number(row.count || 0) : total, 0); res.json({ ok: true, photos: Number(photoCounts.pending || 0) + Number(photoCounts.processing || 0), photosErrors: Number(photoCounts.error || 0), activities: Number(activityCounts.pending || 0) + Number(activityCounts.processing || 0), activitiesErrors: Number(activityCounts.error || 0), faces: countStatus(faceCounts, ['pending', 'processing']), facesErrors: countStatus(faceCounts, ['error']), locations: countStatus(geocodeCounts, ['pending', 'processing']), locationsErrors: countStatus(geocodeCounts, ['error']) }); } catch (err) { console.error('[worker-queues] Errore conteggio code:', err.message); res.status(500).json({ ok: false, error: 'Impossibile leggere le code' }); } }); module.exports = router;