Skip to content

Expose consumers API and recursive export option#7309

Merged
sfmskywalker merged 14 commits intorelease/3.6.0from
copilot/expose-api-endpoint-consumers
Feb 20, 2026
Merged

Expose consumers API and recursive export option#7309
sfmskywalker merged 14 commits intorelease/3.6.0from
copilot/expose-api-endpoint-consumers

Conversation

@sfmskywalker
Copy link
Member

@sfmskywalker sfmskywalker commented Feb 18, 2026

Summary

Introduces a workflow reference graph to reliably discover consuming workflows, exposes a new Consumers API endpoint, and extends workflow export to optionally include transitive consuming workflows.

This replaces the previous recursive, query-based approach with a graph-based model and improves determinism, test coverage, and export behavior.


Key Changes

1. Workflow Reference Graph

  • Added:
    • IWorkflowReferenceGraphBuilder
    • WorkflowReferenceGraph, WorkflowReferenceEdge
    • WorkflowReferenceGraphOptions
    • WorkflowReferenceGraphBuilder (implementation)
  • Registered via WorkflowManagementFeature
  • Replaced recursive consumer discovery in WorkflowReferenceUpdater with graph-based dependency mapping.
  • Removed old recursive helper and related unused code.

2. Consumers API

New endpoint:


GET /workflow-definitions/{definitionId}/consumers

  • Returns all recursive consuming workflow definitions
  • Added:
    • Endpoint + request/response models
    • IWorkflowDefinitionsApi.GetConsumersAsync
    • GetConsumingWorkflowDefinitionsResponse

3. Export Enhancements

  • Added IncludeConsumingWorkflows flag to:
    • Export request
    • BulkExportWorkflowDefinitionsRequest
    • Client ExportAsync (query param, default false)
  • When enabled:
    • Discovers transitive consumers via graph
    • Resolves at VersionOptions.Latest
    • Includes them in the ZIP export

Additional improvements:

  • Deterministic filenames ({Name}-{DefinitionId}.json)
  • Extracted ZIP creation into WriteZipResponseAsync
  • Added .NET 10-compatible async ZIP entry opening

4. API & Signature Adjustments

  • Replaced default parameter defaults with null where appropriate in client APIs
  • Added includeConsumingWorkflows query parameter (default false)
  • No breaking HTTP contract changes (additive only)

5. Tests

  • Unit tests for WorkflowReferenceGraphBuilder
  • Component tests for:
    • Consumers endpoint
    • Export (with and without consumers)
  • Added workflow JSON fixtures for test coverage

Behavioral Impact

  • New Consumers endpoint available.
  • Export can now include transitive consuming workflows.
  • Consumers are resolved using latest versions, regardless of requested version options.
  • Exported filenames are now deterministic and collision-safe.
  • Reference updates now use a graph instead of ad-hoc recursion.

Performance Considerations

  • Graph traversal is recursive but protected by:
    • WorkflowReferenceGraphOptions (MaxDepth, MaxDefinitions)
    • Visited-set tracking
    • Edge deduplication
  • Including consumers may increase:
    • CPU usage
    • Memory usage
    • ZIP size (in-memory creation)

Breaking Changes

None at the HTTP level.

Minor client signature default adjustments (defaultnull) are non-breaking for typical usage.

Internal DI now requires IWorkflowReferenceGraphBuilder (registered via WorkflowManagementFeature).

Copilot AI and others added 4 commits February 17, 2026 19:51
…rkflows option

- New endpoint: GET /workflow-definitions/{definitionId}/consumers
- Export request model: added IncludeConsumingWorkflows boolean property
- Export endpoint: recursive consumer discovery and inclusion in exports

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
…shSet, add version comment, remove unused params

- Extract WriteZipResponseAsync helper to avoid double-fetching definitions from DB
- Remove redundant existingDefinitionIds HashSet in IncludeConsumersAsync
- Add XML doc comment documenting that consumers are resolved at VersionOptions.Latest
- Remove unused constructor parameters (workflowDefinitionService, variableDefinitionMapper)

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
…stic ZIP response, parallel BFS

- Consumers endpoint now returns 404 when the definition ID doesn't exist
- Single-workflow export always returns ZIP when includeConsumingWorkflows=true
- BFS traversal processes each frontier level concurrently via Task.WhenAll

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 18, 2026

Greptile Summary

This PR adds a new /workflow-definitions/{definitionId}/consumers endpoint to list workflows that consume a given definition, and enhances export functionality to recursively include all consuming workflows. The implementation extracts graph traversal logic into a new WorkflowReferenceGraphBuilder service with configurable depth and definition limits (defaults: 100 depth, 1000 definitions).

