chore: snapshot workflow migration progress

This commit is contained in:
2026-04-12 11:49:04 +02:00
parent 0cd02513d5
commit 3e810c74a3
163 changed files with 31774 additions and 2753 deletions
@@ -1,9 +1,16 @@
import type { StepCategory, WorkflowNodeDefinition, WorkflowNodeFamily } from '../../api/workflows'
export type WorkflowNodeFamilyFilter = 'all' | WorkflowNodeFamily
export type WorkflowGraphFamily = WorkflowNodeFamily | 'mixed'
export type WorkflowGraphFamily = Exclude<WorkflowNodeFamily, 'shared'> | 'mixed'
export type WorkflowNodeKindFilter = 'all' | 'legacy' | 'bridge' | 'graph'
export type WorkflowNodeLibraryGroup = 'legacy' | 'bridge' | 'graph'
export type WorkflowAuthoringStage =
| 'cad_intake'
| 'scene_prep'
| 'materials'
| 'render'
| 'publish'
| 'orchestration'
export const CATEGORY_LABELS: Record<StepCategory, string> = {
input: 'Input',
@@ -24,6 +31,7 @@ export const NODE_CATEGORY_ORDER: StepCategory[] = ['input', 'processing', 'rend
export const FAMILY_FILTER_LABELS: Record<WorkflowNodeFamilyFilter, string> = {
all: 'All Nodes',
cad_file: 'CAD Intake',
shared: 'Shared',
order_line: 'Order Rendering',
}
@@ -52,13 +60,51 @@ export const NODE_LIBRARY_GROUP_DESCRIPTIONS: Record<WorkflowNodeLibraryGroup, s
graph: 'Native graph runtime nodes for the non-legacy editor flow.',
}
export const AUTHORING_STAGE_ORDER: WorkflowAuthoringStage[] = [
'cad_intake',
'scene_prep',
'materials',
'render',
'publish',
'orchestration',
]
export const AUTHORING_STAGE_LABELS: Record<WorkflowAuthoringStage, string> = {
cad_intake: 'CAD Intake',
scene_prep: 'Scene Prep',
materials: 'Materials',
render: 'Render',
publish: 'Publish',
orchestration: 'Orchestration',
}
export const AUTHORING_STAGE_DESCRIPTIONS: Record<WorkflowAuthoringStage, string> = {
cad_intake: 'Import CAD sources, extract geometry, and prepare downstream preview assets.',
scene_prep: 'Resolve context, templates, geometry metadata, and upstream render state.',
materials: 'Map, normalize, or override materials before render execution.',
render: 'Generate stills, thumbnails, or other rendered artifacts.',
publish: 'Persist outputs and emit downstream completion signals.',
orchestration: 'Support glue, control flow, or utility nodes that do not belong to a single production stage.',
}
export const AUTHORING_STAGE_STYLES: Record<WorkflowAuthoringStage, string> = {
cad_intake: 'bg-sky-100 text-sky-700 dark:bg-sky-900/40 dark:text-sky-300',
scene_prep: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300',
materials: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300',
render: 'bg-rose-100 text-rose-700 dark:bg-rose-900/40 dark:text-rose-300',
publish: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300',
orchestration: 'bg-slate-100 text-slate-700 dark:bg-slate-900/40 dark:text-slate-300',
}
export const FAMILY_FILTER_DESCRIPTIONS: Record<WorkflowNodeFamily, string> = {
cad_file: 'Start with a CAD file context and produce previews, caches, or derived assets.',
shared: 'Reusable nodes that can be dropped into either CAD-intake or order-rendering workflows.',
order_line: 'Start with an order line context and run production rendering/output steps.',
}
export const FAMILY_FILTER_STYLES: Record<WorkflowNodeFamily, string> = {
cad_file: 'bg-sky-100 text-sky-700 dark:bg-sky-900/40 dark:text-sky-300',
shared: 'bg-violet-100 text-violet-700 dark:bg-violet-900/40 dark:text-violet-300',
order_line: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300',
}
@@ -86,8 +132,16 @@ const CAD_FILE_NODE_STEPS = new Set([
'thumbnail_save',
])
const SHARED_NODE_STEPS = new Set([
'glb_bbox',
])
export function getNodeFamily(step: string, nodeDefinitionsByStep?: WorkflowNodeDefinitionMap): WorkflowNodeFamily {
return nodeDefinitionsByStep?.[step]?.family ?? (CAD_FILE_NODE_STEPS.has(step) ? 'cad_file' : 'order_line')
if (nodeDefinitionsByStep?.[step]?.family) {
return nodeDefinitionsByStep[step].family
}
if (SHARED_NODE_STEPS.has(step)) return 'shared'
return CAD_FILE_NODE_STEPS.has(step) ? 'cad_file' : 'order_line'
}
export function getDefinitionFamily(
@@ -103,7 +157,8 @@ export function isDefinitionAllowedForGraphFamily(
nodeDefinitionsByStep?: WorkflowNodeDefinitionMap,
): boolean {
if (graphFamily === 'mixed') return true
return getDefinitionFamily(definition, nodeDefinitionsByStep) === graphFamily
const family = getDefinitionFamily(definition, nodeDefinitionsByStep)
return family === 'shared' || family === graphFamily
}
export function compareNodeDefinitions(a: WorkflowNodeDefinition, b: WorkflowNodeDefinition) {
@@ -125,12 +180,47 @@ export function getDefinitionModuleLabel(definition: WorkflowNodeDefinition): st
.join(' ')
}
export function getDefinitionAuthoringStage(definition: WorkflowNodeDefinition): WorkflowAuthoringStage {
const moduleKey = definition.module_key.toLowerCase()
if (moduleKey.startsWith('cad.')) {
if (definition.category === 'rendering') return 'render'
if (definition.category === 'output') return 'publish'
return 'cad_intake'
}
if (
moduleKey.startsWith('order_line.')
|| moduleKey.startsWith('geometry.')
|| moduleKey.startsWith('context.')
) {
return 'scene_prep'
}
if (moduleKey.startsWith('materials.')) {
return 'materials'
}
if (moduleKey.startsWith('render.') || moduleKey.startsWith('rendering.')) {
return 'render'
}
if (moduleKey.startsWith('media.') || moduleKey.startsWith('notifications.')) {
return 'publish'
}
if (definition.category === 'rendering') return 'render'
if (definition.category === 'output') return 'publish'
if (definition.category === 'input' || definition.category === 'processing') return 'orchestration'
return 'orchestration'
}
export function groupDefinitionsForStepSelect(definitions: WorkflowNodeDefinition[]) {
const groups = new Map<string, WorkflowNodeDefinition[]>()
for (const definition of [...definitions].sort(compareNodeDefinitions)) {
const family = getDefinitionFamily(definition)
const groupLabel = `${FAMILY_FILTER_LABELS[family]} · ${getDefinitionModuleLabel(definition)} · ${CATEGORY_LABELS[definition.category]}`
const groupLabel = `${FAMILY_FILTER_LABELS[family]} · ${AUTHORING_STAGE_LABELS[getDefinitionAuthoringStage(definition)]} · ${getDefinitionModuleLabel(definition)}`
groups.set(groupLabel, [...(groups.get(groupLabel) ?? []), definition])
}
@@ -145,6 +235,9 @@ export function groupDefinitionsByFamily(
cad_file: definitions
.filter(definition => getDefinitionFamily(definition, nodeDefinitionsByStep) === 'cad_file')
.sort(compareNodeDefinitions),
shared: definitions
.filter(definition => getDefinitionFamily(definition, nodeDefinitionsByStep) === 'shared')
.sort(compareNodeDefinitions),
order_line: definitions
.filter(definition => getDefinitionFamily(definition, nodeDefinitionsByStep) === 'order_line')
.sort(compareNodeDefinitions),