8.7 KiB
NetOps To-Do — Handoff / Project context
Også egnet som
CLAUDE.mdfor fremtidige Claude-sesjoner som jobber videre med koden.
Hva er dette
En enkel, selvstendig to-do-applikasjon tilpasset en network engineer som jobber bredt: L1 felt-kabling, L2 switching, L3 ruting, L4 lastbalansering, BGP, peering, security, NMS, automatisering, dokumentasjon, incident og prosjekt. Hver oppgave har prioritet (P1–P4), estimert tid, status, lokasjon/site, frist, tags og eier.
Det finnes to versjoner levert i samme arbeidsstrøm:
| Versjon | Fil | Lagring | Bruksområde |
|---|---|---|---|
| Standalone | netops-todo.html (ligger ved siden av denne mappa) |
localStorage i nettleseren |
Personlig bruk på én maskin, ingen server nødvendig |
| Server / Apache | Hele netops-todo-server/-mappa |
data/tasks.json på server, fil-låst |
Delt for et team, auth i Apache eller proxy |
Server-versjonen er der man kommer til å være etter første "single user, deretter delt"-overgang.
Filer i server-pakka
netops-todo-server/
├── index.php Frontend (HTML + JS). Tynt PHP-lag øverst leser brukernavn fra Apache.
├── api.php REST-API (single file). Alle actions ligger i én switch.
├── seed.json 16 eksempel-oppgaver. Lastes via "Last inn eksempel-data"-knappen.
├── .htaccess Auth-skeleton + sperrer data/ for direkte web-tilgang.
├── data/
│ ├── .htaccess Nekter all web-tilgang til lagringskatalogen.
│ ├── tasks.json Opprettes av api.php ved første skriv. Liste av task-objekter.
│ └── known_users.json Liste over brukere som har vært innom (for owner-dropdown).
├── INSTALL.txt Installasjonsguide for Apache.
└── CLAUDE.md (denne filen)
Arkitektur
Frontend er én HTML-side med vanilig JS (ingen rammeverk) og Chart.js fra CDN. Backend er to PHP-filer, null dependencies, kjører rett på Apache mod_php / php-fpm.
Dataflyt
- Apache autentiserer brukeren (Basic Auth, ekstern proxy, eller hva enn man velger).
index.phpleserREMOTE_USER/PHP_AUTH_USER/HTTP_X_REMOTE_USER, injiserer det i siden somCURRENT_USER.- JS kaller
api.php?action=listved oppstart, såcreate/update/deleteved endringer. api.phpvaliderer input mot whitelister, normaliserer task-objektet, og skriverdata/tasks.jsonmedflock(LOCK_EX).- Hvert minutt pollere frontend
list-endepunktet for å hente endringer fra andre brukere.
API
Alle endepunkt: POST api.php?action=<name> med JSON-body. list godtar også GET.
| Action | Body | Svar |
|---|---|---|
| list | — | { user, tasks: [...], known_users: [...] } |
| create | task uten id | { task } (med tildelt id og audit-felt) |
| update | task med id | { task } |
| delete | { id } |
{ ok: true } |
| replace | array av tasks | { ok: true, count } (for import) |
| seed | — | { ok: true, count } (kun hvis db er tom) |
Task-skjema (kanonisk form)
{
"id": "t_abc123",
"title": "string ≤200",
"desc": "string ≤4000",
"category": "L1|L2|L3|L4|BGP|PEER|SEC|NMS|AUTO|DOC|INC|PROJ",
"priority": "P1|P2|P3|P4",
"status": "todo|progress|blocked|done",
"estHours": 0,
"location": "string ≤120",
"deadline": "YYYY-MM-DD eller tom",
"tags": ["≤20 strings, hver ≤40"],
"owner": "brukernavn eller tom = utildelt",
"created": "ISO timestamp",
"createdBy": "brukernavn",
"updated": "ISO timestamp",
"updatedBy": "brukernavn",
"completed": "YYYY-MM-DD eller null",
"completedBy": "brukernavn eller null"
}
normalize_task() i api.php er kilden til sannhet. Den whitelister enums, klamper strenger, valider deadline-format, og setter audit-feltene automatisk basert på current_user().
Designvalg som er verdt å vite
- Ingen database. JSON-fil +
flockholder fint helt opp i tusenvis av oppgaver. Hvis det skulle bli ytelsestrøbbel, er det enkleste å bytte til SQLite (PHPpdo_sqlitefølger med). - Auth utenfor koden. Innloggings-logikk er bevisst utelatt. Apache / proxy gjør jobben. Det gjør at koden er trivielt enkel å revidere og bytte ut.
- Felles datalager, ikke per-bruker. Brukerne ser samme oppgaveliste, men
ownerper oppgave + audit-felt gir attribusjon. - No-framework frontend. Holdt bevisst gammeldags vanlig JS for at det skal være lett å patche av neste vakthavende.
- Polling, ikke websocket. En
list-request hvert 60s er nok for et team. Hvis flere skal jobbe samtidig kan intervallet senkes, men brukerne kan også trykke ↻.
Sikkerhetsstatus
| Risiko | Tiltak |
|---|---|
| XSS i task-tekst | escapeHtml() i alle render-paths, htmlspecialchars() for brukernavn i PHP |
| Path traversal | Filsti er hardkodet (__DIR__ . '/data/tasks.json'), ingen brukerinput i path |
| Direct read av tasks.json | Egen .htaccess i data/ med Require all denied |
| Race conditions | flock(LOCK_EX) ved skriving, LOCK_SH ved lesing |
| Injection i enums | Whitelist-validering: in_array($val, $VALID_*, true) |
| Sanitering av brukernavn | preg_replace('/[^A-Za-z0-9._@\-]/', '', $user), maks 64 tegn |
| CSRF | Ikke håndtert eksplisitt. For en intern admin-side bak proxy med Basic Auth er det typisk akseptabelt, men hvis det monteres på offentlig nett bør det legges til en X-Requested-With-sjekk eller token. |
Vanlige utvidelser
Hvis du jobber videre med dette, dette er de mest sannsynlige neste stegene og hvor du putter dem:
Nye kategorier eller prioriteter:
- Frontend: legg til i
CATEGORIES-array ogCAT_COLORS-map iindex.php(JS-delen). - Backend: legg til i
$VALID_CATEGORIES/$VALID_PRIORITIESiapi.php.
Nytt felt per oppgave:
- Legg til input i modal i
index.php. - Plukk opp i
saveForm()(JS) og send med i body. - Legg til i
normalize_task()(PHP) med passende sanitering. - Vis det i
renderTable()om ønskelig.
Bedre samarbeid:
- Server-Sent Events fra PHP: ny
?action=streamsom holder en åpen koblet medCache-Control: no-cache, sjekker fil-mtime og pusher endringer. - Eller bare senke
setInterval(loadAll, 60000)iinit().
Audit-logg / historikk:
- I
normalize_task()legg til append tildata/audit.logmed[$updatedBy] $action $taskId. - Vis logg under hver oppgave-modal med en ny
?action=history&id=....
Per-bruker syn:
- Endre
listtil å filtrere på$userhvis et flagg er satt. - Eller bare la frontend defaulte filter "Eier=Meg" — enklere.
SQLite-migrering (hvis JSON blir tregt):
- Bytt
read_tasks()ogwrite_tasks()mot PDO-kall. - Skjemaet matcher allerede et fornuftig SQL-skjema.
Kjente begrensninger
- Ingen optimistisk locking på enkeltoppgave-nivå. Hvis to brukere lagrer samme oppgave samtidig, vinner den siste. Dette er hentet inn ved at filen i sin helhet låses, men man får ikke conflict-deteksjon.
- Ikke i18n. Norsk er hardkodet i UI. Strings er samlet, så det er ikke vondt å trekke ut.
- Ingen pagination i tabellen. Fungerer fint opp til noen hundre åpne oppgaver, deretter bør man legge til virtual scrolling eller side-knapper.
- Klokken nederst i hover er klient-tid, ikke server-tid.
Testing-status
- PHP-syntaks verifisert med AST-parser (
php-parservia node, PHP 8-modus). - Kryssreferanse JS ↔ PHP: alle
api('X')-kall fra frontend har matchendecase 'X':i api.php. - Kryssreferanse DOM-IDer ↔ JS: alle
getElementById('x')har matchendeid="x"i HTML. - Onclick-handlere ↔ funksjonsdefinisjoner: ingen referanser til udefinerte funksjoner.
- Ikke kjørt end-to-end (sandbox manglet PHP-runtime). Første ekte test bør være:
php -S localhost:8080i mappa og åpne i nettleser.
Hurtigreferanse — installasjon
# 1. Kopier til server
sudo cp -r netops-todo-server /var/www/netops-todo
# 2. Skriverettigheter for data/
sudo chown -R www-data:www-data /var/www/netops-todo/data
sudo chmod 750 /var/www/netops-todo/data
# 3. Basic Auth-brukere (utenfor docroot!)
sudo htpasswd -c /etc/apache2/netops.htpasswd jon
sudo htpasswd /etc/apache2/netops.htpasswd kari
# 4. Aktiver auth-blokken i .htaccess (kommenter ut linjene under "1) Basic Auth")
sudo nano /var/www/netops-todo/.htaccess
# 5. Sørg for at AllowOverride All er aktivt i vhost
# <Directory /var/www/netops-todo>
# AllowOverride All
# Require all granted
# </Directory>
sudo systemctl reload apache2
# Åpne http://din-server.no/netops-todo/ → "Last inn eksempel-data"
Se INSTALL.txt for fyldigere variant og feilsøking.