Files
tischlerCtrl/uiserver/api/output-config.js
sebseb7 86bea2fa6d u
2025-12-26 01:57:15 +01:00

163 lines
6.5 KiB
JavaScript

/**
* Output Config API - CRUD for output channel configurations
*/
module.exports = function setupOutputConfigApi(app, { db, checkAuth, requireAdmin }) {
// Apply checkAuth middleware to output config routes
app.use('/api/output-configs', checkAuth);
// GET /api/output-configs - List all output configs
app.get('/api/output-configs', (req, res) => {
try {
if (!db) throw new Error('Database not connected');
const stmt = db.prepare('SELECT * FROM output_configs ORDER BY position ASC');
const rows = stmt.all();
res.json(rows);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// POST /api/output-configs - Create new output config (admin only)
app.post('/api/output-configs', requireAdmin, (req, res) => {
const { channel, description, value_type, min_value, max_value, device, device_channel } = req.body;
if (!channel || !value_type) {
return res.status(400).json({ error: 'Missing required fields: channel, value_type' });
}
try {
// Get max position
const maxPos = db.prepare('SELECT MAX(position) as max FROM output_configs').get();
const position = (maxPos.max ?? -1) + 1;
const stmt = db.prepare(`
INSERT INTO output_configs (channel, description, value_type, min_value, max_value, device, device_channel, position)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`);
const info = stmt.run(
channel,
description || '',
value_type,
min_value ?? 0,
max_value ?? 1,
device || null,
device_channel || null,
position
);
global.insertChangelog(req.user?.username || 'admin', `Created output config "${channel}"`);
res.json({
id: info.lastInsertRowid,
channel,
description,
value_type,
min_value: min_value ?? 0,
max_value: max_value ?? 1,
device,
device_channel,
position
});
} catch (err) {
if (err.message.includes('UNIQUE constraint')) {
return res.status(400).json({ error: 'Channel name already exists' });
}
res.status(500).json({ error: err.message });
}
});
// PUT /api/output-configs/:id - Update output config (admin only)
app.put('/api/output-configs/:id', requireAdmin, (req, res) => {
const { channel, description, value_type, min_value, max_value, device, device_channel } = req.body;
try {
const oldConfig = db.prepare('SELECT * FROM output_configs WHERE id = ?').get(req.params.id);
if (!oldConfig) {
return res.status(404).json({ error: 'Output config not found' });
}
const stmt = db.prepare(`
UPDATE output_configs
SET channel = ?, description = ?, value_type = ?, min_value = ?, max_value = ?, device = ?, device_channel = ?
WHERE id = ?
`);
const info = stmt.run(
channel ?? oldConfig.channel,
description ?? oldConfig.description,
value_type ?? oldConfig.value_type,
min_value ?? oldConfig.min_value,
max_value ?? oldConfig.max_value,
device ?? oldConfig.device,
device_channel ?? oldConfig.device_channel,
req.params.id
);
if (info.changes > 0) {
const changes = [];
if (oldConfig.channel !== channel) changes.push(`channel: ${oldConfig.channel}${channel}`);
if (oldConfig.device !== device) changes.push(`device: ${oldConfig.device || 'none'}${device || 'none'}`);
if (oldConfig.device_channel !== device_channel) changes.push(`device_channel: ${oldConfig.device_channel || 'none'}${device_channel || 'none'}`);
const changeText = changes.length > 0
? `Updated output config "${channel}": ${changes.join(', ')}`
: `Updated output config "${channel}"`;
global.insertChangelog(req.user?.username || 'admin', changeText);
res.json({ success: true, id: req.params.id });
} else {
res.status(404).json({ error: 'Output config not found' });
}
} catch (err) {
if (err.message.includes('UNIQUE constraint')) {
return res.status(400).json({ error: 'Channel name already exists' });
}
res.status(500).json({ error: err.message });
}
});
// DELETE /api/output-configs/:id - Delete output config (admin only)
app.delete('/api/output-configs/:id', requireAdmin, (req, res) => {
try {
const config = db.prepare('SELECT channel FROM output_configs WHERE id = ?').get(req.params.id);
if (!config) {
return res.status(404).json({ error: 'Output config not found' });
}
const stmt = db.prepare('DELETE FROM output_configs WHERE id = ?');
const info = stmt.run(req.params.id);
if (info.changes > 0) {
global.insertChangelog(req.user?.username || 'admin', `Deleted output config "${config.channel}"`);
res.json({ success: true });
} else {
res.status(404).json({ error: 'Output config not found' });
}
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// POST /api/output-configs/reorder - Reorder output configs (admin only)
app.post('/api/output-configs/reorder', requireAdmin, (req, res) => {
const { order } = req.body;
if (!Array.isArray(order)) {
return res.status(400).json({ error: 'Invalid format' });
}
const updateStmt = db.prepare('UPDATE output_configs SET position = ? WHERE id = ?');
const updateMany = db.transaction((items) => {
for (const item of items) {
updateStmt.run(item.position, item.id);
}
});
try {
updateMany(order);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
};