Merge: Version 1.7.0 — Dokumentation durchgesehen, Roadmap angeglichen

This commit was merged in pull request #18.
This commit is contained in:
2026-08-21 09:41:25 +00:00
9 changed files with 228 additions and 61 deletions
+11
View File
@@ -7,6 +7,17 @@ Versionsnummer in der Fußzeile.
> Diese Datei wird erzeugt: `npm run changelog`. > Diese Datei wird erzeugt: `npm run changelog`.
> Gepflegt wird der Verlauf in `src/lib/changelog.ts`. > Gepflegt wird der Verlauf in `src/lib/changelog.ts`.
## 1.7.0 — 21.08.2026
Logo im Code, Freigabe je Gruppe und ein Domain-Check.
- Ein Logo in der Mitte des Codes — das der Installation oder ein eigenes je Code, 10 bis 25 % der Kantenlänge. Die Fehlerkorrektur springt dabei auf H.
- QR-Typen lassen sich je Gruppe freigeben. Die Grundeinstellung bleibt die Grundlage; eine globale Abschaltung gewinnt immer.
- Der Knopf „Prüfen“ bei jeder Domain meldet DNS, Zertifikat, Erreichbarkeit — und ob dahinter wirklich diese Installation steht.
- Eine Kurzhilfe auf der Domain-Seite führt in sechs Schritten auf, was für eine neue Domain einzurichten ist.
- „Meine Codes“ lässt sich nach Art filtern: alle, nur dynamische, nur statische.
- Beim Ablegen eines statischen Codes wird gewarnt, wenn derselbe Inhalt schon in der Gruppe liegt.
## 1.6.0 — 21.08.2026 ## 1.6.0 — 21.08.2026
Sichtbare Version mit Änderungsverlauf. Sichtbare Version mit Änderungsverlauf.
+14 -7
View File
@@ -20,16 +20,18 @@ entscheidet die Verwaltung — nicht gebrauchte lassen sich ausblenden.
Fehlerkorrektur L/M/Q/H, einstellbarer Rand. Download als PNG und SVG. Fehlerkorrektur L/M/Q/H, einstellbarer Rand. Download als PNG und SVG.
- **Logo in der Mitte:** das Logo der Installation oder ein eigenes je Code, - **Logo in der Mitte:** das Logo der Installation oder ein eigenes je Code,
10–25 % der Kantenlänge, mit erzwungener Fehlerkorrektur H. 10–25 % der Kantenlänge, mit erzwungener Fehlerkorrektur H.
- **Meine Codes:** Liste oder Karten, Suche, Sortierung, Gruppenfilter, - **Meine Codes:** Liste oder Karten, Suche, Sortierung, Filter nach Gruppe
Ziel ändern, löschen. Statische Codes lassen sich auf Wunsch mit Namen und nach Art, Ziel ändern, löschen. Statische Codes lassen sich auf Wunsch
ablegen, um sie wiederzufinden. mit Namen ablegen; liegt derselbe Inhalt schon dort, wird gewarnt.
- **Feedback auswerten:** Durchschnitt, Verteilung und Kommentare — anonym - **Feedback auswerten:** Durchschnitt, Verteilung und Kommentare — anonym
erhoben, ohne Name und IP-Adresse. erhoben, ohne Name und IP-Adresse.
- **Anmeldung abschaltbar.** Mit Anmeldung: Benutzer, Gruppen und die Rollen - **Anmeldung abschaltbar.** Mit Anmeldung: Benutzer, Gruppen und die Rollen
Administrator, Bearbeiter und Betrachter. Administrator, Bearbeiter und Betrachter.
- **Mehrere Domains** für Kurz-URLs, den Gruppen zugeteilt. - **Mehrere Domains** für Kurz-URLs, den Gruppen zugeteilt — mit Kurzhilfe
zur Einrichtung und einer Prüfung, ob eine Domain wirklich hierher führt.
- **Single Sign-on** über Authentik oder einen anderen OIDC-Anbieter. - **Single Sign-on** über Authentik oder einen anderen OIDC-Anbieter.
- **Typen abschaltbar:** Was ihr nicht braucht, erscheint gar nicht erst. - **Typen abschaltbar:** Was ihr nicht braucht, erscheint gar nicht erst —
für die ganze Installation oder je Gruppe.
- **Eigenes Erscheinungsbild:** Name, Logo, Favicon und Akzentfarbe im - **Eigenes Erscheinungsbild:** Name, Logo, Favicon und Akzentfarbe im
Admin-Bereich einstellbar. Admin-Bereich einstellbar.
- **Hell und dunkel:** folgt dem Betriebssystem, mit Umschalter für eine - **Hell und dunkel:** folgt dem Betriebssystem, mit Umschalter für eine
@@ -609,7 +611,7 @@ Zwei Eigenschaften sind dabei zu unterscheiden:
| | Bedeutung | Woher | | | Bedeutung | Woher |
| --- | --- | --- | | --- | --- | --- |
| **umgesetzt** | Der Typ ist ausprogrammiert. In Version 1 gilt das nur für „Website“. | Registry im Code | | **umgesetzt** | Der Typ ist ausprogrammiert. Seit 1.1.0 gilt das für alle fünfzehn. | Registry im Code |
| **freigegeben** | Die Verwaltung zeigt den Typ an. | Datenbank, jederzeit änderbar | | **freigegeben** | Die Verwaltung zeigt den Typ an. | Datenbank, jederzeit änderbar |
Nur umgesetzt **und** freigegeben heißt benutzbar. Freigegeben, aber nicht Nur umgesetzt **und** freigegeben heißt benutzbar. Freigegeben, aber nicht
@@ -673,7 +675,10 @@ Kurz-URL rückt dann unter den Namen. Zum Herunterladen dient dort die
Kartenansicht. Kartenansicht.
Abgelegte **statische Codes** stehen mit in der Liste, tragen aber ein Abgelegte **statische Codes** stehen mit in der Liste, tragen aber ein
Abzeichen „statisch“ statt einer Kurz-URL und zählen keine Scans. Steht der Abzeichen „statisch“ statt einer Kurz-URL und zählen keine Scans. Beim
Ablegen läuft eine **Dublettenprüfung**: Liegt in derselben Gruppe schon ein
statischer Code mit identischem Inhalt, hält das Ablegen an und nennt ihn —
eine Rückfrage mit dem Knopf „Trotzdem ablegen“, keine Sperre. Verglichen wird nur der Inhalt, nicht die Gestaltung. Steht der
Filter auf „Nur statische“, fällt die Scan-Spalte weg und die Sortierung nach Filter auf „Nur statische“, fällt die Scan-Spalte weg und die Sortierung nach
Scans mit ihr — bei einer Liste aus lauter Nullen sagt sie nichts. Scans mit ihr — bei einer Liste aus lauter Nullen sagt sie nichts.
@@ -1017,6 +1022,8 @@ deutschen Meldung.
| `GET` | `/r/{slug}` | Weiterleitung, erhöht den Scan-Zähler | | `GET` | `/r/{slug}` | Weiterleitung, erhöht den Scan-Zähler |
| `GET` | `/api/admin/types` | Zustand aller QR-Typen (`?group={id}` je Gruppe) | | `GET` | `/api/admin/types` | Zustand aller QR-Typen (`?group={id}` je Gruppe) |
| `PATCH` | `/api/admin/types` | Typ freigeben oder abschalten (`groupId` optional) | | `PATCH` | `/api/admin/types` | Typ freigeben oder abschalten (`groupId` optional) |
| `POST` | `/api/admin/domains/{id}/check` | Domain prüfen: DNS, Zertifikat, Erreichbarkeit, Ziel |
| `GET` | `/api/domain-check` | Beweis für die Domain-Prüfung (`?nonce=…`, ohne Anmeldung) |
Beispiel: Beispiel:
+92 -3
View File
@@ -112,12 +112,40 @@ gescannt zu werden.
das Scannen erschweren, weil der Scanner den Code nicht mehr vom Hintergrund das Scannen erschweren, weil der Scanner den Code nicht mehr vom Hintergrund
trennen kann. trennen kann.
### Ein Logo in die Mitte setzen
Ganz unten in der Gestaltung steht **Logo in der Mitte**. Ein Haken genügt,
dann fragt die Anwendung, woher das Bild kommen soll:
- **Logo dieser Installation** — das, was unter Verwaltung → Erscheinungsbild
hinterlegt ist. Kein Upload je Code nötig. Die Wahl erscheint nur, wenn dort
überhaupt eines liegt.
- **Eigenes Logo** — je Code hochgeladen, für Kundenprojekte mit fremdem
Zeichen. PNG, JPEG, WebP oder AVIF, bis 2 MB.
Die **Größe** liegt zwischen 10 und 25 % der Kantenlänge; voreingestellt sind
20 %, das verdeckt rund 4 % der Fläche. Hinter dem Bild liegt eine Fläche in
der Hintergrundfarbe, damit es sich absetzt.
**Die Fehlerkorrektur springt dabei auf H** und lässt sich nicht mehr ändern —
was das Bild verdeckt, muss sie ausgleichen. Das steht auch so unter der
Auswahl; heimlich geschieht es nicht.
Ab 22 % erscheint eine Warnung. Die Fehlerkorrektur trägt das zwar, aber
manche Scanner-Apps suchen in der Mitte nach Ausrichtungsmustern.
> **Einmal selbst scannen, bevor etwas in den Druck geht.** Ein Code mit Logo
> ist die einzige Stelle, an der die Anwendung etwas ausliefern kann, das auf
> dem einen Gerät geht und auf dem anderen nicht. Zwei verschiedene Apps
> kosten eine halbe Minute und ersparen eine Neuauflage.
--- ---
## Meine Codes ## Meine Codes
Hier stehen alle **dynamischen** Codes. Statische erscheinen nicht — sie Hier stehen die **dynamischen** Codes und die statischen, die du abgelegt
werden nicht gespeichert. hast. Beide Arten stehen nebeneinander in derselben Liste — ein statischer
trägt statt einer Kurz-URL das Abzeichen „statisch“ und zählt keine Scans.
![Meine Codes als Liste](bilder/04-meine-codes-liste.png) ![Meine Codes als Liste](bilder/04-meine-codes-liste.png)
@@ -128,6 +156,10 @@ Projekte nebeneinander.
- Die **Sortierung** kennt neueste, älteste, Name und Scan-Anzahl. - Die **Sortierung** kennt neueste, älteste, Name und Scan-Anzahl.
- Ein **Gruppenfilter** erscheint, sobald Codes in mehr als einer Gruppe - Ein **Gruppenfilter** erscheint, sobald Codes in mehr als einer Gruppe
liegen. liegen.
- Ein **Filter nach Art** erscheint, sobald dynamische und statische Codes
nebeneinander liegen: *Alle Arten*, *Nur dynamische*, *Nur statische*.
Steht er auf „Nur statische“, fällt die Scan-Spalte weg und die Sortierung
nach Scans mit ihr — bei einer Liste aus lauter Strichen sagt sie nichts.
- Das Symbol neben der Kurz-URL kopiert sie in die Zwischenablage. - Das Symbol neben der Kurz-URL kopiert sie in die Zwischenablage.
Über die beiden Schalter rechts geht es zur **Kartenansicht** mit großer Über die beiden Schalter rechts geht es zur **Kartenansicht** mit großer
@@ -135,6 +167,21 @@ Vorschau. Die Wahl merkt sich der Browser.
![Meine Codes als Karten](bilder/05-meine-codes-karten.png) ![Meine Codes als Karten](bilder/05-meine-codes-karten.png)
### Statische Codes ablegen
Ein statischer Code ist mit dem Download eigentlich fertig — sein Inhalt
steckt in ihm. Der Knopf **In „Meine Codes“ ablegen** legt ihn trotzdem in die
Liste, damit du ihn wiederfindest und erneut herunterladen kannst.
Liegt dort schon ein statischer Code mit **identischem Inhalt**, hält das
Ablegen an und zeigt, welcher das ist und wann er entstand. Der Knopf heißt
dann **Trotzdem ablegen** — es ist eine Warnung, keine Sperre. Verglichen wird
nur der Inhalt, nicht die Gestaltung: Derselbe Code in Schwarz-Weiß und in
Hausfarben gilt hier als Dublette.
Bei **dynamischen** Codes fragt niemand nach. Zwei Kurz-Links auf dasselbe
Ziel sind der Normalfall, sobald zwei Kampagnen getrennt gezählt werden.
### Ziel ändern ### Ziel ändern
![Dialog zum Ändern des Ziels](bilder/06-ziel-bearbeiten.png) ![Dialog zum Ändern des Ziels](bilder/06-ziel-bearbeiten.png)
@@ -247,6 +294,25 @@ sich Typen abschalten; sie verschwinden dann aus der Auswahl.
unverändert weiter** — sie leiten weiter, zählen Scans und lassen sich unverändert weiter** — sie leiten weiter, zählen Scans und lassen sich
bearbeiten. Nur neue lassen sich nicht mehr anlegen. bearbeiten. Nur neue lassen sich nicht mehr anlegen.
**Freigabe je Gruppe.** Über der Liste steht die Auswahl **Freigabe für**:
| Auswahl | Wirkung |
| --- | --- |
| Alle Gruppen (Grundeinstellung) | gilt für die ganze Installation |
| Nur: *eine Gruppe* | weicht für diese eine Gruppe ab |
So bekommt die Marketingabteilung Social Media und die Werkstatt nur Website
und PDF. Fehlt eine Abweichung, folgt die Gruppe der Grundeinstellung.
**Die Grundeinstellung gewinnt immer.** Ein Typ, der dort abgeschaltet ist,
lässt sich in keiner Gruppe einschalten — der Schalter steht dann ausgegraut
und nennt den Grund. Andersherum wäre „hier abgeschaltet“ keine verlässliche
Aussage mehr.
Wer in mehreren Gruppen ist, sieht auf der Startseite die **Vereinigung**.
Welche Freigabe zählt, entscheidet sich beim Anlegen anhand der gewählten
Gruppe.
### Gruppen ### Gruppen
![Gruppen verwalten](bilder/13-verwaltung-gruppen.png) ![Gruppen verwalten](bilder/13-verwaltung-gruppen.png)
@@ -275,7 +341,30 @@ mehreren Gruppen dienen; die Codes bleiben trotzdem strikt nach Gruppe
getrennt. getrennt.
Damit das funktioniert, muss der Reverse Proxy jede dieser Domains auf diese Damit das funktioniert, muss der Reverse Proxy jede dieser Domains auf diese
Anwendung leiten — siehe README, Abschnitt „Mehrere Domains“. Anwendung leiten. Was dafür einzurichten ist, steht nicht nur im README: Der
Knopf **Kurzhilfe** über der Liste führt es in sechs Schritten auf — DNS,
Weiterleitung im Proxy samt der drei nötigen Kopfzeilen, Zertifikat,
Registrieren, Gruppenzuteilung, Nachprüfen.
**Prüfen, ob eine Domain wirklich hierher führt.** Bei jedem Eintrag steht ein
Knopf **Prüfen**. Er geht den Weg der Scanner nach und meldet vier Dinge:
| Schritt | Was er sagt |
| --- | --- |
| DNS | ob der Name auflöst, und auf welche Adressen |
| Zertifikat | gültig bis wann, von wem ausgestellt |
| Erreichbar | ob dort ein Webserver antwortet, und wie schnell |
| Ziel | ob dahinter **diese** Installation steht |
Der letzte Schritt ist der eigentliche Wert. Dass irgendwo etwas antwortet,
sagt wenig; die Prüfung lässt sich beweisen, dass es diese Anwendung ist.
Scheitert schon DNS, fallen die drei Folgeschritte aus — dreimal dieselbe
Meldung würde die eine wichtige verdecken.
> **Der Aufruf startet dort, wo der Container läuft.** Bei internem DNS oder
> Hairpin-NAT kann er scheitern, obwohl von außen alles stimmt. Und
> umgekehrt: Ein Erfolg von innen beweist noch nicht, dass die Domain von
> außen erreichbar ist. Dafür bleibt der Blick von einem fremden Netz aus.
--- ---
+54 -2
View File
@@ -315,8 +315,9 @@ Die **Vorschau** wird serverseitig gerendert und aktualisiert sich bei jeder
## Meine Codes ## Meine Codes
Zeigt alle dynamischen Codes — statische erscheinen nicht, weil sie nicht Zeigt die dynamischen Codes und die statischen, die abgelegt wurden. Ein
gespeichert werden. abgelegter statischer Code trägt statt einer Kurz-URL das Abzeichen
„statisch“ und zählt keine Scans.
- **Zwei Ansichten:** Liste (Voreinstellung, eine Zeile je Code) und Karten - **Zwei Ansichten:** Liste (Voreinstellung, eine Zeile je Code) und Karten
mit großer Vorschau. Die Wahl merkt sich der Browser. mit großer Vorschau. Die Wahl merkt sich der Browser.
@@ -324,6 +325,10 @@ gespeichert werden.
- **Sortierung** nach neueste, älteste, Name oder Scan-Anzahl. - **Sortierung** nach neueste, älteste, Name oder Scan-Anzahl.
- **Gruppenfilter**, sobald Codes in mehr als einer Gruppe liegen; dann gibt - **Gruppenfilter**, sobald Codes in mehr als einer Gruppe liegen; dann gibt
es auch eine Gruppenspalte. es auch eine Gruppenspalte.
- **Filter nach Art** (*Alle Arten*, *Nur dynamische*, *Nur statische*),
sobald beide Arten vorkommen. Bei „Nur statische“ verschwindet die
Scan-Spalte und mit ihr die Sortierung danach: Statische zählen keine
Scans, die Spalte wäre eine Reihe aus Strichen.
- **Kurz-URL kopieren** mit einem Klick. - **Kurz-URL kopieren** mit einem Klick.
- **Ziel ändern** — die Kurz-URL und damit der gedruckte Code bleiben gültig. - **Ziel ändern** — die Kurz-URL und damit der gedruckte Code bleiben gültig.
- **Löschen** mit Rückfrage, die den betroffenen Code nennt. - **Löschen** mit Rückfrage, die den betroffenen Code nennt.
@@ -426,6 +431,53 @@ Domains werden in der Verwaltung angelegt und Gruppen zugeteilt.
Damit das funktioniert, muss der Reverse Proxy jede dieser Domains auf diese Damit das funktioniert, muss der Reverse Proxy jede dieser Domains auf diese
Anwendung leiten. Anwendung leiten.
### Kurzhilfe zur Einrichtung
Was außerhalb der Anwendung einzurichten ist, steht nicht nur im README: Auf
der Domain-Seite öffnet der Knopf **Kurzhilfe** eine Erklärung in sechs
Schritten — DNS-Eintrag, Weiterleitung im Reverse Proxy samt der drei nötigen
Kopfzeilen zum Abtippen, Zertifikat, Registrieren, Gruppenzuteilung,
Nachprüfen. Der Hostname aus `BASE_URL` wird als Beispiel eingesetzt.
Bewusst ein Dialog und kein Dauertext: Die Erklärung braucht man einmal beim
Einrichten und danach nie wieder.
### Prüfen, ob eine Domain hierher führt
Bei jedem Eintrag steht ein Knopf **Prüfen**. Er geht den Weg der Scanner nach
und meldet vier Dinge:
| Schritt | Was geprüft wird |
| --- | --- |
| DNS | Löst der Name auf? Auf welche Adressen? |
| Zertifikat | Gültig, von wem ausgestellt, wie lange noch? |
| Erreichbar | Antwortet dort ein Webserver, und wie schnell? |
| Ziel | Steht dahinter **diese** Installation? |
Der letzte Schritt ist der eigentliche Wert. Dass irgendwo etwas antwortet,
sagt wenig — es könnte die Parkseite des Registrars sein oder eine andere
Installation dieser Anwendung. Deshalb ruft die Prüfung unter der Domain eine
eigene Route auf und lässt sich einen HMAC über eine frische Zufallszahl
zurückgeben. Das Geheimnis dafür entsteht beim ersten Check, liegt in der
Datenbank und verlässt den Server nie.
Die Meldungen sind im Klartext: abgelaufen, selbst ausgestellt, gilt für einen
anderen Namen, Zwischenzertifikat fehlt, Port 443 nimmt nichts an, „es
antwortet etwas, aber nicht diese Anwendung“. Läuft ein Zertifikat in
höchstens 14 Tagen ab, gilt der Schritt als Warnung statt als Erfolg.
Scheitert schon DNS, fallen die drei Folgeschritte aus — dreimal dieselbe
Meldung würde die eine wichtige verdecken.
**Die Grenze der Aussage** steht unter jedem Bericht: Der Aufruf startet dort,
wo der Container läuft. Bei internem DNS oder Hairpin-NAT kann er scheitern,
obwohl von außen alles stimmt; umgekehrt beweist ein Erfolg von innen nicht,
dass die Domain von außen erreichbar ist.
Geprüft wird ausschließlich ein Hostname **aus der Datenbank**, nie einer aus
der Anfrage — sonst wäre die Route ein Werkzeug, mit dem sich vom Server aus
beliebige Adressen abklopfen ließen. Näheres in
[sicherheit.md](sicherheit.md).
--- ---
## Erscheinungsbild ## Erscheinungsbild
+24 -38
View File
@@ -15,8 +15,13 @@ Fußzeile.
Kurz gefasst: Version 1.0.0 (13.08.2026) brachte das Grundgerüst mit dem Typ Kurz gefasst: Version 1.0.0 (13.08.2026) brachte das Grundgerüst mit dem Typ
Website, 1.1.0 alle fünfzehn Typen samt Anmeldung, Gruppen und Domains, Website, 1.1.0 alle fünfzehn Typen samt Anmeldung, Gruppen und Domains,
1.2.0 Single Sign-on und die Sicherheitsdurchsicht, 1.3.0 Erscheinungsbild 1.2.0 Single Sign-on und die Sicherheitsdurchsicht, 1.3.0 Erscheinungsbild
und Dark Mode, 1.4.0 sprechende Kurz-Links, 1.5.0 benennbare statische Codes und Dark Mode, 1.4.0 sprechende Kurz-Links, 1.5.0 benennbare statische Codes,
und 1.6.0 diesen Versionshinweis. 1.6.0 den Versionshinweis und 1.7.0 sechs Erweiterungen auf einmal — Logo im
Code, Freigabe je Gruppe, Domain-Check, Dublettenprüfung, Filter nach Art und
die Kurzhilfe zu den Domains.
Damit sind zwei Punkte erledigt, die hier lange unter „Als Nächstes“ standen:
**QR-Typen je Gruppe freigeben** und **Logo im QR-Code**.
--- ---
@@ -25,27 +30,7 @@ und 1.6.0 diesen Versionshinweis.
In dieser Reihenfolge. Die Einschätzungen sind grobe Hausnummern für eine In dieser Reihenfolge. Die Einschätzungen sind grobe Hausnummern für eine
Person, die den Code kennt. Person, die den Code kennt.
### 1. QR-Typen je Gruppe freigeben · mittel ### 1. Statistik über die Zeit · mittel
Heute gilt die Freigabe eines Typs für die ganze Installation: Was
abgeschaltet ist, ist für alle weg. Bei mehreren Gruppen ist das zu grob — die
Marketingabteilung braucht Social Media, die Werkstatt nur Website und PDF.
Geplant: Die Freigabe bekommt eine zweite Dimension. Es bleibt eine globale
Einstellung als Grundlage, und je Gruppe lässt sich davon abweichen. Wer in
mehreren Gruppen ist, sieht auf der Startseite die Vereinigung; beim Anlegen
entscheidet die gewählte Gruppe.
Zu klären ist der Fall, in dem ein Typ global aus, in einer Gruppe aber an
ist — entweder die Gruppe darf das überstimmen, oder die globale Abschaltung
gewinnt immer. Die zweite Lesart ist die weniger überraschende und
wahrscheinlich die richtige.
Berührt: `QrTypeSetting` (zusammengesetzter Schlüssel aus Typ und Gruppe),
`src/lib/qr/availability.ts`, die Startseite und die Typ-Verwaltung, die dann
eine Gruppenauswahl bekommt.
### 2. Statistik über die Zeit · mittel
Der Zähler weiß heute nur, wie oft und wann zuletzt. Gebraucht wird der Der Zähler weiß heute nur, wie oft und wann zuletzt. Gebraucht wird der
Verlauf: Wie lief die Kampagne in den ersten Tagen, wann ist Ruhe Verlauf: Wie lief die Kampagne in den ersten Tagen, wann ist Ruhe
@@ -59,7 +44,7 @@ sagt nichts über einzelne Menschen aus und braucht deshalb weder Einwilligung
noch Löschfristen. Wer mehr will, muss sich mit beidem befassen — das ist eine noch Löschfristen. Wer mehr will, muss sich mit beidem befassen — das ist eine
andere Entscheidung als „ein Diagramm wäre schön“. andere Entscheidung als „ein Diagramm wäre schön“.
### 3. Papierkorb statt Löschen · klein ### 2. Papierkorb statt Löschen · klein
Heute ist ein gedruckter Code nach einem Fehlklick unwiederbringlich tot, Heute ist ein gedruckter Code nach einem Fehlklick unwiederbringlich tot,
samt seiner Dateien und Rückmeldungen. samt seiner Dateien und Rückmeldungen.
@@ -69,20 +54,7 @@ Geplant: Gelöschte Codes 30 Tage aufheben und dann endgültig entfernen. In
im Papierkorb liegt, bleibt sein Slug belegt — sonst könnte ihn ein neuer Code im Papierkorb liegt, bleibt sein Slug belegt — sonst könnte ihn ein neuer Code
bekommen und die gedruckten Codes zeigten plötzlich woandershin. bekommen und die gedruckten Codes zeigten plötzlich woandershin.
### 4. Logo im QR-Code · mittel ### 3. Ablaufdatum und Zeitsteuerung · mittel
Ein kleines Bild in die Mitte setzen, wie man es von Firmen-Codes kennt.
Geplant: Upload eines Logos je Code, mittig eingesetzt, mit erzwungener
Fehlerkorrektur **H** und einer Warnung, sobald zu viel Fläche verdeckt wird.
Das ist der Punkt mit dem größten Risiko, etwas Kaputtes auszuliefern: Ein
Code, der auf dem eigenen Handy noch funktioniert, kann bei anderen
Scanner-Apps durchfallen. Gehört deshalb nicht ohne eine ehrliche Prüfung mit
mehreren Geräten und Apps ausgeliefert — und mit einer klaren Obergrenze für
die verdeckte Fläche.
### 5. Ablaufdatum und Zeitsteuerung · mittel
Ein Code, der ab einem Datum woandershin führt oder abläuft — für Ein Code, der ab einem Datum woandershin führt oder abläuft — für
Veranstaltungen, Aktionen und Aushänge mit Verfallsdatum. Veranstaltungen, Aktionen und Aushänge mit Verfallsdatum.
@@ -99,6 +71,20 @@ Geplant, in zwei Stufen:
Zu bedenken: Zeitzonen und die Frage, was beim Bearbeiten mit vergangenen Zu bedenken: Zeitzonen und die Frage, was beim Bearbeiten mit vergangenen
Fenstern geschieht. Fenstern geschieht.
### 4. Gestaltung eines gespeicherten Codes ändern · klein
Aufgefallen beim Einbau des Logos: In „Meine Codes“ lässt sich die Gestaltung
eines abgelegten Codes gar nicht mehr anfassen — weder Farben noch Größe noch
Logo. Wer ein Logo nachrüsten will, kommt nur über die Schnittstelle daran.
Bei einem **dynamischen** Code ist das unnötig streng: Das gedruckte Bild
bleibt zwar, wie es ist, aber der erneute Download soll ja gerade die neue
Gestaltung tragen. Geplant: derselbe Gestaltungsbereich wie im Generator, im
Bearbeiten-Dialog.
Bei einem **statischen** Code bleibt es beim Nein — er ist ein Schnappschuss,
und eine geänderte Gestaltung ergäbe ein anderes Bild als das gedruckte.
--- ---
## Später denkbar ## Später denkbar
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "qrcode-generator", "name": "qrcode-generator",
"version": "1.6.0", "version": "1.7.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
+13 -5
View File
@@ -98,13 +98,21 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;`}</HelpCode>
</HelpStep> </HelpStep>
<HelpStep n={6} title="Nachprüfen"> <HelpStep n={6} title="Nachprüfen">
<p>Von außerhalb des eigenen Netzes:</p> <p>
Dafür gibt es den Knopf <strong>Prüfen</strong> bei jedem Eintrag
in der Liste. Er meldet DNS, Zertifikat, Erreichbarkeit — und ob
hinter der Domain wirklich diese Installation steht.
</p>
<p>
Der Aufruf startet dort, wo dieser Container läuft. Bei internem
DNS oder Hairpin-NAT kann er scheitern, obwohl von außen alles
stimmt. Von einem fremden Netz aus hilft dann:
</p>
<HelpCode>{`curl -I https://${beispiel}/`}</HelpCode> <HelpCode>{`curl -I https://${beispiel}/`}</HelpCode>
<p> <p>
Kommt eine Antwort dieser Anwendung, stimmen DNS, Proxy und Zum Schluss einen Code der zugeteilten Gruppe anlegen, die Domain
Zertifikat. Danach einen Code der zugeteilten Gruppe anlegen, die auswählen und den fertigen Code einmal mit dem Handy scannen — das
Domain auswählen und den fertigen Code einmal mit dem Handy ist die einzige Prüfung, die wirklich zählt.
scannen — das ist die einzige Prüfung, die wirklich zählt.
</p> </p>
</HelpStep> </HelpStep>
</ol> </ol>
+17 -4
View File
@@ -8,10 +8,10 @@ import pkg from "../../package.json";
* unweigerlich auseinander; eine Prüfung wacht darüber, dass die erzeugte * unweigerlich auseinander; eine Prüfung wacht darüber, dass die erzeugte
* Datei zu dieser Quelle passt. * Datei zu dieser Quelle passt.
* *
* Die Einträge sind aus dem Abschnitt „Gebaut“ der Roadmap und der * Die Einträge bis 1.5.0 sind aus dem Abschnitt „Gebaut“ der Roadmap und der
* Git-Historie zusammengetragen. Versionsnummern gab es dabei nie — es * Git-Historie zusammengetragen: Versionsnummern gab es damals nicht, deshalb
* existieren keine Tags —, deshalb ist je **Erscheinungstag** eine Version * ist je **Erscheinungstag** eine gebildet. Nachträglich vergeben, aber die
* gebildet. Das ist nachträglich vergeben, aber die Daten selbst stimmen. * Daten selbst stimmen. Ab 1.6.0 trägt jede Fassung einen Git-Tag.
*/ */
export type ChangelogEntry = { export type ChangelogEntry = {
version: string; version: string;
@@ -23,6 +23,19 @@ export type ChangelogEntry = {
}; };
export const CHANGELOG: readonly ChangelogEntry[] = [ export const CHANGELOG: readonly ChangelogEntry[] = [
{
version: "1.7.0",
date: "2026-08-21",
summary: "Logo im Code, Freigabe je Gruppe und ein Domain-Check.",
changes: [
"Ein Logo in der Mitte des Codes — das der Installation oder ein eigenes je Code, 10 bis 25 % der Kantenlänge. Die Fehlerkorrektur springt dabei auf H.",
"QR-Typen lassen sich je Gruppe freigeben. Die Grundeinstellung bleibt die Grundlage; eine globale Abschaltung gewinnt immer.",
"Der Knopf „Prüfen“ bei jeder Domain meldet DNS, Zertifikat, Erreichbarkeit — und ob dahinter wirklich diese Installation steht.",
"Eine Kurzhilfe auf der Domain-Seite führt in sechs Schritten auf, was für eine neue Domain einzurichten ist.",
"„Meine Codes“ lässt sich nach Art filtern: alle, nur dynamische, nur statische.",
"Beim Ablegen eines statischen Codes wird gewarnt, wenn derselbe Inhalt schon in der Gruppe liegt.",
],
},
{ {
version: "1.6.0", version: "1.6.0",
date: "2026-08-21", date: "2026-08-21",
+2 -1
View File
@@ -17,7 +17,8 @@ import {
* Zwei voneinander unabhängige Eigenschaften bestimmen, was ein Typ kann: * Zwei voneinander unabhängige Eigenschaften bestimmen, was ein Typ kann:
* *
* - `implemented` — steht in der Registry und sagt, ob der Typ überhaupt * - `implemented` — steht in der Registry und sagt, ob der Typ überhaupt
* ausprogrammiert ist. In V1 gilt das nur für „Website“. * ausprogrammiert ist. Seit 1.1.0 gilt das für alle fünfzehn; die
* Unterscheidung bleibt für Typen, die später dazukommen.
* - `enabled` — kommt aus der Datenbank und sagt, ob die Verwaltung den Typ * - `enabled` — kommt aus der Datenbank und sagt, ob die Verwaltung den Typ
* freigegeben hat. Fehlt der Eintrag, ist der Typ freigegeben. * freigegeben hat. Fehlt der Eintrag, ist der Typ freigegeben.
* *