80 Commits
Author SHA1 Message Date
TanerUsluandClaude Opus 5 6688efc546 README: Zählen-Abschnitte auf Aufnahme statt Dauerbetrieb aktualisiert
Beschreibt die neue Aufnahme-Schaltfläche ("Zählen"/"Nochmal zählen"), die
fünf Bilder je Aufnahme samt Median, die um die Einzelmessungen erweiterte
Diagnosezeile und das Zurücksetzen beim Verlassen der Funktion. Aufbau-
Tabelle, Testanzahl und der Prüfabschnitt "Am Gerät noch zu prüfen" folgen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 09:37:10 +02:00
TanerUsluandClaude Opus 5 4b6bb065b1 Zählen: Aufnahme statt Dauerbetrieb
Die Zaehlanzeige sprang beim Nutzer im Dauerbetrieb wild zwischen etwa 3
und 60, obwohl dasselbe Verfahren an einem Standfoto stabil 18 lieferte -
eine Schaetzung wird durch staendiges Neuanzeigen nicht praeziser, nur
unruhig. "Zählen" laeuft jetzt wie "Text erkennen" auf Knopfdruck: eine
Aufnahme nimmt binnen rund einer Sekunde fuenf Bilder aus dem Zielrahmen
auf, zaehlt jedes einzeln (count-objects.js unveraendert) und zeigt deren
Median (neues Modul count-capture.js). Das Ergebnis bleibt stehen, bis
erneut angetippt wird; die Diagnosezeile zeigt zusaetzlich die fuenf
Einzelmessungen. Der gleitende Median ueber neun Durchlaeufe der
Dauerzaehlung (count-history.js) entfaellt, da die Aufnahme dieselbe
Robustheit bereits selbst leistet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 09:36:43 +02:00
TanerUsluandClaude Opus 5 d84c15e0d0 Diagnoseanzeige fuer die Funktion "Zählen" ergaenzt
Der Nutzer meldet eine stark schwankende Zaehlanzeige im Livebetrieb
(3-60), obwohl dasselbe Verfahren an einem Standfoto stabil 18 liefert -
er kann aber keine Bilder hochladen und muss Messwerte daher vom
Bildschirm ablesen und durchgeben koennen.

- count-objects.js liefert additiv Zwischenwerte (Bildgroesse nach
  Normierung, Flaechen vor/nach Filterung, groesste Flaeche, typische
  Groesse, gewinnende Polaritaet) - auch bei count 0 sinnvoll belegt.
  Die eigentliche Zaehllogik bleibt unveraendert.
- count-history.js (neu): gleitender Median der letzten 9 Messungen,
  unterdrueckt einzelne Ausreisser ohne die Anzeige traege zu machen.
- main.js zeigt den Median als grosse Zahl, misst den Zeitbedarf des
  Zaehldurchlaufs und baut daraus die Diagnosezeile; der Verlauf wird
  bei jedem Funktionswechsel zurueckgesetzt.
- scan-view.js/styles.css: die grosse Zahl ist antippbar und blendet
  eine anfangs verborgene Diagnosezeile ein/aus, ohne selbst zu
  verrutschen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 08:56:26 +02:00
