Skip to content

feat(workflow): MDL workflow support - CREATE/DROP/DESCRIBE + BSON round-trip#20

Merged
ako merged 43 commits intomendixlabs:mainfrom
engalar:pr/workflow
Mar 22, 2026
Merged

feat(workflow): MDL workflow support - CREATE/DROP/DESCRIBE + BSON round-trip#20
ako merged 43 commits intomendixlabs:mainfrom
engalar:pr/workflow

Conversation

@engalar
Copy link
Contributor

@engalar engalar commented Mar 21, 2026

Summary

  • Grammar: Add MDL syntax for CREATE/DROP/DESCRIBE WORKFLOW, GRANT/REVOKE EXECUTE ON WORKFLOW, CALCULATED BY attribute, and ENTITY clause for CREATE DEMO USER
  • SDK: Add BSON serialization/deserialization for all workflow activity types; fix UnknownElement to use bson.D for ordering-preserving round-trips; fix LoopSource interface handling in microflow writer
  • Executor: Implement SHOW/DESCRIBE/CREATE/DROP WORKFLOW and workflow security commands; add calculated attribute and demo user entity support; extend catalog with workflow entries
  • Tests: BSON parse/write unit tests with BSON fixtures; MDL round-trip test (CREATE → DESCRIBE comparison)
  • Docs: Update MDL_QUICK_REFERENCE.md, MDL_FEATURE_MATRIX.md, language reference, and skill files

Workflow Activity Types Supported

USER TASK, CALL MICROFLOW (with WITH parameter mappings), CALL WORKFLOW, DECISION, PARALLEL SPLIT, JUMP TO, WAIT FOR TIMER, WAIT FOR NOTIFICATION, ANNOTATION, END

Boundary events: ON ERROR, ON TIMEOUT

Test Plan

  • make test passes (all 7 test packages green)
  • SHOW WORKFLOWS lists workflows in a project with existing workflows
  • DESCRIBE WORKFLOW Module.Name produces valid MDL output
  • CREATE WORKFLOW ... BEGIN ... END WORKFLOW writes to MPR without CE errors (mx check)
  • DROP WORKFLOW Module.Name removes workflow from MPR
  • GRANT/REVOKE EXECUTE ON WORKFLOW updates access rules
  • Workflow BSON round-trip: parse existing workflow → write back → mx check clean

engalar and others added 25 commits March 21, 2026 23:02
…ulated attributes

- Add CREATE/DROP/DESCRIBE WORKFLOW grammar with all activity types:
  USER TASK, CALL MICROFLOW, CALL WORKFLOW, DECISION, PARALLEL SPLIT,
  JUMP TO, WAIT FOR TIMER, WAIT FOR NOTIFICATION, ANNOTATION, END
- Add GRANT/REVOKE EXECUTE ON WORKFLOW security grammar
- Add CALCULATED BY <microflow> attribute syntax
- Add ENTITY clause for CREATE DEMO USER
- Regenerate ANTLR4 parser (MDLLexer.interp, mdl_parser.go, etc.)
…with RawDoc

- Add writer_workflow.go: serialize all workflow activity types to BSON
- Add parser_workflow.go: parse all workflow $Types with table-driven registry
- Add parser_unknown.go: UnknownElement fallback using bson.D (preserves ordering)
- Fix UnknownElement.RawDoc field type (bson.D instead of map[string]any)
  for round-trip fidelity
- Fix writer_microflow.go: handle LoopSource as interface (IterableList/WhileLoopCondition)
- Add CALCULATED attribute support in domain model writer
…mo user entity

- Add SHOW/DESCRIBE WORKFLOW with full MDL-formatted output
- Add CREATE/DROP WORKFLOW executing AST against BSON writer
- Add GRANT/REVOKE EXECUTE ON WORKFLOW for security access control
- Add CALCULATED BY <microflow> support in CREATE/ALTER ENTITY
- Add ENTITY clause support in CREATE DEMO USER
- Add workflow entries to catalog (builder_modules, builder_strings)
- Extend LSP completions for workflow keywords
- Update help topics (entity, security, workflow)
- Fix DESCRIBE WORKFLOW round-trip: USER TASK due date, boundary events,
  multi-user task, CALL MICROFLOW WITH parameter mappings
