6 Commits
Author SHA1 Message Date
Harlekin e0b03ea336 Gedankenstriche durch Bindestriche ersetzt
Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die
README; an keiner Stelle Bedeutung, nur Zeichensetzung.
2026-09-04 08:54:52 +02:00
Harlekin e2feaccf68 Beteiligte in den Suchindex der Fallakte
Wer „Jonathan Fletcher" eingibt, will die Akten sehen, in denen er vorkommt -
auch die, in denen er weder im Titel steht noch im Text erwähnt wird, sondern
nur als Betroffener eingetragen ist. Genau das wurde nicht gefunden.

Die Namen der Beteiligten stehen jetzt im Vektor der Fallakte, Gewicht B: ein
Name sagt etwas über die Akte aus, aber weniger als ihr Titel. In allen sechs
Vektoren und nicht erst ab einer Stufe - das ist die Stelle, an der man zweimal
hinsehen muss, und sie war bereits entschieden: der Name eines Beteiligten
steht in der Beteiligtenliste jeder Akte, die man lesen darf, zurückgehalten
wird allein der Verweis auf seine Personalakte. Der Index gibt also nichts
heraus, was die Akte nicht ohnehin zeigt.

Die Akte selbst muss man weiterhin lesen dürfen. Ein Test prüft genau das: eine
Stufe-4-Akte wird über den Namen ihres Zeugen für Stufe 1 nicht auffindbar,
auch nicht als Trefferzahl.

Drei Auslöser halten den Index aktuell: geänderte Beteiligung, geänderter Name
in einer Personalakte, geänderter Anzeigename eines Kontos. Den letzten gleicht
der Worker mit Discord ab; ohne ihn fände die Suche nach einer Umbenennung
weiter den alten Namen.

Die Trefferzeile sagt dazu, warum sie passt: „Jonathan Fletcher als
Betroffener". Ohne den Hinweis sieht ein Treffer, dessen Begriff nirgends im
sichtbaren Text steht, wie ein Fehlgriff aus.
2026-09-03 22:29:52 +02:00
Harlekin 4b794ec9a8 Suche fängt bei „Alle" an, Bereiche in der Kopfzeile sind Knöpfe
**Suche.** Sie startete auf den Fallakten, und man musste die Art vorher
wählen - die falsche Reihenfolge: wer einen Namen eintippt, weiss noch nicht,
ob er eine Fallakte, ein Dokument oder eine Personalakte sucht. Er will wissen,
wo der Name vorkommt.

„Alle" ist jetzt der Auslieferungszustand und zeigt je Art fünf Treffer als
eigenen Block, mit dem Weg in die volle Liste daneben. Getrennte Blöcke statt
einer gemischten Liste nach Rang: ein Aktenzeichen neben einem Namen neben
einer Dokumentnummer hat keine erkennbare Ordnung. Die einzelnen Arten bleiben
als Filter, und nur dort gibt es Facetten und Blättern - beides bezieht sich
auf eine Grundmenge, ein Statusfilter über Fall- und Personalakten zugleich
wäre bei der einen ein Filter und bei der anderen ein Ausschluss.

**Kopfzeile.** Die Bereiche waren Textlinks: von einem Fliesstextlink nicht zu
unterscheiden und ohne Hinweis darauf, wo man gerade ist. Jetzt dieselbe
Knopfform wie alles Bedienbare, der aktive Bereich gefüllt.

Der gefüllte Zustand trägt hellen Text statt der Akzentfarbe: auf der getönten
Fläche wäre Akzent auf Akzent und der Kontrast fiele unter die Untergrenze.
Dazu etwas grosszügigere Polsterung an beiden Knopfgrössen, .btn-count für
Zahlen in Knöpfen, und kein Doppelring mehr am Profilbild.

Nachgesehen mit dem gebauten CSS im Browser, hell und dunkel.
2026-09-03 21:59:06 +02:00
Harlekin 89bbed8679 Suche zeigt alle Arten, nur Arbeitsrollen öffnen die Akte
Punkt 1 und 2 der Wünsche, plus zwei Lücken, die dabei sichtbar wurden.

**Suche.** Wer nach Alvarez sucht, landet auf den Fallakten und erfährt nie,
dass es dazu auch eine Personalakte gibt: die Suche fand sie, aber hinter einem
Reiter, auf den nichts hindeutete. Die Reiter tragen jetzt ihre Trefferzahl,
und ein leeres Ergebnis nennt ausdrücklich, wo etwas liegt.

Dabei fiel auf, dass searchPersonnel das Recht personnel.read nicht prüfte. Die
Kommandopalette tat es, die Aktenseite tat es, die Suche nicht - über
/suche?kind=personnel kam jeder mit ausreichender Stufe an eine Liste aller
Personalakten mit Namen, Dienstgrad und Etiketten. Die Prüfung steht jetzt
dort, wo diese Akten herausgegeben werden. Die Trefferzahl einer Art, die es
für den Nutzer nicht gibt, ist null und nicht 0: eine Null wäre die Auskunft
„hier ist nichts", und die steht ihm nicht zu.

**Täter und Mittäter** als Beteiligtenrollen - und damit wurde eine ältere
Lücke offensichtlich: ein Beteiligter durfte die Akte lesen, gleich in welcher
Rolle. Bei „Betroffener" fiel das nicht auf, bei „Täter" wäre es offensichtlich
falsch. Der Beschuldigte hätte die Ermittlung gegen sich selbst mitgelesen.

