Commit Graph
249 Commits
Author SHA1 Message Date
HartmutandClaude Sonnet 4.6 34ed511d9d fix: remove stale cinematic legacy-only guard in dispatch_service
The guard forced all cinematic output types to legacy dispatch because
BLENDER_CINEMATIC did not exist in the workflow graph. M1 added that node,
so the guard is now stale — it was preventing cinematic output types from
ever using graph mode even after an admin sets workflow_rollout_mode=graph.

The normal gate path handles it correctly: workflow_rollout_mode=legacy_only
keeps it on legacy, and find_unsupported_graph_nodes preflight catches any
workflow that doesn't actually contain a BLENDER_CINEMATIC node.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 16:33:40 +02:00
HartmutandClaude Sonnet 4.6 23605783bd feat: multi-GPU queue routing for legacy still renders (M2)
dispatch_order_line_render now routes still renders (non-animation,
non-cinematic) to a secondary GPU queue when MULTI_GPU_LIGHT_RENDER_QUEUE
is configured and that queue has active Celery workers.

- config.py: multi_gpu_light_render_queue setting (default "" = disabled)
- render_order_line.py: implement the routing stub — load output_type via
  selectinload, check render_settings.animation + .cinematic flags, call
  _inspect_active_worker_queues (reused from workflow_graph_runtime) with
  0.5s timeout to check if the light queue is live

No behaviour change when MULTI_GPU_LIGHT_RENDER_QUEUE is not set.
Enable by setting it to "asset_pipeline_light" and adding a
render-worker-light service with concurrency=1 to docker-compose.

docs: learnings erfasst — multi-GPU queue routing M2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 15:12:07 +02:00
HartmutandClaude Sonnet 4.6 3401b06b19 feat: BLENDER_CINEMATIC workflow graph node (M1)
Add StepName.BLENDER_CINEMATIC and full graph runtime support so cinematic
output types can be promoted from legacy_only to graph/shadow rollout mode.

- process_steps.py: add BLENDER_CINEMATIC = "blender_cinematic" enum value
- workflow_executor.py: map to render_cinematic_task in STEP_TASK_MAP
- workflow_node_registry.py: node definition with render/scene/camera fields
  (no animation params — cinematic is fixed at 250 frames @ 25fps)
- workflow_graph_runtime.py: _ORDER_LINE_RENDER_STEPS, _CINEMATIC_TASK_KEYS,
  shadow queue routing, predict_render_output_artifact (mp4),
  _build_task_kwargs, _artifact_kind_override_for_step
- tasks.py: _normalize_cinematic_params + render_cinematic_task Celery task
  (calls render_cinematic_to_file, publishes as turntable asset type since mp4)

No DB migration needed: admins can now manually set cinematic output types
to graph rollout mode via the admin panel and assign a workflow definition.

docs: learnings erfasst — BLENDER_CINEMATIC workflow graph node M1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 15:09:47 +02:00
HartmutandClaude Sonnet 4.6 10a8bbd977 fix: low audit items — email channel, debug cleanup, roadmap sync, bare except logging
L18: remove comingSoon from email notification channel (SMTP backend already exists).
L19: remove console.debug useEffect from InlineCadViewer.tsx.
L20: sync ROADMAP.md priority status sections (P1/P2/P3/P8) with status snapshot — all Done.
L22: replace 8 bare except blocks in step_processor.py with logger.debug/warning
     so geometry calculation failures are visible in logs instead of silently discarded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 14:06:31 +02:00
HartmutandClaude Sonnet 4.6 507858cf31 fix: medium audit items — CORS config, invoice description, path helper, node failure, order prefix
M3: cors_origins setting in config.py (env CORS_ORIGINS); main.py reads from settings.
M4: add build_order_line_step_render_dir() to render_paths.py; tasks.py drops placeholder.mp4 trick.
M5: unknown workflow graph nodes now fail the run (status="failed" + logger.error) instead of silently skipping.
M6: invoice line description is now "{product} — {output_type}" instead of bare UUID; eager-loads relations.
M7: order_number_prefix setting in config.py (env ORDER_NUMBER_PREFIX, default "SA").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 13:57:04 +02:00
HartmutandClaude Sonnet 4.6 3c2d0816e5 fix: JWT secret startup guard and order number advisory lock
H1: model_validator in Settings raises ValueError when jwt_secret_key is
    "changeme" and the process is running inside a container — fast-fail
    prevents insecure deployments; local dev outside Docker is unaffected.

