← back to Resume Queue Viewer
Refactor: extract readBody + sendJSON helpers, DRY out POST routes
620dc5fe97b90b168042502f544f9e6e946a0c97 · 2026-05-18 17:35:11 -0700 · SteveStudio2
Files touched
Diff
commit 620dc5fe97b90b168042502f544f9e6e946a0c97
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Mon May 18 17:35:11 2026 -0700
Refactor: extract readBody + sendJSON helpers, DRY out POST routes
---
server.js | 70 +++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 39 insertions(+), 31 deletions(-)
diff --git a/server.js b/server.js
index 881d1e2..77e81ec 100644
--- a/server.js
+++ b/server.js
@@ -17,6 +17,28 @@ function readJSON(name) {
catch (e) { return []; }
}
+// Write a JSON response in one call.
+function sendJSON(res, code, obj) {
+ res.writeHead(code, { 'Content-Type': 'application/json' });
+ res.end(JSON.stringify(obj));
+}
+
+// Collect and JSON-parse a request body (capped at 100 KB).
+function readBody(req) {
+ return new Promise((resolve, reject) => {
+ let body = '';
+ req.on('data', c => {
+ body += c;
+ if (body.length > 1e5) { req.destroy(); reject(new Error('body too large')); }
+ });
+ req.on('end', () => {
+ try { resolve(JSON.parse(body || '{}')); }
+ catch (e) { reject(new Error('bad JSON')); }
+ });
+ req.on('error', reject);
+ });
+}
+
// Build the unified queue from the three CNCP stores.
function buildQueue() {
const parking = (readJSON('cncp-parking-lot.json') || []).map(p => ({
@@ -359,43 +381,29 @@ setInterval(load, 30000);
</html>`;
const server = http.createServer((req, res) => {
- if (req.url === '/api/queue') {
- res.writeHead(200, { 'Content-Type': 'application/json' });
- res.end(JSON.stringify(buildQueue()));
- return;
- }
+ if (req.url === '/api/queue') return sendJSON(res, 200, buildQueue());
+
if (req.url === '/api/run' && req.method === 'POST') {
- let body = '';
- req.on('data', c => { body += c; if (body.length > 1e5) req.destroy(); });
- req.on('end', async () => {
- let item;
- try { item = JSON.parse(body || '{}'); }
- catch (e) { res.writeHead(400, { 'Content-Type': 'application/json' });
- return res.end(JSON.stringify({ ok: false, message: 'bad JSON' })); }
- if (!item || !item.title) { res.writeHead(400, { 'Content-Type': 'application/json' });
- return res.end(JSON.stringify({ ok: false, message: 'missing item' })); }
- const result = await runItem(item);
- res.writeHead(result.ok ? 200 : 500, { 'Content-Type': 'application/json' });
- res.end(JSON.stringify(result));
- });
+ readBody(req)
+ .then(item => {
+ if (!item || !item.title) return sendJSON(res, 400, { ok: false, message: 'missing item' });
+ return runItem(item).then(r => sendJSON(res, r.ok ? 200 : 500, r));
+ })
+ .catch(e => sendJSON(res, 400, { ok: false, message: e.message }));
return;
}
+
if (req.url === '/api/discussed' && req.method === 'POST') {
- let body = '';
- req.on('data', c => { body += c; if (body.length > 1e5) req.destroy(); });
- req.on('end', () => {
- let p;
- try { p = JSON.parse(body || '{}'); }
- catch (e) { res.writeHead(400, { 'Content-Type': 'application/json' });
- return res.end(JSON.stringify({ ok: false, message: 'bad JSON' })); }
- if (!p || !p.id) { res.writeHead(400, { 'Content-Type': 'application/json' });
- return res.end(JSON.stringify({ ok: false, message: 'missing id' })); }
- const result = setDiscussed(p.id, !!p.discussed);
- res.writeHead(result.ok ? 200 : 500, { 'Content-Type': 'application/json' });
- res.end(JSON.stringify(result));
- });
+ readBody(req)
+ .then(p => {
+ if (!p || !p.id) return sendJSON(res, 400, { ok: false, message: 'missing id' });
+ const r = setDiscussed(p.id, !!p.discussed);
+ sendJSON(res, r.ok ? 200 : 500, r);
+ })
+ .catch(e => sendJSON(res, 400, { ok: false, message: e.message }));
return;
}
+
if (req.url === '/healthz') { res.writeHead(200); res.end('ok'); return; }
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(PAGE);
← 6f6a34a Add Done/Reopen toggle on parking items — writes discussed f
·
back to Resume Queue Viewer
·
404 unknown routes instead of serving the page on every URL 3609a67 →