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> |
||
|---|---|---|
| .. | ||
| lib | ||
| public | ||
| test | ||
| .gitignore | ||
| CLAUDE.md | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| seed.json | ||
| server.js | ||
| setup-debian13.sh | ||
NetOps To-Do (Node-versjon)
Sanntids oppgavetavle for et nettverksdrift-team. Node + Express + WebSockets. Endringer fra én bruker dukker opp hos alle andre umiddelbart — ingen polling, ingen manuell refresh.
Kom i gang
npm install
npm start # → http://localhost:3000
Utvikling med auto-restart ved kodeendring:
npm run dev
Tester:
npm test
Miljøvariabler
| Variabel | Default | Beskrivelse |
|---|---|---|
PORT |
3000 |
HTTP-port |
HOST |
0.0.0.0 |
Lytteadresse |
DATA_DIR |
./data |
Katalog for tasks.json / activity.json / users.json |
DISABLE_COOKIE_AUTH |
(av) | Sett til 1 for å skru av selvvalgt navn via cookie — da gjelder kun proxy-headere |
Autentisering
Påloggingslogikk er bevisst holdt utenfor appen. Brukernavn hentes fra, i prioritert rekkefølge:
X-Remote-User-header — satt av reverse proxy (oauth2-proxy, Authelia, …)Authorization: Basic— Basic Auth terminert i proxy, brukernavnet gjenbrukesnetops_user-cookie — selvvalgt navn via "Sett navn"-knappen (hjemme/dev-bruk)anon
For team-bruk bak proxy: sett DISABLE_COOKIE_AUTH=1 så ingen kan velge navn selv.
Rask installasjon på Debian 13 (LXC/VM)
# Som root i containeren:
apt-get update && apt-get install -y git
git clone <din-remote> /opt/netops
bash /opt/netops/netops-todo-node/setup-debian13.sh
setup-debian13.sh installerer Node fra apt, kjører npm ci og setter opp
systemd-tjenesten (DynamicUser + StateDirectory, data i
/var/lib/netops-todo). Kjør skriptet på nytt etter git pull for å
oppgradere. Med proxy-auth: DISABLE_COOKIE_AUTH=1 bash setup-debian13.sh.
Bak reverse proxy
WebSocket-endepunktet er /ws og krever upgrade-støtte i proxyen.
Appen må ligge på rota av et (sub)domene (f.eks. todo.hjemme.lan) —
frontend bruker absolutte stier, så sti-prefiks (proxy.lan/todo/) fungerer ikke.
Nginx Proxy Manager
- Hosts → Proxy Hosts → Add Proxy Host
- Domain Names:
todo.dittdomene.no - Scheme:
http· Forward Hostname/IP: LXC-ens IP · Forward Port:3000 - Websockets Support: PÅ (påkrevd — sanntidssynken bruker
/ws) - Cache Assets: AV (ellers kan gammel
app.jsserveres etter oppgradering) - Block Common Exploits: valgfritt, fungerer fint sammen med appen
- Domain Names:
- SSL-fanen: Request a new SSL Certificate (Let's Encrypt) + Force SSL.
Frontend bytter selv til
wss:når siden er https. - Auth (valgfritt): Access Lists → lag liste med brukere (Basic Auth) og
knytt den til proxy-hosten. NPM/nginx sender
Authorization-headeren videre, og appen bruker brukernavnet derfra — da får hver kollega riktig attribusjon. Sett i så fallDISABLE_COOKIE_AUTH=1på tjenesten. Uten access list velger folk navn selv i UI-et (cookie).
nginx:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Remote-User $remote_user; # ved basic auth i nginx
}
Apache (mod_proxy_wstunnel):
ProxyPass /ws ws://127.0.0.1:3000/ws
ProxyPassReverse /ws ws://127.0.0.1:3000/ws
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Remote-User %{REMOTE_USER}s
Kjør som tjeneste (systemd)
# /etc/systemd/system/netops-todo.service
[Unit]
Description=NetOps To-Do
After=network.target
[Service]
# DynamicUser + StateDirectory: systemd lager bruker og /var/lib/netops-todo
# med riktige rettigheter automatisk — ingen useradd/chown nødvendig.
DynamicUser=yes
StateDirectory=netops-todo
WorkingDirectory=/opt/netops-todo
ExecStart=/usr/bin/node server.js
Environment=PORT=3000
# HOST=127.0.0.1 hvis proxyen kjører på samme maskin. Står proxyen i en annen
# container/host: fjern linjen (lytt på alt) og brannmur port 3000 til kun proxyen.
Environment=HOST=127.0.0.1
Environment=DATA_DIR=/var/lib/netops-todo
Environment=DISABLE_COOKIE_AUTH=1
Restart=on-failure
[Install]
WantedBy=multi-user.target
Funksjoner
- Sanntidssynk — alle endringer pushes til alle åpne faner via WebSocket
- Presence — se hvem som er pålogget akkurat nå
- Kanban-tavle med drag & drop mellom statuskolonner, pluss klassisk tabellvisning
- Dagsplan — plukk oppgaver fra lista og bygg en ordnet plan for dagen (dra for å sortere, kapasitet i timer, datovelger). Planen er personlig og synkes mellom dine egne faner.
- Kommentar ved statusbytte — når du markerer ferdig eller blokkert (via knapp, kanban-drag eller modal) tilbys du å skrive en kommentar som festes til oppgaven og vises i aktivitetsloggen
- Hurtig-registrering med tokens:
Bytt SFP #l1 p2 @me !imorgen ~1h loc:DC-OSL-1 - Kommentarer per oppgave
- Aktivitetslogg — hvem gjorde hva, når (sidepanel)
- Konfliktdeteksjon — versjonsnummer per oppgave; lagring fra utdatert versjon avvises med tydelig varsel i stedet for stille overskriving
- "Redigerer nå"-indikator — ser om en kollega har samme oppgave åpen
- Angre sletting direkte fra toast
- KPI-er, grafer (kategori/prioritet/eier), filtre, sortering, søk
- Eksport/import av JSON, eksempeldata for demo
- Tastatursnarveier:
nny ·/søk ·vbytt visning ·pdagsplan ·aaktivitet ·esclukk
API
Alle endepunkt under /api/, JSON inn/ut. v er versjonsnummer for
optimistisk låsing — send med ved update, få 409 hvis noen andre har lagret.
| Metode | Endepunkt | Beskrivelse |
|---|---|---|
| GET | /api/state |
Bruker, oppgaver, aktivitet, kjente brukere, online, og dagens plan |
| POST | /api/tasks |
Opprett oppgave (title påkrevd) |
| PUT | /api/tasks/:id |
Oppdater (delvis OK; send v for konfliktsjekk; valgfri comment festes som status-kommentar) |
| DELETE | /api/tasks/:id |
Slett |
| POST | /api/tasks/:id/comments |
Legg til kommentar { text } |
| DELETE | /api/tasks/:id/comments/:cid |
Slett egen kommentar |
| GET | /api/plan?date=YYYY-MM-DD |
Hent egen dagsplan (ordnet liste av task-ids) |
| PUT | /api/plan |
Lagre egen dagsplan { date, items: [id…] } |
| POST | /api/replace |
Erstatt hele listen (import) |
| POST | /api/seed |
Last eksempeldata (kun hvis tomt) |
| POST | /api/login |
Sett navn-cookie (hvis cookie-auth er på) |
| GET | /healthz |
Helsesjekk |
Eksempel:
curl -s -X POST localhost:3000/api/tasks \
-H 'Content-Type: application/json' \
-H 'X-Remote-User: jon' \
-d '{"title":"Sjekk BGP-sesjon mot AS2119","category":"BGP","priority":"P1"}'
Lagring
JSON-filer i DATA_DIR (atomisk skriv via tmp-fil + rename, serialisert i
prosessen): tasks.json, activity.json, users.json og plans.json
(dagsplaner per bruker per dato; planer eldre enn 30 dager ryddes ved oppstart).
Én node-prosess per datakatalog. Holder fint til tusenvis av oppgaver; blir det
trangt er SQLite (node:sqlite) neste naturlige steg.