netops/netops-todo-node/CLAUDE.md
Jon Vanvik 6b9dbf8254 Legg til Node/npm-versjon med sanntidssynk + Debian 13-oppsettsskript
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>
2026-06-12 11:54:22 +02:00

6 KiB
Raw Blame History

NetOps To-Do (Node) — Handoff / Project context

Egnet som CLAUDE.md for 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 L1L4, BGP, peering, security, NMS, automatisering, dokumentasjon, incident, prosjekt. Hver oppgave har prioritet (P1P4), 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åsingv-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 med DISABLE_COOKIE_AUTH=1) > anon. Samme oppslag for HTTP og WS-upgrade (userFromRequest i 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/:id med 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/login avviser 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() og parseQuickAdd() om ønskelig (app.js) → normalizeTask() (store.js) → diffDetail() for aktivitetsloggen → renderCard()/renderTable().
  • Ny kategori: CATEGORIES/CAT_COLORS i app.js + VALID_CATEGORIES i store.js.
  • SQLite: bytt persistens i Store (load/_persist) mot node:sqlite — resten av appen er uberørt siden alt går gjennom Store-metodene.
  • Varsler ved frist: server har allerede deadline per task; en setInterval i 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 start og flytte kort på tavla.