invoice-processing-pipeline

Install

How to get LedgerFlow running from a clean machine. The local path (steps 1–4) needs no Azure account — SQL Server and blob storage run in Docker, and every Azure boundary is behind an interface, so the domain and the API work offline. The Azure path (step 5) is needed only for live document extraction and the Functions pipeline.

For what LedgerFlow is and how the three-way match works, see README.md.

1. Prerequisites

Tool Version Needed for
.NET SDK 8.0 every C# project
Node.js 20 LTS web/ — the review-queue UI
Docker Desktop latest local SQL Server + Azurite
Git any recent clone
Azure Functions Core Tools v4 v4 only to run the Functions worker locally
dotnet --version && node --version && docker --version

2. Clone and build

git clone https://github.com/NickZivkovic1993/invoice-processing-pipeline.git
cd invoice-processing-pipeline

dotnet restore LedgerFlow.sln
dotnet build LedgerFlow.sln
cd web && npm ci && cd ..

3. Verify the install

No Docker, no Azure, no network — the tests run against an in-memory database and a fake ERP. This is exactly what CI runs:

dotnet test LedgerFlow.sln       # matcher, per-supplier policy, pipeline orchestration
cd web && npm run build && cd ..

InvoiceProcessorTests covers the whole extract → match → post-or-queue path including duplicate suppression, so a green run means the core is genuinely working — not just compiling.

4. Run it locally

docker compose up -d                       # SQL Server :1433 + Azurite :10000/:10001
dotnet run --project src/LedgerFlow.Api    # exception-queue API on :5080
cd web && npm run dev                      # review UI on :5173, proxied to the API

docker-compose.yml brings up SQL Server 2022 (SA password Your_strong_Pass123 — local only, never reuse it) and Azurite. Give SQL Server ~30 seconds on first start before the API connects.

What works locally: the exception queue, approve/reject, the analytics aggregates, and the matcher itself. What doesn’t: live extraction and the queue-triggered Functions — Document Intelligence and Service Bus have no local emulator, so they’re stubbed at their interfaces in tests and need real resources to run for real.

5. Provision Azure (optional)

az login
az deployment group create -g <resource-group> -f infra/main.bicep

infra/ provisions the whole estate with managed identity throughout — no secrets in app settings. Then LedgerFlow.Functions reads (via managed identity in Azure, local.settings.json locally):

Setting Purpose
DocumentIntelligenceEndpoint Azure AI Document Intelligence resource URL
ServiceBusConnection Service Bus namespace
BlobServiceUri storage account holding the invoice inbox
SqlConnectionString Azure SQL exception-queue database
ErpBaseUrl ERP posting + reference-data API

To run the Functions worker locally against those resources:

cd src/LedgerFlow.Functions
# create local.settings.json with the settings above (it is gitignored — never commit it)
func start

Troubleshooting