feat(tags): QR-Aufkleber, Geraeteseite, Etikettendruck und Scanner
Der Einstieg, fuer den die Anwendung gebaut ist: scannen, sehen was zu tun ist,
loslegen. `/t/<tagCode>` kennt drei Faelle — registriertes Geraet, vorgedruckter
Tag, unbekannter Code —, die Geraeteseite zeigt Zuweisungen, Schnellstart und
Historie, und beides ist am Handy bedienbar.
Im QR steht ausschliesslich `{APP_URL}/t/{tagCode}`: kein Name, keine
Seriennummer, kein Besitzer. Ein Aufkleber haengt jahrelang sichtbar am Geraet
und wird von jedem Telefon gelesen; was darauf steht, ist veroeffentlicht. Die
Masse sind gemessen, nicht behauptet: ein echtes PDF liefert 62 x 29 mm und A4,
und ein bei 300 dpi gerastertes Etikett wird mit demselben Decoder
zurueckgelesen, den auch der Scanner benutzt.
Drei Defekte zeigte erst der gebaute Stand, alle an den Naehten zwischen den
parallel gebauten Teilen: „Starten“ setzte IN_ARBEIT und sprang nicht, „Vorlage
zuweisen“ bot Vorlagen an, die der Dienst danach ablehnte, und die Geraeteliste
verlinkte nichts. Der unabhaengige Review fand drei Blocker — darunter, dass der
Scanner nie die native BarcodeDetector-API benutzte und dass ein Unterpfad in
APP_URL aus dem gedruckten QR herausfiel.
Closes #14
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c78a6ac1af
commit
5f1b0d1435
@@ -200,6 +200,46 @@ hat. Bei verstecktem Tab pausiert die Abfrage.
|
||||
Der Route Handler prüft sein Recht selbst und gibt einen fremden Lauf als „nicht gefunden“ zurück.
|
||||
Die Hülle unter `src/app/(app)/layout.tsx` deckt `src/app/api/` nicht ab.
|
||||
|
||||
## 5e. Der Aufkleber ist die Schnittstelle
|
||||
|
||||
Jedes Objekt traegt einen QR-Aufkleber mit einem `tagCode`, der **nie geaendert
|
||||
und nie wiederverwendet** wird — auch nicht, nachdem das Geraet geloescht wurde
|
||||
(`TagCodeVergabe`, #006). Der Aufkleber ist damit die einzige Angabe am Geraet,
|
||||
die Jahre haelt: Hostnamen aendern sich, Besitzer wechseln, Seriennummern werden
|
||||
abgeschrieben.
|
||||
|
||||
**Im QR steht ausschliesslich `{APP_URL}/t/{tagCode}`.** Kein Name, keine
|
||||
Seriennummer, kein Besitzer. Ein Aufkleber haengt sichtbar am Geraet und wird von
|
||||
jedem Telefon gelesen, auch von einem fremden; was darauf steht, ist
|
||||
veroeffentlicht. Die Adresse selbst verraet nichts — dahinter verlangt
|
||||
`/t/[tagCode]` eine Anmeldung und zeigt einem fremden Kunden dieselbe Antwort wie
|
||||
bei einem Code, den es nicht gibt.
|
||||
|
||||
Drei Dinge daran sind nicht mehr zu korrigieren, sobald gedruckt ist, und stehen
|
||||
deshalb fest:
|
||||
|
||||
1. **Die Basisadresse kommt aus `APP_URL`, mit ihrem Pfad.** Liegt die Anwendung
|
||||
unter `https://firma.de/laufzettel`, muss genau das im QR stehen;
|
||||
`basisAdresse()` in `src/lib/adressen.ts` haelt den Pfad fest, `tagAdresse()`
|
||||
haengt relativ an. Ohne gesetzte `APP_URL` warnt die Druckseite, statt still
|
||||
`localhost` zu drucken.
|
||||
2. **Der QR entsteht lokal** (`qrcode`, Fehlerkorrektur M, Ruhezone 4). Eine
|
||||
externe API bekaeme mit jedem Aufruf den Bestand an Tag-Codes geliefert.
|
||||
3. **Die Masse sind geprueft, nicht behauptet.** `tests/e2e/etiketten.spec.ts`
|
||||
misst die Seitengroesse an einem echten PDF (62 × 29 mm bzw. A4) und liest
|
||||
ein bei 300 dpi gerastertes Etikett mit demselben Decoder zurueck, den auch
|
||||
der Scanner benutzt.
|
||||
|
||||
Der Scanner laedt `barcode-detector/polyfill`: wo der Browser eine
|
||||
`BarcodeDetector`-API mitbringt, laeuft sie, sonst springt WebAssembly ein. Dessen
|
||||
`.wasm` kommt aus dem eigenen Haus (`scripts/wasm-bereitstellen.mjs` legt es unter
|
||||
`public/zxing/`), weil die Content-Security-Policy nur `connect-src 'self'`
|
||||
erlaubt und die Anwendung ohne Internet laufen soll; dafuer traegt `script-src`
|
||||
ein `'wasm-unsafe-eval'` — die schmale Erlaubnis, WebAssembly zu uebersetzen, und
|
||||
**nicht** `unsafe-eval`. Laeuft die Kamera nicht oder faellt der Decoder aus, steht
|
||||
an derselben Stelle ein Feld fuer den abgetippten Code: der steht lesbar unter
|
||||
jedem QR, und ein Scanner, der nicht startet, darf keine Sackgasse sein.
|
||||
|
||||
## 6. Betrieb: zwei Wege, eine Regel
|
||||
|
||||
Die Datenbank ist auf beiden Wegen von außen nicht erreichbar:
|
||||
|
||||
Reference in New Issue
Block a user