H7: generate_order_number now acquires pg_advisory_xact_lock before SELECT MAX,
    matching the same pattern used in generate_invoice_number (billing/service.py).
    Concurrent order creation can no longer race to produce duplicate numbers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 13:45:39 +02:00
HartmutandClaude Sonnet 4.6 df304dc021 fix: configurable internal API URL and upload size enforcement
H4: add internal_api_base_url setting to config.py (default http://localhost:8888,
    env-overridable via INTERNAL_API_BASE_URL); replace all 5 hardcoded base_url
    strings in chat_service.py.

H6: add post-read size check in both Excel and STEP upload handlers;
    raises HTTP 413 when content exceeds settings.max_upload_size_mb.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 13:43:04 +02:00
HartmutandClaude Sonnet 4.6 b69190dd86 fix: billing tenant isolation, invoice status validation, SMTP password masking
H2: list_invoices now passes tenant_id (from current_user) to get_invoices;
    get_invoices applies WHERE tenant_id filter for non-global-admin users;
    get_invoice_endpoint returns 404 when tenant mismatch for non-admins.

H3: InvoiceStatusUpdate.status changed to Literal["draft","sent","paid","cancelled"]
    for schema-level validation; guard also added in update_invoice_status service.

H5: _settings_to_out masks smtp_password as "***" when set, "" when empty;
    update_settings skips writing when value is the "***" sentinel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 13:40:59 +02:00
HartmutandClaude Sonnet 4.6 a11d2fb1e7 refactor: extract turntable branch and exhausted-retry handler from render_order_line_task
_render_turntable: Option B — resolved objects as params (render_invocation, step_path,
output_path, template, emit, pl). Session and PipelineLogger stay in the caller so
no second DB connection is opened and log steps roll up to the main task.

_handle_render_task_exhausted: extracted 68-line mark-as-failed block; retry/raise
logic with Celery self.retry stays in render_order_line_task since it needs the
bound-task context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 13:11:27 +02:00
Hartmut 1c4ca6998f docs: learnings erfasst — workflow Phase 5/6 fixes 2026-07-22 11:39:12 +02:00
HartmutandClaude Sonnet 4.6 e8b4580608 fix: workflow editor Phase 5/6 sign-off — save guard, conflict detection, dispatch pre-check
- Save button disabled for non-admins (canSave prop threaded through
  WorkflowEditor → WorkflowCanvas → WorkflowCanvasToolbar); tooltip
  explains why when hovered
- Optimistic concurrency: migration 072 adds updated_at to
  workflow_definitions; PUT /workflows/:id returns 409 when client sends
  a stale updated_at; frontend shows a specific reload-prompt toast
- _legacy_dispatch now routes through dispatch_order_line_render instead
  of calling render_order_line_task directly, so cancelled/rejected
  order lines are skipped before queueing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 11:39:02 +02:00
HartmutandClaude Sonnet 4.6 53b19f2ba1 fix: workflow blueprints freely editable after creation (preserve_user_graph)
canonicalize_workflow_config was silently rebuilding any workflow with
ui.blueprint or ui.preset == still_graph from the canonical template on
every save, preflight, and read — making blueprint-based workflows
effectively read-only.

Add preserve_user_graph=True flag that skips the rebuild blocks. Only
create_workflow still uses preserve_user_graph=False so blueprints are
correctly expanded at creation time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 11:17:32 +02:00
Hartmut 4ea6c4ee9c docs: learnings erfasst — editierbares branding, public settings endpoint 2026-07-22 11:10:22 +02:00
HartmutandClaude Sonnet 4.6 4946cc300a feat: editable branding — app name and subtitle configurable in Admin Settings
Adds app_name and app_subtitle as system settings with a dedicated
Branding tab in the Admin panel. Both values are served via a public
GET /api/admin/branding endpoint (no auth) so the login page can also
show the configured name before the user signs in.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 11:02:38 +02:00
HartmutandClaude Sonnet 4.6 c262b31bc5 chore: cleanup #6 #8 #9 — delete debug dir, rename glbUrl prop, sync docs
- delete renderproblems_tmp/ (7 debug images + USD test files, orphaned)
- rename ThreeDViewer prop geometryGltfUrl → glbUrl; update CadPreview.tsx
  caller (productionGltfUrl distinction was never needed, only one GLB type)
