import { Router } from 'express'; import { getTopicsForBroker, updateTopic, startDiscovery, addManualTopic, } from '../../modules/mqtt/topic-discovery'; import { createDatapointFromMqtt, getDatapointByTopicId } from '../../modules/datapoints/datapoint-manager'; import { getConnection } from './../../modules/mqtt/broker-manager'; import { getDb } from '../../db/index'; const router = Router({ mergeParams: true }); // GET /api/mqtt/brokers/:brokerId/topics?search=grid&selected=1&limit=50&offset=0 router.get('/', (req, res): void => { try { const brokerId = parseInt(req.params.brokerId); const search = req.query.search as string | undefined; const selectedOnly = req.query.selected === '1'; const limit = parseInt(req.query.limit as string) || 50; const offset = parseInt(req.query.offset as string) || 0; res.json(getTopicsForBroker(brokerId, { search, selectedOnly, limit, offset })); } catch (err) { res.status(500).json({ error: (err as Error).message }); } }); // PUT /api/mqtt/brokers/:brokerId/topics/:id router.put('/:id', (req, res): void => { try { const topicId = parseInt(req.params.id); const topicRow = getDb().prepare('SELECT * FROM mqtt_topics WHERE id = ?').get(topicId) as any; if (!topicRow) { res.status(404).json({ error: 'Topic not found' }); return; } const topic = updateTopic(topicId, req.body); // If selecting a topic, auto-create a datapoint if (req.body.selected === 1 || req.body.selected === true) { const existing = getDatapointByTopicId(topicId); if (!existing) { createDatapointFromMqtt(topicRow.broker_id, topicId, topicRow.topic); } // Subscribe to the topic on the broker connection const client = getConnection(topicRow.broker_id); if (client?.connected) client.subscribe(topicRow.topic); } res.json(topic); } catch (err) { res.status(500).json({ error: (err as Error).message }); } }); // POST /api/mqtt/brokers/:brokerId/topics/discover router.post('/discover', (req, res): void => { const brokerId = parseInt(req.params.brokerId); const { prefix } = req.body; res.json({ message: 'Discovery started', brokerId, prefix: prefix ?? null }); // Run in background startDiscovery(brokerId, prefix).catch((err) => { console.error('Discovery error:', (err as Error).message); }); }); // POST /api/mqtt/brokers/:brokerId/topics/manual router.post('/manual', (req, res): void => { try { const brokerId = parseInt(req.params.brokerId); const { topic } = req.body; if (!topic) { res.status(400).json({ error: 'topic is required' }); return; } res.status(201).json(addManualTopic(brokerId, topic)); } catch (err) { res.status(500).json({ error: (err as Error).message }); } }); export default router;