Zum Inhalt springen

Blog ·

Eine Verknüpfung ist ein Verweis, kein Recht

Sechs Karten für das Dashboard und Verknüpfungen, die nur erscheinen, wenn der Betrachter das Ziel heute noch sehen darf. Zwei Funde aus einem echten Lauf.

Von Provibr

Das Dashboard eines Hosting-Panels ist der Bildschirm, den jeder zuerst sieht und zu dem fast niemand eine Meinung hat, bis er für ihn falsch steht. Die Bitte war bescheiden: Menschen sollen Karten hinzufügen können, und sie sollen Verknüpfungen zu einem Server oder einer Integration setzen können, zu der sie immer wieder zurückkehren.

Bescheidene Bitten sind der Ort, an dem sich die interessanten Entscheidungen verstecken, denn eine Verknüpfung ist eine gespeicherte Vorliebe, die auf ein echtes Objekt mit echten Rechten zeigt. Dieses Verhältnis falsch zu legen ist der Weg, auf dem ein Panel jemandem eine Maschine zeigt, von der er vor drei Monaten abgezogen wurde.

Sechs Karten, keine Migration, und nichts kommt ungefragt

Es gibt sechs hinzufügbare Karten: eine Liste der Agenten, eine Liste der Server, eine Liste der Integrationen, eine Liste der Tickets, das Guthaben und eine Verknüpfung. Alle sechs sind halbbreit, denn es sind Übersichten nebeneinander und nicht etwas, das die ganze Zeile braucht.

Die Anordnung wird als JSON gespeichert, und diese Runde hat keine Migration hinzugefügt. Das ist eine Entscheidung und kein Versäumnis. Ein Eintrag war eine ID und ein Verborgen-Kennzeichen; er trägt jetzt auch eine Instanz-ID und eine Konfiguration je Karte. Eine alte Zeile liest sich sauber in die neue Form ein, mit der aus der Karten-ID ergänzten Instanz-ID und leerer Konfiguration, und ein Test prüft genau das: eine alte Anordnung liest sich als dieselben Karten in derselben Reihenfolge ein. Eine Migration setzte hier nur einen Zeitstempel ins Journal, und ein Zeitstempel, der sich später als zu hoch erweist, ist für die nächste Runde ein echtes Problem.

Die zweite Regel lautet, dass eine optionale Karte nie von selbst erscheint. Es gibt eine Schleife, die Karten ergänzt, die eine Anordnung nicht nennt, damit eine neue feste Karte bei allen auftaucht, und diese Schleife deckt bewusst nur die festen Karten ab. Machte eine optionale mit, wäre „hinzufügen“ keine Handlung mehr, und jedes Dashboard im Produkt wüchse bei jeder Freigabe um eine Karte, nach der niemand gefragt hat.

Welche Karten fehlen, ist ebenso eine Entscheidung wie die, welche dabei sind. Überwachung und Sicherungen existieren im Code hinter Ausrollflaggen, die aus sind, eine Karte dafür wäre also eine Karte ohne Nutzer. Die letzte Aktivität fiel weg, weil es sie bereits als feste Karte gibt.

Zwei Hälften einer Regel

In der gespeicherten Anordnung eines Nutzers ist eine Verknüpfung nichts als eine Art und eine ID. Alles, was auf den Bildschirm kommt, der Name, der Status, der Verweis, wird bei jedem Seitenaufbau neu geholt, mit den Rechten dessen, der in diesem Moment hinsieht. Diese Regel hat zwei Hälften, und beide werden gebraucht.

Die erste ist das Modul. Ein Mitglied, das das Modul Agenten verliert, sieht seine Verknüpfung zu einem Agenten nicht mehr, obwohl sie noch in seiner Anordnung steht. Dieses Tor kennt auch die Oberflächen, auf der eigenen Markendomäne eines Kunden, auf der Abrechnung überhaupt nicht existiert, verschwindet die Verknüpfung zum Guthaben also konstruktionsbedingt und nicht durch eine zweite, eigens dafür geschriebene Regel.

