diff --git a/server/index.js b/server/index.js index 56b8579..4e22aff 100644 --- a/server/index.js +++ b/server/index.js @@ -1,11 +1,36 @@ const path = require('path'); const express = require('express'); +const { getDoc, putDoc } = require('./db'); const app = express(); app.use(express.json({ limit: '5mb' })); +const KEYS = ['employees', 'duties', 'vacation']; +const EMPTY = { employees: [], duties: {}, vacation: {} }; + app.get('/api/health', (req, res) => res.json({ status: 'ok' })); +app.get('/api/state', (req, res) => { + const state = { ...EMPTY, updatedAt: null }; + for (const key of KEYS) { + const doc = getDoc(key); + if (doc) { + state[key] = doc.value; + if (!state.updatedAt || doc.updatedAt > state.updatedAt) state.updatedAt = doc.updatedAt; + } + } + res.json(state); +}); + +app.put('/api/state', (req, res) => { + const body = req.body || {}; + const now = new Date().toISOString(); + for (const key of KEYS) { + if (body[key] !== undefined) putDoc(key, body[key], now); + } + res.json({ status: 'ok', updatedAt: now }); +}); + // Statisches Frontend (Repo-Root). Dotfiles werden per Default nicht ausgeliefert. app.use(express.static(path.join(__dirname, '..'))); diff --git a/server/state.test.js b/server/state.test.js new file mode 100644 index 0000000..b8f76f3 --- /dev/null +++ b/server/state.test.js @@ -0,0 +1,42 @@ +const { test } = require('node:test'); +const assert = require('node:assert'); +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +process.env.DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'dp-state-')); +const app = require('./index'); + +async function req(port, method, body) { + const opts = { method, headers: { 'Content-Type': 'application/json' } }; + if (body) opts.body = JSON.stringify(body); + const res = await fetch(`http://127.0.0.1:${port}/api/state`, opts); + return { status: res.status, body: await res.json() }; +} + +test('leerer Server liefert leeren State', async () => { + const server = app.listen(0); + const { port } = server.address(); + try { + const { status, body } = await req(port, 'GET'); + assert.strictEqual(status, 200); + assert.deepStrictEqual(body.employees, []); + assert.deepStrictEqual(body.duties, {}); + assert.deepStrictEqual(body.vacation, {}); + assert.strictEqual(body.updatedAt, null); + } finally { server.close(); } +}); + +test('PUT dann GET Roundtrip', async () => { + const server = app.listen(0); + const { port } = server.address(); + try { + const put = await req(port, 'PUT', { employees: ['Max'], duties: { Max: { '2026-07': [] } } }); + assert.strictEqual(put.status, 200); + assert.strictEqual(put.body.status, 'ok'); + const get = await req(port, 'GET'); + assert.deepStrictEqual(get.body.employees, ['Max']); + assert.deepStrictEqual(get.body.duties, { Max: { '2026-07': [] } }); + assert.strictEqual(typeof get.body.updatedAt, 'string'); + } finally { server.close(); } +});