{"id":47661509,"url":"https://github.com/aliivaezii/kpi-lens","last_synced_at":"2026-04-02T11:24:24.026Z","repository":{"id":346409438,"uuid":"1190093858","full_name":"aliivaezii/kpi-lens","owner":"aliivaezii","description":"Supply chain intelligence platform — KPI monitoring, anomaly detection, LLM analyst, and automated Excel/PPT reporting via FastAPI + MCP","archived":false,"fork":false,"pushed_at":"2026-03-24T00:53:49.000Z","size":106,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-24T16:35:52.902Z","etag":null,"topics":["anomaly-detection","anthropic","data-engineering","docker","fastapi","fastmcp","kpi","llm","machine-learning","mcp","pydantic","python","sqlalchemy","streamlit","supply-chain"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/aliivaezii.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","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-03-24T00:49:54.000Z","updated_at":"2026-03-24T07:14:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aliivaezii/kpi-lens","commit_stats":null,"previous_names":["aliivaezii/kpi-lens"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/aliivaezii/kpi-lens","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliivaezii%2Fkpi-lens","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliivaezii%2Fkpi-lens/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliivaezii%2Fkpi-lens/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliivaezii%2Fkpi-lens/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aliivaezii","download_url":"https://codeload.github.com/aliivaezii/kpi-lens/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliivaezii%2Fkpi-lens/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31305335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T09:48:21.550Z","status":"ssl_error","status_checked_at":"2026-04-02T09:48:19.196Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["anomaly-detection","anthropic","data-engineering","docker","fastapi","fastmcp","kpi","llm","machine-learning","mcp","pydantic","python","sqlalchemy","streamlit","supply-chain"],"created_at":"2026-04-02T11:24:23.193Z","updated_at":"2026-04-02T11:24:24.020Z","avatar_url":"https://github.com/aliivaezii.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# KPI-Lens\n\n[![CI](https://github.com/aliivaezii/kpi-lens/actions/workflows/ci.yml/badge.svg)](https://github.com/aliivaezii/kpi-lens/actions/workflows/ci.yml)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue)]()\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![Release](https://img.shields.io/github/v/release/aliivaezii/kpi-lens)](https://github.com/aliivaezii/kpi-lens/releases)\n[![Deploy on Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/aliivaezii/kpi-lens)\n\n\u003e An AI-powered supply chain intelligence platform that monitors 8 operational KPIs,\n\u003e detects anomalies using an ensemble of statistical detectors, and explains root causes\n\u003e via Claude — all accessible through a Streamlit dashboard, FastAPI, and an MCP server.\n\nSupply chain teams spend hours manually reviewing KPI dashboards and writing exception reports.\nKPI-Lens automates the entire loop: ingest → detect → explain → report.\nA single `docker compose up` gives you a live anomaly feed, LLM-generated root-cause narratives,\nand one-click Excel/PPT exports ready for SteerCo.\n\n## Features\n\n- **8 supply chain KPIs** tracked weekly: OTIF, Fill Rate, DFA, Inventory Turnover, DIO, Supplier DPPM, Lead Time Variance, PO Cycle Time\n- **Ensemble anomaly detection**: Z-score + IQR + CUSUM + Isolation Forest detectors with weighted voting\n- **LLM root-cause analysis**: Claude generates narrative explanations and recommended actions for each anomaly\n- **FastAPI backend** with 10+ endpoints for KPI data, anomaly management, and LLM chat\n- **Streamlit dashboard** with 5 pages: Command Center, KPI Deep Dive, Anomaly Log, LLM Analyst, Reports\n- **MCP server** for Claude Desktop integration — query live KPI data conversationally\n- **Automated ingestion**: CSV/Excel file watcher with Pydantic v2 validation and APScheduler cron\n- **Report generation**: Excel workbooks and PowerPoint decks for SteerCo presentations\n- **80%+ test coverage** across unit and integration tests; CI runs on Python 3.11 + 3.12\n\n## Quick Start\n\n### Docker Compose (recommended)\n\n```bash\ngit clone https://github.com/aliivaezii/kpi-lens.git\ncd kpi-lens\ncp .env.example .env          # Add your ANTHROPIC_API_KEY\ndocker compose up -d api dashboard\n\n# Seed 2 years of synthetic KPI data (first run only)\ndocker compose run --rm api python scripts/seed_database.py\n\n# Open the dashboard\nopen http://localhost:8501\n```\n\n### Local Development\n\n```bash\npython -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -e \".[dev]\"\ncp .env.example .env          # Add your ANTHROPIC_API_KEY\n\n# Seed the database\npython data/seeds/generate_kpis.py\n\n# Start services (three terminals)\nuvicorn kpi_lens.api.main:app --reload --port 8000\nstreamlit run kpi_lens/dashboard/app.py\npython -m kpi_lens.mcp_server.server   # optional: MCP for Claude Desktop\n```\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│  External Sources (CSV/Excel exports from ERP)              │\n└──────────────────────────┬──────────────────────────────────┘\n                           │ ingestion/loader.py + validator.py\n                           ▼\n┌─────────────────────────────────────────────────────────────┐\n│  SQLite DB  ←──  db/repository.py (only DB gateway)        │\n└──────┬────────────────────────────────────────────────────┬─┘\n       │                                                    │\n       ▼                                                    ▼\n┌─────────────────────┐                     ┌──────────────────────────┐\n│  anomaly/ensemble   │   AnomalyResult     │  api/  (FastAPI)         │\n│  ┣ threshold        │ ────────────────►   │  dashboard/ (Streamlit)  │\n│  ┣ zscore/iqr/cusum │                     │  mcp_server/ (FastMCP)   │\n│  ┗ isolation forest │                     └──────────────────────────┘\n└─────────┬───────────┘\n          │ async (non-blocking)\n          ▼\n┌─────────────────────────────────────────────────────────────┐\n│  llm/analyst.py  →  Claude via Anthropic SDK               │\n│  Generates narrative + recommended actions per anomaly      │\n└─────────────────────────────────────────────────────────────┘\n          │\n          ▼\n┌─────────────────────────────────────────────────────────────┐\n│  reporting/  →  Excel workbook  +  PowerPoint deck          │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## KPI Reference\n\n| KPI | Unit | Direction | Green threshold | Industry Benchmark |\n|---|---|---|---|---|\n| OTIF Delivery Rate | % | Higher is better | 95% | 95.5% |\n| Order Fill Rate | % | Higher is better | 97% | 96% |\n| Demand Forecast Accuracy | % | Higher is better | 85% | 80% |\n| Inventory Turnover | turns/yr | Higher is better | 12 | 10 |\n| Days Inventory Outstanding | days | Lower is better | 30 | 35 |\n| Supplier DPPM | ppm | Lower is better | 500 | 800 |\n| Lead Time Variance | days | Lower is better | 3 | 5 |\n| PO Cycle Time | days | Lower is better | 14 | 18 |\n\n## API Reference\n\n| Method | Endpoint | Description |\n|---|---|---|\n| GET | `/api/health` | Health check |\n| GET | `/api/kpis/snapshot` | Latest value + health status for all 8 KPIs |\n| GET | `/api/kpis/{name}/series` | Time-series data for one KPI |\n| GET | `/api/kpis/{name}/entities` | Entity (supplier) breakdown |\n| GET | `/api/kpis/{name}/benchmarks` | Industry benchmark percentiles |\n| GET | `/api/anomalies` | Recent anomalies with severity filter |\n| POST | `/api/anomalies/{id}/acknowledge` | Acknowledge an anomaly |\n| POST | `/api/llm/chat` | Chat with the supply chain analyst |\n| POST | `/api/reports/enqueue` | Enqueue an anomaly report |\n\nInteractive docs: `http://localhost:8000/api/docs`\n\n## Project Structure\n\n```\nkpi_lens/\n├── db/           # repository.py — the only DB gateway; schema.py — ORM models\n├── kpis/         # definitions.py — 8 KPI constants; snapshot.py — enrichment\n├── anomaly/      # base.py, threshold, statistical, ml, ensemble detectors\n├── llm/          # client.py (retry), analyst.py, context_builder.py, prompts.py\n├── ingestion/    # loader.py, validator.py (Pydantic v2), scheduler.py (APScheduler)\n├── reporting/    # excel_exporter.py, powerpoint.py, pdf_converter.py\n├── api/          # FastAPI app + routes (kpis, anomalies, llm, reports, health)\n├── dashboard/    # Streamlit app + 5 pages\n└── mcp_server/   # FastMCP tools for Claude Desktop\nconfig/           # kpis.yaml, anomaly.yaml, report.yaml (change without redeploy)\nscripts/          # seed_database.py, run_anomaly_scan.py\ntests/\n├── unit/         # 8 test files, 70+ tests, no I/O\n└── integration/  # FastAPI test client, in-memory DB, mocked LLM\n```\n\n## Running Tests\n\n```bash\n# Unit tests (fast, no infrastructure needed)\npytest tests/unit/ -v --cov=kpi_lens --cov-fail-under=80\n\n# Integration tests (FastAPI + in-memory DB)\npytest tests/integration/ -v\n\n# All tests\npytest tests/ -v --cov=kpi_lens --cov-fail-under=80\n```\n\n## Seeding Data\n\n```bash\n# Default: 104 weeks (2 years) of synthetic data for all 8 KPIs\npython scripts/seed_database.py\n\n# Custom parameters\npython scripts/seed_database.py --weeks 52\n\n# Run anomaly detection on seeded data\npython scripts/run_anomaly_scan.py\n```\n\n## Deployment\n\n### Render (full stack — API + Dashboard)\n\nClick **Deploy on Render** above or create a `Web Service` pointing to this repo.\nRender reads `render.yaml` automatically. Set `ANTHROPIC_API_KEY` in the environment\nvariables panel before deploying.\n\n### Streamlit Community Cloud (dashboard only)\n\n1. Fork this repo\n2. Go to [share.streamlit.io](https://share.streamlit.io) → New app\n3. Set **Main file path**: `kpi_lens/dashboard/app.py`\n4. Under **Advanced settings → Secrets**, add:\n   ```toml\n   ANTHROPIC_API_KEY = \"sk-ant-...\"\n   DATABASE_URL = \"sqlite:///kpi_lens.db\"\n   ```\n5. Deploy — Streamlit seeds the demo DB on first run\n\n### Docker Compose (self-hosted)\n\n```bash\ngit clone https://github.com/aliivaezii/kpi-lens.git\ncd kpi-lens\ncp .env.example .env   # add ANTHROPIC_API_KEY\ndocker compose up -d api dashboard\ndocker compose run --rm api python scripts/seed_database.py\nopen http://localhost:8501\n```\n\n## Data\n\nThe platform ships with a realistic **synthetic dataset** generated by `data/seeds/generate_kpis.py`:\n- 104 weeks × 8 KPIs × 5 supplier entities = 4,160 weekly records\n- Additive model with seasonality, trend, and deliberate anomaly injection at known dates\n- Designed to exercise all four detector types (threshold, Z-score, IQR, CUSUM)\n\nTo use your own data, drop a CSV into `data/imports/` and run the ingestion scheduler,\nor POST directly to `POST /api/ingest`. Format reference: `data/samples/sample_kpi_data.csv`.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliivaezii%2Fkpi-lens","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faliivaezii%2Fkpi-lens","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliivaezii%2Fkpi-lens/lists"}