- plan.md: mark all 4 cinematic tasks [x] (all implemented + seeded in 070)
- 0001-step-to-usd: mark Phase 4 ThreeDViewer acceptance gates [x] (P4 done)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 10:22:08 +02:00
HartmutandClaude Sonnet 4.6 c87857f836 feat: turntable + blend export smoke test coverage
- build_graph_turntable_config: accept render_params kwarg so smoke can
  use low settings (512x512, 24 frames) without touching golden case defaults
- add smoke naming + template functions for turntable and blend
- add ensure_workflow_turntable_smoke_resources() — provisions output type
  (mp4/turntable_video) + workflow graph, binds to
  Blender_Studio_Schadowcatcher_Anim template
- add ensure_workflow_blend_smoke_resources() — provisions output type
  (blend/blend_asset) + workflow graph, binds to BlenderStudio template
- add test_workflow_turntable_smoke() — preflight + dispatch + run tracking
- add test_workflow_blend_smoke() — preflight + dispatch + blend node check
- 6 new harness unit tests (17 total, all passing), using real asset:
  cad_file_id 8dd73335 (81113-l_cut.stp, has USD master + GLB)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 10:17:47 +02:00
HartmutandClaude Sonnet 4.6 44b52d05cc fix: cinematic output type guard + legacy_only migration
- Migration 070: seeds 'Cinematic Highlight' output type (legacy_only, no
  workflow link) for fresh installs
- Migration 071: patches existing cinematic output types — clears
  workflow_definition_id and forces legacy_only rollout mode. The row
  existed since 2026-03 with shadow mode + a linked workflow def;
  no BLENDER_CINEMATIC graph node exists so shadow execution would fail.
- API guard in output_types POST + PATCH: cinematic output types cannot
  receive a workflow_definition_id (HTTP 400)
- Defense-in-depth in dispatch_service: early legacy exit if
  render_settings.cinematic is true, regardless of rollout mode
- docs: learning erfasst — cinematic rollout mode footgun

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 10:04:07 +02:00
HartmutandClaude Sonnet 4.6 971074fedd docs: learnings erfasst — cinematic render pipeline fixes 2026-07-21
Drei Bugs aus Cinematic-Render-Session dokumentiert:
- is_cinematic immer False wegen Invocation-Override-Filter
- usd_path.exists() auf str (fehlender str→Path-Cast in turntable/cinematic)
- NameError stdout/stderr in cinematic error path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 07:12:30 +02:00
HartmutandClaude Sonnet 4.6 7179023458 chore: extend project Claude permissions for docker, curl and hartomat MCP tools
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 22:34:21 +02:00
HartmutandClaude Sonnet 4.6 bb2b0f51b5 fix: cinematic render is_cinematic detection and usd_path str/Path handling
Three bugs causing all cinematic renders to silently fall through to the
turntable path and then immediately crash:

1. is_cinematic read from filtered invocation-override dict — 'cinematic' key
   is not in the allowed override key list for turntable_video, so it gets
   stripped. Fixed: read directly from output_type.render_settings.

2. render_turntable_to_file and render_cinematic_to_file both call
   usd_path.exists() but receive a str from the caller. Added the same
   isinstance str→Path conversion that render_still_to_file already had.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 22:32:16 +02:00
HartmutandClaude Sonnet 4.6 6459b9e62d docs: learnings erfasst - cinematic render NameError, cancel-race, legacy-only pfad
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 19:10:22 +02:00
HartmutandClaude Sonnet 4.6 d2e4934cca feat: workflow graph system — blocks 1-20 complete checkpoint
Full graph-based workflow execution engine with:
- WorkflowGraphRuntime with two-phase dispatch (collect → fire Celery tasks)
- Node registry with contract validation, socket types, execution kinds
- WorkflowRuntimeServices: preflight, context resolution, shadow-mode A/B
- WorkflowRouter: CRUD + dispatch/preflight/run-history API endpoints
- OutputTypeContracts: workflow binding, rollout-mode resolution
- Admin router: output-type workflow binding endpoints
- Frontend: complete workflow editor with drag-drop canvas, node inspector,
  module bundles, reference bundles, preflight panel, validation banner,
  authoring guidance, blueprint templates, shadow/rollout gate UI