Key Changes:

  • New consumers API endpoint with proper 404 handling for unknown definitions
  • Export endpoints now accept IncludeConsumingWorkflows flag to include full consumer graph
  • All consumers are resolved at Latest version regardless of initially requested version
  • Filenames now include DefinitionId to prevent collisions (addresses previous comment)
  • Comprehensive test coverage including cycles, diamonds, and transitive relationships

Note: The PR description mentions "parallel BFS" but the implementation uses sequential depth-first traversal with cycle detection, which is appropriate for this use case.

Confidence Score: 4/5

  • Safe to merge with minor documentation clarification needed.
  • Implementation is solid with good test coverage. The traversal algorithm correctly handles cycles and has configurable limits. One point deducted for minor inaccuracy in PR description (claims parallel BFS but implements DFS).
  • No files require special attention. The duplicate filename issue noted in previous reviews has been resolved.

Important Files Changed

Filename Overview
src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Consumers/Endpoint.cs New endpoint to list consuming workflows. Properly validates existence with 404, uses correct permissions.
src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Endpoint.cs Adds recursive consumer export. Filename collision issue already noted. Deterministic ZIP generation looks good.
src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceGraphBuilder.cs New depth-first traversal with cycle detection and limits. Not parallel BFS as PR claims, but implementation is sound.
src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceUpdater.cs Refactored to use WorkflowReferenceGraphBuilder instead of inline recursion. Cleaner implementation.
src/modules/Elsa.Workflows.Management/Models/WorkflowReferenceGraph.cs Well-designed graph data structure with pre-computed lookups for efficient queries.
test/unit/Elsa.Workflows.Management.UnitTests/Services/WorkflowReferenceGraphBuilderTests.cs Comprehensive unit tests cover cycles, diamonds, depth limits, and multi-root scenarios.

Sequence Diagram

sequenceDiagram
    participant Client
    participant ConsumersEndpoint
    participant ExportEndpoint
    participant GraphBuilder
    participant Query as IWorkflowReferenceQuery
    participant Store as IWorkflowDefinitionStore

    Note over Client,Store: Consumers API Flow
    Client->>ConsumersEndpoint: GET /workflow-definitions/{id}/consumers
    ConsumersEndpoint->>Store: FindAsync(definitionId, Latest)
    Store-->>ConsumersEndpoint: WorkflowDefinition or null
    alt Definition not found
        ConsumersEndpoint-->>Client: 404 Not Found
    else Definition found
        ConsumersEndpoint->>GraphBuilder: BuildGraphAsync(definitionId)
        loop Recursive DFS
            GraphBuilder->>Query: ExecuteAsync(definitionId)
            Query-->>GraphBuilder: List of consumer IDs
            Note over GraphBuilder: Builds edges, checks cycles<br/>and depth/definition limits
        end
        GraphBuilder-->>ConsumersEndpoint: WorkflowReferenceGraph
        ConsumersEndpoint-->>Client: 200 OK with consumer IDs
    end

    Note over Client,Store: Export with Consumers Flow
    Client->>ExportEndpoint: GET /workflow-definitions/{id}/export?includeConsumingWorkflows=true
    ExportEndpoint->>Store: FindAsync(definitionId)
    Store-->>ExportEndpoint: WorkflowDefinition
    ExportEndpoint->>GraphBuilder: BuildGraphAsync(definitionId)
    GraphBuilder-->>ExportEndpoint: WorkflowReferenceGraph
    ExportEndpoint->>Store: FindManyAsync(consumerIds, Latest)
    Store-->>ExportEndpoint: Consumer WorkflowDefinitions
    Note over ExportEndpoint: Generate ZIP with all<br/>definitions (deterministic)
    ExportEndpoint-->>Client: ZIP file with all workflows
Loading

Last reviewed commit: 897de6d

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

- Added `IWorkflowReferenceGraphBuilder` interface for building complete graphs of workflow references.
- Created `WorkflowReferenceGraph` and `WorkflowReferenceEdge` models.
- Implemented `WorkflowReferenceGraphBuilder` service for recursive graph building.
- Replaced previous workflow reference query logic with the new graph-based approach in consumers.
…kflows and update nullable default values across endpoints and models.
…iguration

