ls -la /Users/marcus.hinz/claude-projects/robotunits/memory 2>/dev/null; echo "=== docs mentioning visualisierung/fehler/rollenf ==="; grep -rliE "visualis|fehler|error|rollenf" /Users/marcus.hinz/claude-projects/robotunits/memory /Users/marcus.hinz/claude-projects/robotunits/doc /Users/marcus.hinz/claude-projects/robotunits/OFFENE-PUNKTE.md 2>/dev/null | head

List robotunits memory and docs


total 112
drwxr-xr-x  14 marcus.hinz  staff   448 Jul  3 12:47 .
drwxr-xr-x  16 marcus.hinz  staff   512 Jul  9 08:14 ..
-rw-r--r--   1 marcus.hinz  staff  1717 Jul  3 12:47 MEMORY.md
-rw-r--r--   1 marcus.hinz  staff   885 Jun 24 19:00 cpq-branching-mr-ziel.md
-rw-r--r--   1 marcus.hinz  staff  1741 Jul  3 12:46 cpq-configurator-modul-registry.md
-rw-r--r--   1 marcus.hinz  staff   467 Jun 26 19:40 cpq-storybook-start.md
-rw-r--r--   1 marcus.hinz  staff  1358 Jul  3 12:46 cpq-verbau-90grad-steher.md
-rw-r--r--   1 marcus.hinz  staff  6683 Jun 24 19:00 cpq-verbau-architektur.md
-rw-r--r--   1 marcus.hinz  staff   687 Jun 26 22:13 feedback-git-nur-fast-forward.md
-rw-r--r--   1 marcus.hinz  staff   739 Jun 24 19:00 feedback-kein-nexttick.md
-rw-r--r--   1 marcus.hinz  staff  1258 Jun 24 19:00 feedback-keine-intent-unterstellung.md
-rw-r--r--   1 marcus.hinz  staff   995 Jul  3 12:47 feedback-suche-nur-projektordner.md
-rw-r--r--   1 marcus.hinz  staff  6641 Jun 27 09:49 fire-visual-placement-mode.md
-rw-r--r--   1 marcus.hinz  staff   857 Jun 12 12:00 wuerth-plato-backend-read-only.md
=== docs mentioning visualisierung/fehler/rollenf ===
/Users/marcus.hinz/claude-projects/robotunits/memory/cpq-verbau-architektur.md
/Users/marcus.hinz/claude-projects/robotunits/memory/fire-visual-placement-mode.md


Bash

grep -rln "\"gruppen\"" /Users/marcus.hinz/claude-projects/robotunits /Users/marcus.hinz/projects/adesso-cpq 2>/dev/null | grep -v node_modules | head; echo "=== head of a schutzzaun_allround product json that matched ==="; head -c 600 /Users/marcus.hinz/claude-projects/robotunits/katalog/schutzzaun_allround/SAP4180DNA.json; echo; echo "=== R5S.json top head ==="; head -c 800 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S.json

Find gruppen tree and inspect product json heads