TanerUsluandClaude Opus 5 f0705a010c Doku: Zaehlfunktion und ihre Grenzen auf das neue Verfahren aktualisiert
Beschreibt oertlichen Kontrast statt Otsu (Normierung, Glaettung,
oertlicher Hintergrund, Massstab relativ zur groessten Flaeche) und die
neuen Grenzen: Untergrund muss sich abheben, gleichmaessige Ausleuchtung
hilft, auseinandergelegt zaehlt besser als aufgehaeuft, stark
unterschiedlich grosse Teile verfaelschen die Hochrechnung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 16:21:35 +02:00
TanerUsluandClaude Opus 5 089d47a1ec Synthetische Zaehl-Tests an das oertlich-kontrastbasierte Verfahren angepasst
Das neue Verfahren braucht ein Umgebungsfenster (Radius max(Breite,Hoehe)/12),
das an jeder Fundstueck-Stelle noch echten Untergrund sieht - die alten
40x40-/80x80-Testbilder mit 10x10-Quadraten waren dafuer zu klein. Bildgroesse
und Quadratmasse angepasst (300x300/600x600), Kernaussagen unveraendert:
leeres Bild -> null, getrennte gleich grosse Flaechen -> ihre Anzahl, Rauschen
zaehlt nicht mit, Hochrechnung beruehrender Teile, kein Doppelzaehlen leicht
groesserer Einzelteile, beide Polaritaeten, 4er- statt 8er-Nachbarschaft
(Luecke statt gemeinsamem Eckpixel, da die Glaettung Raender aufweitet).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 16:21:24 +02:00
TanerUsluandClaude Opus 5 75c479860f Zaehlung auf oertlichen Kontrast umgestellt (Otsu versagte am echten Foto)
Otsu (bisheriges Verfahren) meldete am echten Foto des Auftraggebers
(~20 Schrauben auf Leder, unter 1% Flaechenanteil) 76712 statt rund
zwanzig - Otsu taugt nur bei etwa gleich grossen Objekt-/
Untergrundflaechen. countObjects() vergleicht jetzt jeden Bildpunkt mit
einem oertlichen Hintergrund (Kastenfilter ueber Summenbild, Radius
max(Breite,Hoehe)/12), was Ausleuchtungsunterschiede abfaengt und am
echten Foto 18 statt 76712 liefert (Test in
test/count-objects-photo.test.js, ~30-49ms Laufzeit).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 16:21:13 +02:00
TanerUsluandClaude Opus 5 ffb2409c24 Doku: vierte Funktion "Zählen" im README ergänzt
Funktionstabelle, Ablaufbeschreibung, Aufbau-Tabelle (threshold.js,
count-objects.js), Testzahl (165), neuer Grenzen-Abschnitt (beruehrende/
gestapelte Teile, ungleichmaessige Ausleuchtung, geringer Kontrast, stark
unterschiedliche Teilegroessen) sowie ein Geraete-Pruefpunkt fuer "Zählen".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 15:48:04 +02:00
TanerUsluandClaude Opus 5 8c761c6fb5 Vierte Scan-Funktion "Zählen": laufende Anzeige, keine Buchung
Neue Funktion in scan-modes.js (Merkmal continuousCount), verdrahtet in
main.js ueber denselben Zeitgeber/dieselbe Ueberlappungssperre wie die
Barcode-Dauersuche (continuousSearchLoop ruft jetzt runCountAttempt()
zusaetzlich zu runSearchAttempt(); jeder bricht selbst ab, wenn die
Funktion nicht passt) - kein zweiter, paralleler Mechanismus. Kein "Modul
scannen"-Knopf, keine Treffer-Rueckmeldung, kein roter Dialog, keine
Stapel-Zuweisung; die grosse Zaehlanzeige (scan-view.js/styles.css) ist
reine Anzeige und speichert nichts.

buildRecognitionAdapters() liefert fuer "Zählen" zusaetzlich leere Adapter
(Absicherung gegen den seltenen Datei-Ersatzweg ohne Kamera). Die drei
bestehenden Funktionen bleiben unveraendert; einzige notwendige Anpassung an
scan-modes.test.js war die Anzahl-Pruefung (3 -> 4 Funktionen).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 15:47:44 +02:00
TanerUsluandClaude Opus 5 5e64d260c5 Reine Zaehl-Berechnung fuer Fundstuecke in einem Bildausschnitt
Neues Modul src/count-objects.js: Otsu-Schwellwert (threshold.js) teilt den
Ausschnitt in zwei Klassen, die flaechenmaessig kleinere gilt als Objekt
(funktioniert fuer helle wie dunkle Teile auf beliebigem Untergrund).
Connected-Component-Labeling ueber eine eigene Arbeitsliste statt Rekursion
(vermeidet Stapelueberlauf bei ~1 Mio. Bildpunkten), Rauschflaechen werden
verworfen, beruehrende Teile anhand des Flaechen-Medians hochgerechnet.

Test-Driven: leeres Bild, einzelne/mehrere getrennte Flaechen, verworfenes
Rauschen, Hochrechnung ohne ein nur leicht groesseres Einzelteil zu
verdoppeln, helle wie dunkle Objekte, Bild ohne Bildpunkte, diagonal statt
flaechig beruehrende Teile bleiben getrennt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 15:47:33 +02:00
TanerUsluandClaude Opus 5 500f9b6c3d Otsu-Schwellwert in eigenes reines Modul ausgelagert (threshold.js)
Zieht otsuThreshold()/grayscaleHistogram() aus ocr.js in src/threshold.js,
ohne das Verhalten von preprocess() zu aendern (bestehende Tests in
ocr-preprocess.test.js bleiben unveraendert gruen). Vorbereitung fuer die
neue Zaehl-Funktion, die dieselbe Schwellwertbestimmung braucht, aber nichts
mit tesseract.js (ocr.js) zu tun haben soll.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 15:47:22 +02:00
TanerUslu 87ba439287 Doku: voller OCR-Rohtext in "Text erkennen" (Rahmen, Whitelist, Anzeige)
README auf den aktuellen Stand gebracht: Zielrahmen ist jetzt auch in "Text
erkennen" wirksam (grabFrameRegion statt grabFrame), breitere Zeichen-
Whitelist samt Abwägung, additiver OCR-Rohtext (rawText) in Pipeline,
Speicherung und Anzeige, wartende statt automatisch ausblendende
Rückmeldung in "Text erkennen". Datei-Tabelle, Abschnitt
"Sitzungssicherung im Detail", "Grenzen" und die manuelle Geräte-Prüfliste
entsprechend ergänzt; Testanzahl 144 → 154.
2026-07-29 15:19:34 +02:00
TanerUslu b903b1c7aa OCR-Rohtext additiv zurückgeben, je Eintrag speichern und anzeigen
recognize() (pipeline.js) liefert zusätzlich den ungefilterten OCR-Rohtext
(rawText) zurück - leer, wenn keine Texterkennung lief. Rein additiv: die
Stapelzuordnung (session.js/spec.js, unangetastet) stützt sich weiterhin
ausschließlich auf die daraus abgeleiteten, verstandenen Spec-Felder.

