fix(critical): SQLAlchemy mapper crash + material matching for USD renders + kanban drag-to-reject
- beat_tasks.py: import app.models at module level so SQLAlchemy can
resolve relationship("Template") and relationship("User") when domain
models are imported in isolation inside task functions. Fixes all
beat tasks (batch_render_notifications, recover_stuck_cad_files) that
crashed every 60s with mapper initialization error.
- _blender_materials.py: build_mat_map_lower() now adds a slug-normalized
key variant (re.sub([^a-z0-9]+, _, kl)) for each mat_map entry. OCC
part names like 'F-802007_TR4-D1-H122AG' → slug 'f_802007_tr4_d1_h122ag'
now matches USD-imported Blender objects. Existing prefix fallback
(key.startswith(part_key)) catches AF-suffix variants.
- Orders.tsx: kanban drag-to-reject implemented. submitted/processing
cards are draggable (cursor-grab). Rejected column highlights with
red ring on drag-over. Drop opens reject reason modal via createPortal.
Confirm calls rejectOrder() mutation + invalidates orders cache.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,27 @@
|
||||
|
||||
## Learnings
|
||||
|
||||
### 2026-03-12 | Caching | Composite Cache Keys für Tessellierung
|
||||
Hash-basiertes Caching in Celery Tasks muss alle relevanten Parameter einschließen, nicht nur den Datei-Hash. Bei `generate_gltf_geometry_task` und `generate_usd_master_task` wurde der Cache-Key auf `{hash}:{linear}:{angular}:{engine}` erweitert. Außerdem: immer Disk-Existenz des gecachten Assets prüfen (`storage_key.exists()`) bevor ein Cache-Hit zurückgegeben wird — der Asset-Record kann existieren, die Datei aber nicht.
|
||||
|
||||
### 2026-03-12 | React | Modal in <tr> braucht createPortal
|
||||
Ein Modal-Dialog, der aus einer `<tr>`-Tabellenzeile gerendert wird, erzeugt invalides HTML (`<div>` in `<tr>` nicht erlaubt). Fix: `createPortal(modal, document.body)` — rendert das Modal am Body-Root, außerhalb der Tabellen-Hierarchie.
|
||||
|
||||
### 2026-03-12 | Prozess | ROADMAP war dem Code weit hinterher
|
||||
Pre-flight code audit vor dem Schreiben eines Plans ist zwingend erforderlich. Beim Sprint vom 2026-03-12 zeigte sich: P1 (dead-code cleanup, blender_render.py split), P5 (USD render wiring), P8 (Celery tenant context) und P10 (UI polish) waren bereits größtenteils im Code implementiert, aber nicht im ROADMAP.md reflektiert. Lesson: Immer zuerst grep/ls-Gates und Line-Count-Checks laufen lassen, bevor Tasks geplant werden.
|
||||
|
||||
### 2026-03-12 | Material | SQLAlchemy Mapper-Fehler bei isoliertem Domain-Import
|
||||
Wenn eine Celery-Task nur `from app.domains.orders.models import Order` importiert (ohne `app.models`), kann SQLAlchemy die String-Referenzen `relationship("Template", ...)` und `relationship("User", ...)` nicht auflösen — alle Mapper-Initialisierungen schlagen fehl. Fix: `import app.models as _all_models` am Modul-Level von `beat_tasks.py` eintragen. So werden alle Models geladen bevor irgendeine Task-Funktion die Mapper initialisiert. Gilt für alle Tasks die Domain-Models direkt importieren.
|
||||
|
||||
### 2026-03-12 | Material | OCC-Part-Namen vs. USD-Part-Keys beim Material-Matching
|
||||
OCC XCAF-Namen enthalten Bindestriche und _AF\d+-Suffixe (z.B. `GE360-HF-0011-EIN_HAELFTE_AF0_1_AF0`). Das USD-Export-Tool slugifiziert den Namen: `[^a-z0-9]+` → `_` (d.h. `ge360_hf_0011_ein_haelfte_af0_1_af0`). Blender importiert das USD-Objekt als `ge360_hf_0011_ein_haelfte` (base-name aus XCAF). Das Mat-Map aus der DB ist lowercased mit Bindestrichen. Fix: In `build_mat_map_lower()` auch eine slug-normierte Variante jeden Keys hinzufügen (`re.sub(r'[^a-z0-9]+', '_', kl).strip('_')`). Der bestehende Prefix-Fallback (`key.startswith(part_key)`) fangt dann den Rest ab.
|
||||
|
||||
### 2026-03-12 | USD | Stale USD-Master-Assets invalidieren
|
||||
USD-Assets die vor dem `elif shape_has_loc`-Fix (Commit `de7f97b`, 2026-03-12 16:43) generiert wurden, haben fehlerhafte Geometrie (double-transform). Fix: `DELETE FROM media_assets WHERE asset_type='usd_master' AND created_at < '2026-03-12 16:43:33'` + `UPDATE cad_files SET step_file_hash = NULL WHERE id IN (...)`. Nächster Render generiert neue korrekte USD-Datei.
|
||||
|
||||
### 2026-03-12 | USD | Mesh-Prim-Benennung für Blender 5.0
|
||||
Blender 5.0 importiert USD und kollabiert single-child Xform+Mesh-Hierarchien zu einem einzigen Objekt. Der Objektname entspricht dabei dem Leaf-Namen des Mesh-Prims (nicht dem Xform). Die Lösung: `mesh_path = f"{part_path}/{part_key}"` statt `f"{part_path}/Mesh"`. Damit importiert Blender jedes Objekt direkt mit dem korrekten part_key als Namen — kein Post-Import-Rename nötig. Blender setzt `obj["usd:path"]` nicht, daher ist der pfadbasierte Rename-Ansatz nicht funktionsfähig.
|
||||
|
||||
### 2026-01-15 | Architektur | Backend-Port-Konflikt
|
||||
Port 8000 war belegt → Port 8888 in `docker-compose.yml` + Vite-Proxy. Früh festlegen und in CLAUDE.md dokumentieren.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user