- Tests: comprehensive coverage for all workflow modules
- Docs: NODE_CONTRACT_AUDIT and VALIDATION_ERROR_INVENTORY

All 20 blocks from NEXT_20_BLOCK_BATCH_PLAN completed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 19:09:54 +02:00
HartmutandClaude Sonnet 4.6 c51dd8cd67 fix: guard persist_order_line_output against cancelled lines
Completed renders no longer overwrite a cancelled status — a Blender job
that finishes after a cancel is issued is now silently dropped instead of
flipping the line back to completed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 19:09:34 +02:00
HartmutandClaude Sonnet 4.6 84f40647b0 fix: resolve NameError masking cinematic render errors and fix frame count
- `render_cinematic_to_file` referenced undefined `stdout`/`stderr` in the
  Blender error path; replaced with `log_lines`/`stderr_lines` so the real
  Blender error is actually stored in render_log instead of a Python NameError
- Progress callback hardcoded 480 frames; now uses the `frame_count` variable
- Updated docstring to reflect actual 250 frames @ 25fps (not 480 @ 24fps)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 19:09:28 +02:00
Hartmut 715cef7971 Document block 20 workflow checkpoint 2026-04-18 13:17:07 +02:00
Hartmut 98455ee579 Close workflow smoke template drift 2026-04-18 13:16:54 +02:00
Hartmut 9f1ccec8f0 docs: optimize readme landing layout for gitea 2026-04-12 14:44:13 +02:00
Hartmut 04a08a8bdf docs: refine project presentation and refresh dark screenshots 2026-04-12 12:02:29 +02:00
Hartmut 10fcb2817b docs: add project overview with quickstart and screenshots 2026-04-12 11:56:41 +02:00
Hartmut 3e810c74a3 chore: snapshot workflow migration progress 2026-04-12 11:49:04 +02:00
Hartmut 0cd02513d5 fix: normalize host runtime service endpoints 2026-04-09 19:47:17 +02:00
Hartmut e5c8ac7592 fix: align workflow material resolution with scene manifest 2026-04-09 19:41:13 +02:00
Hartmut d685031c1a fix: stabilize shadow workflow smoke comparison 2026-04-08 22:14:33 +02:00
Hartmut 375339eb74 feat: add canonical still workflow smoke harness 2026-04-08 22:10:01 +02:00
Hartmut dde04fcaa5 feat: unify order-line render invocation paths 2026-04-08 21:57:37 +02:00
Hartmut 042f62fe55 feat: refactor workflow editor authoring surfaces 2026-04-08 21:44:08 +02:00
Hartmut fe46dabfc5 feat: add workflow rollout gate signals 2026-04-08 21:44:02 +02:00
Hartmut 8c9648d5dc feat: make output types workflow-first contracts 2026-04-08 21:43:55 +02:00
Hartmut bd18cccb5e feat: harden workflow graph contracts 2026-04-08 21:32:14 +02:00
Hartmut 22981af1d2 docs: add workflow worker orchestration 2026-04-08 21:14:34 +02:00
Hartmut 7e100ed334 feat: expose graph still workflow in editor 2026-04-08 11:16:47 +02:00
Hartmut ffcaef4659 feat: add workflow output comparison tooling 2026-04-07 11:45:28 +02:00
Hartmut f43f1e7420 feat: add duplicate-safe workflow shadow dispatch 2026-04-07 11:35:32 +02:00
Hartmut 26046fb2d6 feat: expose workflow execution modes in editor 2026-04-07 11:10:58 +02:00
Hartmut f9d4da52b9 feat: add graph workflow fallback and retry metadata 2026-04-07 10:56:45 +02:00
Hartmut c17b7d2e8f feat: execute workflow bridge nodes in graph runtime 2026-04-07 10:42:59 +02:00
Hartmut 6ad34ceed2 feat: add workflow run dispatch foundation 2026-04-07 10:11:46 +02:00
Hartmut ab1b220e79 test: close workflow phase 3 executor coverage 2026-04-07 10:00:38 +02:00
Hartmut 98b3eadcb2 feat: extract workflow notifications phase 3 2026-04-07 09:57:39 +02:00
Hartmut 160c198bb3 feat: extract workflow output save phase 3 2026-04-07 09:50:58 +02:00