const router = require('express').Router(); const crypto = require('crypto'); const { query } = require('../storage/postgres'); const sets = ['forecasts', 'sensors', 'marine']; function hashSensorCode(code) { return crypto.createHash('sha256').update(code).digest('hex'); } /** * Middleware: valida sensor code e verifica che il sensore sia attivo. * Salva sensor.id in req.sensorId. */ async function authenticateSensor(req, res, next) { const { sensorCode } = req.params; try { const hashed = hashSensorCode(sensorCode); const sensor = await query( 'SELECT id, active FROM sensors WHERE code_hash = $1', [hashed], 'sensors' ); if (!sensor.rows[0]) { return res.status(401).json({ error: 'Sensor code not valid' }); } if (!sensor.rows[0].active) { return res.status(403).json({ error: 'Sensor is not active' }); } req.sensorId = sensor.rows[0].id; next(); } catch (err) { console.error('[PARAMS/SENSOR] Auth error:', err.message); res.status(500).json({ error: 'Internal server error' }); } } /** * GET /params/sensor/:sensorCode/active?set=sensors * Ritorna il set di parametri attivo (forecasts, sensors, marine) */ router.get('/:sensorCode/active', authenticateSensor, async (req, res) => { const { set } = req.query; if (!set || !sets.includes(set)) return res.status(400).json({ error: 'SET parameter invalid' }); try { const result = await query( `SELECT * FROM ${set} WHERE active = true LIMIT 1`, [], 'references' ); res.json(result.rows[0] || null); } catch (err) { console.error('[PARAMS/SENSOR] Error:', err.message); res.status(500).json({ error: 'Internal server error' }); } }); // --- Mapping tipo rules → tabelle --- const RULES_TYPE_MAP = { weather: { rules: 'weather', items: 'weatheritems' }, laterforecasts: { rules: 'laterforecasts', items: 'laterforecastitems' }, data: { rules: 'dataread', items: 'datareaditems' }, logs: { rules: 'logs', items: 'logitems' } }; /** * GET /params/sensor/:sensorCode/rules?type=weather * Ritorna la rule attiva con items per il tipo specificato. * Autenticazione tramite sensor code (non richiede JWT/API key). */ router.get('/:sensorCode/rules', authenticateSensor, async (req, res) => { const { type } = req.query; if (!type || !RULES_TYPE_MAP[type]) { return res.status(400).json({ error: `invalid type, must be one of: ${Object.keys(RULES_TYPE_MAP).join(', ')}` }); } const tables = RULES_TYPE_MAP[type]; try { const { rows: ruleRows } = await query( `SELECT * FROM ${tables.rules} WHERE active = true AND archived = false LIMIT 1`, [], 'rules' ); if (ruleRows.length === 0) { return res.status(404).json({ error: `no active ${type} rule found` }); } const rule = ruleRows[0]; const { rows: items } = await query( `SELECT * FROM ${tables.items} WHERE rule_id = $1 AND enabled = true`, [rule.id], 'rules' ); res.json({ id: rule.id, version: rule.version, description: rule.description, tags: rule.tags, items }); } catch (err) { console.error('[PARAMS/SENSOR] Rules error:', err.message); res.status(500).json({ error: 'Internal server error' }); } }); module.exports = router;