chore: Spezifikation und Umsetzungsplan

This commit is contained in:
vchuser
2026-07-28 14:07:51 +02:00
commit 82898a1539
6 changed files with 2855 additions and 0 deletions
@@ -0,0 +1,253 @@
# RAM-Sortierhilfe — Design
**Datum:** 2026-07-28
**Status:** Freigegeben, bereit für Umsetzungsplan
## Zweck
Eine Sortierhilfe für gebrauchte Server-RAM-Module. Beim Wareneingang werden Module
einzeln gescannt; die App sagt sofort, auf welchen Stapel das Modul gehört. Ziel ist
das physische Sortieren am Tisch — aus einer gemischten Charge entstehen Stapel
identischer Module, die als Kit verkauft werden können.
Die App ist eine reine Sortierhilfe. Nach der Sitzung werden die Daten nicht weiter
gebraucht.
## Ausgangslage
Der vorhandene Netum 2D Tischscanner liest ausschließlich Barcodes und gibt dekodierte
Strings als Tastatureingabe aus. Er stellt kein Rohbild bereit, kann also kein OCR
leisten. Klartext auf Etiketten muss über eine Kamera erfasst werden.
Die Ware ist gemischt: teils Hersteller-Etiketten mit lesbarem Barcode (Samsung, Hynix,
Micron), teils OEM-überklebt (Oracle, HP, Dell, Lenovo), wobei die Hersteller-PN dann
verdeckt sein kann.
## Nicht im Umfang
- Bestandsführung über Sitzungen hinweg
- Ein- und Ausbuchen, Verkaufsabwicklung
- Export nach CSV, Excel oder in ein Warenwirtschaftssystem
- Anbindung des Netum-Scanners an die App (er bleibt für andere Abläufe im Einsatz)
- Andere Komponenten als RAM-Module
- Mehrbenutzerbetrieb, Benutzerkonten, Server
## Hardware und Zugang
- **Kamera:** Handykamera. Die App wird im Handy-Browser geöffnet.
- **HTTPS:** Kamerazugriff verlangt eine sichere Verbindung. Die VCH-Preview-URL
liefert SSL.
- **Netz:** Erkennung und Sortierung laufen vollständig lokal im Browser; während einer
laufenden Sitzung wird keine Netzverbindung gebraucht. Zum Laden der Seite selbst
(und beim ersten Start zusätzlich für die Tesseract-Sprachdaten) ist eine Verbindung
nötig. Echte Offline-Fähigkeit über einen Service Worker ist nicht im Umfang.
## Erkennungsstrategie
Gewählt wurde lokale Erkennung ohne Cloud-Dienst. Die bekannten Schwächen von Tesseract
auf glänzenden Metall-Etiketten werden durch drei Maßnahmen aufgefangen:
1. **Barcode zuerst.** Code-128 und DataMatrix werden aus dem Kamerabild dekodiert.
Barcode-Dekodierung ist exakt, im Gegensatz zu OCR. Aus der Hersteller-PN leitet ein
Decoder die Specs ab. Gelingt das, entfällt OCR vollständig.
2. **Kleiner Erwartungsraum.** RAM-Specs sind kein Freitext. Kapazität, Speed und Rank
stammen aus kurzen, bekannten Wertelisten. Das OCR-Ergebnis wird dagegen abgeglichen;
typische Verwechslungen (0/O, 1/I, 8/B) lassen sich dadurch eindeutig auflösen.
3. **Toleranter Stapel-Abgleich.** Ein neuer Scan wird gegen die bereits offenen Stapel
geprüft. Weicht ein Fingerabdruck nur in einer typischen Verwechslung ab, gilt er als
derselbe Stapel und nicht als neuer.
## Ablauf pro Modul
1. **Kamerabild** — Live-Vorschau, Etikett ins Bild halten.
2. **Barcode-Versuch** — laufende Suche nach Code-128 und DataMatrix.
3. **PN-Decoder** — Hersteller-PN wird in Spec-Felder zerlegt. Erfolg beendet die
Erkennung.
4. **OCR-Fallback** — nur wenn kein Barcode lesbar oder die PN unbekannt ist.
Bildaufbereitung (Graustufen, Kontrast, Schwellwert), Texterkennung, Abgleich der
Felder gegen die bekannten Werte.
5. **Bewertung** — grün bei Barcode, gelb bei eindeutig zugeordnetem OCR-Ergebnis, rot
bei Unsicherheit.
6. **Stapel-Zuweisung** — Ergebnis und Stapelbuchstabe werden groß angezeigt.
Grün und Gelb laufen ohne Eingabe durch. Nur Rot hält den Ablauf an.
## Fingerabdruck
Ein Modul wird auf folgende Merkmale reduziert:
| Merkmal | Beispiel | Quelle |
|---|---|---|
| Kapazität | 64 GB | PN-Decoder oder OCR |
| Bauform | LRDIMM | PN-Decoder |
| Organisation/Rank | 4DRx4 | PN-Decoder oder OCR |
| Speed | PC4-2400 | PN-Decoder oder OCR |
| Hersteller-PN | M386A8K40BM1-CRC4Y | Barcode |
**Gruppierungsstufe:** Elektrische Spec **und** Hersteller-PN müssen übereinstimmen.
Module mit gleicher Spec, aber unterschiedlichem Hersteller bilden getrennte Stapel.
Diese Stufe entspricht dem, was im Gebrauchthandel als "matched kit" gilt.
Der Datumscode wird erfasst und angezeigt, ist aber **nicht** Teil des Fingerabdrucks.
## Stapel-Logik
- Die Sitzung startet mit leerem Tisch, ohne vorab definierte Fächer.
- Erster Scan erzeugt Stapel A, der nächste unbekannte Fingerabdruck Stapel B und so
weiter.
- Vor dem Anlegen eines neuen Stapels wird geprüft, ob ein bestehender Stapel bis auf
typische OCR-Verwechslungen identisch ist. Trifft das zu, wird dorthin einsortiert.
- Die Stapelbuchstaben gelten nur für die laufende Sitzung.
## Rot-Kriterien
Die App fragt nach, wenn:
- kein Barcode lesbar war und OCR keine bekannte Spec-Kombination ergeben hat
- das OCR-Ergebnis auf zwei bestehende Stapel gleich gut passt
- die Kapazität fehlt
Im Rot-Fall zeigt die App die in Frage kommenden Stapel als große, antippbare Flächen,
zusätzlich "neuer Stapel". Ein Tipp setzt den Ablauf fort.
## Korrekturweg
Da grün und gelb ohne Bestätigung durchlaufen, braucht es einen Rückweg:
- Der zuletzt erfasste Eintrag bleibt am unteren Bildschirmrand sichtbar, mit
Rückgängig-Fläche.
- Eine Sitzungsliste zeigt alle Einträge der laufenden Sitzung; jeder lässt sich einem
anderen Stapel zuordnen oder entfernen.
## Oberfläche
Mobil zuerst, große Flächen, im Stehen und mit einer Hand bedienbar.
**Scan-Ansicht** (Hauptansicht):
```
┌──────────────────────────┐
│ │
│ Kamera-Vorschau │
│ ┌────────────────┐ │
│ │ Zielrahmen │ │
│ └────────────────┘ │
│ │
├──────────────────────────┤
│ A:12 B:4 C:7 │ Stapel-Leiste, laufende Zählung
├──────────────────────────┤
│ Zuletzt: 64GB PC4-2400 │
│ LRDIMM → Stapel B [↶] │
└──────────────────────────┘
```
**Treffer-Rückmeldung** (kurz eingeblendet, dann automatisch weiter):
```
┌──────────────────────────┐
│ │
│ ► STAPEL B ◄ │ sehr groß, farbig hinterlegt
│ │
│ 64GB 4DRx4 PC4-2400 │
│ LRDIMM │
│ M386A8K40BM1-CRC4Y │
│ │
└──────────────────────────┘
```
Hintergrundfarbe grün bei Barcode-Erkennung, gelb bei OCR.
**Rot-Dialog** (wartet auf Eingabe):
```
┌──────────────────────────┐
│ Nicht eindeutig │
│ Gelesen: 64GB PC4-24?? │
├──────────────────────────┤
│ ┌────────┐ ┌────────┐ │
│ │Stapel B│ │Stapel D│ │ große Flächen
│ └────────┘ └────────┘ │
│ ┌────────────────────┐ │
│ │ neuer Stapel │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ nochmal scannen │ │
│ └────────────────────┘ │
└──────────────────────────┘
```
**Sitzungsliste:** erreichbar über die Stapel-Leiste. Zeigt Stapel mit ihren Modulen,
erlaubt Umsortieren und Entfernen einzelner Einträge sowie "Sitzung beenden".
Die konkrete Farb- und Typografiegestaltung wird während der Umsetzung festgelegt.
## Technik
- **Vanilla JavaScript mit Vite.** Kein Framework — der Funktionsumfang rechtfertigt
keins, und die Ladezeit auf dem Handy bleibt niedrig. `base: './'` in der
Vite-Konfiguration, damit die App hinter dem VCH-Reverse-Proxy funktioniert.
- **`zxing-wasm`** für Code-128 und DataMatrix.
- **`tesseract.js`** für OCR.
- **Node-eigener Test-Runner** (`node:test`) — keine zusätzliche Test-Abhängigkeit.
Weitere Abhängigkeiten werden bewusst vermieden.
## Module
Jedes Modul hat eine Aufgabe und kennt die Interna der anderen nicht.
| Modul | Aufgabe | Abhängigkeiten |
|---|---|---|
| `camera` | Kamerastrom, Einzelbilder liefern | Browser-API |
| `barcode` | Bild → dekodierte Codes | `zxing-wasm` |
| `pn-decoder` | Hersteller-PN → Spec-Felder | keine |
| `ocr` | Bildaufbereitung, Texterkennung, Feldextraktion | `tesseract.js`, `spec` |
| `spec` | Normalisierung, Fingerabdruck, toleranter Vergleich | keine |
| `session` | Stapel halten, zuweisen, rückgängig machen | `spec` |
| `ui` | Ansichten und Eingaben | alle |
`pn-decoder` und `spec` sind reine Funktionen ohne Kamera- und DOM-Zugriff und damit
vollständig testbar. Sie bilden den fachlichen Kern.
### PN-Decoder
Tabellengesteuert, ein Eintrag pro Herstellerschema. Die Zuordnung von Codefragmenten zu
Kapazität, Bauform und Speed wird gegen reale Module validiert und nicht aus dem
Gedächtnis festgelegt. Unbekannte Schemata sind kein Fehler, sondern führen zum
OCR-Weg. Die Tabelle ist so aufgebaut, dass neue Hersteller ohne Codeänderung ergänzt
werden können.
## Fehlerfälle
| Fall | Verhalten |
|---|---|
| Kamera verweigert oder nicht verfügbar | Hinweis, dazu Datei-Auswahl als Ersatzweg (App bleibt am Rechner nutzbar) |
| Tesseract lädt nicht | App bleibt voll nutzbar, aber barcode-only; sichtbarer Hinweis |
| PN unbekannt | Kein Fehler — regulärer Übergang zum OCR-Weg |
| Barcode unlesbar und OCR unbrauchbar | Rot-Dialog |
| Versehentlicher Seiten-Neuladen | Stapel werden bei jeder Änderung lokal gesichert und beim Start zur Fortsetzung angeboten. Absturzschutz, keine Bestandsführung. "Sitzung beenden" räumt auf. |
## Tests
Mit `node:test`:
- **`pn-decoder`** gegen reale Teilenummern mehrerer Hersteller, einschließlich
`M386A8K40BM1-CRC4Y` (Samsung, 64GB LRDIMM PC4-2400)
- **`spec`** — Normalisierung und toleranter Vergleich, gezielt mit den typischen
Verwechslungen 0/O, 1/I, 8/B
- **`session`** — Szenariotests: eine Folge von Scans hinein, die erwartete
Stapelverteilung heraus, inklusive Rückgängig
- **OCR-Korrektur** — verrauschte Texteingaben gegen die Liste bekannter Spec-Werte
Kamera und Oberfläche werden manuell geprüft; dafür lohnt keine Testautomatisierung.
## Referenzmaterial
Zwei Beispielaufnahmen liegen der Gestaltung zugrunde:
- Oracle-überklebtes Modul, Etikett `Oracle ®PN: 7325773` mit Code-128
- Rückseite desselben Moduls, Samsung-Etikett mit Serial `K136000908252DF287`,
`64GB 4DRx4 PC4-2400T-LD1-11-MC0`, PN `M386A8K40BM1-CRC4Y`, Datumscode `1908`,
dazu DataMatrix und Code-128
Diese beiden dienen als erste Testfälle für den PN-Decoder und die OCR-Feldextraktion.