main.js hängt den Rohtext nach dem Buchen als zusätzliche Eigenschaft an den
Eintrag (analog zu den bereits vorhandenen Barcode-Inhalten je Eintrag).
storage.js sichert/prüft/stellt entry.rawText nach demselben optionalen
Muster wie entry.codes wieder her - ein gesicherter Stand ohne dieses Feld
wird nicht verworfen.

In Funktion "Text erkennen" bleibt die Treffer-Rückmeldung jetzt stehen, bis
der Nutzer sie wegtippt, und zeigt den vollen erkannten Text (lesbar über
dasselbe Scroll-Muster wie die übrigen Vollbild-Overlays); in den beiden
Barcode-Funktionen bleibt es beim automatischen Ausblenden. Das
zurückgegebene Versprechen von showResult löst in jedem Fall - Zeitgeber,
Wegtippen, verdrängende neue Rückmeldung - genau einmal ein, damit die
Bedienung nie dauerhaft gesperrt bleibt. Die Sitzungsliste zeigt den Rohtext
zusätzlich je Eintrag zum Nachlesen.

Tests (pipeline.test.js, storage.test.js): rawText nur bei tatsächlich
gelaufener Texterkennung, unterschiedlicher Rohtext beeinflusst die
Stapelzuordnung nachweislich nicht, Rohtext übersteht Sichern/Laden inkl.
Abwärtskompatibilität zu einem Stand ohne dieses Feld.
2026-07-29 15:19:13 +02:00
TanerUslu 1c10c68053 Zeichen-Whitelist der Texterkennung um Kleinbuchstaben erweitert
tessedit_char_whitelist ließ bisher nur Großbuchstaben, Ziffern und wenige
Sonderzeichen zu. Der Nutzer will den vollständigen Etikettentext sehen, nicht
nur die von der App verstandenen Felder - die Whitelist deckt deshalb jetzt
Groß- und Kleinbuchstaben, Ziffern sowie die auf Etiketten üblichen Satz- und
Sonderzeichen ab. Das kann die Genauigkeit bei den Codeteilen (Kapazität,
Rank, Geschwindigkeit, Teilenummer) etwas verringern - eine bewusst in Kauf
genommene Abwägung, siehe Kommentar an Ort und Stelle.
2026-07-29 15:18:56 +02:00
TanerUslu 54b1447f21 Text erkennen liest den Zielrahmen in voller Auflösung, nicht das Vollbild
grabFrameRegion() statt grabFrame(): "Modul scannen" bekam bisher das ganze
Kamerabild, auf 1280 Pixel herunterskaliert - der Zielrahmen war dabei rein
kosmetisch, obwohl er dem Nutzer einen wirksamen Ausschnitt suggeriert. Jetzt
liest die Texterkennung genau den Rahmenausschnitt, in nativer Auflösung -
denselben, den auch die laufende Barcode-Suche längst benutzt. Die
Dateiauswahl (onPickFile) bleibt unverändert beim Vollbild, da sie keinen
Zielrahmen kennt.
2026-07-29 15:18:48 +02:00
TanerUsluandClaude Opus 5 3907204209 Change QR-Code function label from "2D-Code" back to "QR-Code"
The function keeps reading all 2D-code types (QR-Code, MicroQRCode, RMQRCode,
DataMatrix, Aztec, PDF417) as requested. The label is now "QR-Code" per the
client's preference for their terminology. Added clarifying comments explaining
the intentional mismatch between the name and the supported formats, since the
hardware labels use DataMatrix (not QR). Updated README and test accordingly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 14:50:24 +02:00
TanerUsluandClaude Opus 5 2d7778cea8 Funktion 2 liest 2D-Codes statt nur QR (Auftraggeber-Entscheidung revidiert)
Der Auftraggeber hatte Funktion 2 ausdruecklich auf QR beschraenkt, obwohl
die 2D-Codes auf seinen RAM-Etiketten DataMatrix sind. Am Geraet zeigte sich,
dass die Funktion auf seiner Ware nichts fand - er hat die Entscheidung
revidiert. Funktion 2 liest jetzt zusaetzlich zu QRCode/MicroQRCode/RMQRCode
auch DataMatrix, Aztec und PDF417 und heisst in der Oberflaeche "2D-Code"
statt "QR-Code". Die Kennung bleibt aus historischen Gruenden `qrcode`.

