An inventory & supply-chain risk analytics API. Given historical demand for a set of SKUs across multiple sites — plus lead time, ordering cost, holding cost, and a target service level — SupplyLens calculates, for each SKU/site combination:
- Economic Order Quantity (EOQ) — the order size that minimises total ordering + holding cost
- Safety Stock — buffer stock to cover demand variability during lead time, at a chosen service level
- Reorder Point (ROP) — the stock level that should trigger a new order
- Stockout risk flag — 🔴 / 🟠 / 🟢 per SKU/site, comparing current on-hand stock to the ROP
It surfaces which sites and SKUs are at risk of running out, and what to order — the kind of operations-research logic used in warehousing and mine-site inventory planning.
🔗 Live demo: coming soon 📂 Frontend: a
/projects/supplylenspage in my portfolio site (coming soon)
A single solution split into three projects, so business logic never lives in a web controller:
flowchart LR
FE[Frontend<br/>Next.js page] -- HTTP/JSON --> API
subgraph Backend [Backend solution]
API[SupplyLens.Api<br/>controllers · DTOs · auth · Swagger]
CORE[SupplyLens.Core<br/>EOQ / safety-stock / ROP logic · models]
INFRA[SupplyLens.Infrastructure<br/>EF Core · PostgreSQL]
API --> CORE
API --> INFRA
INFRA --> CORE
end
INFRA -- SQL --> DB[(PostgreSQL)]
SupplyLens.Core— domain models and the EOQ / safety-stock / ROP calculations. Pure C#, depends on nothing. This is where the business logic lives.SupplyLens.Infrastructure— data access: EF CoreDbContext, migrations, PostgreSQL.SupplyLens.Api— the web layer: HTTP endpoints, request validation, JWT auth, Swagger docs.SupplyLens.Core.Tests— xUnit tests for the calculation logic.
Dependencies point one way (Api → Core ← Infrastructure): the math has no knowledge of the web
or the database, which keeps it isolated, testable, and reusable.
| Layer | Technology |
|---|---|
| Language / runtime | C# · .NET 10 |
| Web framework | ASP.NET Core (controllers) |
| Data access | EF Core · Npgsql |
| Database | PostgreSQL (Azure Database for PostgreSQL) |
| Auth | JWT · BCrypt password hashing |
| API docs | Swagger / OpenAPI |
| Tests | xUnit |
| Hosting | Azure App Service (planned) |
Prerequisites: .NET SDK 10 and a PostgreSQL database (this project uses Azure Database for PostgreSQL; any Postgres works — local, Docker, or hosted).
# from the repository root
dotnet build # build all projects
dotnet test # run the unit tests
dotnet run --project SupplyLens.Api # start the APIThe API prints the URL it's listening on (e.g. http://localhost:5xxx). Open /swagger on that
URL for interactive API documentation.
| Metric | Formula |
|---|---|
| EOQ | sqrt( (2 × annualDemand × orderingCost) / holdingCostPerUnit ) |
| Safety Stock | zScore × stdDevOfDemandDuringLeadTime |
| Reorder Point | (averageDailyDemand × leadTimeDays) + safetyStock |
The service-level z-score uses a lookup table for common confidence levels (90% → 1.28, 95% → 1.645, 99% → 2.33).
🚧 Work in progress — built as a focused portfolio project to demonstrate production-quality C# / ASP.NET Core. See commit history for progress.