Files
claude-robotunits/memory/cpq-verbau-architektur.md
2026-07-09 09:21:49 +02:00

6.5 KiB

name, description, metadata
name description metadata
cpq-verbau-architektur adesso-cpq Verbau/Modell-Architektur (Product/Modell/Graph, BLAST-Validierung) + nächster Schritt für morgen früh
node_type type originSessionId
memory project d789290f-6631-426e-9639-e7ea7a60e8f9

Stand der Architektur-Diskussion adesso-cpq (Schutzzaun-Konfigurator). Repos: ~/projects/adesso-cpq (frontend/CPQ), ~/projects/geko-core (Speedmaxx-Backend). Constraint-Typen folgen noch; jetzt erst Infrastruktur.

Kernmodell (erarbeitet, trägt)

  • Product = zweigeteilt: (1) Graph mit PMIs/Collidern/Transforms = der „wertlose" Graph (keine Autorität, nur Darstellung + Approximationsdaten); (2) Variablen = Config + Constraints.
  • Product = Entity (BaseEntity, BLAST-validiert). Konstrukt aus Produkten = auch Entity = Modell. Rekursiv: Modell = Produkt (Blatt) | Konstrukt aus Modellen. Aus den Entities wird am Ende der wertlose Graph projiziert.
  • Quellen (mehrere!): Speedmaxx ist führend (~60%), daneben eigene Modelle (optimaler gestaltbar) + weitere Lieferanten. Darum muss BLAST gegen ein normalisiertes Modell validieren, nicht gegen Quell-Spezifika oder den rohen Graphen. Im Zweifel ein Converter, der Speedmaxx & whatever normalisiert.

Speedmaxx-Realität (Quelle der Wahrheit, NICHT der cpq-Mock)

  • Branch geko-core feature/get-scene-from-speedmaxx: executeCommandExecuteCommandResponse { ui: Record<string,SpeedmaxxVariable>, viewing, error }.
  • ui = Config+Constraints: domain.{min,max,step,valuelist,default}, required/visible/editable/multivalue/datatype/unit/.... Hier stecken „≤6m / ≤10 Teile".
  • viewing = die Szene (wertloser Graph). Controller loadScene ruft combo1_cmd, ProductCategory "Schutzzaun", Variables wizard → gibt result.viewing.
  • Format des Graphen (= Alttool = assets/scenes/zaun.json): sceneGraph_entity { handles[] }; Hierarchie flach über component_transform.key/parentKey (root → asm_root → produkt-node → ~50 Blatt-Teile); component_pmi (z.B. CS_SVS/CS_BASIS am Produkt-Knoten) = Andockpunkte; component_collider; Länge teils in scale.z eingebacken.
  • FALSCH in cpq: packages/frontend/src/util/speedMaxx2Visual.ts erfindet {environmentId, nodes:[{id,label}]} — gibt es bei Speedmaxx nicht. Muss korrigiert werden.

Validierung / BLAST (entschieden)

  • Variablen → BLAST direkt (per-Produkt + Querregeln).
  • Geometrie-Constraints (≤10 Teile, Gesamtlänge, PMI-Kompatibilität, Platz/Kollision) stehen NICHT in Variablen → ergeben sich aus PMIs/Collidern/Transforms.
  • Geometrie-RECHNUNG läuft in der Engine (nicht im BLAST-Kern, der ist geometrie-agnostisch). Aber: Engine wird AUS BLAST getriggert. BLAST ist der Orchestrator und reaktiv (Änderung → sofort wirksam), Cache sparse pro Entity-ID → Engine läuft nur für den betroffenen Bauzug.
  • Zwei Topos-Ebenen: per Einzelteil + konsolidiert (Bauzug). Konsolidierter Topos ruft die Engine, holt Verdikt, validiert.
  • Hebel = Abhängigkeitsschärfe (welcher Topos hängt woran). Wird über Constraint-Typen geregelt (kommt noch).
  • Roher Graph geht NIE nach BLAST; nur Variablen + destillierte Graph-Fakten/Verdikte.