Veralteten Kommentar in scan-modes.js berichtigt, Test auf die neue
Codeliste/Beschriftung umgestellt (statt geloescht) und einen Test ergaenzt,
der paarweise verschiedene Kennungen/Beschriftungen der drei Funktionen
erzwingt. README-Funktionstabelle und Geraete-Checkliste entsprechend
angepasst.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 14:32:41 +02:00
TanerUslu ebff173443 Doku: drei Scan-Funktionen statt automatischem Barcode/OCR-Ausweichen
Funktionsweise-Abschnitt, Technik- und Aufbau-Tabelle sowie die
Geraete-Checkliste auf die neue Funktionswahl gebracht. Haelt fest,
dass in "Text erkennen" mangels Barcode-Teilenummer allein die
technischen Angaben ueber die Stapelzuordnung entscheiden, und dass
"QR-Code" bewusst kein DataMatrix liest. Testanzahl auf 143 aktualisiert.
2026-07-29 13:37:18 +02:00
TanerUslu 2e619ed64d Funktionswahl vor der Kamera, Wechsel und Knopf-Sichtbarkeit je Funktion
Neuer Vollbild-Dialog (src/ui/mode-dialog.js) mit drei grossen Flaechen,
gebaut nach dem Muster der bestehenden Dialoge. Ablauf beim Start: erst
die Fortsetzen-Frage (falls eine gesicherte Sitzung vorliegt), dann die
Funktionswahl, erst danach startet die Kamera.

Die gewaehlte Funktion steht antippbar in der Scan-Ansicht und laesst
sich dort jederzeit wechseln - der Wechsel gilt sofort: laufende Suche
startet/stoppt, "Modul scannen" erscheint nur noch in Funktion "Text
erkennen", der Zielrahmen wird beim Wechsel weg von laufender Suche
zurueckgesetzt. pipeline.js bleibt unangetastet; main.js reicht je nach
Funktion nur unterschiedliche Adapter hinein (scan-recognition.js).
2026-07-29 13:37:12 +02:00
TanerUslu 2eb9d1ecf8 Barcode-Adapter nimmt Codearten entgegen, Adapter-Weiche je Funktion
decodeBarcodes(imageData, formats) bekommt die zu suchenden Codearten
uebergeben; ohne Angabe unveraendertes Verhalten (Code128 + DataMatrix).

buildRecognitionAdapters() baut daraus und aus dem echten OCR-Adapter
die an recognize() (pipeline.js, unveraendert) uebergebenen Adapter:
in Strichcode/QR-Code liefert die Texterkennung sofort leeren Text ohne
Tesseract anzustossen, in Text-erkennen liefert die Barcode-Dekodierung
sofort eine leere Liste ohne zxing-wasm anzustossen.
2026-07-29 13:37:05 +02:00
TanerUslu 9ef038ca98 Reines Funktionen-Modul fuer die drei Scan-Funktionen
Kennung, deutsche Beschriftung, Codearten, laufende Suche und
Texterkennung je Funktion an einer einzigen Stelle (src/scan-modes.js),
ohne Browser-Zugriff und damit unter Node pruefbar. Funktion "QR-Code"
enthaelt bewusst kein DataMatrix.
2026-07-29 13:36:58 +02:00
TanerUslu 5a055923fe Trenne Dialogtexte fuer echte Mehrdeutigkeit und nichts erkannt
Der rote Dialog zeigte bisher immer "Nicht eindeutig", auch wenn die
Erkennung schlicht nichts Verwertbares geliefert hat (kein Barcode, kein
brauchbarer Klartext). Das verwirrt: es klingt nach mehreren Kandidaten,
obwohl gar keine Erkennung stattfand.

askForStack() bekommt einen expliziten Parameter nothingRecognized, da
sich die beiden Lagen nicht zweifelsfrei aus spec/candidates ableiten
lassen (main.js reicht bei "nichts erkannt" als Rueckfall alle
vorhandenen Stapel als candidates durch). main.js setzt ihn anhand von
plan.kind === 'ambiguous' (echte Mehrdeutigkeit) vs. allem anderen
(nur wegen roter Konfidenz im Dialog).

