Files
SDS-CRM/server/routes/api/machines.js
2026-03-23 02:09:14 +01:00

145 lines
4.9 KiB
JavaScript

import { randomUUID } from 'crypto';
import db from '../../db.js';
import { badRequest, UUID } from '../../lib/http.js';
import { mapMachine } from '../../lib/mappers.js';
const ALLOWED_LIST_STATUS = new Set([
'',
'PRUEFEN',
'VERSCHROTTET',
'SN_GEAENDERT',
'IN_BEARBEITUNG',
'UPDATE_RAUS',
]);
function normalizeListStatus(v) {
if (v == null || v === '') return '';
const s = String(v).trim();
return ALLOWED_LIST_STATUS.has(s) ? s : null;
}
/** @returns {{ ok: true, json: string | null } | { ok: false, message: string }} */
function parseExtrasField(extras) {
if (extras === null || extras === '') {
return { ok: true, json: null };
}
if (typeof extras === 'object' && extras !== null) {
try {
return { ok: true, json: JSON.stringify(extras) };
} catch {
return { ok: false, message: 'extras ist kein gültiges JSON-Objekt.' };
}
}
if (typeof extras === 'string') {
try {
JSON.parse(extras);
return { ok: true, json: extras };
} catch {
return { ok: false, message: 'extras ist kein gültiger JSON-String.' };
}
}
return { ok: false, message: 'extras hat ein ungültiges Format.' };
}
export function registerMachineRoutes(api) {
api.get('/machines', (_req, res) => {
const rows = db
.prepare('SELECT * FROM machines ORDER BY seriennummer ASC')
.all();
res.json(rows.map(mapMachine));
});
api.post('/machines', (req, res) => {
const b = req.body || {};
const { name, typ, seriennummer, standort, listStatus } = b;
if (!name || !typ || !seriennummer || !standort) {
return badRequest(res, 'Pflichtfelder fehlen.');
}
const ls = normalizeListStatus(listStatus);
if (ls === null) return badRequest(res, 'Ungültiger Listen-Status.');
let extrasJson = null;
if (Object.prototype.hasOwnProperty.call(b, 'extras')) {
const p = parseExtrasField(b.extras);
if (!p.ok) return badRequest(res, p.message);
extrasJson = p.json;
}
const id = randomUUID();
const row = db
.prepare(
`INSERT INTO machines (id, name, typ, seriennummer, standort, list_status, extras, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now')) RETURNING *`,
)
.get(id, name, typ, seriennummer, standort, ls, extrasJson);
res.status(201).json(mapMachine(row));
});
api.get('/machines/:id', (req, res) => {
const { id } = req.params;
if (!UUID.test(id)) return res.status(404).json({ message: 'Nicht gefunden' });
const row = db.prepare('SELECT * FROM machines WHERE id = ?').get(id);
if (!row) return res.status(404).json({ message: 'Nicht gefunden' });
res.json(mapMachine(row));
});
api.put('/machines/:id', (req, res) => {
const { id } = req.params;
if (!UUID.test(id)) return res.status(404).json({ message: 'Nicht gefunden' });
const cur = db.prepare('SELECT * FROM machines WHERE id = ?').get(id);
if (!cur) return res.status(404).json({ message: 'Nicht gefunden' });
const b = req.body || {};
const next = {
name: b.name ?? cur.name,
typ: b.typ ?? cur.typ,
seriennummer: b.seriennummer ?? cur.seriennummer,
standort: b.standort ?? cur.standort,
};
let listStatusVal = cur.list_status ?? '';
if (Object.prototype.hasOwnProperty.call(b, 'listStatus')) {
const ls = normalizeListStatus(b.listStatus);
if (ls === null) return badRequest(res, 'Ungültiger Listen-Status.');
listStatusVal = ls;
}
let extrasJson = cur.extras;
if (Object.prototype.hasOwnProperty.call(b, 'extras')) {
const p = parseExtrasField(b.extras);
if (!p.ok) return badRequest(res, p.message);
extrasJson = p.json;
}
const row = db
.prepare(
`UPDATE machines SET name = ?, typ = ?, seriennummer = ?, standort = ?, list_status = ?, extras = ?, updated_at = datetime('now')
WHERE id = ? RETURNING *`,
)
.get(
next.name,
next.typ,
next.seriennummer,
next.standort,
listStatusVal,
extrasJson,
id,
);
res.json(mapMachine(row));
});
api.delete('/machines/:id', (req, res) => {
const { id } = req.params;
if (!UUID.test(id)) return res.status(404).json({ message: 'Nicht gefunden' });
const cur = db.prepare('SELECT * FROM machines WHERE id = ?').get(id);
if (!cur) return res.status(404).json({ message: 'Nicht gefunden' });
const tc = db
.prepare('SELECT COUNT(*) AS c FROM tickets WHERE machine_id = ?')
.get(id);
if (tc.c > 0) {
return res.status(409).json({
message:
'Maschine kann nicht gelöscht werden: Es existieren noch zugeordnete Tickets.',
});
}
const row = db
.prepare('DELETE FROM machines WHERE id = ? RETURNING *')
.get(id);
res.json(mapMachine(row));
});
}