/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/catalog.json
=== head of a schutzzaun_allround product json that matched ===
{"_resourceClass":"sceneGraph_entity","handles":[{"id":"X-3950a88b-f92f-4f4d-b577-e7e1e7f71c8e","properties":{"custom-selection":{"type":"string","value":"self"}},"components":[{"_resourceClass":"component_transform","key":"root","translation":[0,0,0],"rotation":[0,0,0],"scale":[1,1,1]},{"_resourceClass":"component_pmi","id":"CS_EIN","tags":["name-CS_EIN"],"type":"point","properties":{"position":{"type":"vector3","value":[-40,-33,0],"usage":"position"},"rotation":{"type":"quaternion","value":[0,270,0],"usage":"rotation"}}},{"_resourceClass":"component_pmi","id":"CS_BASE_PRE","tags":["name-CS_B
=== R5S.json top head ===


ls -la /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S.json /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/*.json 2>/dev/null | head; echo "=== storybook products dir ==="; find /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products -maxdepth 2 2>/dev/null | head -40

Check R5S.json size and storybook products


-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:39 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S.json
-rw-rw-rw-@ 1 marcus.hinz  staff   3900 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/CAP4013.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_600x600.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_FOERDERRICHTUNG.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_MOTORROLLE_ENDSEITE.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_MOTORROLLE_RIEMENSEITE.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_RIEMEN_160.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_TRAGROLLE_ENDSEITE.json
-rw-rw-rw-@ 1 marcus.hinz  staff      0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/R5S_TRAGROLLE_RIEMENSEITE.json
-rw-rw-rw-@ 1 marcus.hinz  staff   2580 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x600/ROP1006.json
=== storybook products dir ===
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/.DS_Store
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/powered_roller_conveyor.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_allround
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/safety_fence_allround.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/safety_fence_basic.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/catalog.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBS1044PRA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1163PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0776SNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0389SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBD2083SRA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1206SNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0561PNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1034PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1507PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0432SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0518PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0432SNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0647SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0174PNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0475SNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1249PNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1077SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0862PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1120SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBF0872PRA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0518SNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0905SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0604PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0819PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0174PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1292PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1292PNA.png
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1249PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0948SNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0260PNA.json
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE0733SNA.png


python3 -c "
import json
d=json.load(open('/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/catalog.json'))
def walk(n,p=''):
    if isinstance(n,dict):
        for k in ('gruppe','name','scenegraph','bild'):
            if k in n: pass
        # print rollenf related
    pass
print('top keys:', list(d.keys()) if isinstance(d,dict) else type(d))
print(json.dumps(d, ensure_ascii=False)[:1500])
"

Inspect catalog.json tree structure


top keys: ['version', 'gruppen']
{"version": 1, "gruppen": [{"gruppe": "schutzzaun_basic", "kataloggruppen": [{"name": "Element", "artikelgruppen": [{"name": "SBE1507PNA", "fuellung": "polycarbonat", "artikel": [{"artikelnummer": "SBE1507PNA", "initialartikel": false, "masse": {"laenge": 2200, "breite": 174, "hoehe": 40}, "filter": {"fuellung": "polycarbonat", "breite": 174}, "stammdatenBild": "basic_element_polycarbonat.png", "assets": {"scenegraph": "schutzzaun_basic/SBE1507PNA.json", "bild": "schutzzaun_basic/SBE0174PNA.png"}}, {"artikelnummer": "SBE0217PNA", "initialartikel": false, "masse": {"laenge": 2200, "breite": 217, "hoehe": 40}, "filter": {"fuellung": "polycarbonat", "breite": 217}, "stammdatenBild": "basic_element_polycarbonat.png", "assets": {"scenegraph": "schutzzaun_basic/SBE0217PNA.json", "bild": "schutzzaun_basic/SBE0217PNA.png"}}, {"artikelnummer": "SBE0260PNA", "initialartikel": false, "masse": {"laenge": 2200, "breite": 260, "hoehe": 40}, "filter": {"fuellung": "polycarbonat", "breite": 260}, "stammdatenBild": "basic_element_polycarbonat.png", "assets": {"scenegraph": "schutzzaun_basic/SBE0260PNA.json", "bild": "schutzzaun_basic/SBE0260PNA.png"}}, {"artikelnummer": "SBE0303PNA", "initialartikel": false, "masse": {"laenge": 2200, "breite": 303, "hoehe": 40}, "filter": {"fuellung": "polycarbonat", "breite": 303}, "stammdatenBild": "basic_element_polycarbonat.png", "assets": {"scenegraph": "schutzzaun_basic/SBE0303PNA.json", "bild": "schutzzaun_basic/SBE0303PNA.png"}}, {"artikelnummer": "SB


Let me check whether catalog.json includes the rollenförderer group and how many served scene-graph files are empty (0 bytes).


python3 -c "
import json
d=json.load(open('/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/catalog.json'))
for g in d['gruppen']:
    print('GRUPPE:', g['gruppe'])
    if 'rollen' in g['gruppe']:
        for kg in g['kataloggruppen']:
            for ag in kg['artikelgruppen']:
                for a in ag['artikel']:
                    print('  ', kg['name'], a.get('artikelnummer'), a.get('initialartikel'), a.get('assets',{}).get('scenegraph'))
"

Check rollenfoerderer group in catalog.json


echo "=== 0-byte json in SERVED storybook rollenfoerderer ==="; find /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer -name "*.json" -size 0 | wc -l; echo "total json:"; find /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer -name "*.json" | wc -l; echo "=== top-level product graphs served (R5*.json direct) sizes ==="; find /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer -maxdepth 1 -name "*.json" -exec ls -la {} \; 2>/dev/null; echo "=== 0-byte json in robotunits rollenfoerderer ==="; find /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer -name "*.json" -size 0 | wc -l

Count empty json files in served and source catalogs


GRUPPE: schutzzaun_basic
GRUPPE: schutzzaun_allround
GRUPPE: rollenfoerderer
   Gerade R5S_600x400 True rollenfoerderer/R5S_600x400.json
   Gerade R5S_400x600 True rollenfoerderer/R5S_400x600.json
   Gerade R5S_400x300 True rollenfoerderer/R5S_400x300.json
   Gerade R5S_300x400 True rollenfoerderer/R5S_300x400.json
   Dreheinheit R5R_600x400 True rollenfoerderer/R5R_600x400.json
   Dreheinheit R5R_400x600 True rollenfoerderer/R5R_400x600.json
   Dreheinheit R5R_400x300 True rollenfoerderer/R5R_400x300.json
   Dreheinheit R5R_300x400 True rollenfoerderer/R5R_300x400.json
   Eckumsetzer50 R5T050_ANFANG_600x400 True rollenfoerderer/R5T050_ANFANG_600x400.json
   Eckumsetzer50 R5T050_MITTE_600x400 True rollenfoerderer/R5T050_MITTE_600x400.json
   Eckumsetzer50 R5T050_ENDE_600x400 True rollenfoerderer/R5T050_ENDE_600x400.json
   Eckumsetzer50 R5T050_ANFANG_400x600 True rollenfoerderer/R5T050_ANFANG_400x600.json
   Eckumsetzer50 R5T050_MITTE_400x600 True rollenfoerderer/R5T050_MITTE_400x600.json
   Eckumsetzer50 R5T050_ENDE_400x600 True rollenfoerderer/R5T050_ENDE_400x600.json
   Kurve R5C45_0_600x400 True rollenfoerderer/R5C45_0_600x400.json
   Kurve R5C45_0_400x600 True rollenfoerderer/R5C45_0_400x600.json
   Kurve R5C90_0_600x400 True rollenfoerderer/R5C90_0_600x400.json
   Kurve R5C90_0_400x600 True rollenfoerderer/R5C90_0_400x600.json
   Kurve R5C45_1_600x400 True rollenfoerderer/R5C45_1_600x400.json
   Kurve R5C45_1_400x600 True rollenfoerderer/R5C45_1_400x600.json
   Kurve R5C90_1_600x400 True rollenfoerderer/R5C90_1_600x400.json
   Kurve R5C90_1_400x600 True rollenfoerderer/R5C90_1_400x600.json


=== 0-byte json in SERVED storybook rollenfoerderer ===
       0
total json:
       2
=== top-level product graphs served (R5*.json direct) sizes ===
-rw-rw-rw-@ 1 marcus.hinz  staff  64998 Jul  8 11:44 /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer/rollenfoerderer.json
-rw-r--r--  1 marcus.hinz  staff  2154 Jul  8 17:07 /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer/rollenfoerdererprofil_aussenradius.json
=== 0-byte json in robotunits rollenfoerderer ===
     231


Key finding emerging. Let me confirm the referenced product graphs are missing/empty and contrast with the working schutzzaun case.


echo "=== Does served dir have the referenced R5S_600x400.json etc? ==="; for f in R5S_600x400 R5R_600x400 R5T050_ANFANG_600x400 R5C45_0_600x400; do ls -la "/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer/$f.json" 2>&1 | sed 's|.*/products/||'; done
echo "=== Source size of these per-size product graphs (robotunits, nested) ==="; find /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer -name "R5S_600x400.json" -o -name "R5R_600x400.json" -o -name "R5C45_0_600x400.json" 2>/dev/null | xargs ls -la 2>/dev/null
echo "=== Working contrast: served schutzzaun_basic file size ==="; ls -la /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1507PNA.json
echo "=== schutzzaun_basic 0-byte json count (served) ==="; find /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic -name "*.json" -size 0 | wc -l

Verify missing/empty rollenfoerderer graphs vs working schutzzaun


=== Does served dir have the referenced R5S_600x400.json etc? ===
rollenfoerderer/R5S_600x400.json: No such file or directory
rollenfoerderer/R5R_600x400.json: No such file or directory
rollenfoerderer/R5T050_ANFANG_600x400.json: No such file or directory
rollenfoerderer/R5C45_0_600x400.json: No such file or directory
=== Source size of these per-size product graphs (robotunits, nested) ===
-rw-rw-rw-@ 1 marcus.hinz  staff  0 Jul  7 21:39 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5R/R5R_600x400/R5R_600x400.json
-rw-rw-rw-@ 1 marcus.hinz  staff  0 Jul  7 21:40 /Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/R5S/R5S_600x400/R5S_600x400.json
=== Working contrast: served schutzzaun_basic file size ===
-rw-r--r--  1 marcus.hinz  staff  25431 Jul  8 18:16 /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic/SBE1507PNA.json
=== schutzzaun_basic 0-byte json count (served) ===
       0


Ich habe die vier Verzeichnisse durchsucht. Hier die Ergebnisse.

## Kurzfassung

Die Visualisierung des Rollenförderers scheitert, weil die vom Katalog referenzierten Szenegraph-Dateien für den Rollenförderer im ausgelieferten Verzeichnis **fehlen** bzw. in der Quelle **0 Byte groß (leer)** sind und zusätzlich die referenzierten `.glb`-Geometrien **nirgends existieren**. Der Schutzzaun funktioniert im Kontrast, weil dort alle Dateien vorhanden und gefüllt sind.

---

## 1. Wo ist der "Produktkatalog" definiert?

Es gibt zwei Ebenen:

**a) Katalog-Quelle (DSL / Tcl-artiges Format `json set json_string ARTIKEL …`)**
- `/Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/rollenfoerderer.json` — Artikeldefinitionen. Hier steht z.B. (Zeilen ~9-11):
  - `ARTIKEL R5S benennung_de "Rollenförderer Gerade"` / `benennung_en "Powered roller conveyor straight"`
  - `ARTIKEL R5C benennung_de "Rollenförderer Kurve"` / `"Powered roller conveyor curve"`
  - Feld `visualisierung "1"`, `fangpunktdefinition "rollenfoerderer_gerade"`
- Analog: `katalog/schutzzaun_basic/…`, `katalog/schutzzaun_allround/…`

**b) Kompilierter Katalog-Baum (wird vom Frontend/Storybook konsumiert)**
- `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/catalog.json`
- Struktur: `version` + `gruppen[] → kataloggruppen[] → artikelgruppen[] → artikel[] → assets.{scenegraph,bild}`
- Enthält die Gruppe `rollenfoerderer` mit Artikeln (Gerade/Dreheinheit/Eckumsetzer50/Kurve), jeweils `initialartikel: true` und `assets.scenegraph` z.B. `"rollenfoerderer/R5S_600x400.json"`.

Die eigentlichen Szenegraphen (`_resourceClass: "sceneGraph_entity"`, `handles[]`) liegen unter `katalog/<gruppe>/…` und referenzieren `.glb`-Geometrien, Materialien und Unter-Szenegraphen (`sceneGraph_reference`).

---

## 2. Wo taucht "Rollenförderer" auf?

- Katalog-Quelle: `/Users/marcus.hinz/claude-projects/robotunits/katalog/rollenfoerderer/**` (785 JSON-Dateien; Unterordner R5S, R5C, R5M, R5R, R5T)
- Kopie in adesso-cpq: `/Users/marcus.hinz/projects/adesso-cpq/ressources/katalog/rollenfoerderer/**` und `/Users/marcus.hinz/projects/adesso-cpq/ressources/rollenfoerderer.xlsx`
- Ausgeliefert (Storybook/App): `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer/`
- Code-Referenzen:
  - `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/components/building-blocks/ProductBrowser.vue:89` → `rollenfoerderer: "powered_roller_conveyor.png"` (GROUP_IMAGES)
  - `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/components/building-blocks/ProductBrowserPanel.stories.ts:11` (gleicher Eintrag)
  - `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/components/visual/ProductEditorDemo.vue:15,43` → `name: "Conveyor Roller"`, `productCategory: "conveyor_roller"`

---

## 3. Wo passiert die Visualisierung (Rendering-Code)?

Datenfluss beim Auswählen eines Produkts:

1. `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/components/visual/ProductConfigurator.vue`
   - Zeile 16: `new DefaultProductService(new FetchAssetLoader("/products/"))`
   - Zeile 31-35: `onProductSelected` → `productType = node.scenegraph.replace(/\.json$/,"")` → `getProduct(...)` → `fire.dispatch({eventTypeName:"add-product", handles})`
   - Zeile 38: lädt `/fire/environment.config.json`
2. `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/services/product-service.ts`
   - Zeile 53-59 `FetchAssetLoader.resolve`: `fetch(/products/<path>)`; bei `!ok` → **`throw new Error("Asset nicht gefunden: ... (Status)")`**
   - Zeile 58: `response.json()` (wirft bei leerer Datei einen Parse-Fehler)
3. `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/components/visual/Fire3D.vue`
   - Zeile 36/192: `createVisual3D(...)`; Zeile 135-143 `setScene`/`execute`
4. `/Users/marcus.hinz/projects/adesso-cpq/packages/runtime/visual/src/visual-3d.ts` — Wrapper um die Fire-Engine `@ad/fire`
   - Zeile 165-224 `buildConnector`: lädt Sub-Assets (glb/scenes) per `fetch`; bei `!ok` → **`throw new Error("HTTP <status> fetching <uri>")`** (Zeile 184)
5. Die eigentliche 3D-Engine ist **geko-fire** (`/Users/marcus.hinz/projects/geko-fire/`, kompiliert: `browser/index.js`, `fbxProcessor.worker.js`, `glbProcessor.worker.js`; three.js-basiert). Connector-Pfade in `/Users/marcus.hinz/projects/geko-fire/assets/environment.config.json` (Zeilen 401-466): `./assets/glb/<%=path%>`, `./assets/scenes/<%=path%>` etc.

---

## Ursache des Fehlers (belegt)

**Problem A — referenzierte Szenegraphen fehlen im ausgelieferten Verzeichnis:**
`catalog.json` verweist für jeden Rollenförderer-Artikel auf flache Pfade wie `rollenfoerderer/R5S_600x400.json`, `rollenfoerderer/R5R_600x400.json`, `rollenfoerderer/R5T050_ANFANG_600x400.json`, `rollenfoerderer/R5C45_0_600x400.json`.
Im ausgelieferten Ordner `/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/rollenfoerderer/` existieren aber **nur 2 Dateien**: `rollenfoerderer.json` und `rollenfoerdererprofil_aussenradius.json`. Alle in catalog.json referenzierten Produkt-Szenegraphen **fehlen** → `fetch` 404 → `product-service.ts:56` wirft `Asset nicht gefunden: rollenfoerderer/R5S_600x400.json (404)`.

**Problem B — Quell-Szenegraphen sind leer (0 Byte):**
In `robotunits/katalog/rollenfoerderer` sind **231 von 785** JSON-Dateien 0 Byte groß, u.a. genau die per-Größe-Produktgraphen (`R5S/R5S_600x400/R5S_600x400.json`, `R5R/R5R_600x400/R5R_600x400.json` = 0 Byte) und viele Teilgraphen (`R5S_TRAGROLLE_*.json`, `R5S_MOTORROLLE_*.json`, `R5S_RIEMEN_160.json`, `R5S.json` …). Eine leere Datei über `response.json()` (visual-3d.ts:195 / product-service.ts:58) → JSON-Parse-Fehler.

**Problem C — Geometrie (.glb) fehlt vollständig:**
Die nicht-leeren Szenegraphen referenzieren `.glb`-Dateien, z.B. `katalog/rollenfoerderer/R5S/R5S_600x600/R5S_TRAGROLLE_RIEMENSEITE.glb`. Unter `robotunits` gibt es **keine einzige** `.glb`-Datei; in `adesso-cpq/ressources` existiert nur `SBS1044SRA.glb` (Schutzzaun). Der Fire-Connector wirft dann `HTTP 404 fetching …glb` (visual-3d.ts:184).

**Kontrast (funktionierend):** Schutzzaun — `catalog.json` verweist auf `schutzzaun_basic/SBE1507PNA.json`; die ausgelieferte Datei existiert und ist 25 KB groß; **0** leere JSON-Dateien im Schutzzaun-Verzeichnis.

**Pfad-Mismatch als Nebenbefund:** catalog.json nutzt flache Pfade (`rollenfoerderer/R5S_600x400.json`), die Quelle ist aber verschachtelt (`rollenfoerderer/R5S/R5S_600x400/R5S_600x400.json`) — selbst wenn die Dateien gefüllt wären, würde die flache Referenz sie nicht finden.

Zusätzliche Doku im Projekt zur Fire-Visualisierung: `/Users/marcus.hinz/claude-projects/robotunits/memory/fire-visual-placement-mode.md` und `/Users/marcus.hinz/claude-projects/robotunits/memory/cpq-verbau-architektur.md`.