Signatur, Rueckgabeform, Schaltflaechen, Klassennamen, die
Mehrfachausloese-Sperre und die inert-Handhabung bleiben unveraendert.
2026-07-29 13:05:37 +02:00
TanerUsluandClaude Opus 5 b94639ccd1 Laufende Barcode-Suche statt Einzelbild beim Knopfdruck
Solange Kamera laeuft und keine Erkennung/kein Dialog/keine
Sitzungsliste im Weg steht, sucht die App ~5x/s im Zielrahmen nach
Barcodes. Ein gefundener Code durchlaeuft denselben Weg wie der
Knopfdruck (processCapture). Sperrzeit von 2s plus Codevergleich
verhindert, dass ein laenger vor die Kamera gehaltenes Modul mehrfach
gebucht wird, ohne einen zuegigen Modulwechsel auszubremsen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:59:23 +02:00
TanerUsluandClaude Opus 5 abb70e8b23 Zielrahmen aus FRAME_INSET setzen, Erkennungs-Hervorhebung ergaenzen
scan-view.js setzt die Rahmenlage jetzt aus camera.js' FRAME_INSET
statt aus einem im Stilblatt duplizierten Wert. Neue Methode
setFrameDetected() faerbt den Rahmen gruen, sobald die Dauersuche
einen Barcode im Ausschnitt findet - schlichte Farbaenderung, keine
Animation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:59:14 +02:00
TanerUsluandClaude Opus 5 44526e7d3b Ausschnitt in nativer Aufloesung fuer Barcode-Erkennung
FRAME_INSET und frameRect() legen die Rahmenmasse einmalig fest, statt
sie nur im Stilblatt zu duplizieren. grabFrameRegion() liefert den
Zielrahmen unskaliert aus dem Kamerabild - grabFrame() (fuer OCR)
bleibt unveraendert. Ein Code-128 auf kleinem Etikett braucht die
volle Aufloesung, sonst verschmieren die Striche unlesbar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:59:08 +02:00
TanerUslu 69dbeeb062 fix: dist-Pfad im Server absolut aufloesen, unabhaengig vom Startverzeichnis 2026-07-29 10:39:30 +02:00
TanerUslu 8858ab2f88 feat: Passwortschutz im Server statt im Browser
Ohne gueltiges Passwort gibt der Server weder Seite noch Skript heraus.
Das Passwort kommt aus APP_PASSWORD; fehlt die Variable, startet der Server
absichtlich nicht. /healthz bleibt passwortfrei, damit die Ueberwachung den
geschuetzten Dienst nicht faelschlich fuer ausgefallen haelt.
2026-07-29 10:32:41 +02:00
TanerUslu d3be44e5d3 chore: VCH-Deploykonfiguration fuer statische Auslieferung 2026-07-29 10:08:40 +02:00
vchuser b679df6fd3 Doku: Codeabgleich nur innerhalb vertraeglicher Angaben, Grenze ergaenzt
README beschreibt jetzt, dass ein Codetreffer einen Widerspruch der
technischen Angaben nicht mehr ueberstimmt (Fehler 1) und dass die
Codemenge eines Stapels ein abgeleiteter statt angesammelter Wert ist
(Fehler 2). Neue Grenze dokumentiert: ein gelesener Barcode-Inhalt ist exakt
gelesen, aber nicht garantiert eine Teilenummer - eine geteilte Los- oder
Wiederverkaeufer-Kennung kann zwei verschiedene Module verbinden, wogegen
die neue Widerspruchspruefung schuetzt. Testanzahl auf 124 aktualisiert.
2026-07-29 09:22:11 +02:00
vchuser 266babc8bf Codemenge eines Stapels beim Laden aus den Eintraegen ableiten statt uebernehmen
Ergaenzt src/session.js aus dem vorigen Commit: Da stack.codes jetzt aus
entry.codes abgeleitet wird statt angesammelt zu werden, muss loadSession
denselben Ansatz verfolgen (wie bereits bei stack.count) - sonst wuerde ein
gesicherter, zwischenzeitlich per Umsortieren/Entfernen bereinigter Stand beim
Wiederherstellen einen laengst nicht mehr zutreffenden Code zurueckbringen.
entry.codes ist wie stack.codes optional, ein Stand ohne dieses Feld gilt
weiterhin nicht als unstimmig (Abwaertsvertraeglichkeit bleibt erhalten).
2026-07-29 09:22:04 +02:00
vchuser f948620555 Codetreffer ueberstimmt keinen Widerspruch der technischen Angaben mehr
Ein gelesener Rohcode ist nicht garantiert eine Teilenummer: teilen sich
zwei technisch verschiedene Module z.B. denselben Los-Tag, hat der bisherige
Codeabgleich sie ohne Rueckfrage auf denselben Stapel gezogen. proposeAssignment
verlangt fuer einen Codekandidaten jetzt zusaetzlich specsCompatible; widerspricht
der einzige Treffer, faellt die Zuordnung auf den Vergleich der technischen
Angaben zurueck und im Zweifel auf einen eigenen Stapel.

TDD: Test zuerst rot gesehen (Los-Tag-Fall aus der Beanstandung), dann die
Filterung ergaenzt.
2026-07-29 09:21:42 +02:00
vchuser 7b4a3532bb Aktualisiere README fuer Barcode-Codeabgleich und gelockerten Gruen-Massstab
Beschreibt die neue Vorrangregel (bekannter Barcode-Inhalt entscheidet vor
dem Vergleich der technischen Angaben), dass eine exakt gelesene Teilenummer
allein fuer Gruen genuegt, und den OCR-Kurzschluss bei bereits bekanntem
Code. Ergaenzt entsprechende Pruefpunkte im Abschnitt "Am Gerät noch zu
pruefen" und aktualisiert die Testanzahl auf 121.
2026-07-29 09:05:35 +02:00
vchuser c9084830b8 Verdrahte Barcode-Codeabgleich und OCR-Kurzschluss in main.js
processCapture() reicht der Pipeline jetzt eine isKnownCode-Abhaengigkeit
herein, die gegen die Codes der Stapel der aktuellen Sitzung prueft, und
gibt die von recognize() gelieferten Rohcodes an proposeAssignment und
commitAssignment weiter, damit ein bereits bekannter Barcode-Inhalt die
Stapelzuordnung entscheidet.
2026-07-29 09:05:29 +02:00
vchuser 61dde3eb08 Stapel merken sich gelesene Barcode-Inhalte, entscheiden die Zuordnung
Jeder Stapel fuehrt jetzt die Menge der Barcode-Zeichenketten, die bei
seinen Modulen gelesen wurden (stack.codes). Traegt ein gescanntes Modul
einen Code, den ein Stapel bereits kennt, hat das Vorrang vor dem Vergleich
der technischen Angaben - ein Barcode ist exakt gelesen, abgeleitete Angaben
koennen fehlerbehaftet sein. Genau ein Stapel ueber einen bekannten Code
-> Zuweisung, auch bei unvollstaendigen Angaben; mehrere -> weiterhin
mehrdeutig, der Nutzer entscheidet; kein passender Code -> unveraendert die
bisherige Regel. Eine Seriennummer, die bei jedem Modul anders ist, laeuft
dabei einfach ins Leere, ohne die Zuordnung ueber die Teilenummer zu
verhindern.

