main
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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. |
||
|
|
18c9a71fda |
Export ohne Vier-Augen, Wiedervorlage setzbar, Druckansicht mit Weg zurück
**Export.** Das Vier-Augen-Verfahren ab Stufe 3 ist weg. Wer exportiert, entscheidet jetzt allein die Freigabestufe: mindestens die des Ziels. Das ist strenger als das Lesen - wer als Beteiligter ausnahmsweise in eine höher eingestufte Akte darf, darf sie deshalb noch nicht ausser Haus geben. Dabei fiel eine Lücke auf: hängte man sich an einen laufenden Auftrag, entstand kein Protokolleintrag. „Jeder Export wird protokolliert" heisst jeder Abruf, nicht jeder Rendervorgang - wer dieselbe Datei bekommt, muss genauso darin stehen. **Fristen.** dueAt wurde überall gelesen - Übersicht, Suchfilter, Ausdruck - und nirgends gesetzt. Es gab keine Stelle, an der man ein Datum einträgt, deshalb stand unter „Fristen" immer „Nichts steht an". Jetzt im Kopf der Akte, mit Protokolleintrag und ohne Verlaufseintrag: eine Wiedervorlage ist eine Merkhilfe, keine Aussage über den Fall. **Statuswechsel.** Aus einem Entwurf führt laut Lebenszyklus nur „Offen" heraus, deshalb standen dort nie mehr als zwei Ziele. Das sah aus wie ein Fehler und war keiner - jetzt steht die Erklärung daneben und an jeder Option. **Druckansicht.** Sie hatte kein eigenes Layout: das weisse Blatt lag auf dem dunklen Thema und es gab keinen Weg zurück. Jetzt heller Grund, eine Leiste mit Zurück und Drucken, beides beim Drucken ausgeblendet. Das Ziel wird aus dem Pfad abgeleitet, damit es auch beim direkten Aufruf stimmt. **Abteilungsstatistik.** Eine Abteilung ohne Freigabe wird als „Ohne Freigabe" geführt statt weggelassen - sonst summierten sich die Anteile nicht auf die Zahl daneben. Mehrere ergeben ein Stück, sonst stünde dort, wie viele es sind. Dazu: Dienstgrad in eckigen Klammern vor dem Namen und in dessen Grösse, in einer eigenen Spalte; Knopfform für „Personalakte anlegen"; die abgeschnittene Anzahl im Kopf der Personalaktenliste; „Zuletzt geöffnet" ohne die zwei Hinweistexte, leer als Zeichen statt als Satz. |
||
|
|
9c24858d75 |
Feste Spaltenbreiten für jede Listenzeile
„Keine Textzentrierung" - die Beobachtung stimmte an einundzwanzig Stellen, und die Ursache war überall dieselbe: die Zeilen waren Flex-Behälter, in denen jedes Element so breit war wie sein Inhalt. Damit fing der Titel in jeder Zeile woanders an, und die Stempelmarken hatten nur rechts eine gemeinsame Kante. Bei „ETHIK" und „WS" untereinander sieht man es sofort. Die Breiten stehen jetzt einmal in globals.css - record-key, record-label, record-title, record-meta, stamp-mark - und sind über Variablen je Liste anpassbar: eine Liste von Abteilungskürzeln braucht keine vierzehn Zeichen, eine Liste von Aktenzeichen schon. Zwei Dinge, die dabei mehr sind als Kosmetik: Eine Spalte wird auch reserviert, wenn sie leer ist. Vorher hing der Dienstgrad an einer Bedingung, und bei einer Person ohne Rang rutschte alles Folgende nach links. Was keine Kennung ist, gehört nicht in die Kennungsspalte. In „Zuletzt geöffnet" stand der Name einer Person dort, wo sonst das Aktenzeichen steht: in Mono, abgeschnitten, und der Dienstgrad wanderte an die Stelle des Titels. Für eine Person ist der Name der Titel. Die Stempelmarke ist überall gleich breit; ein zu langer Name wird gekürzt, die Stufenziffer bleibt stehen - sie ist die eigentliche Auskunft. Unter 40 rem fallen die festen Breiten weg, sonst liefen sie über. Nachgesehen im Browser mit dem gebauten CSS, Fallakten, Abteilungen, Zuletzt geöffnet und Beteiligte. |
||
|
|
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. |
||
|
|
75c22ff4f8 |
Ladegrenzen für jede Route, Turbopack im Entwicklungsserver
Gemessen statt vermutet: die Datenschicht war nie das Problem. resolvePermissions unter 1 ms, loadDashboard 11 ms, searchCases 5 ms, die Abteilungsabfragen 3–4 ms. Die Sekunden kamen aus zwei Ecken. **Fehlende Ladegrenzen.** Den meisten Routen fehlte loading.tsx - unter anderem der Übersicht, der Suche und dem gesamten Adminbereich. Ohne diese Datei hat der Router keine Grenze, wartet stumm auf die fertige Serverantwort, und bis dahin steht die alte Seite: man klickt, und scheinbar passiert nichts. Neunzehn Skelette nachgetragen, jede Route hat jetzt eine. Dazu quittiert der geklickte Link den Klick selbst, mit einem ruhig pulsierenden Punkt statt eines Kreisels. Regel 5 verbietet den Blockade-Spinner, der Inhalt ersetzt; eine Quittung im Link ersetzt nichts, und die eigentliche Antwort auf das Warten bleibt das Skelett. **Webpack.** Der Entwicklungsserver übersetzte jede Route beim ersten Aufruf neu: 8 s für die Übersicht, 2,8 s für die Fallliste. Mit Turbopack sind es 0,43 s beim ersten Aufruf und 0,1 s danach. Nur pnpm dev, der Produktionsbau bleibt unverändert. Gegengeprüft, dass die Anmeldeseite mit CSS und ohne Fehler im Log rendert. Nebenbei die eine Abfrage, die schlecht skalierte: die Übersicht zählte ungelesene Nachrichten mit einer Abfrage je Ort - bei hundert Akten hundert Hin- und Rückwege. Jetzt ein einziges groupBy mit der Lesemarke im ODER-Zweig des jeweiligen Ortes. Ein Test prüft, was dabei leicht verrutscht: die Marke gilt je Ort, und eigene Nachrichten zählen nie mit. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |