TopLogic - the automated application engine
  • Releases
  • Dokumentation
  • Github
  • Discord
  1. Home
  2. Releases
  3. TL_8.0.0-alpha10
  4. #29716

8.0.0-alpha10
TopLogic Release

2026-10-09

enhancement

major
#29651
TL Views: Container <accordion> mit einklappbaren Abschnitten
#29652
TL Views: Hinweisbox <alert> im Inhalt einer View
#29654
TL Views: Auswahlfeld als Radio-Gruppe für beliebig viele Optionen
#29661
TL Views: Prototyp "TopLogic UI on MUI" – Adaptermodul mit Material UI für die ersetzbaren Komponenten
#29692
TL Views: Formularfelder, Tabellenzellen und das Bearbeiten eines Formulars richten sich nach den Modell-Zugriffsrechten
#29693
TL Views: Große und mehrwertige Werte erscheinen in Tabellenzellen als einzeilige Vorschau mit einem Knopf, der den vollständigen Editor in einem Dialog öffnet
#29707
Reduce PR CI build time: parallel reactor build, sharded scripted tests, affected-module builds
#29730
React-Oberfläche: Kanban-Board als View-Element (Karten per Drag & Drop zwischen Spalten verschieben)
#29735
User menu: the application cannot say what the account is called
#29741
anonymous-Benutzer soll per Default nicht in Personenauswahlfeldern auftauchen
#29744
TL Views: Entwicklerwerkzeuge (Designer, Aufzeichnen, Untersuchen, Agentenzugriff) in einem eigenen Entwicklungsmenü der App-Leiste
#29752
React-UI: Kleine Verbesserungen der Oberfläche (Snackbar, Hover, Tooltips, Schieberegler, Abstände)
#29758
ModelAccessRights: Anlegerecht in Kompositionsattribut für Spezialisierung des Zieltyps prüfen
#29759
React-UI: Commit-Nachrichten für Änderungen aus Sichten (TL-Script-Aktionen, Transaktionen, Löschen) konfigurierbar, sinnvolle Standard-Nachrichten
#29760
Improve the React UI of the model-based security configuration; let a TL-Script function determine the access parent of a type
#29765
Engine developer docs (FAQ) are not discoverable when developing an application based on the engine
minor
#29513
Drag&Drop: Commit-Nachricht für Drop-Operationen konfigurierbar, sinnvolle Standard-Nachricht
#29747
Make the LDAP configuration ldapConf.xml configurable by system properties / environment variables
#29754
OpenAPI-Server: Variablenname für Request-Parameter, deren Name kein gültiger TL-Script-Bezeichner ist (z.B. Header X-Gitea-Event)

defect