- Introduced `WorkflowReferenceGraphOptions` to configure max depth and definition limits for reference graph building.
- Updated `WorkflowManagementFeature` to support configuring these options.
- Enhanced `WorkflowReferenceGraphBuilder` to respect configuration limits during graph construction process.
Introduced JSON files for parent-child-grandchild workflow hierarchy tests and implemented unit tests for `WorkflowReferenceGraphBuilder`. Also added component tests for workflow export and consumers endpoint validation. Updated project configuration for workflow JSON to always copy to output directory.
…with `SetupGraph`, replace repeated assertions with helper methods.
@sfmskywalker sfmskywalker requested a review from Copilot February 19, 2026 19:53
@sfmskywalker
Copy link
Member Author

@greptile please do another review.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces reverse dependency analysis and enhanced export capabilities for workflow definitions in Elsa Workflows. It adds a new API endpoint to discover consuming workflows and extends the export functionality to recursively include all workflows that depend on a given workflow.

Changes:

  • Introduces IWorkflowReferenceGraphBuilder with graph-based workflow reference discovery
  • Adds /workflow-definitions/{definitionId}/consumers endpoint with 404 handling for unknown workflows
  • Enhances export endpoints with IncludeConsumingWorkflows flag for recursive consumer inclusion
  • Refactors WorkflowReferenceUpdater to use the new graph builder, eliminating duplicate traversal logic

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceGraphBuilder.cs Implements recursive DFS traversal to build consumer reference graphs with configurable depth/size limits
src/modules/Elsa.Workflows.Management/Models/WorkflowReferenceGraph.cs Defines graph data structure with edges, lookups, and helper methods for dependency analysis
src/modules/Elsa.Workflows.Management/Options/WorkflowReferenceGraphOptions.cs Configuration options for traversal limits (MaxDepth=100, MaxDefinitions=1000)
src/modules/Elsa.Workflows.Management/Contracts/IWorkflowReferenceGraphBuilder.cs Interface for building single-root and multi-root reference graphs
src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs Registers graph builder service and configuration options
src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceUpdater.cs Refactored to use graph builder instead of custom recursion, leverages OutboundEdges for topological sort
src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Consumers/Endpoint.cs New endpoint returning transitive consumers with 404 for unknown definitions
src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Consumers/Models.cs Request/response models for consumers endpoint
src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Endpoint.cs Enhanced with IncludeConsumersAsync method, refactored ZIP generation, improved file naming with definitionId suffix
src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Models.cs Added IncludeConsumingWorkflows flag, changed default! to null! for nullable properties
src/clients/Elsa.Api.Client/Resources/WorkflowDefinitions/Contracts/IWorkflowDefinitionsApi.cs Added GetConsumersAsync method and includeConsumingWorkflows parameter to export methods
src/clients/Elsa.Api.Client/Resources/WorkflowDefinitions/Models/BulkExportWorkflowDefinitionsRequest.cs Added IncludeConsumingWorkflows parameter
src/clients/Elsa.Api.Client/Resources/WorkflowDefinitions/Responses/GetConsumingWorkflowDefinitionsResponse.cs Response model for consumers endpoint
test/unit/Elsa.Workflows.Management.UnitTests/Services/WorkflowReferenceGraphBuilderTests.cs Comprehensive unit tests covering direct/transitive consumers, diamond graphs, cycles, and traversal limits
test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowReferenceGraph/WorkflowReferenceGraphTests.cs Component tests for consumers endpoint with parent→child→grandchild hierarchy
test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionExport/WorkflowDefinitionExportTests.cs Component tests verifying export with/without consumers for single and bulk operations
test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowReferenceGraph/Workflows/*.json Test workflow definitions forming parent→child→grandchild reference chain
test/component/Elsa.Workflows.ComponentTests/Elsa.Workflows.ComponentTests.csproj Added test workflow files to build output

@sfmskywalker
Copy link
Member Author

@copilot open a new pull request to apply changes based on the unresolved comments in this thread

Copy link
Contributor

Copilot AI commented Feb 19, 2026

@sfmskywalker I've opened a new pull request, #7312, to work on those changes. Once the pull request is ready, I'll request review from you.

…#7312)

* Initial plan

* Fix deterministic ZIP export and add 404 test for consumers endpoint

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
Copy link
Contributor

@lukhipolito-nexxbiz lukhipolito-nexxbiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good

@sfmskywalker sfmskywalker merged commit 0a2e99a into release/3.6.0 Feb 20, 2026
2 checks passed
@sfmskywalker sfmskywalker deleted the copilot/expose-api-endpoint-consumers branch February 20, 2026 16:40
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.

Expose API endpoint to list consuming workflows and enhance export endpoint to include consumers

4 participants