Drei Zustaende in der Kopfzeile — System, Hell, Dunkel. Drei statt zwei, weil ein reiner Ein/Aus-Schalter nach dem ersten Klick fuer immer eine feste Wahl bedeutet; wer "System" waehlt, bekommt abends dunkel und morgens hell. Umgesetzt ueber `light-dark()` im CSS, nicht ueber `dark:`-Klassen. Die Oberflaeche benutzt an rund 440 Stellen feste Farbklassen; jede davon zu verdoppeln waere eine riesige Fleissarbeit, und jede kuenftige Zeile muesste daran denken. Stattdessen entscheiden die Farbvariablen selbst, welchen Wert sie tragen — gesteuert ueber `color-scheme`. Deshalb genuegt fuer den Umschalter ein Attribut am html-Element, und die Systemwahl funktioniert sogar ohne JavaScript. Das Skript im Kopf setzt nur eine ausdrueckliche Wahl, damit die helle Fassung nicht kurz aufblitzt. Zwei Faelle liessen sich nicht ueber Variablen loesen: `bg-white` muss im Dunkeln eine dunkle Flaeche sein, `text-white` dagegen weiss bleiben — beide teilen sich aber dieselbe Variable. Fuer Flaechen gibt es deshalb jetzt `bg-surface`. Ebenso brauchen Akzent-Links im Dunkeln eine hellere Stufe als Akzent-Knoepfe: dafuer `text-accent-text` und `bg-accent-soft`. Bewusst unveraendert bleiben die QR-Codes selbst — deren Farben legt die Gestaltung fest. Die dunklen Werte sind keine Spiegelung: Reines Schwarz unter weisser Schrift flimmert. Alle Textkontraste sind gemessen und liegen ueber 4,5:1, der niedrigste bei 5,9:1.
226 lines
9.0 KiB
Markdown
226 lines
9.0 KiB
Markdown
# Roadmap
|
|
|
|
Was gebaut ist, was als Nächstes kommt und was danach denkbar wäre. Die
|
|
Aufwände sind grobe Einschätzungen, keine Zusagen.
|
|
|
|
---
|
|
|
|
## Gebaut
|
|
|
|
### Version 1 — Grundgerüst (13.08.2026)
|
|
|
|
- Next.js-Anwendung und PostgreSQL als Docker-Compose-Stack, ohne Reverse
|
|
Proxy, Migrationen beim Start
|
|
- QR-Typ-Registry als Dispatch-Tabelle — ein neuer Typ ist ein Modul plus ein
|
|
Formular, ohne Eingriff in den übrigen Code
|
|
- Typ **Website**, statisch und dynamisch, mit Kurz-URL, 302-Weiterleitung und
|
|
Scan-Zähler
|
|
- Gestaltung: Farben mit Kontrastwarnung, Größe, Fehlerkorrektur, Rand
|
|
- Download als PNG und SVG, serverseitig gerendert
|
|
- „Meine Codes“ mit Ziel ändern und Löschen
|
|
- Deutsche Oberfläche, deutsche Fehlermeldungen, Validierung mit Zod
|
|
- Update-Skript für Linux/macOS und Windows
|
|
|
|
### Typen einzeln freigeben (14.08.2026)
|
|
|
|
Ausblenden nicht gebrauchter Typen in der Verwaltung. Bereits erstellte Codes
|
|
eines abgeschalteten Typs funktionieren weiter.
|
|
|
|
### Phase A — acht weitere Typen (14.08.2026)
|
|
|
|
vCard, App-Link, WhatsApp, E-Mail, SMS, Standort, Zahlung (GiroCode und
|
|
Zahlungslink), WLAN.
|
|
|
|
### Phase B1 — Anmeldung, Gruppen, Rollen (14.08.2026)
|
|
|
|
Abschaltbare Anmeldung, Benutzerverwaltung, Gruppen mit den Rollen
|
|
Administrator, Bearbeiter und Betrachter, Sitzungen in der Datenbank,
|
|
scrypt-Passwörter, Sperre nach Fehlversuchen.
|
|
|
|
### Phase B2 — mehrere Domains (14.08.2026)
|
|
|
|
Domains für Kurz-URLs, den Gruppen zugeteilt. Slug je Domain eindeutig,
|
|
Host-Header gegen die registrierten Domains geprüft.
|
|
|
|
### Listenansicht (14.08.2026)
|
|
|
|
„Meine Codes“ als Liste mit Suche, Sortierung und Gruppenfilter — gedacht für
|
|
viele Projekte nebeneinander. Karten bleiben als zweite Ansicht.
|
|
|
|
### Phase C — die letzten sechs Typen (14.08.2026)
|
|
|
|
Mehrere Links, Social Media, Video, PDF, Bild, Feedback. Dazu:
|
|
|
|
- Landingpages als eigene Gattung (`/s/{slug}`), ohne App-Navigation
|
|
- Datei-Upload mit Inhaltsprüfung, Größengrenze und Aufräumen
|
|
- Feedback mit anonymer Erhebung und Auswertung
|
|
|
|
Damit sind **alle 15 vorgesehenen Typen** gebaut.
|
|
|
|
### Single Sign-on (15.08.2026)
|
|
|
|
Anmeldung über Authentik und andere OIDC-Anbieter, mit PKCE und geprüftem
|
|
ID-Token.
|
|
|
|
### Erscheinungsbild (16.08.2026)
|
|
|
|
Name, Logo, Favicon und Akzentfarbe im Admin-Bereich einstellbar. Die Farbe
|
|
wirkt über die Farbvariablen, die Tailwind ohnehin benutzt — deshalb ohne
|
|
Umbau der rund 60 eingefärbten Stellen.
|
|
|
|
### Dark Mode (16.08.2026)
|
|
|
|
Folgt dem Betriebssystem, mit Umschalter für Hell, Dunkel und System.
|
|
Umgesetzt über `light-dark()` statt über `dark:`-Klassen — deshalb ohne
|
|
Änderung an den rund 440 Farbklassen und ohne JavaScript für die Systemwahl.
|
|
|
|
### Dokumentation (15.08.2026)
|
|
|
|
Bedienungsanleitung mit Bildern, Authentik-Anleitung, Funktionsübersicht.
|
|
Die Bilder erzeugt ein Skript, damit sie nicht veralten.
|
|
|
|
---
|
|
|
|
## Als Nächstes
|
|
|
|
In dieser Reihenfolge. Die Einschätzungen sind grobe Hausnummern für eine
|
|
Person, die den Code kennt.
|
|
|
|
### 1. QR-Typen je Gruppe freigeben · 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
|
|
Verlauf: Wie lief die Kampagne in den ersten Tagen, wann ist Ruhe
|
|
eingekehrt?
|
|
|
|
Geplant: eine Tabelle mit einer Zeile je Code und Tag, dazu ein Diagramm in
|
|
der Codeansicht und die Zahlen der letzten 7, 30 und 365 Tage.
|
|
|
|
Bewusst **ohne** Herkunft, Gerät oder Verweisseite. Ein reiner Tageszähler
|
|
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
|
|
andere Entscheidung als „ein Diagramm wäre schön“.
|
|
|
|
### 3. Papierkorb statt Löschen · klein
|
|
|
|
Heute ist ein gedruckter Code nach einem Fehlklick unwiederbringlich tot,
|
|
samt seiner Dateien und Rückmeldungen.
|
|
|
|
Geplant: Gelöschte Codes 30 Tage aufheben und dann endgültig entfernen. In
|
|
„Meine Codes“ ein Reiter „Papierkorb“ mit Wiederherstellen. Solange ein Code
|
|
im Papierkorb liegt, bleibt sein Slug belegt — sonst könnte ihn ein neuer Code
|
|
bekommen und die gedruckten Codes zeigten plötzlich woandershin.
|
|
|
|
### 4. Logo im QR-Code · 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
|
|
Veranstaltungen, Aktionen und Aushänge mit Verfallsdatum.
|
|
|
|
Geplant, in zwei Stufen:
|
|
|
|
- **Ablauf:** ab einem Zeitpunkt zeigt der Code eine erklärende Seite statt
|
|
des Ziels. Wichtig ist der Text — wer davorsteht, soll erfahren, dass die
|
|
Aktion vorbei ist, nicht dass „etwas nicht gefunden“ wurde.
|
|
- **Zeitplan:** mehrere Ziele mit Gültigkeitsfenstern, damit derselbe
|
|
Aufsteller montags auf die Mittagskarte und samstags auf die Veranstaltung
|
|
zeigt.
|
|
|
|
Zu bedenken: Zeitzonen und die Frage, was beim Bearbeiten mit vergangenen
|
|
Fenstern geschieht.
|
|
|
|
---
|
|
|
|
## Später denkbar
|
|
|
|
**Das Fenster der Ersteinrichtung schließen** · klein
|
|
Heute wird das erste Konto ohne jede Legitimation angelegt und ist gleich
|
|
Administrator. Wer die Anwendung öffentlich stellt, bevor er sein Konto
|
|
angelegt hat, kann sie an einen Fremden verlieren. Vorschlag: ein einmaliges
|
|
Token, das beim ersten Start ins Protokoll geschrieben wird und für die
|
|
Ersteinrichtung nötig ist. Klein im Aufwand — und das Erste, was zu tun ist,
|
|
falls die Anwendung je aus dem eigenen Netz herausgeht. Siehe
|
|
[sicherheit.md](sicherheit.md).
|
|
|
|
**Codes exportieren** · klein
|
|
Eine CSV aller Codes einer Gruppe mit Name, Kurz-URL, Ziel und Scans — für
|
|
die Übergabe an eine Druckerei oder die Ablage.
|
|
|
|
**Codes duplizieren** · klein
|
|
„Wie dieser, aber mit anderem Ziel“ — bei vielen ähnlichen Projekten spart
|
|
das jedes Mal ein paar Minuten.
|
|
|
|
**Stapelverarbeitung** · mittel
|
|
Eine CSV hochladen und daraus 200 Codes erzeugen, als ZIP zurück. Sinnvoll,
|
|
sobald jedes Produkt oder jeder Tisch einen eigenen Code bekommt.
|
|
|
|
**Gruppen aus dem Verzeichnis übernehmen** · mittel
|
|
Die OIDC-Anbindung übernimmt heute bewusst nur die Identität. Eine Zuordnung
|
|
von Verzeichnisgruppen zu Gruppen dieser Anwendung ist möglich, braucht aber
|
|
eine klare Regel dafür, was mit von Hand vergebenen Rollen geschieht — sonst
|
|
verliert jemand beim nächsten Anmelden stillschweigend seine Rechte.
|
|
|
|
**Passwortgeschützte Landingpages** · mittel
|
|
Für Unterlagen, die nicht jeder sehen soll, der den Aushang fotografiert.
|
|
Heute ist die Empfehlung klar: Vertrauliches gehört nicht hinter einen
|
|
offenen QR-Code.
|
|
|
|
**Dateien außerhalb der Datenbank** · mittel
|
|
Heute liegen Uploads in PostgreSQL, damit es bei einem Volumen bleibt. Wer
|
|
sehr viele oder sehr große Dateien ablegt, will sie irgendwann auf einem
|
|
Objektspeicher (S3) haben. Der Wechsel betrifft nur `src/lib/uploads.ts` und
|
|
die Auslieferungsroute — aber auch die Sicherungsstrategie.
|
|
|
|
**Erscheinungsbild je Gruppe** · groß
|
|
Seit dem 16.08. lassen sich Name, Logo, Favicon und Farbe für die ganze
|
|
Installation einstellen. Der nächste Schritt wäre, das je Gruppe zu erlauben
|
|
und die Landingpages mit dem Logo der jeweiligen Gruppe zu versehen — damit
|
|
eine gescannte Seite nach der Firma aussieht, der sie gehört. Technisch
|
|
überschaubar, gestalterisch eine eigene Aufgabe; es braucht Grenzen, damit
|
|
nichts Unlesbares entsteht.
|
|
|
|
**Mehrsprachige Oberfläche** · groß
|
|
Die Anwendung ist durchgehend deutsch, auch in den Fehlermeldungen und den
|
|
Landingpages. Eine zweite Sprache berührt jede Datei.
|
|
|
|
---
|
|
|
|
## Wie ein neuer Typ dazukommt
|
|
|
|
Falls doch noch einer fehlt: Er besteht aus einem Modul in
|
|
`src/lib/qr/types/`, einer Formular-Komponente, je einem Registry-Eintrag und
|
|
— wenn er eine eigene Seite braucht — einer Landingpage. Am übrigen Code
|
|
ändert sich nichts. Näheres im [README](../README.md), Abschnitt „Einen
|
|
weiteren Typ ergänzen“.
|