* feat(bpmn): add Analyze/Import/Export endpoints to Elsa.Bpmn.Interchange Thin FastEndpoints wrappers over Bpmn.Interchange, sharing one BpmnInterchangeDocumentService so Analyze and Import can never disagree about what a document costs. Import surfaces capability refusal (BpmnCapabilityRequirements.Analyze, walked into nested processes) with the missing capability and offending element ids, and reuses BpmnWorkBinder to bind the root BpmnProcess scope. Export re-reads the original XML persisted alongside the workflow definition and re-runs it through BpmnXmlWriter, so retained extension elements, foreign attributes and BPMN DI layout survive the round trip without being reconstructed from the reduced Elsa activity graph. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(bpmn): make a stale BPMN export refuse instead of mislead Export now refuses with 422 (naming the reason) when a workflow definition's BPMN source is missing or no longer matches the definition's version, rather than exporting stale or absent content while reporting success. Import records the definition's version alongside the source XML so Export can detect drift caused by a later save replacing custom properties wholesale. Also: the interchange package now consumes the runtime host's declared capability set from a new public Elsa.Bpmn.Hosting.BpmnRuntimeCapabilities instead of restating it (one value, one home); the Import endpoint's capability-refusal message no longer misattributes driving elements across capabilities; the three BPMN REST endpoints get HTTP-level test coverage (multipart validation, exception-to-status-code mapping, permission gating); and the wiki documents the endpoints and Export's known limitation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * test(bpmn): alert when the library defines a capability Elsa does not declare Restores the deleted comparison between BpmnRuntimeCapabilities.Declared (ours) and BpmnHostCapabilities.Full (the library's) — these are two different constants, not the tautology the earlier deletion assumed. The pinned Bpmn.Semantics 0.1.1-preview.19 currently defines exactly the four flags Elsa declares, so capability refusal at import/build is wired but unreachable; this test is what will say the moment a library bump changes that, and its failure message names the decision (implement and declare, or leave undeclared on purpose) rather than just failing silently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(bpmn): return 400 for a malformed export version and clarify a partial-import refusal - Export/Endpoint.cs: a non-numeric or out-of-range VersionOptions query value now returns a 400 naming the offending value instead of throwing through FromString and bubbling into a 500. - BpmnInterchangeDocumentService: the message shown when a definition carries BPMN source but not its version marker (a second save that never completed after ImportAsync's first) now says so explicitly, distinct from "never imported" and "stale". - BpmnInterchangeDocumentService: replace the implicit filter in EnsureCapabilitiesSatisfied's foreach with an explicit .Where(...), same behaviour. - Test projects: extract the duplicated ReadAsset/Path.Combine helper in BpmnInterchangeTestBase and BpmnInterchangeEndpointTests into a single BpmnAssetReader, guarded against a rooted or nested file name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(bpmn): write both BPMN import markers in one save Move the BPMN source XML off the pre-import model and onto the same explicit save that already records the definition's version, so a failed or cancelled post-import save leaves neither custom property behind instead of a partial, undiagnosable state. Update BpmnAssetReader to use Path.Join instead of Path.Combine so its rooted/nested-name guard is defence-in-depth rather than the only thing standing between the code and a wrong path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.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.