{"id":51288706,"url":"https://github.com/kazemmdev/elsa-workflow-demo","last_synced_at":"2026-06-30T08:32:10.139Z","repository":{"id":368004415,"uuid":"1282833750","full_name":"kazemmdev/elsa-workflow-demo","owner":"kazemmdev","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-28T15:53:52.000Z","size":202,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T17:17:16.028Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kazemmdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-28T08:44:45.000Z","updated_at":"2026-06-28T15:53:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kazemmdev/elsa-workflow-demo","commit_stats":null,"previous_names":["kazemmdev/elsa-workflow-demo"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/kazemmdev/elsa-workflow-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kazemmdev%2Felsa-workflow-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kazemmdev%2Felsa-workflow-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kazemmdev%2Felsa-workflow-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kazemmdev%2Felsa-workflow-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kazemmdev","download_url":"https://codeload.github.com/kazemmdev/elsa-workflow-demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kazemmdev%2Felsa-workflow-demo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34959505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-30T08:32:09.991Z","updated_at":"2026-06-30T08:32:10.129Z","avatar_url":"https://github.com/kazemmdev.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Purchase Request Approval — Elsa Workflow Demo\n\nA backend demo showing how to build a multi-step approval workflow using [Elsa Workflows v3](https://docs.elsaworkflows.io) with ASP.NET Core, PostgreSQL, and a custom identity bridge.\n\nThe workflow covers the full lifecycle of a purchase request: submission → manager review → finance review → outcome.\n\n---\n\n## How it works\n\nAn employee submits a purchase request via HTTP. The workflow suspends, waits for a manager to approve or reject, and if approved, hands off to finance for a second review. Each approval step is an external task — the workflow holds state between steps, so nothing is lost if the server restarts.\n\n![image](/assets/image.png)\n\n## Stack\n\n| Layer       | Technology                                              |\n| ----------- | ------------------------------------------------------- |\n| Runtime     | .NET 10 / ASP.NET Core                                  |\n| Workflows   | Elsa Workflows 3.5.3                                    |\n| Identity    | ASP.NET Core Identity (custom bridge to Elsa)           |\n| Database    | PostgreSQL (EF Core, separate schemas for app and Elsa) |\n| Workflow UI | Elsa Studio (Docker)                                    |\n\n---\n\n## Running locally\n\n**Prerequisites:** Docker, .NET 10 SDK, Make\n\n```bash\nmake up\n```\n\nThat's it. Starts PostgreSQL and Elsa Studio in the background, waits for the database to be ready, then runs the API in the foreground.\n\n- \u003chttp://localhost:5000\u003e — API\n- \u003chttp://localhost:3000\u003e — Elsa Studio (workflow designer)\n\n**Studio login:** `admin` / `Admin@12345!`\n\n---\n\n## Roles\n\n| Role     | Access                               |\n| -------- | ------------------------------------ |\n| Admin    | Full access                          |\n| Manager  | Approves/rejects at the manager step |\n| Finance  | Approves/rejects at the finance step |\n| Employee | Submits requests                     |\n\n---\n\n## API\n\n### Submit a purchase request\n\n```bash\nPOST /purchase-request\nContent-Type: application/json\n\n{\n  \"employee\": \"Ali\",\n  \"amount\": 1200,\n  \"description\": \"Laptop\"\n}\n```\n\nResponse includes `instanceId` — keep it, you need it for approvals.\n\n### Check pending tasks for an instance\n\n```bash\nGET /api/approvals/{instanceId}/tasks\n```\n\n### Manager decision\n\n```bash\nPOST /api/approvals/{instanceId}/manager\nContent-Type: application/json\n\n{ \"decision\": \"approved\" }   # or \"rejected\"\n```\n\n### Finance decision\n\n```bash\nPOST /api/approvals/{instanceId}/finance\nContent-Type: application/json\n\n{ \"decision\": \"approved\" }   # or \"rejected\"\n```\n\n---\n\n## Project structure\n\n```text\nbackend/\n├── Controllers/\n│   ├── AuthController.cs          # Login, token issuance\n│   └── ApprovalsController.cs     # Manager + finance approval endpoints\n├── Data/                          # EF Core DbContext and entities\n├── Identity/                      # Role constants\n├── Infrastructure/\n│   ├── AspNetIdentityUserProvider.cs           # Bridges ASP.NET Identity → Elsa identity model\n│   └── AspNetIdentityUserCredentialsValidator.cs\n├── Security/                      # JWT options and token service\n├── Seeding/                       # Seeds roles and admin user on startup\n└── Extensions/                    # Service registration helpers\n\nworkflows/\n└── purchase-request-approval.json  # Workflow definition (import via Elsa Studio)\n```\n\n---\n\n## Notes\n\n- The workflow definition lives in `workflows/` as a JSON export. Import it in Elsa Studio under **Workflow Definitions → Import**.\n- Workflow state is persisted to PostgreSQL — approvals survive server restarts.\n- The approval endpoints resolve the internal Elsa `taskId` from the bookmark store so callers only need the `instanceId`.\n\n---\n\n## Tear down\n\n```bash\nmake down          # Stop containers, keep data\nmake clean         # Stop and wipe everything\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkazemmdev%2Felsa-workflow-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkazemmdev%2Felsa-workflow-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkazemmdev%2Felsa-workflow-demo/lists"}