Legg til dagsplan + kommentar ved statusbytte
Dagsplan: tredje visning ved siden av tavle/tabell. To-kolonne planlegger der man plukker oppgaver fra backlog og bygger en ordnet plan for dagen (drag-sortering, kapasitet i timer, datovelger). Per bruker, per dato, lagret i plans.json; synkes mellom egne faner via plan-WS-melding. Kommentar ved statusbytte: når en oppgave markeres ferdig/blokkert (knapp, kanban-drag eller modal) tilbys en valgfri kommentar som festes til oppgaven (kind:status) og legges i aktivitetsloggen — atomisk i ett update-kall. 20 integrasjonstester (8 nye), alle grønne. README + CLAUDE.md oppdatert. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6b9dbf8254
commit
be166034de
8 changed files with 686 additions and 32 deletions
|
|
@ -93,6 +93,15 @@ function createServer({ dataDir = path.join(__dirname, 'data') } = {}) {
|
|||
}
|
||||
}
|
||||
|
||||
// Send kun til samme brukers tilkoblinger (dagsplan er privat, men skal synke
|
||||
// mellom f.eks. desktop og laptop hos samme bruker).
|
||||
function sendToUser(user, obj) {
|
||||
const msg = JSON.stringify(obj);
|
||||
for (const [ws, meta] of clients) {
|
||||
if (meta.user === user && ws.readyState === ws.OPEN) ws.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function onlineUsers() {
|
||||
const set = new Set();
|
||||
for (const meta of clients.values()) set.add(meta.user);
|
||||
|
|
@ -154,10 +163,14 @@ function createServer({ dataDir = path.join(__dirname, 'data') } = {}) {
|
|||
heartbeat.unref();
|
||||
|
||||
// ---------- REST API ----------
|
||||
const todayStr = () => new Date().toISOString().slice(0, 10);
|
||||
const validDate = d => typeof d === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(d);
|
||||
|
||||
app.get('/healthz', (req, res) => res.json({ ok: true, tasks: store.tasks.length }));
|
||||
|
||||
app.get('/api/state', (req, res) => {
|
||||
store.rememberUser(req.user);
|
||||
const today = todayStr();
|
||||
res.json({
|
||||
user: req.user,
|
||||
canSetName: COOKIE_AUTH_ENABLED,
|
||||
|
|
@ -165,9 +178,22 @@ function createServer({ dataDir = path.join(__dirname, 'data') } = {}) {
|
|||
activity: store.activity,
|
||||
known_users: [...store.knownUsers].sort(),
|
||||
online: onlineUsers(),
|
||||
plan: { date: today, items: store.getPlan(req.user, today) },
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/plan', (req, res) => {
|
||||
const date = validDate(req.query.date) ? req.query.date : todayStr();
|
||||
res.json({ date, items: store.getPlan(req.user, date) });
|
||||
});
|
||||
|
||||
app.put('/api/plan', (req, res) => {
|
||||
const date = validDate(req.body && req.body.date) ? req.body.date : todayStr();
|
||||
const items = store.setPlan(req.user, date, req.body && req.body.items);
|
||||
sendToUser(req.user, { type: 'plan', date, items });
|
||||
res.json({ date, items });
|
||||
});
|
||||
|
||||
app.post('/api/login', (req, res) => {
|
||||
if (!COOKIE_AUTH_ENABLED) return res.status(403).json({ error: 'Navnevalg er deaktivert — auth styres av proxy' });
|
||||
const raw = req.body && req.body.name;
|
||||
|
|
@ -188,7 +214,10 @@ function createServer({ dataDir = path.join(__dirname, 'data') } = {}) {
|
|||
});
|
||||
|
||||
app.put('/api/tasks/:id', (req, res) => {
|
||||
const { task, activity } = store.update(req.params.id, req.body, req.user);
|
||||
// Valgfri `comment` følger med ved statusbytte; normalizeTask ignorerer
|
||||
// ukjente felter, så den blir ikke en del av selve oppgaven.
|
||||
const comment = req.body && typeof req.body.comment === 'string' ? req.body.comment : '';
|
||||
const { task, activity } = store.update(req.params.id, req.body, req.user, { comment });
|
||||
broadcast({ type: 'task', op: 'update', task, by: req.user, activity });
|
||||
res.json({ task });
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue