Skip to content
Hafizullah Mahmudi Data Systems & Business Intelligence Developer
Supply Dashboard Data Analysis AI

Nexora Supply Intelligence

Nexora Supply
Self-hosted · ASP.NET Core + PostgreSQL

Supply-chain analytics · Case study

Nexora Supply Intelligence

A faithful port of a supply-chain analytics platform from a Cloudflare edge stack to a self-hosted ASP.NET Core (.NET 10) API over PostgreSQL 18 — serving the same React frontend, with parity guaranteed by construction.

Role · Full-stack port & data layer Stack · React · ASP.NET Core · PostgreSQL Year · 2026
GET /api/analytics/executive
{
  "ok": true,
  "data": {
    "kpis": [
      {
        "metricId": "revenue",
        "value": 802343764,
        "previousValue": 966125736,
        "deltaPct": -0.1695,
        "sparkline": [ /* 12 buckets */ ]
      }, /* …29 more metrics */
    ]
  },
  "meta": { "generatedAt": "2026-…" }
}
30
Metrics in one semantic layer
62,000+
Deterministic seed rows
4
Minimal-API endpoints
21
Parity tests, all green
01

The brief

The original Nexora ran entirely on Cloudflare — a React frontend, Pages Functions in TypeScript, and a D1 (edge SQLite) database. The goal: move it to a self-hosted, portable stack that any team can run on their own infrastructure, without changing a single pixel of the frontend.

The constraint that shaped everything: parity by construction. Rather than hand-transcribing logic and hoping it matched, the port reuses the original's validated artifacts — the same metric definitions, the same deterministic data generator — so the new edition produces the same numbers as the old one, provably.

02

Architecture

The React build is served as static files straight from wwwroot; every /api/* call lands on an ASP.NET Core minimal API, which reads through Dapper and hand-written SQL against PostgreSQL. A domain layer holds the metric registry and KPI math.

Browser React · Vite · ECharts ASP.NET Core minimal API · .NET 10 endpoints · filters headers · CSP · cache Domain metrics · KPI math Dapper hand-written SQL Postgres v18 /api/*
Concern Original — Cloudflare This edition
Frontend React 18 · Vite · ECharts same build, served from wwwroot
API Pages Functions (TypeScript) ASP.NET Core minimal API (.NET 10)
Data access D1 SQL bindings Dapper + hand-written SQL
Database D1 — edge SQLite PostgreSQL 18
AI copilot Workers AI binding disabled — no edge binding off Cloudflare
03

What's inside

Semantic layer

One source of metric truth

Thirty metric definitions — formats, targets, status bands, direction — extracted verbatim from the original TypeScript registry into a single metrics.json, so definitions match exactly rather than being re-typed.

30 metrics · extracted, not transcribed
Data access

Dapper + hand-written SQL

No ORM guesswork — explicit SQL against PostgreSQL, with null-safe ratio math, ABC/XYZ segmentation, and alert-rule metadata ported into the domain layer.

weekly buckets · date_trunc('week', col::date)
Parity

Same generator, same rows

Seed data is emitted by the same validated TypeScript generator as the original, as PostgreSQL INSERTs. A deterministic RNG means the same rows as the D1 database — locked down by 21 xUnit parity tests.

21 tests · 0 failures
Endpoints

Faithful API contract

Each route mirrors its Pages Functions counterpart — the same response envelope, filters, pagination, and cache + security headers / CSP — so the untouched React app can't tell the difference.

envelope · { ok, data, meta }
04

Data model & API surface

Four PostgreSQL migrations (translated from the SQLite schema) load a deterministic seed of ~62,000 rows across six tables. Dates are stored as ISO text and booleans as smallint 0/1, matching D1 for parity.

Seed data — verified row counts
products72
inventory_snapshots6,412
sales_orders3,680
purchase_orders3,386
shipments3,671
alerts114
API endpoints
GET /api/healthliveness
GET /api/metaregistry + ranges
GET /api/analytics/executiveKPI board
GET /api/analytics/inventoryABC / XYZ
GET /api/alertsrules feed
Backend
ASP.NET Core .NET 10C#Minimal APIDapperNpgsql
Data
PostgreSQL 18Hand-written SQLDimensional schemaRLS-ready
Frontend (reused)
React 18ViteECharts
05

Ship it

Because it's self-contained, deployment doesn't depend on the host having a runtime installed — the whole thing travels as one artifact and points at a Postgres it can reach.

  • LiveSelf-contained win-x64 build — the .NET 10 runtime is bundled, so it runs on shared Windows hosting regardless of installed frameworks.
  • LiveDeployed to SmarterASP.NET over a remote PostgreSQL, with the connection string injected via configuration — no control-panel setup beyond the app pool.
  • LiveVerified end-to-end — schema + ~62k-row seed loaded remotely, and every endpoint returns real data against the live database.
  • NextRe-enable an AI copilot through a pluggable provider, restoring the natural-language query path the edge binding used to serve.

Nexora Consumer Products, Inc. is a fictitious company. All data is synthetic and generated for demonstration purposes only. Metrics, seed counts, and the API contract shown here reflect the actual build.