wiki/c-work/4-done/2026-05-udb-toggle-spec-recovery.md

3.8 KiB

UDB Toggle Spec Recovery

Kontext

Nach dem Generic Tree Refactor (2026-05-18) waren im Code sechs Aggregations-Routinen (_aggregatePersonalRoot, _aggregateConnection, _aggregateMandateGroup, _resolveAttrsForKey, getAttributesForKeys), ein paralleler Endpoint POST /tree/attributes und ein Bug bei virtuellen Coordinates (kein aggregate fuer Records ohne DB-Eintrag) entstanden. Das Frontend nutzte refreshAttributes als optionalen Pfad und refreshAfterAction als Opt-in-Prop, obwohl die Spec nur einen Pipeline-Pfad vorsieht.

Ziel

Wiederherstellung der dokumentierten Spec (2026-05-18 "Generic Tree Refactor"): Eine Pipeline, ein Resolver, ein Mixed-Symbol, drei Flags generisch durch denselben Code-Pfad. Keine optimistic updates, keine Fallbacks, keine doppelte Logik.

Durchgefuehrte Aenderungen

S1 - Backend: virtuelle Coordinates auf aggregate-Pfad

_inheritFlags.py: resolveEffectiveForPath und resolveEffectiveForFds rufen im else-Zweig (virtual record, kein DB-Match) nun getEffectiveFlag(virtualRec, flag, allDs, mode=mode) bzw. getEffectiveFlagFds(...) statt _resolveWalkValue auf. Damit koennen virtuelle Coordinates (z.B. Connection ohne eigenen Root-Record) korrekt 'mixed' zurueckgeben, wenn ihre Descendants divergieren.

S2 - Backend: sechs Aggregatoren entfernt

_buildTree.py: Geloescht: _aggregatePersonalRoot, _aggregateConnection, _aggregateMandateGroup, _resolveAttrsForKey, getAttributesForKeys. Diese waren ausschliesslich fuer den parallelen tree/attributes-Endpoint noetig. Synthetic Container (personalRoot, mgrp) haben laut Spec keine Flags (UI blendet sie aus); data-bearing Nodes nutzen bereits resolveEffectiveForPath/resolveEffectiveForFds via den tree builder.

S3 - Backend: Endpoint tree/attributes entfernt

routeFeatureWorkspace.py: Route POST /{instanceId}/tree/attributes und Model _TreeAttributesRequest ersatzlos geloescht.

S4 - Frontend: refreshAttributes-Pfad entfernt

  • UdbSourcesProvider.tsx: refreshAttributes-Methode entfernt.
  • FolderFileProvider.tsx: refreshAttributes-Methode entfernt.
  • FormGeneratorTree.tsx: _refreshVisibleAttributes nutzt nur noch den Refetch-All-Expanded-Pfad. _runAction ruft immer _refreshVisibleAttributes ohne Bedingung. refreshAfterAction-Prop entfernt.
  • types.ts: refreshAttributes aus TreeNodeProvider, refreshAfterAction aus FormGeneratorTreeProps entfernt.
  • SourcesTab.tsx, FilesTab.tsx: refreshAfterAction-Prop-Nutzung entfernt.

S5 - Klick-Semantik dokumentiert

wiki/b-reference/platform/neutralization.md: Klick auf mixed-Symbol setzt explizit false (alle Flags). Begruendung: Toggle behaelt zwei klare End-Zustaende; Reset auf null/inherit durch Parent-Toggle.

S6 - Tests

8 neue Tests in test_inheritFlags.py::TestVirtualCoordAggregate:

  • virtual folder mixed neutralize/scope/rag
  • virtual folder uniform returns concrete
  • virtual FDS workspace mixed/uniform
  • virtual connection root mixed via diverging services

Frontend-Test refreshAfterAction angepasst: zweiter Test (does NOT refetch when false) entfernt, da Verhalten nun immer refetch ist.

Resultat: test_inheritFlags.py 79/79 gruen, test_buildTree.py 19/19 gruen.

Validierung (Smoke-Tests vor Merge)

  1. Folder mit zwei Subfolders, einer toggeln -> Parent zeigt mixed, Root zeigt mixed, Personal Root zeigt mixed.
  2. Parent toggeln (war mixed) -> Parent + alle Descendants zeigen den Parent-Wert.
  3. Klick auf mixed-Symbol -> setzt explizit false, Spinner bleibt bis Refetch durch ist.
  4. Toggle in collapsed Subtree (verstecktem Knoten) -> nach expand zeigt Subtree die neuen Werte.
  5. Mandate mit zwei Workspaces, einer toggeln -> mgrp zeigt mixed.