proposeAssignment und commitAssignment bekommen dafuer einen neuen, optional
en codes-Parameter (Vorgabe []); bestehende Aufrufe ohne diesen Parameter
verhalten sich unveraendert.

storage.js sichert und prueft stack.codes jetzt mit: fehlt das Feld (Stand
aus einer aelteren Fassung), gilt der Stapel als ohne bekannte Codes statt
den ganzen Stand zu verwerfen; ist es vorhanden, muss es eine Liste von
Zeichenketten sein wie jedes andere Feld auch.
2026-07-29 09:05:23 +02:00
vchuser 661bd07a26 Barcode-Teilenummer allein genuegt fuer Gruen, bekannter Code ueberspringt OCR
Der Teilenummer-Decoder kennt bislang nur das Samsung-Schema; ein Hynix-Modul
mit einwandfrei gelesenem, aber unbekanntem Barcode-Schema endete deshalb in
Rot. Zum Sortieren muss keine Kapazitaet bekannt sein - eine exakt gelesene
Teilenummer genuegt, um ein Modul wiederzuerkennen. recognize() greift jetzt
erst dann auf Rot zurueck, wenn auch die Texterkennung keine Kapazitaet und
keine eindeutige Teilenummer liefert; die bestehende Vorsicht bei
widerspruechlichen unverwertbaren Barcodes bleibt dabei unangetastet.

Zusaetzlich kann recognize() jetzt ueber deps.isKnownCode (optional) erfahren,
dass ein gelesener Code bereits einem Stapel bekannt ist, und die bis zu 20
Sekunden dauernde Texterkennung dann ueberspringen. Ohne diese Abhaengigkeit
verhaelt sich die Pipeline unveraendert. recognize() liefert zusaetzlich die
rohen gelesenen Barcode-Inhalte (codes), damit session.js sie einem Stapel
zuordnen kann.
2026-07-29 09:05:05 +02:00
vchuserandClaude Opus 5 70f6a4fbce Benenne Konstante REFERENZ zu REFERENCE um und entferne Vorlagenfelder aus package.json
- Benenne REFERENZ in test/ocr-extract.test.js zu REFERENCE um
  (Bezeichner auf Englisch, Kommentare/Texte auf Deutsch)
- Entferne »main«: "index.js" (Datei existiert nicht, nicht relevant für Anwendung)
- Entferne »directories«: { "doc": "docs" } (nicht relevant)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:33:13 +02:00
vchuserandClaude Opus 5 5413be105d Exportiere nextStackId aus session.js (ergaenzt vorigen Commit)
Wurde versehentlich nicht mit "Konsolidiere Spec-Kurzbeschreibung..."
committet, obwohl main.js dort bereits auf den Export umgestellt wurde.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:25:28 +02:00
vchuserandClaude Opus 5 1acfee76d8 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>
2026-07-28 18:25:15 +02:00
vchuserandClaude Opus 5 e50e8f4cd2 Korrigiere package.json Metadaten
private als Wahrheitswert statt Zeichenkette "true"; description war noch
der unveraenderte Vorlagen-Platzhalter, jetzt ein kurzer deutscher Satz
passend zur App.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:25:02 +02:00
vchuserandClaude Opus 5 096b687d06 Entferne unerreichbaren Zweig im Rank-Muster, korrigiere Testnamen
src/ocr-extract.js: RANK_PATTERN enthielt [Xx], obwohl der Text an dieser
Stelle bereits vollstaendig grossgeschrieben ist (normalizeToken laeuft
vorher) - das kleine x konnte nie ankommen. Auf X reduziert, mit Kommentar
begruendet. Die uebrigen Muster im Modul (CAPACITY_PATTERN, SPEED_PATTERN,
PART_NUMBER_PATTERN, das formFactor-Muster, DATE_CODE_PATTERN) geprueft:
keine weiteren unerreichbaren Zweige, alle nutzen bereits ausschliesslich
Grossbuchstaben-Zeichenklassen bzw. Ziffern.

