v0.5.2
07.06.2026- Neue Sektion „Gerät einrichten" ganz oben in den Einstellungen: Auf einem neuen Gerät einmal den kurzen Einrichtungs-Code eingeben — die App holt sich KI-Key (Anthropic) und Upload-Token automatisch vom Server, kein Abtippen langer Schlüssel mehr. Zusammen mit „DATANORM vom Server laden" ist ein neues Tablet damit in unter einer Minute eingerichtet.
v0.5.1
07.06.2026- DATANORM-Material-Stamm (OBETA) lässt sich jetzt direkt vom Server laden — neuer Knopf "DATANORM vom Server laden" in den Einstellungen (Bereich Material-Stamm). Damit muss der ~1,1-Mio-Artikel-Stamm auf einem neuen Gerät bzw. nach dem Umzug auf preuss.arriflex.de nicht mehr per USB-Stick eingelesen werden, sondern kommt mit einem Tipp aus dem Web.
- Auch künftige Stamm-Updates laufen so: die schlanke OBETA-Datei wird auf dem Server ausgetauscht, in der App einmal neu laden — fertig. Der Knopf erscheint nur, wenn auf dem Server eine Datei bereitliegt (mit Stand-Datum + Größe).
v0.5.0
07.06.2026- Meilenstein: Server-Anbindung an das neue Archiv (preuss.arriflex.de). Die App läuft jetzt direkt aus dem Web statt nur per USB-Stick — Updates kommen automatisch über den Service Worker.
- Neuer Versand-Weg: Beim "An Kunde senden" / "An Preuß senden" lädt die App den fertigen Bericht zum Server-Archiv und der Server verschickt die Mail selbst per SMTP. Kunde und Firma Preuß bekommen wie gehabt getrennte Mails mit unterschiedlichen PDF-Varianten (Kunde ohne Fotos, intern mit Fotos + Bestellzettel).
- Robustheit im Funkloch: Ist der Server beim Senden nicht erreichbar, geht die Mail sofort über K-9 raus (alter Weg) UND der Bericht wandert in eine Upload-Warteschlange, die beim nächsten Online-Moment automatisch nachreicht (archiv-only, keine Doppel-Mail). Scheitert nur der serverseitige Mailversand, springt ebenfalls K-9 ein.
- Neue Einstellung "Server / Archiv & Mailversand": Upload-Token eintragen + "Verbindung testen" (prüft Erreichbarkeit, Token-Gültigkeit und ob der Mailversand scharf ist). Ohne Token bleibt alles beim bisherigen K-9-Weg. Offene Warteschlange wird hier angezeigt und kann manuell nachgereicht werden.
- Web-Archiv mit Login (preuss.arriflex.de/archiv): durchsuchbare Liste aller eingegangenen Berichte (Nr./Kunde/E-Mail), pro Bericht die Varianten Kunde/Intern als PDF öffnen, Versand-Status (✓/✗ Mail) sichtbar.
- Service Worker lässt /api und /archiv jetzt unberührt durch (kein Cache/Offline-Fallback für Server-Pfade). Datenmodell v8: neue Tabelle uploadQueue für ausstehende Uploads.
v0.4.26
19.05.2026- PWA-Härtung gegen das Phänomen "App ist nach 2 Tagen Inaktivität halb kaputt". Bisher hat ein einzelner Netz-Hiccup während eines SW-Updates dazu geführt, dass einzelne APP_ROUTES nicht im Cache landen, der SW aber trotzdem als installiert galt — Folge: fehlende Seiten, die später zur Offline-Fallback-Karte führen.
- Service Worker: Install ist jetzt ALL-OR-NOTHING. Wenn auch nur eine einzige APP_SHELL-URL nicht erfolgreich abgerufen werden kann (oder kein App-HTML zurückgibt), schlägt der gesamte Install fehl, der neue SW geht NICHT live, der alte bleibt aktiv und liefert weiterhin den funktionierenden Cache. Activate löscht alte Caches nur NACHDEM der neue per isStaticCacheComplete-Check verifiziert wurde.
- Service Worker: Neue Message-Handler CACHE_HEALTH_CHECK (liefert Liste fehlender Routen zurück) und REPAIR_CACHE (lädt fehlende Routen nach). Damit kann der Client jederzeit prüfen ob alles da ist und ggf. reparieren — ohne den User zu stören.
- ServiceWorkerRegister-Komponente komplett überarbeitet: navigator.storage.persist() wird beim Mount erzwungen; nach SW.ready läuft sofort ein Health-Check; bei fehlenden Routen läuft automatisch ein Repair; periodische Re-Checks alle 6h, plus bei visibilitychange (Tab kommt in den Vordergrund) und bei online-Event. Bei gescheitertem Repair erscheint ein roter Banner oben mit Aktualisieren-Knopf, der SW und Caches komplett wegputzt und neu lädt.
- Effekt für den User: solange der Tablet-Browser irgendwann mal online ist (auch nur kurz), repariert sich der App-Cache selbst. Kein "App geht plötzlich nicht mehr"-Reset mehr, kein manuelles Cache-Löschen nötig.
v0.4.25
17.05.2026- Fotos und Bestellzettel-Positionen werden nicht mehr versehentlich gelöscht, wenn man direkt nach + Neuer Bericht ohne Umweg über den Hauptteil des Editors zu Fotos/Bestellzettel wechselt und dort etwas einträgt. Vorher: Auto-Save der beiden Subseiten speicherte den Bericht zwar, vergaß aber den Flag istUnberuehrt auf false zu kippen — beim nächsten Aufruf der /berichte/-Liste hat der Cleanup den Bericht inklusive der frisch eingetragenen Fotos/Positionen weggeräumt. Jetzt prüfen auch fotos/page.tsx und bestellung/page.tsx über istBerichtInhaltlichBeruehrt() und kippen den Flag.
v0.4.24
17.05.2026- Berichts-Nr. wird nicht mehr verbrannt, wenn ein Entwurf gelöscht wird — der „Bericht löschen"-Button im Editor ruft jetzt loescheBericht(), das gleich naechsteBerichtsNr neu setzt: naechsteBerichtsNr = max(verbleibende Berichts-Nrn) + 1. Folgendes Verhalten: wenn man den zuletzt angelegten Bericht löscht, bekommt der nächste neue Bericht wieder dieselbe Nr. Wenn man Berichte in der Mitte löscht (Nr-Lücke), wirkt sich das nicht aus.
- Cleanup-Logik für unberührte Entwürfe ("+ Neuer Bericht" → leer schließen) verwendet dieselbe max+1-Regel statt der bisherigen "nur zusammenhängende Lücke am Ende"-Heuristik — robuster und konsistent.
- Bei vollständig leerer Bericht-Tabelle (alle gelöscht) bleibt naechsteBerichtsNr unverändert — der User entscheidet selbst, ob er von vorne zählen will (über die Einstellungen).
v0.4.23
17.05.2026- „+ Neuer Bericht" hinterlässt keinen Müll mehr, wenn der User direkt wieder schließt — der Editor markiert den frisch angelegten Bericht als istUnberuehrt=true; sobald der User irgendeinen inhaltlichen Wert einträgt (Adresse, Arbeit, Zeiten, Material, Fotos, Status, Unterschrift…), wird der Flag im nächsten Auto-Save-Tick auf false gekippt. Die /berichte/-Liste räumt beim Mount alle istUnberuehrt=true-Berichte weg und gibt die zuletzt verbrauchten Berichts-Nrn an die naechsteBerichtsNr zurück, wenn sie zusammenhängend waren — keine Lücken durch verlassene Entwürfe
- Schema-Migration v7 markiert bestehende komplett leere Entwürfe (alle 3 Adressen leer, keine Arbeit/Material/Fotos/Bestellzettel/Zeiten/Unterschrift, Status=entwurf) automatisch als istUnberuehrt — beim ersten /berichte/-Aufruf nach dem Update verschwinden sie still und die Bericht-Nr wird soweit möglich zurückgesetzt
- /berichte/-Liste hat einen zweiten Sicherheitsfilter (istUnberuehrt !== true), falls eine Cleanup-Race-Condition jemals etwas durchrutschen lässt
v0.4.22
17.05.2026- Bericht-Editor legt bei ungültiger ID in der URL keinen neuen Bericht mehr klammheimlich an — vorher hat ein Aufruf wie /berichte/edit/?id=NICHT-VORHANDEN still einen neuen Bericht inkl. nächster Berichts-Nr. erzeugt und die URL umgeschrieben; jetzt klare „Bericht nicht gefunden"-Karte mit Link zur Liste
- Fotos-Seite und Bestellzettel-Seite hängen nicht mehr ewig auf „Lade Bericht…", wenn die ID in der URL nicht in der IDB existiert — jetzt analog „Bericht nicht gefunden"-Karte (konsistent zu /kunden/detail/)
- leererBericht() initialisiert fotos und bestellzettel explizit als leere Arrays — vorher waren beide Felder undefined, was die Subseiten zwar defensiv behandelt haben, aber unsauber war und Edge-Cases bei JSON-Export/Migration auslösen konnte
- tools/cdp-tablet.js: offline-tour testet jetzt zusätzlich /berichte/edit/, /berichte/fotos/, /berichte/bestellung/ und /kunden/detail/ — vorher waren genau diese Detail-Routen aus der Offline-Verifikation ausgespart, was beim v0.4.21-Fix unbemerkt eine kritische Lücke gelassen hat
- tools/cdp-tablet.js: Header-Kommentar korrigiert von `npx serve -s out` zu `npx serve out` (das -s-Flag vergiftet bekanntermaßen den SW-Precache)
v0.4.21
15.05.2026- Offline-Bug behoben: Editor öffnete sich nicht und sprang automatisch zur Startseite zurück — Ursache waren mehrere Routen (`/berichte/neu/`, `/berichte/edit/`, `/berichte/fotos/`, `/berichte/bestellung/`, `/kunden/detail/`, `/lebensakte/`), die nicht im Service-Worker-Precache lagen; offline lieferte der Catch-Branch dann die Startseite aus
- Service-Worker-Precache (`APP_ROUTES`) wird jetzt beim Build automatisch aus `src/app/`-Struktur generiert — neue page.tsx-Routen landen ohne Handarbeit im Cache
- Offline-Fallback bei wirklich unbekannter Route ist keine stille Weiterleitung zur Startseite mehr, sondern eine klare Karte „Seite offline nicht verfügbar"
- Real-Device-Diagnose-Tool `tools/cdp-tablet.js` ergänzt: `diag`/`update`/`neu-bericht`/`offline-tour`/`full` per ADB+CDP gegen das Tablet, echter Flugmodus via `adb shell cmd connectivity airplane-mode`
v0.4.20
11.05.2026- Einstellungs-Seite lädt jetzt wirklich sofort: der teure Lieferanten-Index-Scan (uniqueKeys über 1,1 Mio Artikel-Records, blockierte alle IDB-Tx auf Android-Chrome ~30 s) ist durch einen Cache in der meta-Tabelle ersetzt. Bei Import / Lieferant-Löschen / Stamm-Clear wird der Cache mitgeführt — kein Voll-Scan mehr
- Erst-Mount nach Schema-Migration (oder bei leerem Cache) berechnet einmalig live und legt das Ergebnis ab; danach instant
- Neue Sektion „Log / Diagnose" in den Einstellungen: zeigt Fehler und Schlüssel-Ereignisse (PDF-Erzeugung, Mail-Versand, DATANORM-Import, FSA-Speicherung) — letzte 500 Einträge in IDB, exportierbar als JSON
- Globale window.onerror und unhandledrejection-Handler schreiben automatisch ins Log, damit man im Feld nachgucken kann was kaputt war — ohne USB / DevTools
v0.4.19
11.05.2026- Einstellungs-Seite öffnet sich jetzt sofort: der teure Lieferanten-Index-Scan (uniqueKeys über 1,1 Mio Artikel-Records, ~30 s auf Android-Chrome) läuft hinter setTimeout 0, damit der erste Paint nicht blockiert wird
- Während des Scans zeigt die Sektion einen dezenten „Statistik wird geladen…"-Hinweis; danach erscheinen Lieferant + Anzahl wie gewohnt
v0.4.18
11.05.2026- Einstellungen-Seite öffnet sich jetzt schnell auch bei großer Verwendungs-Statistik: Gesamt-Summe der Artikel-Verwendungen kommt aus einem mitgeführten Cache (neue meta-Tabelle, Schema v5), kein Voll-Scan mehr beim Mount
- recordArtikelVerwendung läuft jetzt in einer Transaction über artikelVerwendung + meta, damit der Counter auch bei parallelen Auswahl-Klicks konsistent bleibt
- Backfill setzt die Cache-Summe gleich mit; nach Migration auf Tablets mit bestehenden Daten wird die Summe beim ersten Settings-Öffnen einmalig berechnet und persistent abgelegt
v0.4.17
11.05.2026- Einstellungen werden jetzt 500 ms nach jeder Änderung automatisch gespeichert — Unterschrift kann nicht mehr verloren gehen weil Speichern-Klick vergessen wurde
- Berichte-Ordner-Sektion ist jetzt status-aware: nach Browser-Restart („Berechtigung abgelaufen") zeigt sie den gemerkten Ordnernamen plus Reaktivieren-Button — kein erneutes Picken mehr nötig
- Statusanzeige am Save-Button: „wird automatisch gespeichert" / „✓ gespeichert"
v0.4.16
11.05.2026- Artikel-Autocomplete-Dropdown öffnet sich nur noch wenn der User aktiv im Feld steht — keine Doppel-Bestätigung mehr nach Cross-Spalten-Auswahl (Bezeichnung ↔ Artikel-Nr. setzen sich gegenseitig, jetzt geht das Dropdown der anderen Spalte nicht mehr auf)
- Beim erneuten Öffnen eines Berichts bleiben alle Material-Dropdowns geschlossen — Suche läuft erst wenn der User wirklich tippt
v0.4.15
11.05.2026- Artikel-Suche jetzt echtes Multi-Wort-AND: pro Wort eigener Token-Index-Lookup, Schnittmenge bildet die Treffer — Reihenfolge ist garantiert egal, „busch schalter" findet dasselbe wie „schalter busch"
- Hersteller-Artikelnummer als Einzel-Eingabe matcht zuverlässig: Code-artige Wörter (mit Ziffer) werden zusätzlich gegen die OBETA-Bestellnummer geprüft, mit und ohne Sonderzeichen (z.B. „6213-200" findet Artikel mit „6213200" in der Nummer)
- Spezifischste Wörter (= längste) laufen zuerst — bei früh leerer Schnittmenge spart die Suche restliche Index-Hits
v0.4.14
11.05.2026- Artikel-Autocomplete sortiert Treffer jetzt nach Verwendungs-Häufigkeit — oft gewählte Artikel (Standard-Programme wie Reflex SI, Standard 55 …) kommen oben
- Neue Dexie-Tabelle `artikelVerwendung` (Schema v4) — bleibt bei DATANORM-Re-Import erhalten
- Backfill-Funktion baut die Statistik aus allen vorhandenen Berichten und Bestellzetteln initial auf
- Neue Sektion „Häufig benutzte Artikel" in Einstellungen mit Top-10-Liste und Backfill-Button
v0.4.13
11.05.2026- Kunden-Mail-Vermerk verweist jetzt fest auf info@elektrohaus-preuss.de als Kontaktadresse (statt auf den variablen preussInternEmail)
v0.4.12
11.05.2026- Kunden-Mail bekommt No-Reply-Vermerk am Ende: Hinweis dass die E-Mail direkt vom Techniker-Tablet kommt und nicht überwacht wird, mit Verweis auf preussInternEmail für Rückfragen
- Interner Versand an Preuß bekommt kurzen No-Reply-Vermerk („Diese Mail kommt direkt vom Tablet — bitte nicht antworten")
v0.4.11
11.05.2026- Lebensakte als Route `/lebensakte` mit Versions-Historie — Klick auf Versions-Badge im Header öffnet sie
- PwaInstallBanner oben in Einstellungen: warnt wenn IndexedDB-Storage nicht persistent ist (sonst räumt Chrome zwischen Sessions weg)
- Banner bietet Install-Button (PWA installieren = persistenter Storage) und „Persist-Status anfordern"; zeigt belegten Speicher und Quota
v0.4.10
11.05.2026- Bitte nachtragen
v0.4.9
11.05.2026- Bitte nachtragen
v0.4.8
11.05.2026- Bitte nachtragen
v0.4.7
11.05.2026- Bitte nachtragen
v0.4.6
11.05.2026- Bitte nachtragen
v0.4.5
11.05.2026- Bitte nachtragen
v0.4.4
11.05.2026- Bitte nachtragen
v0.4.3
11.05.2026- Bitte nachtragen
v0.4.2
11.05.2026- Bitte nachtragen
v0.4.1
10.05.2026- DATANORM-Import optimiert: Token-Index (Multi-Entry `*tokens`) für ms-schnelle Autocomplete-Suche bei 1,1 Mio OBETA-Artikeln
- gzip-Auto-Dekompression via DecompressionStream — App akzeptiert direkt .gz-Dateien
- ArtikelAutocomplete in Material- und Bestellzettel-Rows: Klick setzt Bezeichnung + Obeta-Bestellnummer gleichzeitig
v0.4.0
10.05.2026- DATANORM-4.0-Großhändler-Anbindung an OBETA Berlin (Oskar Böttcher GmbH & Co. KG)
- Neue Dexie-Tabelle `artikel` mit Schema-v3, Batch-Insert in 5000er-Häppchen
- Parser für V- und A-Sätze (fixed-width bei Obeta), Encoding-Auto-Detect CP850→UTF-8
- Sektion „Großhändler-Material-Stamm" in Einstellungen mit Live-Progress-Bar
v0.3.1
10.05.2026- KI-Autokorrektur: Trigger nach jedem Wort-Ende (Whitespace) + onBlur
- Auto-Apply ohne Banner — Korrektur wird direkt eingebaut
- AbortController cancelt vorherige Anfragen; Stale-Request-Schutz via aktiverInput-Ref
- Banner zeigt nur noch dezenten Spinner während busy + Fehler-Banner (4s Auto-Hide)
v0.3.0
10.05.2026- KI-Autokorrektur via Claude Sonnet 4.6 (Anthropic SDK direkt im Browser)
- API-Key in Einstellungen → IndexedDB (Single-User-Tablet)
- Drei Kontext-Modi: arbeit / arbeitsstand / material (Material extra konservativ)
- Integriert in 5 Feldern: auszufuehrendeArbeit, ausgefuehrteArbeit, arbeitsstand, material[].bezeichnung, bestellzettel[].bezeichnung
v0.2.3
10.05.2026- Kunden-Detailseite `/kunden/detail?id=...` mit aggregiertem Fotoalbum über alle Berichte
- „Öffnen"-Button pro Kunde in /kunden
- Match Bericht ↔ Kunde via rechnungsempfaenger.name + plz (case-insensitive)
v0.2.0
10.05.2026- Bestellzettel-Feature: neue Route `/berichte/bestellung?id=...` mit Material-ähnlichem Editor
- Einstieg über Button auf der Edit-Seite (über dem Foto-Block)
- PDF-Anhang `zeichneBestellzettel()` mit Materialzettel-Optik — nur im internen PDF an Preuß, nie beim Kunden
- Daten in `bericht.bestellzettel?: MaterialPosition[]` (optional, keine Migration nötig)
v0.1.0
08.05.2026- Erstversion auf Samsung-Tablet installiert
- Static-Export Next.js 16.2.6 + TypeScript + Tailwind 4 + Dexie + pdf-lib
- PWA mit Service Worker (Stale-While-Revalidate, Navigate-Fallback)
- PDF-Output 1:1 zur Original-Vorlage, pixel-genau via fitLine() + wrapForFit()
- File System Access API für direkte Ablage im Tablet-Ordner
- Unterschriften (Pad + Datei-Upload) und Foto-Upload (Kamera + Galerie getrennt)
- Datenmodell: kunden / mitarbeiter / berichte / einstellungen via Dexie
- Auto-Übernahme von Adressen aus Berichten in Kunden-DB (upsertKundeFromAdresse)