Die zweite ist die Objektabfrage. Die Organisations-ID steht in jedem WHERE, der Filter auf das weiche Löschen daneben, und bei einem Server steht die Serverbegrenzung dieses Mitglieds wieder daneben. Ein Server, der einem Mitglied nie zugewiesen wurde, existiert für dieses Mitglied nicht, und das muss auch für eine Verknüpfung gelten, die es anlegte, als es ihn noch sehen durfte.

Die Verknüpfungskarte ist auch die einzige Karte ohne Modul und die einzige, die mehr als einmal existieren darf. Das ist richtig und nicht schlampig: eine Verknüpfung ist kein eigener Bildschirm, sondern ein Verweis auf einen Bildschirm, der sein eigenes Recht bereits trägt. Gäbe man der Kartenart ein Modul, könnte ein Betrachter mit diesem Modul eine Verknüpfung auf etwas sehen, das er nicht öffnen darf.

Modul weg und Objekt weg sind verschiedene Ereignisse

Zwei Dinge, die auf dem Bildschirm gleich aussehen, werden als Gegensätze behandelt.

Was geschehen istWas der Betrachter sieht
Das Modul wurde entzogenDie Karte verschwindet wortlos und kehrt mit dem Modul zurück
Das Ziel wurde nicht gefundenEine Karte, die sagt, dass es nicht mehr existiert, mit einer Schaltfläche zum Entfernen

Das erste ist still, weil die Verknüpfung nicht die Geschichte ist. Hat sich jemandes Rolle geändert, ist die fehlende Verknüpfung ein Symptom, und sie auf dem Dashboard anzukündigen wäre Rauschen über einer Änderung, die er ohnehin kennt. Sie kehrt außerdem unversehrt zurück, sobald das Modul zurückkehrt, und das geht nur, weil nichts gelöscht wurde.

Das zweite ist laut, weil der Nutzer nichts falsch gemacht hat und ihm etwas genommen wurde. Es ist bewusst kein 404 und keine Fehlermeldung: nur eine Karte, die die Lage benennt und anbietet, sich selbst aufzuräumen.

Nachsichtig darstellen, nicht beim Löschen aufräumen

Die naheliegende Alternative ist, Verknüpfungen zu entfernen, sobald ihr Ziel gelöscht wird. Das haben wir nicht getan, und die Überlegung ist es wert, festgehalten zu werden, weil die gegenteilige Entscheidung anderswo in derselben Codebasis sehr wohl getroffen wurde: verlässt ein Mitglied ein Konto, wird seine gespeicherte Dashboard-Anordnung wirklich vergessen, denn diese Zeile berührt keine Kaskade und bliebe sonst für immer in einem Konto stehen, in das es nie zurückkehrt.

Hier fällt die Abwägung anders aus, aus drei Gründen.

Verschwinden hat mehr Ursachen als Löschen. Ein Mitglied verliert ein Modul, seine Serverbegrenzung ändert sich, es sieht auf eine Markendomäne. Keine Aufräumroutine fängt diese drei, der nachsichtige Darstellungspfad muss also ohnehin bestehen, und ein zweiter Mechanismus ist dann nur eine Stelle, die auseinanderlaufen kann.

Die Anordnung ist je Nutzer gespeichert. Ein gelöschter Server hieße, das JSON jedes Mitglieds der Organisation neu zu schreiben, in einer Transaktion auf dem Löschpfad. Das ist Schreibverstärkung auf einem warmen Pfad im Tausch gegen eine Bildschirmvorliebe.

Und es gibt nichts zu schützen. Die gespeicherte Zeile ist eine UUID eines Objekts der eigenen Organisation und sonst nichts. Sie verrät nichts, sie wächst nicht, und der Nutzer sieht sofort, dass sie weg kann.

Die Ende-zu-Ende-Prüfung dafür ist absichtlich grob. Nachdem ein Server weich gelöscht wurde, kehrt er nicht zurück, und sein Name kommt in der Ausgabe nirgends vor. Ein Mitglied ohne das Modul Agenten bekommt weder Agent noch Integration, und die Auswahl bietet sie nicht an. Eine leere Serverbegrenzung liefert null Zeilen und nicht alles.

Zwei Funde, die nur ein echter Lauf hervorbrachte

Die beiden echten Mängel dieser Runde waren beide für Einheitentests unsichtbar, und beide kosteten etwa zehn Sekunden, sobald etwas Echtes lief.