major
#29581
TopLogicServlet: Vertrag dokumentieren - eine Anfrage hat nur im Fenster einen Benutzer
#29642
React dialog size memory: one key for every dialog, stored size beats the declared width and is never clamped to the window
#29646
TL Views: Der Build der React-Client-Module prüft die TypeScript-Typen nicht, in com.top_logic.layout.react sind dadurch 29 Typfehler aufgelaufen
#29697
HistoryQuery: Start- und Stop-Revision aus HistoryQueryArguments werden bei der Suche ignoriert.
#29701
TL Views: a form shown again after its sidebar section or tab was hidden keeps the values it had when hidden; a reload renders the stale values again
#29711
Setzen einer geordneten Liste (ListStorage) ist beim Einfügen vor bestehenden Elementen überquadratisch langsam; TestListStorage misst Wanduhrzeit und scheitert unter Last
#29712
Problem beim Zurücksetzen einer Selektion im Baum
#29716
Modellbasierte Leseprüfung: Rollen-Lookup kompiliert pro Objekt und Gruppe neue KB-Abfragen, Nicht-Admin wartet 70 s statt 9 s
#29723
Model editor class diagram fails with "Comparison method violates its general contract!"
#29724
PathNavigation: abstract attribute rejected by isDerived() check even though concrete overrides exist and are tracked
#29728
FlowChartComponent: Ein Neubau des Diagramms entfernt Objekte aus der Selektion, die im Diagramm nicht dargestellt werden
#29731
TL Views: <persist-transient> copies the draft's empty values over the creation defaults; a sequence number or creation date computed at commit is lost
#29732
TL Views: <create-transient container="…"> creates the draft without the container's context; option lists and context-dependent defaults of the draft see no container
#29734
View form: <store-form-state/> does not persist new rows of a <composition-table>, so saving a persistent owner fails
#29737
TL Views: a collapsing toolbar measures its commands only when its groups change; a command that shows itself later keeps a 0 px toolbar and draws over the panel title
#29740
Fehlender Schutz für den anonymous-Benutzer
#29745
Zugriff auf ein abstraktes Attribut meldet einen Fehler, der nicht sagt, dass das Attribut abstrakt ist: eigene Storage für abstrakte Attribute
#29746
FileManagerOverlay/FileManagerDelegate cannot read resources inside web-fragment WARs (tl_config overlay fails on engine configuration files)
#29773
PostgreSQL: Große SQL-Migrationen werden durch nicht freigegebene Autosave-Savepoints quadratisch langsam
minor
#29029
Inkrementell deaktiviertes Drop-Down-Selektfeld weiterhin bedienbar
#29514
Befehlsfreigabe und Berechtigung von Drag&Drop
#29696
Scheduler: Start- und Cluster-Verhalten von Tasks bereinigen – <on-startup/> pro Knotenstart, Tasks erst ab RUNNING, run-on-startup entfernen, kein Default für isNodeLocal()
#29699
TL-Script: htmlText(htmlSource($text), images) drops the images of a stored structured text, since it does not accept the "ref:" references it writes itself
#29700
TL Views: the open session of a deleted account keeps evaluating as that account; every model event logs "DeletedObjectAccess … was already deleted" from its observers
#29722
FlowDiagram: Fehlerhafte Baum-Layout-Berechnung
#29727
TL-Script Auswertungen mit Filtern können zu "null"-Literalen führen.
#29733
TL Views: a click on the padding of the React rich-text editor's content area does not focus the editor; the typed text is lost
#29736
Click-region menu opens flush on the window edge and under the trigger's tooltip
#29738
TL Views: the menu cliques of a toolbar are labelled in English in every language ("More", "View", "Export")
#29739
React tooltip stays open at the window's top-left corner when its anchor is removed under the pointer
#29743
React UI: Tooltip eines Menüeintrags erscheint hinter dem Menü
#29753
OpenAPI-Client: NullPointerException bei Antwort ohne Body (z.B. 204) mit Status ungleich 200
#29774
OpenAPI server: API key authentication cannot resolve an account — Person.byName called without an InteractionContext

task

major
#29725
CheckDependencies: npm-Abhängigkeiten werden nicht aktualisiert, transitive Maven-Abhängigkeiten mit bekannten Sicherheitslücken
#29726
WYSIWYG-Editor: Umstellung auf Tiptap 3 (Sicherheitslücke GHSA-cp6q-959q-f8rh)
defect

major

#29716

Modellbasierte Leseprüfung: Rollen-Lookup kompiliert pro Objekt und Gruppe neue KB-Abfragen, Nicht-Admin wartet 70 s statt 9 s

Beobachtung

Anwendung DiFa ProTiCo (classic UI) mit modellbasierten Zugriffsrechten, 95.041 Objekte vom Typ difa.protico.production:VehicleOrder, master 4c6f6d7e21, PostgreSQL 16. Ladezeiten der Ansichten (Median aus 3 Läufen):

= Ansicht = = root = = Benutzer mit Rolle ProTiCoReader = = hasRole-Abfragen (Reader) =
Tabelle all(`difa.protico.production:VehicleOrder`) 9,4 s 69,4 s 589.966
Delta-Dialog "Stand A" (all(...).filter(...).groupBy(...)) 2,0 s 32,7 s 291.955

Von 69,4 s entfallen nur 1,6 s auf die Ausführung in der Datenbank. Der Rest ist Java: Abfragen kompilieren und Logging.

Konfiguration (dokumentierter Weg "Roles held on the security root", docs/faq/access-configuration.md): {{{#!xml <security-parents>

<rule id="lifecycle-secRoot" meta-element="difa.protico.common:LifecycleObject" inherit="true">
<singleton module="SecurityStructure"/>
</rule>

</security-parents> }}} Grants auf Modulebene (Read für ProTiCoReader/ProTiCoWriter). Die Rollen liegen als hasRole-Zeilen auf SecurityStructure#ROOT. Auf den VehicleOrders selbst ist keine Rolle vergeben.

