internal/folderapi: neue Backend-Voraussetzung - GET /folders/{id}/
children (lazy Baum-Ladung), .../breadcrumb (ueber DOC-09s Materialized
Path), .../documents (Dokumentenliste, whitelisted Sortierspalten).
folder.go ergaenzt ListChildren/Breadcrumb (additiv, keine bestehende
Funktion geaendert).
web/dms-browser: Next.js/React/TypeScript. Navigationsbaum laedt Kinder
lazy je Ebene, Dokumentenliste ist virtualisiert (lib/virtualization.ts,
abhaengigkeitsfrei - nur sichtbarer Ausschnitt + Overscan wird gerendert),
Mehrfachauswahl (lib/selection.ts: Klick/Strg/Umschalt), Tastatur-
navigation im Baum (lib/treeKeyboard.ts). Aktueller Ordner steckt in der
URL (Catch-all-Route /browse/[[...path]]) statt nur im React-State - der
Browser verwaltet Vor-/Zurueck-Navigation selbst.
Echter Bug beim Schreiben der Virtualisierungs-Tests gefunden und
behoben: startIndex war bei scrollTop jenseits des tatsaechlichen Inhalts
nicht auf totalRows geklemmt (haette zu ungueltigem slice() gefuehrt).
Pruefungen:
1. Liste mit 10.000 Zeilen scrollt ruckelfrei - Virtualisierung rendert
nachweislich nur ~20 statt 10.000 Zeilen
2. Navigation vollstaendig per Tastatur - 5 Vitest-Tests fuer Pfeiltasten/
Enter im Baum
3. Zustand bleibt beim Zurueck-Navigieren erhalten - Ordner-ID in der URL,
Browser-History uebernimmt die Wiederherstellung
Regressionsfrei: alle bestehenden Go-Pakete PASS.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2.9 KiB
DOC-10 – Prüfprotokoll: Ordner-Navigation & Dokumentenliste
Stand: 2026-09-17. Testhost 192.168.1.131.
Backend-Voraussetzung: internal/folderapi (neu für diese Kachel)
GET /folders/{id}/children (lazy Baum-Ladung je Ebene), GET /folders/{id}/breadcrumb
(Brotkrumenpfad über den Materialized Path aus DOC-09), GET /folders/{id}/documents
(Dokumentenliste, whitelisted Sortierspalten — kein Sprintf mit Nutzereingabe im SQL-Text).
go test ./internal/folderapi/... -v — 3/3 PASS.
Akzeptanzkriterium 1: Baum und Liste bleiben synchron
TestHandleChildrenAndDocuments_ReflectSameFolderState — PASS. Beide Endpunkte fragen denselben
Datenbestand ab, kein separater Baum-Cache im Backend — das Frontend hält ebenfalls keinen eigenen,
potenziell abweichenden Zustand: Ordnerwechsel löst denselben Fetch für Baum-Selektion UND Liste aus.
Prüfung 1: Liste mit 10.000 Zeilen scrollt ruckelfrei
lib/virtualization.ts + computeVisibleRange-Tests (Vitest) — 5/5 PASS. Bei 10.000 Zeilen werden
nachweislich nur die sichtbaren ~20 Zeilen plus Overscan-Puffer gerendert (Test prüft explizit
< 50 gerenderte Elemente), nicht alle 10.000 — der eigentliche Mechanismus hinter "ruckelfrei".
Echter Bug während der Testerstellung gefunden und behoben: startIndex war bei einem
scrollTop jenseits des tatsächlichen Inhalts (z. B. veralteter Scroll-Zustand nach Datenwechsel)
nicht auf totalRows geklemmt — hätte zu einem slice-Aufruf mit startIndex > array.length
geführt. Fix + Regressionstest siehe lib/virtualization.test.ts.
Prüfung 2: Navigation vollständig per Tastatur
lib/treeKeyboard.ts — 5/5 Tests PASS: Pfeil hoch/runter (Fokus bewegen, an Listengrenzen
geklemmt), Pfeil rechts/links (auf-/zuklappen), Enter/Leertaste (auswählen). FolderTree.tsx
verdrahtet das über onKeyDown auf dem role="tree"-Container.
Prüfung 3: Zustand bleibt beim Zurücknavigieren erhalten
Der aktuelle Ordner steckt in der URL (/browse/<id1>/<id2>/..., Next.js Catch-all-Route
[[...path]]) statt nur im React-State — der Browser verwaltet Vor-/Zurück-Navigation über die
URL selbst, kein eigener History-Code nötig. Struktureller Nachweis über den Seitenaufbau; ein
Klick auf einen Baumknoten ruft router.push() auf, wodurch derselbe Ordner nach Zurück-Navigation
erneut aus der URL aufgelöst wird.
Akzeptanzkriterium 3: Mehrfachauswahl mit Umschalt- und Strg-Taste
lib/selection.ts — 5/5 Tests PASS: einfacher Klick, Strg-Klick (Hinzufügen/Abwählen), Umschalt-
Klick (zusammenhängender Bereich, auch rückwärts vom Anker aus).
Build/Test-Ergebnis
npx tsc --noEmit— saubernpm test(Vitest) — 18/18 (api, selection, virtualization, treeKeyboard)npm run build— erfolgreich (/browse/[[...path]]-Route, 2,73 kB / 90 kB First Load JS)- Go:
gofmt -l .,go build ./...,go vet ./...sauber;go test ./...— alle Pakete PASS, keine Regression