Zur Wahl stehen zwei Quellen: das Logo der Installation aus dem
Erscheinungsbild oder ein eigenes je Code. Die Groesse ist zwischen 10 und
25 Prozent der Kantenlaenge einstellbar, hinter dem Bild liegt eine Flaeche
in der Hintergrundfarbe.
Mit Logo gilt die Fehlerkorrektur H, unabhaengig von der Auswahl — was das
Bild verdeckt, muss sie ausgleichen. Die Auswahl steht dann fest auf H und
sagt auch warum; heimlich geschieht das nicht. Ab 22 Prozent kommt eine
Warnung dazu.
Gerendert wird weiterhin serverseitig, damit Vorschau und Download
uebereinstimmen: das SVG bekommt ein eingebettetes Bild, das PNG wird mit
sharp zusammengesetzt. sharp lag ohnehin als Abhaengigkeit von Next im
Baum und steht jetzt ausdruecklich in der package.json.
Ein eigenes Logo gehoert zur Gestaltung, nicht zum Inhalt — es muss
trotzdem an den Code gehaengt werden. Sonst raeumt die Aufraeumroutine es
nach einem Tag weg und der Code verliert sein Bild.
Refs #8
Umschaltbar ueber AUTH_ENABLED in der .env. Steht sie auf false, verhaelt
sich alles wie bisher - geprueft mit den 200 bestehenden Pruefungen.
Kern ist eine Actor- und Policy-Schicht: getActor() liefert bei
ausgeschalteter Anmeldung einen system-Actor mit Vollzugriff, sonst den
angemeldeten Benutzer. Dadurch braucht keine einzige Route ein
'if (anmeldungAktiv)' - sie fragen alle nur can() bzw. requirePermission().
- Datenmodell: User, Session, Group, Membership; Codes bekommen Gruppe und
Ersteller. Die Migration legt eine Standardgruppe an und ordnet ihr
bestehende Codes zu, bevor die Spalte verpflichtend wird - sonst
scheiterte sie auf jeder bereits benutzten Installation.
- Passwoerter mit scrypt aus der Node-Standardbibliothek. Bewusst kein
Argon2: das braeuchte ein natives Modul passend zur Container-Plattform.
- Sitzungen in der Datenbank, im Cookie nur ein Zufallstoken; gespeichert
wird dessen SHA-256. Deaktivieren oder ein neues Passwort beendet alle
offenen Sitzungen sofort.
- Aussperrschutz: der letzte aktive Administrator kann sich nicht selbst
entmachten, deaktivieren oder loeschen. Der Schalter liegt in der .env,
nicht in der Oberflaeche - so bleibt der Weg zurueck immer offen.
- Ersteinrichtung legt den ersten Administrator an und schliesst sich danach.
- Die Weiterleitung /r/{slug} bleibt oeffentlich, sonst liesse sich kein
gedruckter Code mehr scannen.
Zwei Fehler dabei gefunden und behoben:
- 'return handleLogin(...)' innerhalb eines try-Blocks gibt das Promise
zurueck, bevor es sich aufloest. Die Ablehnung kam nie im catch an und
wurde zu einem nackten 500er statt einer 401. Jetzt mit await.
- Die Fehlerklassen wurden ueber instanceof erkannt. type-module.ts landet
aber sowohl im Server- als auch im Client-Buendel, es gibt also zwei
Klassenidentitaeten - saubere 400er wurden dadurch still zu 500ern. Die
Erkennung laeuft jetzt ueber eine Eigenschaft.
Geprueft: 51 neue Pruefungen fuer Anmeldung und die vollstaendige
Rollenmatrix, dazu die 200 bestehenden bei ausgeschalteter Anmeldung.
Neue Seite Verwaltung -> QR-Typen mit einem Schalter je Typ. Abgeschaltete
Typen verschwinden vollstaendig von der Startseite und lassen sich nicht
mehr neu anlegen.
- Neue Tabelle QrTypeSetting; fehlender Eintrag heisst freigegeben, damit
eine frische Installation ohne Vorbelegung laeuft und spaetere Typen
automatisch erscheinen.
- Registry-Feld 'active' heisst jetzt 'implemented' und beschreibt nur noch,
ob der Typ ausprogrammiert ist. Ob er erscheint, entscheidet zusaetzlich
die Freigabe aus der Datenbank (src/lib/qr/availability.ts).
- Bestehende dynamische Codes bleiben von einer Abschaltung unberuehrt: die
Weiterleitung funktioniert weiter und Bearbeiten bleibt moeglich. Ein
gedruckter Code darf durch einen Schalter nicht ungueltig werden.
- resolveQrRequest ist dadurch asynchron geworden; QrRequestError liegt jetzt
in type-module.ts, sonst gaebe es einen Ringschluss mit availability.ts.
- Startseite meldet jetzt auch den Fall, dass nur noch Platzhalter
freigegeben sind - vorher standen dort 14 tote Kacheln ohne Erklaerung.
- Kopfzeile: Schriftzug auf schmalen Geraeten ausgeblendet, sonst passte die
dritte Navigationsschaltflaeche nicht mehr in die Zeile (7px Ueberlauf).
- Erweiterbare Registry aller 15 QR-Typen; nur "Website" ist aktiv, die
uebrigen erscheinen als Platzhalter mit Badge "Bald verfuegbar".
- defineQrType() kapselt Zod-Schema, Kodierung und Redirect-Ziel je Typ,
sodass ein V2-Typ nur aus einem Registry-Eintrag plus Formular besteht.
- Serverseitige QR-Erzeugung (PNG/SVG) mit Farben, Groesse, Fehlerkorrektur
und Rand; Live-Vorschau ueber /api/qr/preview.
- Dynamische Codes: Kurz-URL {BASE_URL}/r/{slug}, 302-Redirect mit
Scan-Zaehler, CRUD unter /api/codes.
- Prisma 7 mit pg-Driver-Adapter und Initial-Migration fuer PostgreSQL.
- Deutsche Oberflaeche mit Tailwind CSS, helles Theme, responsiv.