Die Auswahl hat ein Suchfeld, und die Suche nach Integrationen zerbrach die gesamte Auswahl mit einem Datenbankfehler. Der Grund ist, dass die Spalte mit dem Integrationstyp ein Postgres-Aufzählungstyp ist und es für einen Aufzählungstyp keinen Musteroperator ohne Beachtung der Groß- und Kleinschreibung gibt: die Abfrage meldete 42883 operator does not exist, und weil diese Abfrage die ganze Auswahl speiste, erschien überhaupt nichts. Die Spalte auf Text zu wandeln behebt es. Kein Einheitentest mit einem nachgebildeten Ausführer hätte das gesehen, denn eine Nachbildung hat keine Typen.

Der zweite kam aus der Prüfung auf Barrierefreiheit. Eine Verknüpfungskachel ist ein Name, ein Status und eine Art, und das Ganze ist anklickbar. Die erste Fassung steckte all das in einen Verweis, und die Prüfung meldete einen Unterschied zwischen dem zugänglichen Namen und der sichtbaren Beschriftung, denn verborgener Text zählt für den zugänglichen Namen mit. Die Kachel ist jetzt eine gewöhnliche Hülle mit einem Verweis, der nur den Namen trägt, und einer leeren absoluten Klickfläche, die den Klick auffängt. Das brachte ein zweites, kleineres Problem mit: die Abschneideklasse auf dem Verweis beschnitt die Klickfläche auf die Breite des Textes, wodurch der größte Teil der Kachel nicht mehr anklickbar war. Das Abschneiden zog auf ein inneres Element um, und die Abdeckung wurde gemessen statt angenommen.

Was wir festhalten würden

  1. Speichern Sie einen Verweis, lösen Sie ein Recht auf. In der Vorliebe gehört eine ID. Was auf dem Bildschirm erscheint, gehört jedes Mal mit den Rechten des Betrachters geholt.
  2. Eine Spalte ohne Schema ist eine Migration, die Sie nicht schreiben müssen. Aber nur, wenn Sie beweisen können, dass sich die alte Form gleich zurückliest, und das ist ein Test.
  3. Optional heißt dauerhaft auf Wunsch. Eine Karte, die von selbst erscheint, macht aus „hinzufügen“ ein Wort ohne Bedeutung.
  4. Unterscheiden Sie gelöscht von unerreichbar. Sie sehen auf dem Bildschirm gleich aus und verdienen die gegenteilige Behandlung: Stille für das eine, eine Erklärung für das andere.
  5. Nicht aufzuräumen kann die stärkere Wahl sein. Hat dasselbe Symptom Ursachen, die Ihr Aufräumen nicht sieht, muss der nachsichtige Pfad ohnehin bestehen, und das Aufräumen ist dann nur eine zweite Stelle, die man gleich halten muss.
  6. Lassen Sie das Ding laufen. Ein Aufzählungstyp ohne Musteroperator und ein Verweis, der seine eigene Klickfläche beschneidet, sind beide im Browser sofort sichtbar und beide für eine Testsuite ohne Datenbank unsichtbar.

Zur Klarheit darüber, was das ist: die hier beschriebenen Karten sind für jedes Konto aktiv. Mehrere Dinge sind unbewiesen. Das Umsortieren mit der Maus wurde nicht angetrieben, die geflaggten Überwachungs- und Sicherungskarten existieren nicht, ihr Codepfad wurde also nie genommen, die Markendomäne wurde in einer Abfrage und nicht in einem Browser geprüft, und eine frisch hinzugefügte Karte erscheint erst nach der nächsten Serverrunde.

Aus der Plattformarbeit von Provibr. Was ein Kunde unseres Kunden auf einem Markenpanel sieht und was nicht, steht in White-Label-Panels: was der Kunde sieht, und warum ein Übersichtsbildschirm nie in die Tabellen zurückschreibt, die er liest, steht in projizieren, niemals ersetzen.

Fangen Sie mit einem Host und einem Agenten an

Konto erstellen, den Agenten mit einem einzigen Befehl installieren und Ihren ersten Proxmox-Host verbinden. Die Testphase läuft 14 Tage und fragt nicht nach Zahlungsdaten.