Ursache

  • Jede Leseprüfung (SecurityConfigurationService.isAllowed, aus dem Ergebnisfilter des QueryExecutor und aus AccessLike.lookupValue) landet in BoundedRole.getLocalAndGlobalAndGroupRoles.
  • Dort fragt addRoles für die Stellvertretergruppe und jede Gruppe des Benutzers die hasRole-Zeilen des Objekts und jedes Rollen-Elternteils ab: (1+G) x (1+P) Abfragen pro Objekt. Hier G = 2, P = 1, also 6,2 Abfragen pro Objekt.
  • Jede Abfrage wird mit Objekt und Gruppe als Literalen neu gebaut und kompiliert (roleAssignmentsForContextAndGroup, DBKnowledgeBase.compileSimpleQuery). Nichts davon wird gecacht. Der AccessDecisionCache (#29637) merkt sich nur die Entscheidung pro Objekt, N verschiedene Objekte sind also N echte Prüfungen.
  • Jede Kompilierung ruft 7 x Logger.isDebugEnabled auf. com.top_logic.basic.Logger holt dabei jedes Mal einen slf4j-Logger über LoggerFactory.getLogger, und log4j-slf4j2-impl (Log4jLoggerFactory.getContext) läuft dafür den Stack ab. Das gilt für alle Log-Methoden von Logger.

Per Konfiguration nicht zu umgehen: Ein Access-Parent geht nur über Komposition oder eine to-one-Referenz auf ein persistentes Objekt, und Rollenregeln fragen die direkten Zuordnungen trotzdem pro Objekt ab.

Lösung (Prototyp liegt vor)

  1. Logger: slf4j-Logger einmal pro Namen in einer ConcurrentHashMap halten. Sicher, weil der log4j-Kontext immer vom Classloader von Logger kommt. Rekonfiguration und Level-Änderungen zur Laufzeit wirken weiter auf bestehende Logger (Tests in TestLogger4).
  2. Neue Klasse RoleAssignmentMemo: pro Interaktion und Gruppe alle hasRole-Zeilen der Gruppe mit einer Abfrage laden und Objekt und Rollen-Eltern daraus beantworten. Gültigkeit wie beim AccessDecisionCache: am InteractionContext, verworfen bei neuer KB-Revision. Rückfall auf den bisherigen Code
    • ohne Interaktion,
    • bei ungespeicherten Änderungen im Thread,
    • für historische Objekte oder Objekte einer anderen KB,
    • für eine Person ohne Stellvertretergruppe.

Gruppen mit mehr als 1.000 Zuordnungen werden nicht geladen, sondern pro Objekt abgefragt. Das gemeinsame Rollen-Elternteil wird dabei nur einmal pro Interaktion abgefragt.

Ergebnis mit beiden Änderungen:

= Ansicht = = root = = Reader vorher = = Reader nachher = = hasRole-Abfragen (Reader) =
Tabelle all(VehicleOrder) 9,0 s 69,4 s 9,4 s 589.966 -> 31
Delta "Stand A" 2,0 s 32,7 s 2,4 s 291.955 -> 34

Änderung 1 allein: -22 % bzw. -27 %. Verhalten unverändert: gleiche Zeilenzahlen für Reader und root, Reader darf keine Kostenstelle ändern, Writer schon.

Tests

  • Neu: TestRoleLookupPerInteraction (tl-element): Rolle über Gruppe auf Rollen-Elternteil, direkte Zuordnung, Zuordnung und Mitgliedschaft im selben Request committet bzw. entfernt, ungespeicherte Zuordnung mit Rollback, Gruppe mit 1.001 Zuordnungen. Jede Entscheidung wird zusätzlich mit dem alten Abfrageweg verglichen.
  • Abfragezahl: 2 für 5 Objekte und 2 für 60 Objekte. Ohne den Fix schlägt derselbe Test mit 20 bzw. 240 fehl.
  • Neu: zwei Tests in TestLogger4.
  • Grün: Security-Suiten in tl-core (63 Tests), tl-element (64), model.search (81).
  • Nicht gelaufen: vollständige Modul-Suiten, andere Datenbanken als H2.

Offene Punkte

  • Cluster: Wie beim AccessDecisionCache sieht ein Knoten eine Rollenänderung eines anderen Knotens erst nach dem nächsten Refetch.
  • Pro Objekt bleibt kleine Restarbeit: ElementAccessManager.getRoles löst Gruppen und Rollen-Eltern erneut auf. In den Zeiten nicht mehr sichtbar.
  • Get Started
  • Github
  • Discord
  • Das Unternehmen hinter TopLogic
  • Softwareentwicklung heute
  • Kontakt

© Copyright – Business Operation Systems GmbH

  • top-logic.com
  • Nutzungsbedingungen
  • Impressum
  • Rechtlicher Hinweis
  • Datenschutz
  • EN
  • Login