feat(tags): QR-Aufkleber, Geraeteseite, Etikettendruck und Scanner
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

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 was merged in pull request #28.
This commit is contained in:
2026-09-25 19:30:50 +00:00
co-authored by Claude Opus 5
parent c78a6ac1af
commit e7a2e2d5c7
58 changed files with 4828 additions and 54 deletions
+20
View File
@@ -117,6 +117,16 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
- Abschnitte klappen zu, sobald in ihnen nichts mehr zu tun ist — wer einen wieder aufklappt,
behält ihn offen, auch über das Speichern hinweg (#013)
- QR-Aufkleber: Stapel vorgedruckter Tags, Etikettendruck als Einzeletikett (62 × 29 mm) und als
A4-Bogen (3 × 8 à 70 × 37 mm), je mit QR, lesbarem Code, Hostname und Besitzer (#014)
- `/t/<code>` als Einstieg vom Aufkleber: registriertes Gerät → Geräteseite, vorgedruckter Tag →
Registrierformular, unbekannter Code → Hinweis mit Weg zur Suche (#014)
- Geräteseite mit Kopf, „Zugewiesen“, Schnellstart aus den Gerätetyp-Vorgaben, „Vorlage zuweisen“
und Historie — am Handy bedienbar, weil sie dort benutzt wird (#014)
- „Scannen“ mit der BarcodeDetector-API des Browsers, wo es sie gibt, sonst mit WebAssembly; wo
keine Kamera läuft, steht ein Feld für den abgetippten Code (#014)
- Der Tag-Code in der Geräteliste und in der Tag-Liste führt dorthin, wo auch der Scan landet (#014)
### Sicherheit
- Der Compose-Stand bricht ab, wenn `APP_SECRET`, `POSTGRES_PASSWORD` oder `APP_URL` fehlen,
@@ -202,3 +212,13 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
Bearbeiter fremder Kunden mehr (#013)
- „Nicht zutreffend“ und „fehlgeschlagen“ lassen sich mit einem Klick zurücknehmen. Vorher sah es
danach aus, als wäre nichts gewählt, während in der Datenbank weiter der alte Zustand stand (#013)
- Im QR steht ausschließlich `{APP_URL}/t/{tagCode}` — kein Name, keine Seriennummer, kein
Besitzer. Ein Aufkleber hängt jahrelang sichtbar am Gerät und wird von jedem Telefon gelesen;
was darauf steht, ist veröffentlicht (#014)
- Der QR wird lokal erzeugt, nie über eine externe API: die bekäme mit jedem Aufruf den Bestand an
Tag-Codes geliefert (#014)
- Das WebAssembly des QR-Lesers kommt aus dem eigenen Haus statt aus einem CDN — die
Content-Security-Policy erlaubt nur `connect-src 'self'`, und die Anwendung soll ohne Internet
laufen (#014)
- Ein Tag, ein Etikett und eine Geräteseite eines fremden Kunden sind nicht erreichbar; „gibt es
nicht“ und „darfst du nicht“ sind dieselbe Antwort (#014)