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
gelesen, Hersteller-Teilenummer (`specsCompatible` in `src/spec.js`); ein auf
einer Seite fehlendes Merkmal wird dabei übersprungen, nicht als Widerspruch
gewertet. 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
gewertet. Ein Stapel gilt dabei nur als Kandidat, wenn er mit dem Modul
mindestens ein tatsächlich erkanntes Merkmal teilt (`sharesSetField` in
`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
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
@@ -45,6 +50,20 @@ keine Daten verlassen das Gerät.
durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt oder
widersprüchliche Barcodes) oder mehrdeutiger Stapelzuordnung fragt die
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
Erkennungs-Pipeline (`src/pipeline.js`) bricht einen Barcode-Versuch nach 10
@@ -77,7 +96,7 @@ korrekt funktioniert.
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
und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und
-Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen
@@ -118,7 +137,12 @@ nicht gesetzt ist).
| `src/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg |
| `src/barcode.js` | Adapter zu `zxing-wasm` |
| `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/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**
- 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
*und* die Aufnahme-LED des Geräts erlischt tatsächlich wieder.
- Aufnahme-Knopf antippen, bevor das Kamerabild bereit ist: verständliche
@@ -232,7 +257,8 @@ werden:
darauf zurück?
- Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten
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**
- 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.
- Rücknahme-Fläche nimmt genau den zuletzt erfassten Eintrag zurück, Zähler
sinkt entsprechend.
- Seite neu laden während einer laufenden Sitzung: Stapel und Zähler bleiben
erhalten.
- Seite neu laden während einer laufenden Sitzung: Dialog „Gesicherte
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
sich korrekt neu auf.
- "Sitzung beenden": Ansicht wird leer, und ein anschließendes Neuladen