const express = require('express'); const router = express.Router(); const pool = require('../db'); const { moveByPosition, isMissingPositionColumn } = require("../helpers/positionMove"); const clean = (value) => value === "" ? null : value; const normalizeCost = (value) => { if (value === undefined || value === null || value === "") return null; return String(value).replace(",", "."); }; const mapDomainError = (err, fallbackMessage) => { let message = fallbackMessage; let status = 500; if (err.code === "WARN_DATA_TRUNCATED") { status = 400; message = "Ungueltiges Preisformat"; } if (err.code === "ER_DUP_ENTRY") { status = 400; message = "Domain existiert bereits"; } return { status, message }; }; // GET ALL DOMAINS router.get('/', async (req, res) => { try { let rows; try { [rows] = await pool.query(` SELECT d.id, d.domain_name, d.provider, d.ip_address, d.yearly_cost, d.notes, d.position, r.name AS resource_name FROM domains d LEFT JOIN resource_ips ip ON d.ip_address = ip.ip LEFT JOIN resources r ON ip.resource_id = r.id ORDER BY COALESCE(d.position, d.id) ASC, d.domain_name ASC `); } catch (err) { if (!isMissingPositionColumn(err)) throw err; [rows] = await pool.query(` SELECT d.id, d.domain_name, d.provider, d.ip_address, d.yearly_cost, d.notes, r.name AS resource_name FROM domains d LEFT JOIN resource_ips ip ON d.ip_address = ip.ip LEFT JOIN resources r ON ip.resource_id = r.id ORDER BY d.domain_name ASC `); } res.json(rows); } catch (err) { console.error("GET domains error:", err); res.status(500).json({ error: "DB error" }); } }); // GET SINGLE DOMAIN router.get('/:id', async (req, res) => { try { const [rows] = await pool.query( `SELECT * FROM domains WHERE id = ?`, [req.params.id] ); if (rows.length === 0) { return res.status(404).json({ error: "Domain not found" }); } res.json(rows[0]); } catch (err) { console.error("GET domain error:", err); res.status(500).json({ error: "DB error" }); } }); // CREATE DOMAIN router.post('/', async (req, res) => { try { const domainName = req.body.domain_name ? String(req.body.domain_name).trim() : ""; if (!domainName) { return res.status(400).json({ error: "Domain darf nicht leer sein" }); } let result; try { const [[positionRow]] = await pool.query( "SELECT COALESCE(MAX(position), 0) + 1 AS nextPosition FROM domains" ); [result] = await pool.query( `INSERT INTO domains (domain_name, provider, ip_address, yearly_cost, notes, position) VALUES (?, ?, ?, ?, ?, ?)`, [ domainName, clean(req.body.provider), clean(req.body.ip_address), normalizeCost(req.body.yearly_cost), clean(req.body.notes), positionRow.nextPosition ] ); } catch (err) { if (!isMissingPositionColumn(err)) throw err; [result] = await pool.query( `INSERT INTO domains (domain_name, provider, ip_address, yearly_cost, notes) VALUES (?, ?, ?, ?, ?)`, [ domainName, clean(req.body.provider), clean(req.body.ip_address), normalizeCost(req.body.yearly_cost), clean(req.body.notes) ] ); } res.json({ message: "Domain created", id: result.insertId }); }catch (err) { console.error("CREATE domain error:", err); const { status, message } = mapDomainError(err, "Domain konnte nicht gespeichert werden"); res.status(status).json({ error: message }); } }); // UPDATE DOMAIN router.put('/:id', async (req, res) => { try { const domainName = req.body.domain_name ? String(req.body.domain_name).trim() : ""; if (!domainName) { return res.status(400).json({ error: "Domain darf nicht leer sein" }); } await pool.query( `UPDATE domains SET domain_name = ?, provider = ?, ip_address = ?, yearly_cost = ?, notes = ? WHERE id = ?`, [ domainName, clean(req.body.provider), clean(req.body.ip_address), normalizeCost(req.body.yearly_cost), clean(req.body.notes), req.params.id ] ); res.json({ message: "Domain updated" }); } catch (err) { console.error("UPDATE domain error:", err); const { status, message } = mapDomainError(err, "Domain konnte nicht gespeichert werden"); res.status(status).json({ error: message }); } }); router.post('/:id/move', async (req, res) => { try { const { direction } = req.body const result = await moveByPosition({ db: pool, table: "domains", id: req.params.id, direction, selectQuery: "SELECT id FROM domains ORDER BY position, domain_name, id", missingColumnMessage: "Position-Spalte in domains fehlt noch", notFoundMessage: "Domain nicht gefunden", }); res.status(result.status).json(result.body); } catch (err) { console.error("MOVE domain error:", err); res.status(500).json({ error: "Reihenfolge konnte nicht geaendert werden" }) } }); // DELETE DOMAIN router.delete('/:id', async (req, res) => { try { await pool.query( `DELETE FROM domains WHERE id = ?`, [req.params.id] ); res.json({ message: "Domain deleted" }); } catch (err) { console.error("DELETE domain error:", err); res.status(500).json({ error: "Domain konnte nicht geloescht werden" }); } }); module.exports = router;