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>
This commit is contained in:
@@ -3,7 +3,16 @@ import pytest
|
||||
from app.core.process_steps import StepName
|
||||
from app.domains.rendering.models import OutputType, WorkflowDefinition, WorkflowRun
|
||||
from app.domains.rendering.workflow_config_utils import build_preset_workflow_config
|
||||
from app.domains.rendering.workflow_graph_runtime import _STILL_TASK_KEYS, _TURNTABLE_TASK_KEYS
|
||||
from app.domains.rendering.workflow_graph_runtime import (
|
||||
_AUTO_POPULATE_RUNTIME_KEYS,
|
||||
_GLB_BBOX_RUNTIME_KEYS,
|
||||
_MATERIAL_MAP_RUNTIME_KEYS,
|
||||
_NOTIFY_RUNTIME_KEYS,
|
||||
_OUTPUT_SAVE_RUNTIME_KEYS,
|
||||
_RESOLVE_TEMPLATE_RUNTIME_KEYS,
|
||||
_STILL_TASK_KEYS,
|
||||
_TURNTABLE_TASK_KEYS,
|
||||
)
|
||||
from app.domains.rendering.workflow_node_registry import (
|
||||
get_node_definition,
|
||||
list_node_definitions,
|
||||
@@ -121,6 +130,29 @@ def test_graph_render_node_fields_are_supported_by_runtime_dispatch():
|
||||
assert turntable_runtime_fields <= _TURNTABLE_TASK_KEYS
|
||||
|
||||
|
||||
def test_bridge_node_fields_match_runtime_dispatch_contracts():
|
||||
resolve_template = get_node_definition(StepName.RESOLVE_TEMPLATE)
|
||||
material_map = get_node_definition(StepName.MATERIAL_MAP_RESOLVE)
|
||||
auto_populate = get_node_definition(StepName.AUTO_POPULATE_MATERIALS)
|
||||
glb_bbox = get_node_definition(StepName.GLB_BBOX)
|
||||
output_save = get_node_definition(StepName.OUTPUT_SAVE)
|
||||
notify = get_node_definition(StepName.NOTIFY)
|
||||
|
||||
assert resolve_template is not None
|
||||
assert material_map is not None
|
||||
assert auto_populate is not None
|
||||
assert glb_bbox is not None
|
||||
assert output_save is not None
|
||||
assert notify is not None
|
||||
|
||||
assert {field.key for field in resolve_template.fields} == _RESOLVE_TEMPLATE_RUNTIME_KEYS
|
||||
assert {field.key for field in material_map.fields} == _MATERIAL_MAP_RUNTIME_KEYS
|
||||
assert {field.key for field in auto_populate.fields} == _AUTO_POPULATE_RUNTIME_KEYS
|
||||
assert {field.key for field in glb_bbox.fields} == _GLB_BBOX_RUNTIME_KEYS
|
||||
assert {field.key for field in output_save.fields} == _OUTPUT_SAVE_RUNTIME_KEYS
|
||||
assert {field.key for field in notify.fields} == _NOTIFY_RUNTIME_KEYS
|
||||
|
||||
|
||||
def test_order_line_setup_and_template_contracts_expose_runtime_outputs():
|
||||
setup = get_node_definition(StepName.ORDER_LINE_SETUP)
|
||||
template = get_node_definition(StepName.RESOLVE_TEMPLATE)
|
||||
@@ -178,7 +210,13 @@ def test_order_line_setup_and_template_contracts_expose_runtime_outputs():
|
||||
"include_populated_products",
|
||||
}
|
||||
assert output.input_contract["requires"] == ["order_line_context"]
|
||||
assert output.input_contract["requires_any"] == ["rendered_image", "rendered_frames", "rendered_video"]
|
||||
assert output.input_contract["requires_any"] == [
|
||||
"rendered_image",
|
||||
"rendered_frames",
|
||||
"rendered_video",
|
||||
"blend_asset",
|
||||
]
|
||||
assert "blend_asset" in output.artifact_roles_consumed
|
||||
assert set(output.output_contract["provides"]) >= {"media_asset", "workflow_result"}
|
||||
assert {field.key for field in output.fields} == {
|
||||
"expected_artifact_role",
|
||||
@@ -193,6 +231,7 @@ def test_order_line_setup_and_template_contracts_expose_runtime_outputs():
|
||||
"rendered_frames",
|
||||
"rendered_video",
|
||||
"workflow_result",
|
||||
"blend_asset",
|
||||
]
|
||||
assert {field.key for field in notify.fields} == {"channel", "require_armed_render"}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user