Schichten (Zielbild)

  • UI spricht nur mit dem Scene/Model-Service (Name noch offen), gibt dessen Ergebnis als Graph/Commands an fire.
  • Scene/Model-Service (core): hält Modell/Bauzüge, PMI-Verbindungen, rechnet Constraints, projiziert Modell → Graph. Intern getrennt: Modell/Constraint (entscheidet, kennt Platz) vs. Projektion (stumpf, entscheidet nichts).
  • ProductService (gehört nach core, FE-agnostisch): getProduct/updateProduct, liefert nur Einzelteile, quelle-agnostisch über die Asset-Abstraktion (datamanager-Connectors in environment.config.json: path+typeKey-Templates; dev=Assets, live=Server). Darf NICHT wissen, woher.
  • fire/Graph: rendert, ist außerhalb unserer Engine interaktiv und arbeitet mit Näherungen (Collider). Wir haben das letzte Wort; nach jeder Interaktion Vollaustausch des Graphen.
  • Gemeinsame Constraint-Sprache nötig (3x bestätigt): zwischen zwei gemeldeten Interaktionen handelt fire autonom; es braucht dieselben Constraints. Lösung: deklarative Daten im Graph (Collider/PMI/Grenzen), kein geteilter Code. Offen: diese deklarativen Constraints und die exakten BLAST-Regeln müssen aus EINER Quelle stammen, sonst Drift.

Bestand an Typen (adesso-cpq)

  • shared: BaseEntity { id }. core: nur EntityStore, keine Typen.
  • blast: ObjectSchema<T extends BaseEntity>, ToposKey, BehaviourResolver, HintResolver, Diagnostic, Severity('error'|'warn'|'info'), Behaviours, Hint, FieldState, ItemResult, BlastValidator.
  • visual-runtime: Visual3D (setScene/execute/subscribe/camera), CameraTransformation{translation,rotation,scale}, ConnectorConfig, Visual3DConfig, Observable<T>.
  • Szenegraph-Format-Typen (SceneGraph/Handle/Component, component_transform/pmi/collider) sind HEIMATLOS — nur in utils/sceneMerger.ts (fliegt raus) und als any in Fire3D.vue/DefaultCommandProzessor/SceneReplayProcessor. Brauchen EINEN Besitzer (Fundament für Product/Scene/fire).
  • utils/sceneMerger.ts: addProductInstance/mergeScene/generateUniqueIds/positionScene/calculateNextPosition — fliegt raus (falscher Ort utils, zu groß, vermischt Mechanik/Platzierung/Instanz). generateUniqueIds vom User als „Mist" markiert.

Offene Baustelle aus dieser Session

  • packages/frontend/src/services/product-service.ts habe ich angelegt (getProduct/updateProduct, AssetLoader, lokaler SceneGraph-Typ). User-Kritik: zu nah an UI (gehört nach core), zuviel vorab definiert (Interfaces/Typen ohne Plan). Morgen entscheiden: behalten/verschieben/löschen. NICHT eigenmächtig Typen streuen.

MORGEN FRÜH ZUERST

  1. GENAU auf die Entities für BLAST schauen: was ist exakt die normalisierte Entity (Product, Modell). Wahrscheinlich ein Converter rein, der Speedmaxx (ui+viewing) und andere Quellen normalisiert. Das MUSS sitzen, sonst Schmerzen.
  2. Dann Infrastruktur/Schichten verorten (ProductService → core, Format-Typen-Heimat).
  3. Constraint-Typen erst danach.

Arbeitsregeln des Users (hart)

  • Sehr knapp, exakt das Gefragte, KEINE ungefragten Optionen/Vorschläge/Typen. Eins nach dem anderen, langsam. Nicht 3 Schritte vorausbauen. Keine Antwort mit Rückfrage/Angebot beenden. Kein Claude-Hinweis in Commits. Vor verändernden Aktionen kurz Plan + Go abwarten.
  • Branch+MR-Workflow (adesso-CLAUDE.md); frontend→core ist paketübergreifend → nur mit explizitem Go. Git-Remotes heron.at: HTTPS+Token (osxkeychain), SSH (Port 22) ist geblockt.