Die Beteiligtenliste beantwortet zwei Fragen: wer bearbeitet den Fall, und um
wen geht es darin. Nur die erste ist eine Berechtigung. WORKING_ROLES nennt die
drei, die die Akte öffnen; Zeuge, Betroffener, Täter und Mittäter öffnen
nichts. Das gilt an allen vier Stellen, die auf Beteiligung prüften:
Aktenzugriff, Dokumentzugriff über die besitzende Akte, „meine Fälle" und der
Filter „nur meine".

Zwei bestehende Tests hatten die alte Annahme festgeschrieben und benutzten
WITNESS, um Zugriff zu belegen; sie prüfen jetzt mit INVESTIGATOR.
2026-09-03 19:16:17 +02:00
Harlekin 6af1e437e7 Runde Bedienelemente, Admin zusammengelegt, Kanäle entfallen
Vier der acht Änderungswünsche.

**Knöpfe.** Rund vierzig der siebzig Knöpfe waren blosser Text in Akzentfarbe,
von einem Link nicht zu unterscheiden. Jeder trägt jetzt Rahmen und
Grundfläche, über die Klasse .btn an einer Stelle definiert statt siebzigmal
als Klassenkette. Beim Drücken zieht der Knopf sich zusammen und bekommt einen
inneren Ring - er wirkt kurz dicker, ohne dass die Rahmenbreite sich ändert und
das Umfeld springt; die Rückmeldung setzt ohne Verzögerung ein und klingt
langsam ab, sonst bliebe ein kurzer Klick unsichtbar.

Dazu die neue Regel: Flächen bleiben eckig, alles Bedienbare ist rund. Damit
ist die Rundung eine Auskunft und keine Verzierung.

**Verwaltung.** Rollen, Vorlagen und Änderungsrichtlinie waren drei Einträge in
der Kopfzeile für etwas, das man selten und dann zusammenhängend braucht. Jetzt
ein Eintrag /admin mit Reiterleiste, dazu eine gemeinsame Tabs-Komponente, die
auch der Fallakte zeigt, welcher Reiter offen ist.

**Kanäle.** Ersatzlos entfernt, mitsamt Tabelle. Der Chat gehört dorthin, wo
der Vorgang steht; ein eigener Reiter mit freien Räumen war der Rückweg nach
Discord. Die Personalakte hat jetzt denselben Chat wie die Fallakte - ohne
„als Vermerk übernehmen", denn dafür braucht es einen Verlauf, und Meldungen
gehen nur an Erwähnte, nie in den allgemeinen Kanal: dass es zu jemandem eine
Personalakte gibt, ist selbst eine Auskunft. Ein CHECK erzwingt jetzt, dass
eine Nachricht zu genau einem Ort gehört.

**Kopfzeile.** Suchbalken statt Suchlink, als gewöhnliches Formular ohne ein
Byte im Bündel. Thema, Benachrichtigungen und Abmelden sitzen hinter dem
Profilbild, das von Discord kommt; wer keins hat, bekommt seine Initialen.

Nebenbei: Aktenzeichen in Tests waren nur auf vier Stellen eindeutig und
kollidierten zwischen Läufen, weil Akten nicht löschbar sind.
2026-09-03 15:07:43 +02:00
Harlekin cb0eabb266 Phase 7 abgeschlossen: Suche mit gestuftem Index, Facetten, Palette
Der bisherige Suchvektor enthielt nur, was jeder sehen darf. Das war
leck-sicher und unbrauchbar zugleich: ab Stufe 1 fand die Suche nichts von
dem, was einen Fall ausmacht.

SearchIndex hält jetzt sechs Zeilen je Ziel, eine pro Freigabestufe. Die Zeile
zur Stufe N enthält alles, was ein Leser dieser Stufe sehen darf. Eine Suche
nimmt genau diese eine Zeile und kann deshalb nichts finden, was sie nicht
lesen darf - auch keinen höher eingestuften Eintrag in einer sichtbaren Akte.

Schwärzungen werden dabei stufenweise aufgelöst: strip_redactions_above
entfernt nur, was über der Stufe liegt. Sonst fände ein Leser der Stufe 4
einen Namen nicht, den er auf der Seite im Klartext sieht, und ein Leser der
Stufe 1 einen, den er dort nur als Balken sieht.

Die Suchbedingung ist nicht die Zugriffsprüfung: der Volltext liefert
Kandidaten, die Sichtbarkeit kommt aus visibleCaseWhere - derselben Funktion
wie in der Fallliste, und Treffer, Trefferzahl und Facettenzähler entstehen
gemeinsam in einer Abfrage. Eine in SQL nachgebaute Sichtbarkeitsregel wäre
die Sorte Duplikat, die auseinanderläuft.

Filter stehen in der Adresse. Damit ist jeder Zustand teilbar, der
Zurück-Knopf tut das Richtige, und eine gespeicherte Ansicht ist ein
Lesezeichen. Die mitgelieferten Ansichten stehen im Programm, weil sie von der
Gegenwart abhängen.

Strg+K öffnet die Kommandopalette. Im Grundgerüst steckt nur das
Tastaturereignis, die Palette selbst wird beim Öffnen geholt - das kostet die
anderen Seiten rund hundert Byte.

Offen geblieben: "Zuletzt geöffnet" als Ansicht. Dafür müsste jeder Aufruf
jeder Akte mitgeschrieben werden; das wäre eine Überwachungsfunktion, die
niemand bestellt hat. In TASKS vermerkt.

165 Tests im Web-Paket, 17 in der Datenbank, 7 im Worker, 34 e2e.
Grösste Route bei 119,7 kB gegen 120 erlaubte.
2026-09-02 21:23:01 +02:00