Hartmut
7e47e4aca7
feat(C1+C2): workflow system — WorkflowDefinition + Celery Canvas builder
...
Migrations 037 (workflow tables + 3 seed definitions) + 038 (output_types.workflow_definition_id).
WorkflowDefinition/Run/NodeResult SQLAlchemy models in domains/rendering/models.py.
workflow_builder.py: dispatch_workflow() with Celery Canvas for still/turntable/multi_angle.
workflow_router.py: CRUD endpoints at /api/workflows (admin/PM guards).
dispatch_service.py: dispatch_render_with_workflow() prefers workflow path when
OutputType.workflow_definition_id is set, falls back to legacy dispatch otherwise.
main.py: registers workflows_router.
models/__init__.py: re-exports WorkflowDefinition, WorkflowRun, WorkflowNodeResult.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 17:07:21 +01:00
Hartmut
217555025f
feat(C3): add React Flow workflow editor
...
frontend/src/pages/WorkflowEditor.tsx: full React Flow editor with
custom nodes (Input/Convert/Render/FFmpeg/Output), config sidepanel,
node palette with drag-drop, new workflow dialog.
frontend/src/api/workflows.ts: workflow CRUD API client.
@xyflow/react added to package.json dependencies.
Route /workflows + sidebar link for admin+pm.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 17:06:10 +01:00
Hartmut
5da90b5434
feat(B3): wire X-Tenant-ID header interceptor in axios client
...
Reads schaeffler_tenant_id from localStorage and injects it as
X-Tenant-ID header for all API requests (admin cross-tenant view).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 16:31:04 +01:00
Hartmut
251dd703ed
feat(B2): add tenant model + migrations 035/036 + RLS policies
...
Migration 035: tenants table with 'Schaeffler' default seed.
Migration 036: tenant_id FK on all tables, RLS policies, backfill.
New domains/tenants/ with CRUD router (admin only).
All domain models extended with tenant_id FK.
core/database.py: get_db_for_tenant with RLS context setter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 16:30:41 +01:00
Hartmut
b87df4a3e5
refactor(B1): migrate to domain-driven project structure
...
Move all models/schemas/services/routers into app/domains/.
Keep backward-compat shims in old locations for imports.
Preserves domains/rendering/tasks.py from Phase A.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 16:24:11 +01:00
Hartmut
82bf46725b
feat(B3): add tenant management UI (CRUD + tenant selector)
...
- frontend/src/api/tenants.ts: Tenant CRUD API client (getTenants, getTenant, createTenant, updateTenant, deleteTenant)
- frontend/src/pages/Tenants.tsx: Admin page with table, create/edit modals, delete confirm, and cross-tenant selector persisted in localStorage
- App.tsx: /tenants route (AdminRoute-guarded)
- Layout.tsx: Tenants sidebar link (admin-only, Building2 icon)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 16:13:26 +01:00
Hartmut
995339959e
docs: Phase A abgeschlossen, Learnings und PLAN.md aktualisiert
...
- PLAN.md: Phase A alle Tasks als ✅ markiert, Status IN UMSETZUNG
- LEARNINGS.md: 2 neue Learnings
- .gitignore 'core' Regel trifft Verzeichnisse (Root-relative Fix)
- Blender HTTP-Service vs. direkter Subprocess (render-worker Pattern)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 15:52:35 +01:00
Hartmut
5764118b8e
feat(A5): add app_config table + typed config service
...
- Migration 034: creates app_config table with JSONB columns (render, storage,
worker, notifications, billing); migrates existing system_settings values
- backend/app/core/config_service.py:
- Typed Pydantic models: RenderConfig, WorkerConfig, StorageConfig, etc.
- AppConfig aggregate model
- get_app_config(db) async + get_app_config_sync() for Celery tasks
- update_render_config() / update_worker_config() for partial updates
- system_settings table preserved for backward compat during Phase B migration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 15:51:56 +01:00
Hartmut
c728358fb6
feat(A4): add MinIO service + storage abstraction (core/storage.py)
...
- Add MinIO service to docker-compose.yml (port 9000 API, 9001 console)
- Add minio-data volume for persistent object storage
- Create backend/app/core/storage.py: MinIOStorage + LocalStorage abstraction
- MinIOStorage: boto3-based, auto-creates bucket, upload/download/exists/delete/presign
- LocalStorage: fallback for dev (UPLOAD_DIR filesystem, backward compat)
- get_storage() singleton: auto-selects based on MINIO_URL env var
- Add MINIO_URL/USER/PASSWORD/BUCKET env vars to all service definitions
- backend/pyproject.toml: docker>=6.1.0 → boto3>=1.34.0
- Add docker-compose.worker.yml: external render-worker for remote machines
- Fix .gitignore: 'core' rule was too broad, now only matches root /core dump
- Update .env.example: MinIO connection vars documented
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 15:51:06 +01:00
Hartmut
c8ecc29d40
refactor(A3): remove threejs-renderer service, add migration 033
...
- Migration 033: reset threejs thumbnail_renderer setting → blender,
remove obsolete threejs_render_size system_setting
- step_processor.py threejs code paths already fall through to Pillow
(committed in A2); Three.js browser viewer (ThreeDViewer.tsx) remains
- threejs-renderer/ directory kept for reference but no longer built
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 15:49:16 +01:00
Hartmut
9d1a820295
refactor(A2): replace blender-renderer HTTP service with render-worker Celery container
...
- Create render-worker/ with Dockerfile (Ubuntu + cadquery + Blender via host mount)
- Add render-worker/check_version.py: verifies Blender >= 5.0.1 at startup, Exit 1 on failure
- Add render-worker/scripts/: blender_render.py, still_render.py, turntable_render.py
- Create backend/app/services/render_blender.py: direct subprocess rendering
- convert_step_to_stl() and export_per_part_stls() using cadquery
- render_still(): STEP → STL → PNG via Blender subprocess
- is_blender_available(): detects BLENDER_BIN env for render-worker context
- Create backend/app/domains/rendering/tasks.py: render_still_task + render_turntable_task
- Update step_processor.py: use subprocess path when BLENDER_BIN env is set (render-worker)
- Update step_tasks.py: generate_stl_cache uses direct cadquery instead of HTTP
- Remove blender-renderer and threejs-renderer from docker-compose.yml
- Replace worker-thumbnail with render-worker (Ubuntu + cadquery + Blender mount)
- Remove Docker SDK from backend Dockerfile (was only for flamenco scaling)
- Update .env.example: BLENDER_VERSION=5.0.1 documented
- Update celery_app.py: include domains.rendering.tasks in autodiscover
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 15:48:46 +01:00
Hartmut
1d6864fb64
refactor(A1): remove Flamenco, simplify render pipeline to Celery-only
...
- Remove flamenco-manager and flamenco-worker from docker-compose.yml
- Delete flamenco_client.py, flamenco_tasks.py, docker_scaler.py
- Simplify render_dispatcher.py to Celery-only (removes ~300 lines)
- Remove Flamenco beat schedule from celery_app.py
- Clean admin.py: remove flamenco settings, endpoints, threejs validation
- Clean orders.py cancel-render: Celery revoke only
- Clean worker.py: remove flamenco_job_id from activity response
- Migration 032: cancel lingering flamenco jobs, remove flamenco settings
- PLAN.md: mark all decisions confirmed, status IN UMSETZUNG
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-06 15:38:37 +01:00
Hartmut
552922eb8a
chore: remove build artifacts from tracking, extend .gitignore
2026-03-05 22:13:21 +01:00
Hartmut
bce762a783
feat: initial commit
2026-03-05 22:12:38 +01:00