test/ocr-extract.test.js: Testname behauptete "nur einer plausibel", der
Referenztext enthaelt aber zwei plausible Datumscode-Kandidaten (1234 und
1908) - der Test belegt tatsaechlich, dass bei mehreren plausiblen
Kandidaten der zuletzt vorkommende gewinnt. Umbenannt entsprechend.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:24:52 +02:00
vchuserandClaude Opus 5 4b2553d4f4 Rename deutsche Testbezeichner und ergaenze Mehrstapel-Testabdeckung
test/storage.test.js: wieder -> reloaded, kaputt -> broken, zweiterEintrag
-> secondEntry, vorschlag -> proposal (Bezeichner, nicht die deutschen
Testbeschreibungen).

Neuer Test deckt die bislang nur mit einem einzigen Stapel geprueften
Stapelzaehler-Neuberechnung beim Laden ab: drei gespeicherte Stapel mit
absichtlich falschem count, davon einer (C) ganz ohne zugeordnete
Eintraege - alle drei muessen unabhaengig voneinander korrekt aus den
tatsaechlichen Eintraegen neu berechnet werden (A=2, B=1, C=0).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:24:43 +02:00
vchuserandClaude Opus 5 1ec3ca4054 Ersetze deutsche Bezeichner durch englische im Quelltext
Projektvorgabe: Kommentare und Oberflaechentexte deutsch, Bezeichner im Code
englisch. Betroffen: src/barcode.js (vorbereitungsPromise -> readyPromise,
inkl. Verweis-Kommentar in ocr.js), sowie lokale Variablen in
test/spec-match.test.js, test/session.test.js und test/pipeline.test.js
(u.a. ocrAufgerufen -> ocrCalled, gefunden bei vollstaendigem Durchgang
aller Test-Dateien). Testbeschreibungen (Prosa) und Kommentare bleiben
unangetastet - nur echte Bezeichner wurden umbenannt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:24:30 +02:00
vchuserandClaude Opus 5 7fc7feb1ed Konsolidiere Spec-Kurzbeschreibung in ein gemeinsames Modul
main.js, result-overlay.js und session-list.js loesten dieselbe Aufgabe
(Spec-Felder zu einer Lesehilfe zusammenfassen) bislang mit drei leicht
unterschiedlichen Implementierungen - unterschiedliche Feldauswahl und
unterschiedlicher Umgang mit fehlenden Werten. Neues src/ui/describe-spec.js
buendelt das in describeSpec(spec, { placeholders }): ohne Platzhalter fuer
die kurze Treffer-Rueckmeldung und die "Zuletzt"-Zeile, mit Platzhalter fuer
die Sitzungsliste, wo feste Feldreihenfolge Wiedererkennung schafft.

Nutzt bei main.js zugleich die bereits vorhandene, jetzt exportierte
nextStackId aus session.js statt einer Zeile-fuer-Zeile-Kopie derselben
Buchstaben-Vergabe (nextFreeStackId entfaellt komplett).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:24:07 +02:00
vchuserandClaude Opus 5 8082c4172b Zeige Erkennungsquelle je Eintrag in der Sitzungsliste
commitAssignment speichert je Eintrag bereits, ob per Barcode oder
Texterkennung erkannt wurde - das wurde bisher nirgends angezeigt. Die
Sitzungsliste zeigt es jetzt knapp neben jedem Eintrag, weil der
Unterschied beim Sortieren wertvoll ist: Barcode ist exakt, Texterkennung
fehleranfälliger.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:09:49 +02:00
vchuserandClaude Opus 5 2e8bd29a33 Kamera-Ersatzweg, Sitzungs-Fortsetzung und Sperre während Erkennung
Drei zusammenhängende Verhaltensfehler rund um main.js behoben:

- Kamerafehler ruft die Dateiauswahl nicht mehr ohne Nutzergeste auf
  (Handy-Browser blockieren das). Stattdessen zeigt scan-view.js eine
  sichtbare, dauerhaft eingeblendete Schaltfläche "Bild auswählen"; der
  Kamera-Hinweis wird nicht mehr von der OCR-Verfügbarkeitsanzeige
  überschrieben.
- Eine beim Start gefundene, gesicherte Sitzung wird nicht mehr
  stillschweigend übernommen, sondern über den neuen Dialog
  askResumeSession (resume-dialog.js, nach dem Muster von
  ambiguous-dialog.js) zur Fortsetzung angeboten. Fortsetzen zeigt den
  tatsächlich letzten Eintrag, Verwerfen löscht den gesicherten Stand.
- Während einer laufenden Erkennung sind Sitzungsliste und Rückgängig-
  Fläche gesperrt; zusätzlich bucht ein durch einen zwischenzeitlichen
  Sitzungswechsel verspätetes Erkennungsergebnis nicht mehr in die neue,
  leere Sitzung (targetSession-Vergleich in processCapture).
