Sprechende Kurz-Links: selbst vergeben, aendern, frueher gueltig halten

Schliesst Issue #1. Der Wunsch betraf den Kurz-Link, nicht das Ziel: Er soll
sich von Anfang an bestimmen und spaeter aendern lassen.

Beim Anlegen gibt es dafuer ein Feld, im Bearbeiten-Dialog laesst er sich
aendern. Erlaubt sind Kleinbuchstaben, Ziffern, Bindestriche und „/" als
Trenner — damit sind Adressen wie kunde-a/sommer moeglich. Umlaute bleiben
draussen, weil sie in Adressen unleserlich kodiert werden; Gross- und
Kleinschreibung ist beim Aufrufen egal.

Beim Aendern bleibt die vorherige Adresse gueltig. Das ist der Kern: Auf
gedruckten Codes steht die alte, und genau deren Bestand ist der Sinn eines
dynamischen Codes. Frueher vergebene Adressen stehen im Dialog und lassen
sich einzeln freigeben — fuer den Tippfehler, mit dem noch nichts gedruckt
ist. Solange eine Adresse gehalten wird, kann sie kein anderer Code
uebernehmen; sonst liessen sich fremde gedruckte Codes umlenken.

Vergeben und Aendern ist standardmaessig Administratoren vorbehalten. Ein
Kurz-Link ist eine oeffentliche Adresse, und wer ihn aendert, kann Aushaenge
entwerten. Unter Verwaltung -> Einstellungen laesst sich das fuer Bearbeiter
freigeben; ohne das Recht erscheint das Feld gar nicht, Codes anlegen und
deren Ziel aendern geht weiterhin. Eigene Aktion in der Policy statt Teil von
codes:update, weil sie mehr wiegt.

Technisch: /r und /s sind Sammelrouten, weil ein Kurz-Link „/" enthalten
darf. Die Eindeutigkeit gilt zusaetzlich auf der kleingeschriebenen Form; die
Migration bricht ab, falls der Bestand das nicht zulaesst, statt still Daten
zu verlieren. Der bestehende exakte Index bleibt — er traegt den haeufigen
Fall, den gescannten Code.
This commit is contained in:
Florian Wilde
2026-08-17 10:41:57 +02:00
parent c38b27ca85
commit 46e7eb0b59
24 changed files with 917 additions and 49 deletions
@@ -0,0 +1,12 @@
-- Verhalten der Installation, das sich nicht aus dem Code ergibt.
CREATE TABLE "InstanceSetting" (
"id" TEXT NOT NULL DEFAULT 'instance',
"editorsMaySetSlug" BOOLEAN NOT NULL DEFAULT false,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "InstanceSetting_pkey" PRIMARY KEY ("id")
);
-- Die eine Zeile gleich anlegen, damit die Anwendung sie nur lesen muss.
INSERT INTO "InstanceSetting" ("id", "updatedAt") VALUES ('instance', CURRENT_TIMESTAMP);