V0.1
This commit is contained in:
144
server/routes/api/machines.js
Normal file
144
server/routes/api/machines.js
Normal file
@@ -0,0 +1,144 @@
|
||||
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));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user