Ny app i netops-todo-node/: Express + ws, WebSocket-push i stedet for polling, kanban med drag & drop, kommentarer, aktivitetslogg, optimistisk låsing, quick-add-parsing og presence. 12 integrasjonstester (node:test). setup-debian13.sh setter opp alt på en fersk LXC; README dekker Nginx Proxy Manager-oppsett. PHP-versjonen er uendret (kun handoff-peker). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6 KiB
NetOps To-Do (Node) — Handoff / Project context
Egnet som
CLAUDE.mdfor fremtidige Claude-sesjoner. Dette er videreutviklingen av PHP-versjonen i../netops-todo-server/— samme formål og datamodell, men ombygd til Node/npm med sanntidssynk og flere samarbeidsfunksjoner. PHP-versjonen ligger urørt ved siden av.
Hva er dette
To-do-applikasjon for en network engineer / et lite driftsteam. Kategorier L1–L4, BGP, peering, security, NMS, automatisering, dokumentasjon, incident, prosjekt. Hver oppgave har prioritet (P1–P4), status, estimat, lokasjon, frist, tags, eier, kommentarer og audit-felter.
Nytt mot PHP-versjonen:
- WebSocket-sanntidssynk (erstatter 60s-polling) + presence + "redigerer nå"
- Kanban-tavle med drag & drop, i tillegg til tabellvisning
- Kommentarer per oppgave
- Aktivitetslogg (hvem gjorde hva, server-side, capped til 400 entries)
- Optimistisk låsing —
v-felt per oppgave, 409 ved konflikt - Hurtig-registrering med token-parsing (
#kat @eier p1 !frist ~timer loc:sted) - Angre sletting, tastatursnarveier, persistente filtre (localStorage)
Filer
netops-todo-node/
├── server.js Express + ws. REST-API, WebSocket-hub, auth-oppslag.
├── lib/store.js Datalager: normalisering, validering, aktivitetslogg,
│ atomisk JSON-persistens. Kilden til sannhet for skjema.
├── public/
│ ├── index.html Markup. Ingen templating — app.js fyller alt.
│ ├── app.js All frontend-logikk (vanilla JS, ingen rammeverk).
│ └── style.css Mørkt tema, samme visuelle identitet som PHP-versjonen.
├── seed.json 16 eksempel-oppgaver.
├── test/api.test.js Integrasjonstester (node:test) — REST + WS ende-til-ende.
├── data/ Opprettes ved kjøring: tasks.json, activity.json, users.json.
└── README.md Installasjon, proxy-oppsett, API-referanse.
Arkitektur
- Alle mutasjoner via REST (lett å curl-e/feilsøke). WebSocket (
/ws) brukes kun til push: endringer, presence, editing-signaler. - Én node-prosess eier datakatalogen. Lagring i minnet, skriv til disk er
atomisk (tmp + rename) og serialisert gjennom en promise-kjede i
store.js. - Auth ligger utenfor appen:
X-Remote-User-header > Basic Auth > cookie (netops_user, kan skrus av medDISABLE_COOKIE_AUTH=1) >anon. Samme oppslag for HTTP og WS-upgrade (userFromRequesti server.js).
WebSocket-protokoll (server → klient)
| type | Innhold | Når |
|---|---|---|
hello |
user, online[], editing{} |
Ved tilkobling |
sync |
tasks[], activity[], evt. by |
Ved tilkobling + etter replace/seed |
task |
op: create/update/delete, task/id, by, activity |
Etter hver mutasjon |
presence |
online[] |
Når noen kobler til/fra |
editing |
editing{} = {taskId: [brukere]} |
Når noen åpner/lukker modal |
Klient → server: kun { type: 'editing', id, active }.
Task-skjema (kanonisk form — normalizeTask() i lib/store.js)
Som PHP-versjonen, pluss:
{
"v": 3,
"comments": [{ "id": "c_…", "by": "jon", "at": "ISO", "text": "≤1000" }]
}
v bumpes ved hver felt-oppdatering (ikke ved kommentarer — bevisst, så en
kommentar ikke gir falsk konflikt for noen som redigerer felter samtidig).
Klienten sender v den redigerte fra; mismatch → 409 med serverens task i
svaret. Frontend håndterer det i handleSaveError(): oppdaterer visningen,
viser varsel, og lar brukeren lagre på nytt (som da overskriver bevisst).
Designvalg verdt å vite
- Ingen database, ingen frontend-rammeverk, to npm-avhengigheter (express, ws). Samme "lett å patche for neste vakthavende"-filosofi som før.
- Broadcast går til alle, inkludert avsender. Klienten upserter idempotent på id, så dobbel oppdatering er harmløs. REST-svaret brukes også, slik at UI-et fungerer selv om WS er nede (da poller frontend hvert 30s).
- Delvis update er lov:
PUT /api/tasks/:idmed bare{v, status}— normalisering merger mot eksisterende. Quick-actions bruker dette. - Kommentar-sletting er begrenset til egen bruker (eneste autorisasjonsregel i appen — alt annet er åpent for alle innloggede).
- Chart.js fra CDN; frontend degraderer pent (skjuler grafer) uten nett.
Sikkerhetsstatus
Som PHP-versjonen (XSS-escaping i alle render-paths, whitelist-enums,
strenglengde-klamping, brukernavn-regex [A-Za-z0-9._@-]{1,64}), pluss:
/api/loginavviser ugyldige navn i stedet for å sanitere stille.- Cookie settes med
SameSite=Lax— gir grunnleggende CSRF-vern for cookie-auth-modus. Bak proxy-auth gjelder samme vurdering som før (intern bruk OK; offentlig nett → legg på token). express.json({ limit: '2mb' })begrenser payload (import av store lister).
Vanlige utvidelser
- Nytt felt per oppgave: input i modal (index.html) →
saveForm()ogparseQuickAdd()om ønskelig (app.js) →normalizeTask()(store.js) →diffDetail()for aktivitetsloggen →renderCard()/renderTable(). - Ny kategori:
CATEGORIES/CAT_COLORSi app.js +VALID_CATEGORIESi store.js. - SQLite: bytt persistens i
Store(load/_persist) motnode:sqlite— resten av appen er uberørt siden alt går gjennom Store-metodene. - Varsler ved frist: server har allerede deadline per task; en
setIntervali server.js som broadcaster{type:'due', …}+ Notification API i frontend er den naturlige veien.
Testing-status
npm test: 12 integrasjonstester (node:test), booter ekte server på tilfeldig port med temp-datakatalog. Dekker normalisering, versjonskonflikt, kommentar-autorisasjon, aktivitetslogg, WS-broadcast, persistens på disk, cookie-auth. Alle grønne per 2026-06-12 (Node 25).- Manuell røyk-test utført:
/healthz, statiske filer, seed, state, og WS-push av REST-endring verifisert ende-til-ende. - Ikke testet i nettleser med flere samtidige brukere — første ekte test bør
være to nettleservinduer mot
npm startog flytte kort på tavla.