Inventory forecasting, supplier selection, and AI-driven AP payment agent for a fintech / ops hackathon.
This repo contains:
- a
FastAPIbackend that serves forecast-driven dashboard data, supplier recommendations, and order endpoints - a
React + TypeScript + Vitefrontend that displays inventory risk, recommended suppliers, alternatives, and checkout flow - a
Streamlitpayment app (Black_swan) that handles the full AP processing pipeline — PO creation, invoice matching, Gemini AI analysis, and Swan payment execution
The app covers an end-to-end MRO procurement workflow:
- the backend uses the demand forecasting dataset to build dashboard items enriched with forecast output and ranked supplier options
- the frontend shows items sorted by urgency, lets the user inspect the optimal supplier, compare alternatives, and confirm an order
- on confirmation, the frontend redirects to the Streamlit AP agent, passing item and supplier data via URL parameters
- the AP agent normalises the request, creates a PO, parses the invoice, runs a 2-way match, calls Gemini for a risk recommendation, and presents a payment draft for human approval
- approval triggers a real credit transfer via the Swan sandbox API, including SCA consent redirect
frontend/
src/
components/
api.ts
App.tsx
styles.css
backend/
app/
core/
presentation/
routes/
schemas/
repositories/
services/
main.py
data/
supplier_dataset.xlsx
alembic/
requirements.txt
Black_swan/
streamlit_app.py # main AP agent UI
gemini_service.py # Gemini AI calls (request normalisation, invoice parsing, risk analysis)
services/
audit.py
invoice_parser.py
matching.py
payment_draft.py
po_builder.py
swan_executor.py
pages/
callback.py # Swan OAuth + SCA consent callback handler
data/
mock_request.json
mock_invoice.json
requirements.txt
demand-forecasting-kernels-only/
train.csv
cd frontend
npm install
npm run devURL: http://localhost:5173
cd backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
python -m uvicorn app.main:app --host 127.0.0.1 --port 8000URLs:
- API root:
http://127.0.0.1:8000 - Docs:
http://127.0.0.1:8000/docs - Health:
http://127.0.0.1:8000/health
cd Black_swan
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then fill in credentials (see below)
streamlit run streamlit_app.py --server.port 8501URL: http://localhost:8501
| Variable | Description |
|---|---|
GEMINI_API_KEY |
Gemini API key (or set GOOGLE_CLOUD_PROJECT for Vertex AI ADC) |
SWAN_CLIENT_ID |
Swan sandbox OAuth client ID |
SWAN_CLIENT_SECRET |
Swan sandbox OAuth client secret |
SWAN_REDIRECT_URI |
Must be registered in Swan Dashboard — default http://localhost:8501/callback |
SWAN_USER_ACCESS_TOKEN |
Optional — pre-filled user token; obtained automatically via the OAuth flow |
If you only want the frontend dashboard and its backend data feed:
- you do not need PostgreSQL for
GET /api/v1/dashboard/items - that endpoint uses:
demand-forecasting-kernels-only/train.csvbackend/data/supplier_dataset.xlsx- the forecasting service
You need PostgreSQL if you want to use:
GET /api/v1/suppliersPOST /api/v1/suppliersGET /api/v1/inventory/currentPOST /api/v1/inventoryPOST /api/v1/recommendations/suppliersPOST /api/v1/orders/draftsPOST /api/v1/orders/{order_id}/confirmGET /api/v1/orders/{order_id}
Update backend/.env with a valid DATABASE_URL and run migrations:
cd backend
source .venv/bin/activate
alembic upgrade headQuick start with Docker:
docker run -d --name pg -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgresGET /health
{ "status": "ok" }GET /api/v1/dashboard/items
Example response shape:
{
"items": [
{
"id": "store-8-item-1",
"name": "Thermal Receipt Paper",
"sku": "BOB-POS-ROLL-57",
"unit_label": "rolls",
"store_id": 8,
"item_id": 1,
"current_quantity": 96,
"reorder_point": 168,
"status": "warning",
"expected_shortage_date": "2018-01-03",
"required_quantity": 241,
"forecast_source": "chronos",
"best_option": {
"supplier_name": "Prime Direct",
"unit_price": 282.51,
"lead_time_days": 2,
"reliability_score": 0.6254,
"available_quantity": 745
},
"alternatives": [
{
"supplier_name": "Apex Partners",
"unit_price": 246.05,
"lead_time_days": 25,
"reliability_score": 0.6535,
"available_quantity": 891
}
]
}
]
}POST /api/v1/forecasting/predict
{
"store_id": 1,
"item_id": 1,
"current_stock": 80,
"prediction_days": 14
}Response:
{ "required_quantity": 609 }The frontend:
- fetches dashboard items from
GET /api/v1/dashboard/items - sorts items by priority:
critical, thenwarning, thenhealthy - shows the optimal supplier inside the expanded row
- opens supplier alternatives in a popover
- on supplier confirmation, redirects to the Streamlit payment app (
VITE_PAYMENT_URL, defaulthttp://localhost:8501) with item, SKU, supplier, quantity, and unit price as URL query parameters
On arrival from the frontend, the Streamlit app runs this pipeline:
- Request normalisation — Gemini validates and structures the procurement request
- PO creation — builds a purchase order from the normalised data
- Invoice parsing — generates a mock invoice (exact match / price mismatch / qty mismatch scenario) and structures it via Gemini
- 2-way matching — compares PO vs invoice amounts, quantities, and IBAN
- AI risk analysis — Gemini produces a recommendation (
proceed/hold/block) with confidence score and risk flags - Human approval — the reviewer approves or rejects; approval triggers Swan OAuth if no token is present
- Payment execution — Swan sandbox credit transfer; SCA consent redirect if required
Backend:
cd backend
source .venv/bin/activate
pytestFrontend build:
cd frontend
npm run build