const http = require("http"); const fs = require("fs"); const path = require("path"); const PORT = Number(process.env.PORT || 4173); const WEB_ROOT = path.resolve(__dirname, "../../apps/web"); function clone(value) { return JSON.parse(JSON.stringify(value)); } const baseSpecies = [ { slug: "active-shad", source_file: "Active Shad.txt", title: "Active Shad (Alosa activa)", common_name: "Active Shad", scientific_name: "Alosa activa", flelmr_code: "1001", summary: "An active editor-visible species.", section_count: 2, publication_status: "published", is_archived: false, editor_notes: "", last_modified_by: "system-import", diagnostics: [], sections: [ { id: 1, position: 1, heading: "HEADER", content: "Header content" }, { id: 2, position: 2, heading: "HABITAT", content: "Habitat content" }, ], audit: [], }, { slug: "archived-shad", source_file: "Archived Shad.txt", title: "Archived Shad (Alosa archiva)", common_name: "Archived Shad", scientific_name: "Alosa archiva", flelmr_code: "1002", summary: "An archived species.", section_count: 1, publication_status: "published", is_archived: true, editor_notes: "Archived from prior import.", last_modified_by: "system-import", diagnostics: [], sections: [ { id: 3, position: 1, heading: "HEADER", content: "Archived header" }, ], audit: [ { id: 1, changed_by: "system-import", changed_at: "2026-03-26T00:00:00+00:00", action: "import_archive", details: { is_archived: { from: false, to: true } }, }, ], }, ]; let speciesRecords = clone(baseSpecies); function resetState() { speciesRecords = clone(baseSpecies); } function getSession(req) { const auth = req.headers.authorization || ""; if (auth === "Bearer editor-token") { return { authenticated: true, auth_configured: true, user: { username: "editor", role: "editor" }, }; } return { authenticated: false, auth_configured: true, user: null, }; } function sendJson(res, status, payload) { const body = JSON.stringify(payload); res.writeHead(status, { "Content-Type": "application/json; charset=utf-8", "Content-Length": Buffer.byteLength(body), }); res.end(body); } function sendFile(res, filePath) { fs.readFile(filePath, (error, content) => { if (error) { sendJson(res, 404, { error: "Not found" }); return; } const ext = path.extname(filePath); const type = ext === ".html" ? "text/html; charset=utf-8" : ext === ".js" ? "application/javascript; charset=utf-8" : "text/css; charset=utf-8"; res.writeHead(200, { "Content-Type": type }); res.end(content); }); } function parseBody(req) { return new Promise((resolve, reject) => { let raw = ""; req.on("data", (chunk) => { raw += chunk; }); req.on("end", () => { try { resolve(raw ? JSON.parse(raw) : {}); } catch (error) { reject(error); } }); req.on("error", reject); }); } function getEditorList() { return speciesRecords.map((item) => ({ slug: item.slug, title: item.title, common_name: item.common_name, publication_status: item.publication_status, is_archived: item.is_archived, last_modified_by: item.last_modified_by, diagnostics: item.diagnostics, })); } const server = http.createServer(async (req, res) => { const url = new URL(req.url, `http://${req.headers.host}`); const pathname = url.pathname; if (pathname === "/__reset" && req.method === "POST") { resetState(); sendJson(res, 200, { status: "ok" }); return; } if (pathname === "/api/auth/session" && req.method === "GET") { sendJson(res, 200, getSession(req)); return; } if (pathname === "/api/insights/summary" && req.method === "GET") { sendJson(res, 200, { species_count: 1, section_count: 3, diagnostic_counts: {} }); return; } if (pathname === "/api/editor/species" && req.method === "GET") { sendJson(res, 200, { items: getEditorList(), count: speciesRecords.length }); return; } if (pathname.startsWith("/api/editor/species/") && pathname.endsWith("/audit") && req.method === "GET") { const slug = pathname.slice("/api/editor/species/".length, -"/audit".length).replace(/\/$/, ""); const item = speciesRecords.find((record) => record.slug === slug); if (!item) { sendJson(res, 404, { error: "Not found" }); return; } sendJson(res, 200, { items: item.audit, count: item.audit.length }); return; } if (pathname.startsWith("/api/editor/species/") && pathname.endsWith("/editorial") && req.method === "POST") { const slug = pathname.slice("/api/editor/species/".length, -"/editorial".length).replace(/\/$/, ""); const item = speciesRecords.find((record) => record.slug === slug); if (!item) { sendJson(res, 404, { error: "Not found" }); return; } const payload = await parseBody(req); const beforeArchived = item.is_archived; item.publication_status = payload.publication_status || item.publication_status; item.summary = payload.summary ?? item.summary; item.editor_notes = payload.editor_notes ?? item.editor_notes; item.is_archived = Boolean(payload.is_archived); item.last_modified_by = "editor"; item.audit.unshift({ id: item.audit.length + 1, changed_by: "editor", changed_at: "2026-03-26T00:01:00+00:00", action: "editorial_update", details: { is_archived: { from: beforeArchived, to: item.is_archived }, }, }); sendJson(res, 200, { status: "ok", slug: item.slug, summary: item.summary, publication_status: item.publication_status, editor_notes: item.editor_notes, is_archived: item.is_archived, last_modified_by: item.last_modified_by, changed_fields: { is_archived: { from: beforeArchived, to: item.is_archived }, }, }); return; } if (pathname.startsWith("/api/editor/species/") && req.method === "GET") { const slug = pathname.slice("/api/editor/species/".length).replace(/\/$/, ""); const item = speciesRecords.find((record) => record.slug === slug); if (!item) { sendJson(res, 404, { error: "Not found" }); return; } sendJson(res, 200, item); return; } if (pathname === "/" || pathname === "/index.html") { sendFile(res, path.join(WEB_ROOT, "index.html")); return; } if (pathname === "/app.js" || pathname === "/styles.css") { sendFile(res, path.join(WEB_ROOT, pathname.slice(1))); return; } sendJson(res, 404, { error: "Not found" }); }); server.listen(PORT, "127.0.0.1", () => { process.stdout.write(`UI test server listening on ${PORT}\n`); });