Korrigiere README: erfundene Meldungen, veraltete und fehlende Abschnitte

Entfernt zwei nie existierende Statusmeldungen ("Kamera laeuft", "kein
Barcode gefunden"). Ergaenzt die seit final-fix-1 geltende, bisher
unerwaehnte Kandidaten-Regel fuer Stapel (sharesSetField), sowie zwei seit
final-fix-1 vorhandene, aber nirgends dokumentierte Funktionen:
Sitzungsfortsetzung beim Start und Ersatzweg ohne Kamera. Korrigiert einen
seit final-fix-1 falschen Pruefpunkt (automatische statt tatsaechlicher,
per Dialog bestaetigter Sitzungswiederherstellung nach Neuladen). Ergaenzt
die Dateistruktur-Tabelle um die bisher fehlenden src/ui/*.js-Dateien
(resume-dialog.js, describe-spec.js) und aktualisiert die veraltete
Testanzahl auf den aktuellen Stand.

Fuegt den Abschlussbericht dieser Aufraeumrunde hinzu.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
vchuser
2026-07-28 18:25:15 +02:00
co-authored by Claude Opus 5
parent e50e8f4cd2
commit 1acfee76d8
+37 -9
View File
@@ -6,9 +6,14 @@ App nennt den Stapel. Verglichen wird über alle Merkmale, die bei Modul und
Stapel bekannt sind — Kapazität, Bauform, Rank, Geschwindigkeit und, sofern Stapel bekannt sind — Kapazität, Bauform, Rank, Geschwindigkeit und, sofern
gelesen, Hersteller-Teilenummer (`specsCompatible` in `src/spec.js`); ein auf gelesen, Hersteller-Teilenummer (`specsCompatible` in `src/spec.js`); ein auf
einer Seite fehlendes Merkmal wird dabei übersprungen, nicht als Widerspruch einer Seite fehlendes Merkmal wird dabei übersprungen, nicht als Widerspruch
gewertet. Passt danach genau ein Stapel, wird das Modul zugewiesen; passen gewertet. Ein Stapel gilt dabei nur als Kandidat, wenn er mit dem Modul
mehrere, fragt die App nach (`proposeAssignment` in `src/session.js`). Das hat mindestens ein tatsächlich erkanntes Merkmal teilt (`sharesSetField` in
eine bewusst in Kauf genommene Folge: Konnte die Teilenummer nicht gelesen `src/session.js`) — ein Stapel ganz ohne erkannte Angaben (etwa aus einem
manuell entschiedenen Rot-Fall) ist deshalb nie automatisch treffend, sonst
würde er lautlos jedes folgende Modul an sich ziehen. Passt danach genau ein
Stapel, wird das Modul zugewiesen; passen mehrere, fragt die App nach
(`proposeAssignment` in `src/session.js`). Das hat eine bewusst in Kauf
genommene Folge: Konnte die Teilenummer nicht gelesen
werden — der häufige Fall bei überklebten oder beschädigten Etiketten — und werden — der häufige Fall bei überklebten oder beschädigten Etiketten — und
passt anhand der übrigen Merkmale nur ein Stapel, landet das Modul dort, auch passt anhand der übrigen Merkmale nur ein Stapel, landet das Modul dort, auch
wenn seine tatsächliche Teilenummer eine andere wäre. Diese Abwägung ist wenn seine tatsächliche Teilenummer eine andere wäre. Diese Abwägung ist
@@ -45,6 +50,20 @@ keine Daten verlassen das Gerät.
durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt oder durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt oder
widersprüchliche Barcodes) oder mehrdeutiger Stapelzuordnung fragt die widersprüchliche Barcodes) oder mehrdeutiger Stapelzuordnung fragt die
App nach. App nach.
5. **Sitzungsfortsetzung beim Start.** Findet die App beim Laden eine in
`localStorage` gesicherte, nicht leere Sitzung vor, wird sie nicht
stillschweigend übernommen, sondern zur Fortsetzung oder zum Verwerfen
angeboten (`askResumeSession` in `src/ui/resume-dialog.js`, verdrahtet über
`initResumeOffer()` in `src/main.js`). Erst „fortsetzen“ stellt Stapel,
Zähler und die „Zuletzt“-Zeile wieder her; „verwerfen“ löscht den
gesicherten Stand und die App startet leer.
6. **Ersatzweg ohne Kamera.** Lässt sich die Kamera nicht starten (z. B.
verweigerte Berechtigung), bleibt die App bedienbar: eine dauerhaft
sichtbare Schaltfläche „Bild auswählen“ öffnet stattdessen die native
Dateiauswahl (`setFilePickerVisible` in `src/ui/scan-view.js`). Die App
versucht danach nicht automatisch erneut, die Kamera zu starten - der
Kamera-Hinweistext bleibt für den Rest der Sitzung stehen und wird nicht
von der OCR-Verfügbarkeitsanzeige überschrieben.
Barcode- und OCR-Adapter sind gegen hängende Aufrufe abgesichert: Die Barcode- und OCR-Adapter sind gegen hängende Aufrufe abgesichert: Die
Erkennungs-Pipeline (`src/pipeline.js`) bricht einen Barcode-Versuch nach 10 Erkennungs-Pipeline (`src/pipeline.js`) bricht einen Barcode-Versuch nach 10
@@ -77,7 +96,7 @@ korrekt funktioniert.
npm test npm test
``` ```
97 Tests, alle grün (Stand dieses Dokuments). Getestet werden ausschließlich 101 Tests, alle grün (Stand dieses Dokuments). Getestet werden ausschließlich
die reinen Module ohne Browser-Zugriff: Teilenummer-Decoder, Spec-Normalisierung die reinen Module ohne Browser-Zugriff: Teilenummer-Decoder, Spec-Normalisierung
und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und
-Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen -Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen
@@ -118,7 +137,12 @@ nicht gesetzt ist).
| `src/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg | | `src/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg |
| `src/barcode.js` | Adapter zu `zxing-wasm` | | `src/barcode.js` | Adapter zu `zxing-wasm` |
| `src/ocr.js` | Bildaufbereitung (Otsu) und Adapter zu `tesseract.js` | | `src/ocr.js` | Bildaufbereitung (Otsu) und Adapter zu `tesseract.js` |
| `src/ui/` | Ansichten: Scan-Ansicht, Ergebnis-Einblendung, Rot-Dialog bei Mehrdeutigkeit, Sitzungsliste | | `src/ui/scan-view.js` | Scan-Ansicht: Kamera-Vorschau, Scan-Knopf, Stapel-Leiste, „Zuletzt"-Zeile, Ersatzweg-Schaltfläche bei fehlender Kamera |
| `src/ui/result-overlay.js` | Kurze Treffer-Rückmeldung (grün/gelb), blendet sich nach kurzer Zeit selbst wieder aus |
| `src/ui/ambiguous-dialog.js` | Rot-Dialog bei roter Konfidenz oder mehrdeutiger Stapelzuordnung |
| `src/ui/resume-dialog.js` | Dialog beim Start: gesicherte Sitzung fortsetzen oder verwerfen |
| `src/ui/session-list.js` | Sitzungsliste: Stapel-Übersicht, Umsortieren, Entfernen, Sitzung beenden |
| `src/ui/describe-spec.js` | Gemeinsame Kurzbeschreibung eines Specs (Kapazität, Rank, Geschwindigkeit, Bauform), wahlweise mit Platzhaltern für fehlende Felder; von Treffer-Rückmeldung, „Zuletzt"-Zeile und Sitzungsliste gemeinsam genutzt |
| `src/main.js` | Verdrahtung aller Module zur lauffähigen App | | `src/main.js` | Verdrahtung aller Module zur lauffähigen App |
| `src/styles.css` | Farbvariablen (Grün/Gelb/Rot der Ampel-Rückmeldung), Layout des Kamera-Vollbilds samt Zielrahmen, Stapel-Leiste und Aktionsknöpfe sowie die Overlays für Treffer-Rückmeldung, Rot-Dialog und Sitzungsliste | | `src/styles.css` | Farbvariablen (Grün/Gelb/Rot der Ampel-Rückmeldung), Layout des Kamera-Vollbilds samt Zielrahmen, Stapel-Leiste und Aktionsknöpfe sowie die Overlays für Treffer-Rückmeldung, Rot-Dialog und Sitzungsliste |
@@ -198,7 +222,8 @@ werden:
**Kamera und Aufnahme** **Kamera und Aufnahme**
- Preview-URL auf dem Handy öffnen (muss `https://` sein), Rückkamera-Bild - Preview-URL auf dem Handy öffnen (muss `https://` sein), Rückkamera-Bild
erscheint im Vorschaubereich, "Kamera läuft" wird angezeigt. erscheint im Vorschaubereich; die Statuszeile bleibt leer, solange Kamera
und Texterkennung verfügbar sind.
- Verweigerte Kamera-Berechtigung: verständliche Fehlermeldung erscheint - Verweigerte Kamera-Berechtigung: verständliche Fehlermeldung erscheint
*und* die Aufnahme-LED des Geräts erlischt tatsächlich wieder. *und* die Aufnahme-LED des Geräts erlischt tatsächlich wieder.
- Aufnahme-Knopf antippen, bevor das Kamerabild bereit ist: verständliche - Aufnahme-Knopf antippen, bevor das Kamerabild bereit ist: verständliche
@@ -232,7 +257,8 @@ werden:
darauf zurück? darauf zurück?
- Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten - Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten
Etiketten keine tatsächlich benötigten Zeichen ausschließt. Etiketten keine tatsächlich benötigten Zeichen ausschließt.
- Bild ohne lesbaren Code: "kein Barcode gefunden" statt Fehler oder Absturz. - Bild ohne lesbaren Barcode und ohne verwertbaren OCR-Text: Rot-Dialog
erscheint statt Fehler oder Absturz.
**Bedienung und Anzeige** **Bedienung und Anzeige**
- Zielrahmen liegt sinnvoll über dem Kamerabild, `object-fit: cover` füllt - Zielrahmen liegt sinnvoll über dem Kamerabild, `object-fit: cover` füllt
@@ -254,8 +280,10 @@ werden:
- Ein Modul zweimal scannen: beide Male derselbe Stapel, Zähler steigt. - Ein Modul zweimal scannen: beide Male derselbe Stapel, Zähler steigt.
- Rücknahme-Fläche nimmt genau den zuletzt erfassten Eintrag zurück, Zähler - Rücknahme-Fläche nimmt genau den zuletzt erfassten Eintrag zurück, Zähler
sinkt entsprechend. sinkt entsprechend.
- Seite neu laden während einer laufenden Sitzung: Stapel und Zähler bleiben - Seite neu laden während einer laufenden Sitzung: Dialog „Gesicherte
erhalten. Sitzung gefunden“ erscheint; erst nach „fortsetzen“ bleiben Stapel und
Zähler erhalten und die „Zuletzt“-Zeile zeigt wieder den tatsächlich
letzten Eintrag; „verwerfen“ führt zu einem leeren Start.
- Sitzungsliste öffnen, Eintrag umsortieren, Eintrag entfernen: Ansicht baut - Sitzungsliste öffnen, Eintrag umsortieren, Eintrag entfernen: Ansicht baut
sich korrekt neu auf. sich korrekt neu auf.
- "Sitzung beenden": Ansicht wird leer, und ein anschließendes Neuladen - "Sitzung beenden": Ansicht wird leer, und ein anschließendes Neuladen