- Add workflow_parse_test.go: parse WorkflowBaseline BSON fixtures
- Add workflow_write_test.go: write workflow BSON and verify structure
- Add BSON fixtures: WorkflowBaseline.Workflow.bson, Sub_Workflow.bson
- Add visitor_workflow_test.go: test all workflow activity AST visitors
- Add roundtrip_workflow_test.go: CREATE WORKFLOW → DESCRIBE WORKFLOW comparison
- Fix expected values: TRUE/FALSE capitalization, RETURNS keyword
…urity

- MDL_QUICK_REFERENCE.md: add Workflows section with all activity types
- MDL_FEATURE_MATRIX.md: mark workflow SHOW/DESCRIBE/CREATE/DROP/GRANT/REVOKE
- docs/language-reference.md: add CALCULATED attribute syntax
- Skills: docker-workflow (empty project, port conflicts, runtime copying)
- Skills: generate-domain-model (CALCULATED attribute docs)
- Skills: manage-security (ENTITY clause for CREATE DEMO USER)
- CLAUDE.md: update project status for implemented features
Debug-only `mxcli bson` subcommand suite for BSON field discovery,
cross-MPR comparison, and round-trip validation. Uses reflect-based
TypeRegistry from generated metamodel structs, isolated via
//go:build debug tag to keep release binary unchanged.
Provides foundation for BSON field coverage analysis:
- TypeRegistry mapping all 57 Workflows$ BSON types to reflect.Type
- PropertyMeta and GetFieldMeta for reflecting on struct fields
- FieldCategory classification (Semantic/Structural/Layout)
- All files gated behind //go:build debug tag
Structured diff engine for comparing BSON documents with identity-based
array matching ($Type+Name), default skip set for structural/layout fields,
and formatted output. Cobra command supports same-project and cross-MPR
comparison.
Implements field coverage analysis that compares BSON fields against MDL
text output, reporting covered/uncovered/default semantic fields per $Type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…g isolation

- Create bson parent command (cmd_bson.go) with debug build tag
- Migrate dump-bson to bson dump subcommand (cmd_bson_dump.go)
- Wire up discover and compare subcommands under bson parent
- Fix case-insensitive field matching in discover (BSON PascalCase vs json camelCase)
- Add make build-debug target for debug builds
- Remove old dump-bson command from release build
…RIBE WORKFLOW

- Grammar: DISPLAY STRING_LITERAL, DESCRIPTION STRING_LITERAL, EXPORT LEVEL (IDENTIFIER|API)
- AST: DisplayName, Description, ExportLevel fields on CreateWorkflowStmt
- Visitor: positional STRING_LITERAL extraction for multi-string rules
- Executor CREATE: map AST fields to SDK workflow struct
- Executor DESCRIBE: emit MDL clauses instead of comments
- 5 new visitor tests covering all combinations
…fiers

The workflowParameterMapping rule used IDENTIFIER, but DESCRIBE outputs
qualified names like Module.Microflow.Param. Changed to qualifiedName
to fix a nil pointer panic during round-trip parsing.
Adds two safety mechanisms to prevent runaway statements from filling disk:

- outputGuard (output_guard.go): thread-safe io.Writer wrapper that aborts
  after 10,000 lines per statement; resets before each Execute call
- Execute() now runs statements in a goroutine with a 5-minute wall-clock
  timeout as a secondary guard against infinite compute loops

Motivated by a historical bug where DESCRIBE WORKFLOW entered infinite
recursion on a complex workflow, writing 7.3 GB to /tmp before being killed.
- AutoAssignSingleTargetUser defaults to false (was incorrectly true)
- DueDate in UserTask now uses a.DueDate instead of hardcoded empty string
- NonInterruptingTimerBoundaryEvent now emits Recurrence: null field
  to match Studio Pro reference BSON
Add three fields required by Studio Pro for Workflows$MultiUserTaskActivity:
- AwaitAllUsers: false
- CompletionCriteria: ConsensusCompletionCriteria with FallbackOutcomePointer
  referencing first outcome ID
- TargetUserInput: AllUserInput

Single-user tasks are unaffected.
… to user task

- Remove ParameterExpression from CallWorkflowActivity BSON (not in Studio Pro)
- Add DESCRIPTION clause to USER TASK / MULTI USER TASK MDL syntax
  Grammar: (DESCRIPTION STRING_LITERAL)? after DUE DATE
  AST: TaskDescription field on WorkflowUserTaskNode
  Visitor: extract string at correct positional index
  Executor: pass TaskDescription to SDK struct
  DESCRIBE: emit DESCRIPTION clause when non-empty
  Writer already serialized a.TaskDescription correctly
