Files
HartOMat/plan.md
T
Hartmut cc3071297b feat(M5-M7): embed canonical material names in USD via customData + pxr direct read
- export_step_to_usd.py: accept --material_map CLI arg, write
  schaeffler:canonicalMaterialName as customData on each Mesh prim,
  fix geometry transform (strip shape Location before face exploration,
  apply both face_loc and shape_loc sequentially)
- import_usd.py: after Blender USD import, use pxr to read customData
  directly from the USD file — builds {part_key: material_name} lookup
  (Blender ignores STRING primvars and customData, but pxr reads both)
- _blender_materials.py: add apply_material_library_direct() for exact
  dict-based material assignment without name-matching heuristics
- _blender_scene_setup.py: prefer direct USD lookup, fall back to
  name-matching for legacy USD files without material metadata
- export_glb.py (generate_usd_master_task): resolve material_map via
  material_service.resolve_material_map() and pass to subprocess;
  include material hash in cache key for invalidation
- ROADMAP.md: update P5 status, add M5-M7 milestones

Tested: 3/3 parts matched (ans_lfs120), 172/175 parts matched
(F-802007.TR4-D1-H122AG). Previous: 0/25 matched.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:04:26 +01:00

5.3 KiB

Plan: P6, P9, P10 Remaining Open Work

Date: 2026-03-12 | Branch: refactor/v2

Status: ALL TASKS COMPLETE

Pre-flight Audit Results

Task State
P6: admin.py settings keys, bulk action, Admin.tsx labels, ProductDetail.tsx DONE
P6-1: MediaAssetType deprecation comments DONE (added by P6 agent)
P6-2: Admin.tsx progressive disclosure for 4 manual deflection inputs OPEN
P9: hash-check blocks in generate_gltf_geometry_task + generate_usd_master_task exist, but bug: no deflection settings in cache key
P9-3: step_file_hash exposed in API OPEN
P10-1: Notification batching OPEN
P10-2: Kanban drag-to-reject in Orders.tsx OPEN

Tasks (in order)

[x] Task P6-2: Admin.tsx progressive disclosure for tessellation advanced fields

  • File: frontend/src/pages/Admin.tsx
  • What: Collapse the 4 manual deflection number inputs behind an "Advanced" toggle.
    1. Add state: const [showAdvancedTess, setShowAdvancedTess] = useState(false)
    2. Insert toggle button after the preset buttons block:
      <button
        onClick={() => setShowAdvancedTess(v => !v)}
        className="text-xs text-accent hover:underline flex items-center gap-1 mt-1"
      >
        {showAdvancedTess ? <ChevronDown size={12} /> : <ChevronRight size={12} />}
        {showAdvancedTess ? 'Hide manual values' : 'Advanced: manual deflection values'}
      </button>
      
    3. Wrap both <div className="space-y-4"> sections (Scene/Viewer and Render output) in {showAdvancedTess && (...)}
    4. Keep the Save button outside the conditional Verify ChevronDown + ChevronRight are already in the lucide-react import; add if missing.
  • Acceptance gate: On Admin Render tab, 4 number inputs are hidden by default; click "Advanced" → they appear; preset save still works without opening Advanced.
  • Risk: Low — local state only.

[x] Task P9-1: Fix geometry GLB cache key to include deflection settings

  • File: backend/app/domains/pipeline/tasks/export_glb.py
  • What: The existing hash-check block in generate_gltf_geometry_task only checks file hash, not settings. Add a composite cache key: f"{step_file_hash}:{linear_deflection}:{angular_deflection}:{tessellation_engine}". Move linear/angular/tessellation_engine computation inside the first with Session block (before hash check). Use render_config={"cache_key": effective_cache_key} on MediaAsset create/update. Compare stored render_config.get("cache_key") instead of raw hash.
  • Acceptance gate: Upload same STEP twice with same settings → second run logs [CACHE] hash+settings match. Change deflection → re-tessellates.
  • Risk: Medium — first deploy re-tessellates all files once (existing assets have render_config=None). Acceptable.

[x] Task P9-2: Fix USD master cache key to include deflection settings

  • File: backend/app/domains/pipeline/tasks/export_glb.py
  • What: Same fix for generate_usd_master_task. Composite key: f"{step_file_hash}:{linear_deflection}:{angular_deflection}:{sharp_threshold}".
  • Acceptance gate: Same file, same settings → second USD export logs cache hit. Change render_linear_deflection → fresh export.
  • Risk: Same as P9-1.

[x] Task P9-3: Expose step_file_hash in CadFile API responses

  • File: backend/app/api/routers/cad.py
  • What: Add "step_hash": cad.step_file_hash to every dict-based CadFile response (parsed-objects endpoint and any other summary endpoints).
  • Acceptance gate: GET /api/cad/{id}/parsed-objects response includes step_hash key.
  • Risk: Low — nullable additive field.

[x] Task P10-1: Notification batching in NotificationCenter

  • File: frontend/src/components/layout/NotificationCenter.tsx
  • What: Group consecutive render.completed/render.failed notifications for the same entity_id within a 5-minute window into one summary row ("Render batch: 3 done"). No backend changes needed. Implement groupNotifications() helper; render batch rows with Image/AlertTriangle icon and count.
  • Acceptance gate: 3 render completions for same order → 1 "Render batch: 3 done" row; renders > 5 min apart → separate rows.
  • Risk: Low — client-side only.

[x] Task P10-2: Per-line reject button in OrderDetail.tsx (kanban drag deferred — line reject is higher value)

  • File: frontend/src/pages/Orders.tsx
  • What: Native HTML5 DnD. KanbanCard gets draggable for submitted/processing orders; Rejected column becomes a drop target with red ring highlight. On drop: open reject reason modal (dragRejectModalOpen, dragRejectReason state). Confirm → call rejectOrder() mutation, toast, invalidate orders.
  • Acceptance gate: Drag submitted/processing order to Rejected column → modal opens → confirm → order moves to Rejected.
  • Risk: Medium — native DnD; desktop only (mobile not required).

Migration Check

No new migrations needed (P6 migration 6ebfe2737531 already applied).

Order

P6-2 and P9-1/P9-2 and P10-1/P10-2 can all run in parallel (different files). P9-3 (cad.py) can run alongside any of the above.

Risks / Open Questions

  • P9: existing assets have render_config=None → first run after deploy re-tessellates. Acceptable.
  • P10-2: rejectOrder API function exists in frontend/src/api/orders.ts — verify import before writing.