Merges PLAN.md (Phases A-F), PLAN_REFACTOR.md (Phases 1-8), plan.md (GMSH), docs/rfcs/0001, and visual-audit-report findings into a single prioritized roadmap. 10 priorities with dependency graph and 'what to do next' decision options. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
11 KiB
Schaeffler Automat — Master Roadmap
Consolidated: 2026-03-11 Branch:
refactor/v2Sources merged:PLAN.md(Phases A–F),PLAN_REFACTOR.md(Phases 1–8),plan.md(GMSH),docs/rfcs/0001,visual-audit-report.md
✅ What Is Done
| Area | Detail |
|---|---|
| Phase A | Flamenco removed, blender-renderer → render-worker Celery container, threejs-renderer removed, MinIO added |
| Phase B | Domain-driven project structure, Tenant model + RLS migrations 035/036, Tenant management UI |
| Phase C | WorkflowDefinition model, standard workflows seeded, React Flow Workflow Editor |
| Phase D | OCC mesh attributes extraction, Blender integration |
| Phase E | MediaAsset catalog (model + API + frontend) |
| Sharp Edges V02 | GCPnts curve sampling → 17,129 segment pairs in GLB extras → Blender KD-tree marks sharp+seam |
| Tessellation presets | Draft/Standard/Fine preset buttons in Admin UI, default deflections updated |
| Media cache-bust | ?v={file_size_bytes} in download URLs + Cache-Control: no-cache headers |
| GPU activation order | Fix: _activate_gpu() called before AND after open_mainfile to survive engine reset |
| Material system | Aliases-first lookup, get_material_library_path() via AssetLibrary |
🗺 Open Work — Prioritized
Priority 1 — Tessellation Quality (Blocking visual quality)
Goal: Eliminate fan triangles and faceting on cylindrical surfaces (rings, bearings).
Plan: plan.md (6 tasks, GMSH Frontal-Delaunay as BRepMesh replacement)
| Task | File | What |
|---|---|---|
| T1 | render-worker/Dockerfile |
pip install gmsh>=4.15.0 |
| T2 | export_step_to_gltf.py |
--tessellation_engine occ|gmsh CLI arg |
| T3 | export_step_to_gltf.py |
_tessellate_with_gmsh(): BREP → GMSH → Poly_Triangulation write-back |
| T4 | admin.py |
tessellation_engine setting in SETTINGS_DEFAULTS + SettingsOut |
| T5 | export_glb.py |
Read setting, pass --tessellation_engine to CLI |
| T6 | Admin.tsx |
Dropdown: OCC vs. GMSH with description |
Risk: GMSH Surface-Tag ↔ OCC Face mapping must be verified experimentally.
Status: Not started. /implement to begin.
Priority 2 — Dead Code Deletion (Quick wins, no risk)
Goal: Remove code that is provably dead and confuses future readers.
| Item | Location | Why Dead |
|---|---|---|
| Pillow overlay block | blender_render.py lines 798–851 |
transparent_bg=True always, else: branch never runs |
| STL workflow | admin.py, cad.py, multiple tasks |
Pipeline is GLB-only; stl_quality, VALID_STL_QUALITIES, stl_size_bytes all orphaned |
render_order_line_task in step_tasks |
step_tasks.py lines 705–1050 |
Duplicates rendering/tasks.render_order_line_still_task |
blender-renderer/ directory |
repo root | Removed from docker-compose.yml already |
threejs-renderer/ directory |
repo root | Migration 033 removed it from services |
flamenco/ directory |
repo root | Migration 032 removed Flamenco |
renderproblems_tmp/ directory |
repo root | Temp debugging screenshots, not code |
Estimated effort per agent: 1 session Can run in parallel with Priority 3.
Priority 3 — Celery Task Decomposition (Maintainability, parallel-safe)
Goal: Split step_tasks.py (1,170 lines, 8+ pipeline steps) into focused modules.
Target structure:
backend/app/tasks/
├── step_tasks.py → keep only: process_step_file (thin dispatch)
├── pipeline/
│ ├── extract.py → extract_cad_metadata (OCC parsing, 0.1s)
│ ├── thumbnail.py → render_step_thumbnail (Blender call)
│ ├── stills.py → render_order_line_still_task (Cycles still renders)
│ └── turntable.py → render_order_line_turntable_task
Also: split render-worker/scripts/blender_render.py (853 lines) into sub-modules:
render-worker/scripts/
├── blender_render.py → entry point only (~80 lines)
├── _blender_gpu.py → GPU probe + activation
├── _blender_import.py → GLB import, rotation, smooth shading
├── _blender_materials.py → material library application + fallback
├── _blender_camera.py → auto camera from bbox, clip planes
└── _blender_scene.py → scene setup (Mode A vs Mode B)
Estimated effort: 2 sessions Depends on: Priority 2 (delete duplicate task first)
Priority 4 — Render Job Tracking (Correctness bug)
Goal: Fix the broken render job cancellation (synthetic render-{line_id} ID never matches real Celery task ID → revoke() is a no-op).
What to build:
RenderJobDocumentPydantic schema stored inorder_lines.render_job_doc(JSONB)- Fields:
celery_task_id,stateFSM,steps[]with timing,gpu_info - Migration:
alembic revision— addrender_job_doc JSONBtoorder_lines - Update render tasks to write real
self.request.idinto the document - Fix
orders.pycancel endpoint to readcelery_task_idfrom the document
Files:
- New:
backend/app/domains/rendering/job_document.py - New migration
06x_render_job_document.py - Modified:
render_order_line.py,render_thumbnail.py,orders.py
Estimated effort: 1 session Depends on: Priority 3 (need clean task structure first)
Priority 5 — Structured Logging (Observability)
Goal: Replace inconsistent logger.info(f"...") / emit() / log_task_event() mix with a PipelineLogger that writes to Python logging + Redis SSE + DB.
What to build:
backend/app/core/pipeline_logger.py—PipelineLoggerclassstep_start(step, context)→[STEP_NAME] starting — contextstep_done(step, duration_s, result)→[STEP_NAME] done in 0.34sstep_error(step, error, exc)→[STEP_NAME] ERROR: ...
- Optional new table:
pipeline_events(task_id, step_name, level, message, duration_s, context JSONB) - Migrate all task files to use PipelineLogger
Estimated effort: 1-2 sessions Can start immediately, but has broad blast radius (touches all task files).
Priority 6 — Tenant Isolation Completion (Security/correctness)
Goal: Make RLS actually work. Currently build_tenant_db_dep() yields db without calling set_tenant_context(), so all tenant isolation is silent no-op.
What to build:
TenantContextMiddlewareinbackend/app/core/middleware.py- Extracts
tenant_idfrom JWT, stores inrequest.state - After DB session acquired:
SET LOCAL app.current_tenant_id = '...'
- Extracts
- Celery tasks: add
set_tenant_context(db, tenant_id)call at start of each task (Celery bypasses HTTP middleware) - Role hierarchy migration:
admin→global_admin, addtenant_admin
Files:
- New:
backend/app/core/middleware.py - Migration:
06x_role_hierarchy.py - Modified:
backend/app/main.py(register middleware),utils/auth.py, all routers
Estimated effort: 2 sessions Depends on: Stable auth layer (Priority 3 dead code removal first)
Priority 7 — UV Unwrap Workflow (New feature, user-requested)
Goal: Produce UV-unwrapped geometry GLBs with clean seams for downstream texture authoring. Depends on: Priority 1 (GMSH tessellation must produce conforming seams first).
What to build:
- New Blender script
_blender_uvunwrap.pycalled fromexport_gltf.pyafter sharp edge marking - UV unwrap via
bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=0.001) - Seams are already set by
_apply_sharp_edges_from_occ()(edge.seam=True) - UV coordinates embedded in the production GLB
- Admin toggle:
uv_unwrap_enabledin system_settings
Estimated effort: 1 session Depends on: Priority 1 (GMSH) for clean seams
Priority 8 — UI/UX Polish (from visual-audit-report.md)
Top actionable items from the audit:
| Item | Where | Fix |
|---|---|---|
| Tooltip system | All settings pages | Add title or tooltip component to every input |
| Empty state messages | MediaBrowser, ProductLibrary | "No assets yet — upload a STEP file" |
| Notification batching | NotificationCenter | Group per-render noise into job summaries |
| Mobile navigation | Layout.tsx | Hamburger menu for viewport < 768px |
| Kanban rejection flow | OrderDetail | Drag-to-reject with reason field |
Estimated effort: 2 sessions Independent of all backend priorities.
Priority 9 — Phase F: Hash-based Conversion Caching (Performance)
Goal: Skip re-tessellation if STEP file hash hasn't changed. Cache geometry GLB by sha256(step_file).
What to build:
cad_files.step_hashcolumn (SHA256, nullable)- Before GLB generation: compute hash, check if cached GLB exists for same hash
- If hit: copy cached GLB, skip OCC+GMSH, skip Blender
- Migration:
06x_step_hash_column.py
Estimated effort: 1 session Depends on: Priority 1 (GMSH) stable first
Priority 10 — USD Workflow RFC (Strategic, long-term)
Document: docs/rfcs/0001-step-to-usd-workflow.md
Status: Proposed only — not planned for implementation yet.
Summary: Replace dual-GLB pipeline (geometry GLB → production GLB) with a single USD canonical scene. Three.js has no USD loader, so this requires either switching viewers or waiting for Three.js USD support.
Decision needed: Is the viewer constraint acceptable? Deferred until Priority 1–4 are complete.
Dependency Graph
Priority 1 (GMSH)
└── Priority 7 (UV Unwrap)
└── Priority 9 (Hash Cache)
Priority 2 (Dead Code)
└── Priority 3 (Task Decomposition)
└── Priority 4 (Render Job Tracking)
└── Priority 6 (Tenant Isolation)
Priority 5 (Logging) — independent, can start anytime
Priority 8 (UI/UX) — independent, can start anytime
Priority 10 (USD) — deferred
What To Do Next
Option A — Fix visual quality first:
→ /implement on plan.md (Priority 1: GMSH tessellation)
Option B — Clean up dead code first (low risk, fast wins): → Start Priority 2 dead code deletion, then Priority 3 task decomposition
Option C — Parallel sprint (2 agents): → Agent 1: Priority 1 (GMSH) in worktree → Agent 2: Priority 2+3 (dead code + task split) in separate worktree
Option D — UI/UX sprint: → Priority 8 audit items, completely independent of backend
Archive
Old planning files are kept for reference but superseded by this document:
PLAN.md— original Phase A–F plan (Phases A–E complete, Phase F = Priority 9 here)PLAN_REFACTOR.md— 1,173-line architectural plan (Phases 1–8 mapped to Priorities 2–8 above)plan.md— active GMSH implementation plan (Priority 1)docs/rfcs/0001-step-to-usd-workflow.md— USD RFC (Priority 10)review-report.md— latest code review resultsvisual-audit-report.md— UX audit results