* Adds activity execution call stack support
Implements a call stack mechanism to track the execution chain, enabling visibility into the invocation hierarchy.
Introduces new fields to scheduling models and runtime contexts to store call stack information.
Includes EF Core migrations for various database providers to support new columns in `ActivityExecutionRecords`.
Provides an API to query and reconstruct the call stack for a given activity execution.
* Refactor: Replace `PagedCallStackResult` with `Page<T>` for execution chain pagination
* Remove ambient scheduling scope logic and related methods
Simplifies scheduling logic by removing ambient scope mechanisms, refactoring scheduling context handling, and updating affected classes accordingly.
* Add `GetCallStackAsync` to `IActivityExecutionsApi` for querying activity execution call stack
* Add new properties to `ActivityExecutionRecord` for scheduling and execution tracking
Introduce fields for aggregated fault count, scheduling context, workflow instance details, and call stack depth to enhance execution monitoring and debugging capabilities.
* Add call stack visualization for activity executions
Introduced components and models to display a call stack for activity executions in the Workflow Instance Viewer. This includes UI elements for call stack rendering, error handling, and data integration with activity execution records.
* Remove obsolete ambient scheduling properties from WorkflowExecutionContext
* Fix infinite loop issues in activity execution chain traversal
Added cycle detection using a `HashSet` to prevent infinite loops when traversing activity execution chains in multiple storage implementations. Updated unit tests to validate correct handling of circular references and chain traversal.
* Refactor activity execution chain retrieval logic
Centralized the `GetExecutionChainAsync` method into an extension class to streamline and unify its implementation across stores. Removed redundant implementations from individual stores and updated interfaces to utilize the new extension method. This reduces code duplication and simplifies future maintenance.
* Add CallStackDepth property to activity contexts
Integrated the `CallStackDepth` property into `ActivityExecutionContext`, `ActivityExecutionContextState`, and related classes to track and manage the call stack depth of activity executions. Removed obsolete depth calculation logic to streamline the process.
* Add unit tests for call stack depth calculations and persistence
- Add `WorkflowExecutionContextTests` to verify correct calculation of call stack depth during activity execution.
- Add `WorkflowStateExtractorTests` to ensure call stack depth is preserved during state extraction and application.
* Update src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/GetCallStack/Endpoint.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/GetCallStack/Endpoint.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Enhance activity execution handling with ID filter and task completion logic
- Implement `ActivityExecutionRecordFilter` for precise query matching by ID.
- Add await logic for task completion in command handler middleware.
* Add missing indexes for call stack columns in V3_7 migrations (#7250)
* Initial plan
* Add missing indexes for call stack columns in all provider migrations
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Optimize migrations by creating columns with correct indexable types
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>
* Add unit tests for ActivityExecutionStoreExtensions
- Introduce tests for `GetExecutionChainAsync` covering scenarios of empty results, single records, multi-level chain traversal, workflow boundary constraints, pagination, and circular references.
* Refactor tests for `ActivityExecutionStoreExtensions`
- Replace mock setup with `CreateStore` helper for clean and clear test arrangements.
- Remove unused imports and clean up test setup for improved readability and maintenance.
* Remove unused imports from ActivityExecutionLogStore in Elsa.Persistence.EFCore module.
* Removes obsolete planning document
Removes the activity execution call stack planning document
as the feature has been implemented.
* Remove DefaultActivityExecutionMapperTests
- Deleted `DefaultActivityExecutionMapperTests.cs` as the test class is no longer in use and redundant.
* Address review feedback: Fix corrupted test, Oracle migrations, and call stack depth calculation (#7272)
* Initial plan
* Fix corrupted DefaultActivityExecutionMapperTests.cs test file
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Fix Oracle migration snapshot to use NCLOB for large text fields
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Optimize GetExecutionChainAsync to avoid loading all workflow instance records
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Fix CallStackDepth calculation to support cross-workflow invocations
- Add SchedulingCallStackDepth to ActivityInvocationOptions
- Update WorkflowExecutionContext to use provided depth when scheduling context not found
- Remove problematic test that reveals pre-existing bug with duplicate contexts
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Improve documentation for CallStackDepth calculation
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>
* Add WorkflowStateExtractor to ActivityTestFixture services
* Refactor `DefaultActivityExecutionMapperTests` with `ActivityTestFixture` and add project reference for shared testing utilities.
* Propagate SchedulingCallStackDepth through cross-workflow invocation chain (#7273)
* Initial plan
* Add SchedulingCallStackDepth propagation through cross-workflow invocation chain
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add unit tests for CallStackDepth propagation across workflow boundaries
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>
* Initial plan (#7274)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* Reduce NVARCHAR2 column sizes in Oracle migrations to optimize storage and improve performance.
* Change column types to NCLOB for large text fields in Oracle migrations to enhance data storage capacity.
* Update GitHub Actions to use .NET 10.x and refactor setup classes for consistency
* Improve test project detection in GitHub Actions by handling non-csproj files and updating project sorting mechanism.
* Enhance GitHub Actions to display .NET environment info and enforce .NET 10 toolchain for test execution.
* Update GitHub Actions to use .NET SDK 10.0.1xx and enforce its usage for builds and tests.
* Refine GitHub Actions workflow by narrowing test project search to the `test/unit` directory and removing unnecessary script checks.
* Remove redundant build step from GitHub Actions workflow.
* Enhance GitHub Actions workflow by adding multiple test directories and handling ignored failed sources in .NET restore.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add ADR for Null Tenant ID, implement tenant-agnostic logic
Introduce ADR-0009 to document the use of `null` for tenant-agnostic entities, enhancing multitenancy handling. Update multitenancy features across the codebase, including EF Core query filters and ActivityRegistry, to handle null as a tenant ID, ensuring tenant-agnostic entities are accessible across all tenants.
* Add multitenancy support in `ActivityTestFixture` by registering `ITenantAccessor`.
* Update src/modules/Elsa.Common/Multitenancy/Implementations/DefaultTenantAccessor.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove unused `using Elsa.Common.Multitenancy;` from WorkflowDefinitionActivityDescriptorFactory (#7230)
* Initial plan
* Remove unused using Elsa.Common.Multitenancy statement
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>
* Optimize ActivityRegistry.Find to prefer tenant-specific descriptors without performance regression (#7227)
* Initial plan
* Optimize Find(string type) to prefer tenant-specific descriptors with single-pass iteration
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Apply review feedback: combine if statements and add comprehensive unit tests
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Refactor tests for DRYness using theories and helper methods
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Clean up extra whitespace in test file
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>
* Fix default tenant data visibility leak by removing NullIfEmpty conversion (#7229)
* Initial plan
* Remove NullIfEmpty conversion to align with ADR-0008 and ADR-0009
- Updated ElsaDbContextBase to use empty string for default tenant
- Updated ApplyTenantId to stop converting empty string to null
- Updated TenantAwareDbContextFactory to preserve empty string for default tenant
- Updated Store.cs to preserve empty string for default tenant
- This ensures: null = tenant-agnostic (visible to all), "" = default tenant
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add database migration to convert null TenantId to empty string for SqlServer
- Added Management migration to convert null to "" for WorkflowDefinitions and WorkflowInstances
- Added Runtime migration to convert null to "" for all runtime entities
- This ensures existing default tenant data is properly migrated per ADR-0008
- Note: Similar migrations needed for PostgreSql, MySql, Sqlite, and Oracle providers
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Clarify tenant handling logic in `ElsaDbContextBase` with new ADR references.
* Add tenant ID convention analysis documents and quick reference guide
* Implement tenant-agnostic functionality across modules
- Introduce `AgnosticTenantId` constant to manage tenant-agnostic entities.
- Modify entity handling logic to respect tenant-agnostic designations.
- Adjust workflow processing to include tenant-agnostic workflows.
- Update caching and activity descriptor logic to accommodate the `AgnosticTenantId`.
* Refactor tenant management and registry logic in `ActivityRegistry` for improved clarity and separation of tenant-specific and tenant-agnostic activity descriptors. Remove `TestTenantResolver` and update workflow definition handling for tenant support.
* Refactor `ActivityRegistry`: prioritize tenant-specific descriptors over tenant-agnostic and simplify descriptor retrieval logic.
* Improve async handling in `CommandHandlerInvokerMiddleware` to await tasks without blocking
* Update ADR to use asterisk as sentinel value for tenant-agnostic entities
Replace the previous convention of using `null` for tenant-agnostic entities with an asterisk (`"*"`) for improved clarity and system architecture. Updated ADR documentation, TOC, and dependency graph accordingly.
* Remove migration `ConvertNullTenantIdToEmptyString` and its associated designer file to clean up the codebase.
* Refactor `ActivityRegistry`: streamline activity descriptor removal logic and simplify tenant ID checks.
* Update Elsa.sln
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Simplify `RefreshDescriptorsAsync` by removing unnecessary local variable `currentTenantId`.
* Remove unused `currentTenantId` variable from `ActivityRegistry`.
* Add detailed semantic flow and key points to ADR 0009
Document the tenant ID flow from entity creation to query, emphasizing normalization and tenant-agnostic workflows. Update semantic flow diagrams and provide testing considerations for preserving `"*"` values in multi-tenant scenarios.
* Remove outdated Tenant ID Analysis and associated documents
* Add security-by-default design for tenant-agnostic entities in ADR
Enhance Architecture Decision Record to detail explicit requirements for tenant-agnostic database entities, highlighting differences between in-memory activity descriptors and persistent entities. Emphasize importance of setting `TenantId = "*"` to prevent accidental data leakage.
* Normalize tenant ID grouping in `ActivityRegistry` to unify null and agnostic IDs, reducing redundant processing.
* Refactor `SignalManager`: improve timeout handling and streamline signal task cancellation.
* Update src/modules/Elsa.Workflows.Core/Models/TenantRegistryData.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Refactor tests to use `Tenant.AgnosticTenantId` instead of `null` for tenant-agnostic descriptors.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Enhance logging in recurring tasks: add error handling and logger support to prevent crashes in scheduled timers.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Initial plan
* Fix: Remove bogus duplicate activity registry warnings during refresh
The ActivityRegistry.RefreshDescriptorsAsync() method was starting with existing descriptors, causing false warnings when intentionally repopulating the registry. Now starts fresh but preserves manual descriptors.
Co-authored-by: KnibbsyMan <23156317+KnibbsyMan@users.noreply.github.com>
* Add tests for ActivityRegistry refresh behavior
Added comprehensive tests to verify:
1. No warnings logged during intentional registry refresh
2. Manual descriptors preserved during refresh
3. True duplicates from different providers still logged
Co-authored-by: KnibbsyMan <23156317+KnibbsyMan@users.noreply.github.com>
* Apply code review feedback: track manual descriptors in providersDictionary and clarify comments
- Track _manualActivityDescriptors in providersDictionary under GetType() key for consistency
- Clarify comments to be more specific about GetType() provider and RegisterAsync(Type activityType) method
- Avoid duplicate entries in provider list when descriptor already preserved
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Minor style improvement: use Count > 0 instead of !Count.Equals(0)
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: KnibbsyMan <23156317+KnibbsyMan@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>