* fix(bpmn): make document PUT If-Match and save a compare-and-swap The document PUT checked If-Match, reloaded metadata, then saved through the importer as separate steps. Two writers could both pass If-Match, and a metadata-only save in that window was silently reverted. Add IWorkflowDefinitionStore.TryUpdateLatestAsync — load, match, apply, save as one critical section (memory) or ExecuteUpdate against the loaded snapshot (EF). ImportDocumentAsync reads metadata inside that swap. A lost race throws the same 412 the stale If-Match already returns. Mongo/Dapper/ES stores need the same method before the endpoint is concurrency-safe on those providers. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(bpmn): resolve document-service DI and interleave test compile Drop the cache-manager constructor dependency (only registered when definition caching is on) and evict via DraftSaving/DraftSaved instead. Update the export-availability stub construction and the CAS interleave fixture to parse edited XML through the reader. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(bpmn): close Greptile P1s on document PUT CAS Require IsLatest in the EF ExecuteUpdate WHERE so a published-to-draft loser is Conflict instead of a unique-key failure. Lock Memory CAS on the shared MemoryStore so scoped wrappers cannot stale-overwrite. Dispatch WorkflowDefinitionDraftSaving before the CAS persist so a rejecting handler fails the request before commit. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(bpmn): reuse published draft identity across DraftSaving and CAS Allocate the published-to-draft id, version and created-at once before WorkflowDefinitionDraftSaving. The compare-and-swap still rebuilds from the just-loaded row so metadata is not frozen from the outer Find, then reuses that announced identity and keeps handler-added custom properties. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * test(management): run Memory CAS lock holder off the test thread The shared-lock test blocked inside TryUpdateLatestAsync on the test thread, so it never reached the release signal and hung. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * test(efcore): drop the SQLite CAS harness that cannot match ExecuteUpdate The in-memory SQLite fixture could not satisfy the store's DateTimeOffset ORDER BY plus Data snapshot WHERE, so the winner CAS returned Conflict before the IsLatest loser path ran. Memory already covers that contract. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * fix(bpmn): persist the prepared DraftSaving draft on document PUT CAS Prepare the draft, dispatch WorkflowDefinitionDraftSaving so handlers can mutate or reject, then TryUpdateLatestAsync with If-Match plus the loaded snapshot and update: _ => draft. A metadata change in the window is 412 instead of overwriting the other write. DraftSaved still fires after CAS. Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * docs(bpmn): align document PUT remarks with prepared-draft CAS Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|---|---|---|
| .. | ||
| activities-and-authoring.md | ||
| architecture.md | ||
| bpmn-workflows.md | ||
| build-run-operate.md | ||
| diagnostics-console-logs.md | ||
| diagnostics-structured-logs.md | ||
| expressions-and-scripting.md | ||
| extension-guide.md | ||
| health-checks.md | ||
| http-scheduling-resilience.md | ||
| identity-tenancy-security.md | ||
| module-system.md | ||
| opentelemetry-workflows.md | ||
| output-converters.md | ||
| persistence.md | ||
| README.md | ||
| repository-map.md | ||
| specs-and-adrs.md | ||
| testing-guide.md | ||
| workflow-api.md | ||
| workflow-core.md | ||
| workflow-management.md | ||
| workflow-runtime.md | ||
Elsa Core Wiki
This wiki is a repo-local, code-grounded map of Elsa Core. It is intended for contributors who need the same kind of fast orientation that a DeepWiki-style generated wiki gives: what the system is, where the important code lives, how the pieces connect, and how to safely extend or test them.
The source of truth is still the code, specs, ADRs, and tests. Each page links back to the relevant files so you can jump from explanation to implementation.
Start Here
Elsa Core is a modular .NET workflow engine. The main solution is Elsa.sln. Production code lives under src, tests under test, specifications under specs, and architecture decisions under doc/adr.
The shortest mental model:
- An application calls
services.AddElsa(...). - Elsa builds an
IModuleand configures feature objects. - Features register services, activities, API endpoints, middleware, hosted services, and persistence stores.
- Workflow definitions are created by code, JSON, imported files, or providers.
- The runtime starts, resumes, dispatches, and persists workflow instances.
- APIs, SignalR hubs, HTTP endpoint activities, diagnostics, and persistence packages layer around that core.
flowchart LR
App["Host app"] --> Module["Elsa module system"]
Module --> Core["Workflow core"]
Module --> Management["Workflow management"]
Module --> Runtime["Workflow runtime"]
Module --> Api["Workflow API"]
Module --> Extensions["HTTP, Scheduling, Expressions, Identity, Tenants"]
Management --> Persistence["Stores / EF Core providers"]
Runtime --> Persistence
Runtime --> Logs["Execution logs and diagnostics"]
Api --> Studio["Elsa Studio / API clients"]
Page Map
| Page | Use it for |
|---|---|
| Repository Map | Top-level folders, projects, and where to look first. |
| Architecture | The main system layers and request/execution flow. |
| Module System | How IModule, FeatureBase, feature dependencies, and shell features work. |
| Workflow Core | Activities, execution contexts, pipelines, variables, bookmarks, graphs, and flowchart execution. |
| Workflow Management | Workflow definitions, instances, import/export, materializers, validation, and activity descriptors. |
| Workflow Runtime | Dispatch, triggers, bookmarks, queues, background activity scheduling, graceful shutdown, and recovery. |
| Workflow API | FastEndpoints, route prefixing, API categories, SignalR, and client-facing contracts. |
| Activities And Authoring | How workflows are authored in C#, JSON, ElsaScript, and host methods. |
| Output Converters | How to register, configure, validate, discover, and operate bound-value converters. |
| Expressions And Scripting | Expression evaluators and language feature packages. |
| HTTP, Scheduling, And Resilience | Inbound HTTP workflows, outbound HTTP, scheduled triggers, and resilience strategies. |
| Persistence | In-memory stores, EF Core stores, provider packages, migrations, and multi-provider rules. |
| Diagnostics Structured Logs | ILogger capture, live feed, REST/SignalR surface, redaction, and SQLite persistence. |
| Diagnostics Console Logs | Raw stdout/stderr capture, live feed, REST/SignalR surface, and redaction. |
| Health Checks | Elsa runtime readiness probes, liveness/readiness mapping, and Kubernetes probe guidance. |
| Identity, Tenancy, And Security | Users, applications, roles, API keys, tenant resolution, and authorization touch points. |
| Testing Guide | Test project layout, fixture choices, and targeted commands. |
| Extension Guide | How to add features, activities, expression providers, stores, endpoints, and ingress sources. |
| OpenTelemetry Workflow Instrumentation | First-party workflow and activity traces and metrics emitted through System.Diagnostics. |
| Specs And ADRs | How current specs and ADRs explain design intent. |
| Build, Run, And Operate | Build commands, sample hosts, runtime knobs, Docker notes, and operational endpoints. |
Source Landmarks
- Main public entry: src/modules/Elsa/Extensions/DependencyInjectionExtensions.cs
- Default umbrella feature: src/modules/Elsa/Features/ElsaFeature.cs
- Module implementation: src/common/Elsa.Features/Implementations/Module.cs
- Core workflow feature: src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs
- Management feature: src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
- Runtime feature: src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs
- API feature: src/modules/Elsa.Workflows.Api/Features/WorkflowsApiFeature.cs
- Reference server: src/apps/Elsa.Server.Web/Program.cs
- Structured-log persistence design: specs/005-structured-log-persistence/plan.md
Contributor Workflow
Use targeted reads first, then targeted tests. For most changes, start with the relevant module page, inspect the linked feature class and contracts, add or update tests in the matching test/unit, test/integration, or test/component project, and run the narrowest dotnet test command that proves the behavior.
When changing public behavior, update the related README, spec quickstart, or wiki page in the same PR. This repository is strongly modular, so the best changes keep ownership boundaries clear.