… in DESCRIBE output

The formatCallMicroflowTask function was outputting the full three-segment
parameter name (e.g. WorkflowBaseline.CallMF.Entity) which caused a panic
when the DESCRIBE output was fed back to CREATE WORKFLOW parser. Now strips
to the last segment only (e.g. Entity).
…/visitor/executor

- Grammar: add optional { workflowBody } to workflowBoundaryEventClause
- AST: add Activities field to WorkflowBoundaryEventNode
- Visitor: extract buildBoundaryEventNode helper, parse sub-flow body
- Executor: extract buildBoundaryEvents helper, build Flow from sub-flow activities
- Test: add TestWorkflowVisitor_BoundaryEventWithSubFlow
…ForTimer/CallWorkflow

Changed DESCRIBE output for JumpTo, WaitForTimer, and CallWorkflow from
`-- caption` (line comment, lost during parsing) to `COMMENT 'caption'`
(grammar COMMENT token + STRING_LITERAL). This matches the MDL grammar
and preserves captions during round-trip. Single quotes in captions are
properly escaped.
Add TestWorkflowVisitor_AnnotationRoundTrip confirming ANNOTATION 'text'
parses correctly through visitor into AST. Grammar, visitor, and executor
already handle annotations — no code changes needed.
@ako
Copy link
Collaborator

ako commented Mar 22, 2026

The build for this fails, it broke support for microflow @annotations.

engalar added 4 commits March 22, 2026 17:08
… to prevent duplication

- Add WITH clause to workflowCallWorkflowStmt grammar (matching CALL MICROFLOW)
- Add ParameterMappings field to WorkflowCallWorkflowNode AST
- Parse WITH clause in visitor buildWorkflowCallWorkflow
- Use explicit ParameterMappings in buildCallWorkflowActivity, skip autoBindCallWorkflow
- Output ParameterMappings in formatCallWorkflowActivity DESCRIBE (strip prefix)
- Add visitor test for CALL WORKFLOW WITH clause parsing
Remove //go:build debug tags from all bson package files and cmd/mxcli/cmd_bson*.go.
Update command descriptions to remove debug-only language.
When no --project flag is given, scan the current directory for .mpr
files. If exactly one is found, use it as the default and print a hint
to stderr: "Using project: <file>". Zero or multiple .mpr files leave
behavior unchanged (commands that require -p still error as before).
… round-trip safety

DESCRIBE WORKFLOW previously output BaseWorkflowActivity.Annotation as a SQL
comment (-- text), which the MDL parser ignores and loses on round-trip.

Change formatAnnotation() to emit ANNOTATION 'text'; instead — a parseable MDL
statement that creates a standalone WorkflowAnnotationActivity. The content is
fully preserved across round-trips.

Fixes #15 (annotation loss after round-trip).
engalar added 14 commits March 22, 2026 18:20
Add Step 8 validate-before-exec: run mxcli check --references to catch
type mismatches (e.g., Long vs Integer for count()) and missing module
references before they surface as CE6770 MxBuild errors.
…ntegration

Major TUI overhaul replacing the command bar with lazygit-style direct shortcuts
and adding side-by-side compare view for BSON/MDL debugging.

New components:
- ScrollList: unified scrollable list with smooth scrolling, visual scrollbar,
  mouse support, and fzf-style fuzzy filter
- Breadcrumb: navigation path display with click-to-navigate
- ContentView: vim-style content viewer with line numbers, scrollbar,
  search (/n/N), and mouse scroll
- CompareView: side-by-side panes (NDSL|NDSL, NDSL|MDL, MDL|MDL) with
  fuzzy object picker, sync scroll, and mode switching
- Overlay: fullscreen modal reusing ContentView
- Highlight: chroma-based syntax highlighting for MDL/SQL/NDSL

Key interactions:
- b: BSON dump, m: MDL describe, c: compare view, z: zen mode
- /: search in content views with live matching and n/N navigation
- Tab: switch panels/panes, Enter: drill in or open detail
- Progressive 2-panel expansion, mouse click and scroll everywhere
- Filter mode passes all keys to input (no shortcut conflicts)
@ako ako merged commit a2fa441 into mendixlabs:main Mar 22, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants