Vorab: drei Punkte der Roadmap-Liste waren Fehlannahmen. Eine Analyse mit
anschließender Gegenprüfung (jeder Befund musste einen Widerlegungsversuch
überstehen) hat sie ausgeräumt, bevor Code geändert wurde:
- "ab Seite 2 alles nach rechts verschoben" existiert nicht. Nachgemessen am
Prod-PDF ND2026-0015 mit pdftotext -bbox: Seite 1 und Seite 2 beginnen beide
bei 16,0 mm. Die echten Umbruchfehler waren andere.
- measure_status validieren war seit Phase 1 erledigt.
- Werkzeug-IDs / Teilnetz-Gruppierung / TCPDF-Fußzeile: verworfen, die
vorgeschlagenen Änderungen hätten das PDF verschlechtert.
PDF (alle Punkte am mehrseitigen Dokument nachgeprüft):
- Tabellenkopf der Geräteliste wird auf Folgeseiten wiederholt. Vorher standen
ab Seite 2 unbeschriftete Spalten — bei leeren MAC/Hostname-Feldern vier
namenlose Spalten.
- Messungs-Titelzeile und Ergebnis werden zusammengehalten. Vorher blieb die
Überschrift samt Ampel am Seitenende allein zurück, darunter ein leerer,
unten offener Rahmen; in einem Testlauf über 61 Umbruchlagen 5-mal (~8 %).
- Spalte "Gerätetyp" hatte 15 mm, ließ aber 10 Zeichen zu — "Chromecast/TV"
lief bis 199,0 mm bei 195 mm Tabellenkante über den Rahmen in den Druckrand.
- Deutsche Bezeichnungen mit Einheiten statt roher JSON-Schlüssel: aus
"VerlustProzent: 0 | MinMs: 4.4 | UptimeSek: 8123456" wird "Paketverlust: 0 %
| Kürzeste Antwortzeit: 4.4 ms | Betriebszeit: 94 Tage 1 Std". Als Whitelist
(netdiagKundenfelder(), gemeinsam für Karte und PDF) — interne Felder wie
arpAvailable, mdnsOk, probed, answered fallen damit automatisch heraus.
- "ARP-Tabelle nicht lesbar (/proc/net/arp) — braucht Root" wird beim Drucken
zu einem kundentauglichen Satz. Altdaten stehen so in der DB, deshalb
Ersetzung beim Drucken statt nur in der App.
Gerätemerkmale (der eigentliche Roadmap-Punkt): Der Techniker sah in der App
"Drucker HP, Port 9100", im Kundenprotokoll stand nur die IP. Die Felder
fehlten dabei nicht in der Übertragung, sondern durchgängig — ein Fix allein
in der API wäre folgenlos geblieben, weil Dolibarrs setSaveQuery() nur
deklarierte $fields schreibt. Ergänzt über die ganze Kette:
sql/llx_netdiag_device.sql + neue Migration llx_netdiag_device_v2.sql
(ADD COLUMN IF NOT EXISTS, wiederholbar, läuft bei jedem Modul-Update),
NetDiagDevice::$fields + Properties, api/protocols.php POST und GET,
Kartenansicht und PDF.
Neu: netbios_name, mdns_name, mdns_services, custom_name, open_ports,
found_via, last_seen. Im PDF steht jetzt statt "192.168.178.20" die Zeile
"Brother HL-L2350DW · Brother · Drucker · 80,443,9100" — der Name kommt aus
mDNS, obwohl der Hostname leer ist.
Sprachschlüssel Vendor -> NetDiagVendor: Die Gegenprüfung hielt den Punkt für
falsch (Translate::load() ist first-wins, im CLI-Test kam "Hersteller"), im
Browser stand in der Kartenansicht aber "Lieferant" — im HTTP-Kontext lädt
Dolibarr vorher andere Sprachdateien als im CLI. Statt der Ursache nachzugehen
jetzt ein eigener, kollisionsfreier Schlüssel; im Browser gegengeprüft.
Nebenbei: doppeltes "OK OK" beim Status 0 im PDF.
Gegen das Test-Dolibarr geprüft: Sync über die echte API (Login, POST, GET),
Felder in der DB kontrolliert, Kartenansicht im Browser, mehrseitiges PDF
gerendert und angesehen, Migration zweimal ausgeführt (idempotent).
protocols.php (POST) gab bei JEDEM Sync HTTP 500 zurueck — 0 Protokolle
wurden je gespeichert.
Ursache: protocol/device/measurement-Klassen deklarierten das tms-Feld im
$fields-Array als 'notnull' => 1. Dolibarrs createCommon() bricht ab (-1),
wenn ein notnull-Feld den Wert NULL hat und kein 'default' gesetzt ist.
tms wird von der App nie gesetzt (die DB fuellt es per CURRENT_TIMESTAMP),
also schlug jedes Insert fehl, bevor es ueberhaupt an die DB ging.
Fix: tms auf 'notnull' => 0 — so wie es der Dolibarr-Modul-Builder auch
generiert. Die DB-Spalte bleibt NOT NULL DEFAULT CURRENT_TIMESTAMP.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Netzwerk-Diagnose-Modul mit JSON-API für die NetDiag-App:
- 3 Tabellen (protocol/device/measurement), generisches JSON-result
- JSON-API: auth, customers, orders, protocols (idempotenter Sync), pdf
- JWT-Auth (HS256), CORS für die Capacitor-App
- Tabs an Thirdparty + Auftrag, Protokoll-Card, PDF-Generator
- QR-Code zum App-Download in der Modul-Konfiguration
- de_DE + en_US, Rechtesystem netdiag->protocol read/write/delete
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>