Phase C: die letzten sechs Typen — PDF, Bild, Feedback und Datei-Upload
Damit sind alle 15 QR-Typen gebaut. PDF und Bild brauchen eine hochgeladene Datei. Die liegt in der Datenbank, nicht auf der Platte: damit bleibt es bei einem Volumen, das gesichert werden muss — ein zweites wird beim Sichern zu leicht vergessen. Geprueft wird der Dateiinhalt, nicht die Endung; eine Textdatei namens harmlos.pdf kommt nicht durch. SVG ist bewusst nicht erlaubt, weil es Skripte enthalten darf und von derselben Adresse wie die Anwendung ausgeliefert wuerde. Ausgeliefert wird mit nosniff und einer CSP-Sandbox, damit auch ein PDF mit Skripten nichts anrichtet. Dateien haengen am Code: wird er geloescht, geht sie mit. Eine ausgetauschte oder nie gespeicherte Datei wird nach 24 Stunden weggeraeumt. Eine fremde Datei laesst sich nicht an den eigenen Code haengen — sonst koennte man sie einem anderen Code entziehen. Feedback sammelt Note und Kommentar, ohne Name, IP oder Geraetekennung. Die Auswertung mit Durchschnitt, Verteilung und Kommentaren ist aus der Codeliste erreichbar — ein Feedback-Code ohne Auswertung waere nur die halbe Sache.
This commit is contained in:
@@ -3,9 +3,8 @@
|
||||
Eine Webanwendung zum Erzeugen von QR-Codes — als Docker-Compose-Stack aus
|
||||
zwei Containern: der Next.js-Anwendung und einer PostgreSQL-Datenbank.
|
||||
|
||||
Umgesetzt sind **9 der 15 QR-Typen**. Die übrigen sechs sind in der Oberfläche
|
||||
sichtbar, als Platzhalter markiert und lassen sich über die Verwaltung
|
||||
ausblenden.
|
||||
Umgesetzt sind **alle 15 QR-Typen**. Welche davon in der Oberfläche erscheinen,
|
||||
entscheidet die Verwaltung — nicht gebrauchte lassen sich ausblenden.
|
||||
|
||||
---
|
||||
|
||||
@@ -152,9 +151,10 @@ Für einen Code, dessen Ziel du später ändern kannst:
|
||||
|
||||
### Schritt 8 — Aufräumen, was du nicht brauchst
|
||||
|
||||
Unter **Verwaltung → QR-Typen** kannst du einzelne Typen ausblenden — etwa
|
||||
die sechs, die noch nicht umgesetzt sind, damit sie gar nicht erst
|
||||
auftauchen.
|
||||
Unter **Verwaltung → QR-Typen** kannst du einzelne Typen ausblenden — 15
|
||||
Kacheln sind viel, wenn ihr ohnehin nur drei davon braucht. Ausgeblendete
|
||||
Typen verschwinden aus der Auswahl; bereits erstellte Codes dieses Typs
|
||||
funktionieren unverändert weiter.
|
||||
|
||||
### Die wichtigsten Befehle im Betrieb
|
||||
|
||||
@@ -358,8 +358,7 @@ werden — der Hostname darin bleibt `db` (der Servicename aus
|
||||
### 1. Typ wählen
|
||||
|
||||
Die Startseite zeigt unter „Was möchtest du erstellen?“ ein Kachel-Grid der
|
||||
freigegebenen QR-Typen. Umgesetzte Typen sind anklickbar, die übrigen tragen
|
||||
das Badge „Bald verfügbar“.
|
||||
freigegebenen QR-Typen. Alle 15 Typen sind umgesetzt.
|
||||
|
||||
| Typ | Kodiert als | Statisch | Dynamisch |
|
||||
| --- | --- | :-: | :-: |
|
||||
@@ -368,10 +367,16 @@ das Badge „Bald verfügbar“.
|
||||
| SMS | `SMSTO:` | ✓ | ✓ |
|
||||
| WhatsApp | `https://wa.me/…` | ✓ | ✓ |
|
||||
| Standort | `geo:` — dynamisch über OpenStreetMap | ✓ | ✓ |
|
||||
| Video | die Videoadresse — dynamisch mit Player-Seite | ✓ | ✓ |
|
||||
| vCard | vCard 3.0 | ✓ | — |
|
||||
| WLAN | `WIFI:` | ✓ | — |
|
||||
| App-Link | Weiterleitung je nach Gerät | — | ✓ |
|
||||
| Zahlung | GiroCode (EPC069-12) oder Zahlungslink | ✓ | nur Link |
|
||||
| Mehrere Links | eigene Seite mit Linkliste | — | ✓ |
|
||||
| Social Media | eigene Seite mit den Profilen | — | ✓ |
|
||||
| PDF | hinterlegte Datei auf eigener Seite | — | ✓ |
|
||||
| Bild | hinterlegte Bilder auf eigener Seite | — | ✓ |
|
||||
| Feedback | Bewertungsformular auf eigener Seite | — | ✓ |
|
||||
|
||||
Warum manche Typen nur eine Betriebsart können:
|
||||
|
||||
@@ -386,6 +391,12 @@ Warum manche Typen nur eine Betriebsart können:
|
||||
dynamischer Code funktioniert daher nur die Variante „Zahlungslink“ — die
|
||||
Anwendung weist das beim Speichern ausdrücklich ab, statt einen Code
|
||||
entstehen zu lassen, der beim Scannen ins Leere führt.
|
||||
- **Mehrere Links, Social Media, PDF, Bild und Feedback** brauchen eine Seite,
|
||||
die die Anwendung selbst ausliefert — eine Linkliste oder ein Formular passt
|
||||
nicht in einen einzelnen Code. Diese Seiten liegen unter `/s/{slug}`; der
|
||||
gedruckte Code zeigt weiterhin auf `/r/{slug}` und wird dorthin
|
||||
weitergeleitet. Der Scan-Zähler zählt dabei den Aufruf des Codes, nicht das
|
||||
Neuladen der Seite.
|
||||
|
||||
> **Zum WLAN-Code:** Das Passwort steht im Klartext im Code — wer ihn scannt
|
||||
> oder abfotografiert, kennt es. Für Gästenetze ist das gewollt. Besteht ein
|
||||
@@ -482,9 +493,70 @@ Kartenansicht.
|
||||
|
||||
Statische Codes erscheinen hier nicht, weil sie nicht gespeichert werden.
|
||||
|
||||
> Version 1 ist für den Einzelplatz-/LAN-Betrieb gedacht und hat **keine
|
||||
> Benutzerverwaltung**. Wer die Anwendung erreicht, sieht und ändert alle
|
||||
> Codes. Die App gehört daher nicht ungeschützt ins offene Internet.
|
||||
Bei einem **Feedback-Code** führt aus der Zeile ein Stern-Symbol zur
|
||||
Auswertung: Durchschnitt, Verteilung der Noten und die abgegebenen Kommentare.
|
||||
|
||||
---
|
||||
|
||||
### 7. Eigene Seiten: Links, Profile, Dateien, Feedback
|
||||
|
||||
Fünf Typen haben kein fremdes Ziel, auf das sich weiterleiten ließe — sie
|
||||
brauchen eine Seite. Die liefert die Anwendung selbst aus, unter
|
||||
`{BASE_URL}/s/{slug}`:
|
||||
|
||||
| Typ | Was die Seite zeigt |
|
||||
| --- | --- |
|
||||
| Mehrere Links | Überschrift, kurzer Text, bis zu 20 beschriftete Links |
|
||||
| Social Media | dieselbe Form, aber mit Netzwerk-Auswahl aus einem Katalog |
|
||||
| PDF | das hinterlegte Dokument mit „Öffnen“ und „Herunterladen“ |
|
||||
| Bild | ein Bild oder eine Galerie aus bis zu 10 Bildern mit Bildunterschriften |
|
||||
| Feedback | ein Formular mit Sternen oder Gesichtern und optionalem Kommentar |
|
||||
|
||||
Diese Seiten sind **öffentlich** und zeigen bewusst nichts von der Anwendung:
|
||||
keine Navigation, kein „Verwaltung“, kein Hinweis auf den Generator. Wer einen
|
||||
Aushang scannt, soll nur den Inhalt sehen.
|
||||
|
||||
Der gedruckte Code zeigt weiterhin auf `/r/{slug}`; von dort geht es auf die
|
||||
Seite. Der Scan-Zähler zählt dabei den Aufruf des Codes — ein Neuladen der
|
||||
Seite zählt nicht mit.
|
||||
|
||||
**Bei Social Media** genügt als Eingabe das Kürzel: aus `@firma` wird beim
|
||||
Speichern `https://instagram.com/firma`. Eine vollständige Adresse bleibt
|
||||
unverändert, damit auch abweichende Profil-Adressen möglich sind.
|
||||
|
||||
**Beim Video-Typ** wird der Player von YouTube oder Vimeo erst nach einem Klick
|
||||
geladen, und davor steht, dass dabei Daten an den Anbieter gehen. Ungefragt
|
||||
einen Drittanbieter einzubinden wäre auf einer Seite, die Fremde nach einem
|
||||
Scan zu sehen bekommen, nicht in Ordnung.
|
||||
|
||||
#### Hochgeladene Dateien
|
||||
|
||||
PDFs und Bilder liegen **in der Datenbank**, nicht auf der Platte. Damit gibt
|
||||
es weiterhin genau ein Volumen zu sichern: Wer die Datenbank sichert, hat
|
||||
alles.
|
||||
|
||||
- Die Grenze steht in der `.env` unter `MAX_UPLOAD_MB` (Voreinstellung 10).
|
||||
- Erlaubt sind PDF sowie PNG, JPEG, WebP, GIF und AVIF. **SVG bewusst nicht** —
|
||||
eine SVG-Datei darf Skripte enthalten und würde von derselben Adresse wie die
|
||||
Anwendung ausgeliefert.
|
||||
- Geprüft wird der **Inhalt**, nicht die Dateiendung. Eine Textdatei mit dem
|
||||
Namen `harmlos.pdf` wird abgewiesen.
|
||||
- Wird ein Code gelöscht, verschwindet seine Datei mit ihm. Eine ausgetauschte
|
||||
Datei und eine hochgeladene, aber nie gespeicherte werden nach 24 Stunden
|
||||
aufgeräumt.
|
||||
|
||||
#### Rückmeldungen
|
||||
|
||||
Ein Feedback-Eintrag besteht aus einer Note von 1 bis 5 und einem optionalen
|
||||
Text. Gespeichert wird **kein Name, keine IP-Adresse, keine Gerätekennung** —
|
||||
wer einen Aushang scannt und eine Note vergibt, bleibt anonym. Gegen Fluten
|
||||
gibt es eine Bremse von 10 Rückmeldungen pro Minute und Absender; die Adresse
|
||||
dient dabei nur als Schlüssel im Arbeitsspeicher und wird nirgends gespeichert.
|
||||
|
||||
> Ohne eingeschaltete Anmeldung sieht und ändert jeder, der die Anwendung
|
||||
> erreicht, alle Codes. Für den Einzelplatz- oder LAN-Betrieb ist das gewollt;
|
||||
> ins offene Internet gehört die Anwendung dann nicht. Mit `AUTH_ENABLED=true`
|
||||
> gibt es Benutzer, Gruppen und Rollen — siehe unten.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user