- Auch ohne erfasste Stapel bleibt die Sitzungsliste (und damit "Sitzung
  beenden") über eine Schaltfläche in der Stapel-Leiste erreichbar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:09:42 +02:00
vchuserandClaude Opus 5 00bc62f546 Verhindere Passt-auf-alles-Stapel ohne gemeinsame Merkmale
proposeAssignment verlangt jetzt zusätzlich zur bisherigen
Verträglichkeitsprüfung, dass Stapel und Modul mindestens ein Merkmal
gemeinsam belegt haben. Ein Stapel mit vollständig leerem Spec (Rot-Fall,
"neuer Stapel") hatte sonst mit jedem Modul null gemeinsame Felder und
galt fälschlich als verträglich mit allem.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:09:04 +02:00
vchuser cfdccb3f74 docs: correct stacking rule, barcode flow, and device-check gaps
- README/.vch-description overstated the stacking rule as a hard
  "identical specs AND identical part number" requirement. In reality
  specsCompatible (src/spec.js) only compares fields known on both
  sides, so an unread part number is skipped rather than compared;
  proposeAssignment (src/session.js) only prompts when multiple stacks
  match. Documented the actual rule and its deliberate trade-off.
- Added a sentence on how pipeline.js handles multiple barcodes with
  an unknown numbering scheme that disagree: no part number is taken
  over and OCR alone decides, without prompting.
- Added src/styles.css to the "Aufbau" file table.
- Added the two barcode-adapter device checks from
  .superpowers/sdd/task-9-report.md (first-load timing, reload after
  an interrupted first load) to "Am Gerät noch zu prüfen"; reviewed
  task-8 and task-10..13 reports and confirmed their other device
  checks were already present.
2026-07-28 17:50:38 +02:00
vchuserandClaude Opus 5 2d3a9b0ddb docs: README und Projektbeschreibung
README und .vch-description an den tatsaechlichen Code angeglichen: Otsu-
Schwellwert statt fester Kontrastspreizung fuer OCR, Zeitgrenzen und
Mehrdeutigkeitsbehandlung in der Pipeline, gruendliche Zustandspruefung in
storage.js, 97 Tests. Herstellertabellen-Validierung (Step 3) bleibt
blockiert, da sie reale Module vom Nutzer braucht - pn-tables.js unveraendert.
Ehrlicher Beleg-Stand der Tabellen sowie Erweiterungsanleitung in der README,
plus konsolidierte Liste dessen, was mangels Handy/Browser noch am Geraet zu
pruefen ist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 17:42:29 +02:00
vchuser b06b3abfd5 Fix session-list double-open and end-session re-save
openSessionList() now closes any already-open overlay itself before
rendering, so a double-tap on the stack bar (which has no lock) can no
longer stack two session lists with duplicate handlers. The onMove/
onRemove callbacks no longer need their own closeOverlays() call since
openSessionList() does it unconditionally now.

onEndSession no longer calls syncView() after clearSession(), which
was writing the freshly emptied session straight back into storage and
undoing the clear. It now only refreshes the visible stacks, so ending
a session actually leaves nothing saved, while a subsequent scan still
saves normally via syncView().
2026-07-28 17:37:20 +02:00
vchuser c4ad0416ab feat: Sitzungsliste und Verdrahtung zur vollstaendigen App
Ersetzt das Sichtpruefungs-Geruest in main.js durch die vollstaendige
Verdrahtung aus Kamera, Barcode/OCR-Erkennung, Sitzungsverwaltung,
Speicherung und Oberflaeche. Neu: session-list.js fuer die
Sitzungsliste zum Umsortieren/Entfernen/Beenden.

Gegenueber dem urspruenglichen Plan an den seither geaenderten
Schnittstellen ausgerichtet: commitAssignment erhaelt die tatsaechliche
Erkennungsquelle (source) statt der Konfidenz als drittes Argument, und
die OCR-Verfuegbarkeitsanzeige ueberschreibt keine noch zu lesende
Fehlermeldung mehr. Bezeichner in beiden Dateien auf Englisch
umgestellt, damit sie der bereits etablierten Projektkonvention
entsprechen.
2026-07-28 17:28:15 +02:00
vchuser 0c96743211 Rot-Dialog: Rollbarkeit bei vielen Stapeln und echte Modalität
Beanstandung 1: .overlay bekommt overflow-y:auto, overscroll-behavior:
contain und justify-content:safe center, damit bei vielen Kandidaten-
Stapeln (Rot-Fall bietet alle Stapel der Sitzung an) keine Schaltfläche
mehr unerreichbar aus dem Bildschirm waechst, ohne dass die Seite
dahinter mitrollt oder sich die Optik bei wenigen Stapeln aendert.

Beanstandung 2: askForStack setzt inert auf die Geschwisterelemente von
root, solange der Dialog offen ist, und hebt es beim Schliessen (ueber
jeden der drei Wege) nur fuer selbst gesetzte Elemente wieder auf.
Fokus kehrt nach dem Schliessen zum vorherigen Element zurueck statt auf
dem entfernten Dialog haengen zu bleiben.
2026-07-28 17:20:19 +02:00