Lucrum
Приложение пополнения склада: FastAPI анализирует продажи, остатки, товары в пути и условия поставщиков (IEK, SystemElectric), React-дашборд…
О проекте
Команда: Lucrum
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Приложение пополнения склада: FastAPI анализирует продажи, остатки, товары в пути и условия поставщиков (IEK, SystemElectric), React-дашборд показывает рекомендации к заказу, менеджер утверждает позиции и выгружает их в 1С.
Как устроено
Loader сканирует XLSX партнёра в data/raw, при их отсутствии использует детерминированный синтетический датасет. Engine по POST /api/calculate рассчитывает рекомендации с фильтрами по складу и категории; недостающие сроки поставки по умолчанию 30 дней. Результаты хранятся в SQLite, позиции остаются pending до POST /api/orders/approve, затем идёт экспорт CSV для 1С. Загрузка нового XLSX инвалидирует рекомендации.
Ключевые решения
- replenishment calculation engine
- manager approval workflow
- 1C CSV export
- XLSX upload
- synthetic data fallback
Особенности
Явный human-in-the-loop: система не отправляет заказы поставщикам. Эндпоинт экспорта в 1С. README честно предупреждает, что ключи поставщиков предварительные и не сверены со справочником 1С.
Стек
Python · FastAPI · SQLite · React · TypeScript · Vite · Tremor · pytest
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-f96aaf61-lucrum.
README
README.mdLucrum
Lucrum is a procurement and inventory replenishment application for reviewing supplier order recommendations. The FastAPI backend analyzes sales, stock, goods in transit, and supplier terms. The React dashboard lets a manager inspect recommendations and approve selected positions. Orders remain pending until an employee explicitly approves them; the system does not submit orders to suppliers.
Repository layout
backend/ FastAPI application, calculation engine, XLSX loader, SQLite access
frontend/ React + TypeScript + Vite dashboard and its Node package files
data/raw/ Local partner XLSX inputs (ignored by Git)
data/sample/ Synthetic CSV examples and their documentation
docs/ API contract and calculation methodology
scripts/ Sample-data utility scripts
tests/ Backend pytest suite
requirements.txt
Frontend dependencies belong in frontend/package.json and frontend/package-lock.json. Install and run npm commands from frontend/. Python dependencies are managed separately in the root requirements.txt.
Requirements
- Python 3.10 or newer
- Node.js 20.19+ (or 22.12+) and npm
- Git
Install
Clone the repository and change into its root directory:
git clone <repository-url>
cd Lucrum
Backend dependencies
Create and activate a virtual environment, then install the Python requirements.
Windows PowerShell:
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
macOS or Linux:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
Frontend dependencies
cd frontend
npm ci
Copy the frontend API configuration template to .env.local:
Windows PowerShell:
Copy-Item .env.example .env.local
macOS or Linux:
cp .env.example .env.local
The template sets VITE_API_BASE_URL=http://127.0.0.1:8000. In Vite development mode, the frontend sends same-origin /api requests through its dev proxy to FastAPI. The backend currently has no CORS middleware, so use the Vite proxy for local development.
Run both services
Start the services in two terminals. Keep both running while using the dashboard.
Terminal 1: FastAPI backend
From the repository root, activate .venv if it is not already active, then run:
uvicorn backend.app:app --reload --host 127.0.0.1 --port 8000
The API is available at http://127.0.0.1:8000; Swagger UI is at http://127.0.0.1:8000/docs.
Terminal 2: Vite frontend
From the repository root:
cd frontend
npm run dev
Open the URL printed by Vite, normally http://localhost:5173.
The frontend checks the backend health endpoint and then loads the latest run and stock records. To create current recommendations, use the dashboard's calculation workflow. The backend calculation endpoint is POST /api/calculate.
Verify the integration
With both services running, check the backend directly:
curl http://127.0.0.1:8000/api/health
Expected response:
{"status":"ok","api_version":"v1"}
The dashboard's configured API adapter sends requests through Vite to:
GET /api/healthGET /api/ordersGET /api/stockPOST /api/calculate(optionalwarehouseandcategoryquery filters)POST /api/orders/approveGET /api/orders/export-1cPOST /api/upload
To build the frontend for production, run this in frontend/:
npm run build
npm run preview
Production hosting must route /api to FastAPI on the same origin or configure appropriate CORS middleware in the backend. CORS is not enabled by the current FastAPI application.
Backend tests and utilities
Run backend tests from the repository root with the virtual environment active:
pytest
Generate deterministic synthetic CSV examples with:
python scripts/generate_sample.py
The sample generator writes under data/sample/; these CSV files are documentation/demo data and are not loaded by the XLSX adapter.
Data and configuration
At startup, the backend scans data/raw/ for recognized XLSX source workbooks. If inputs are missing or malformed, it logs a warning and uses its deterministic in-memory synthetic dataset. Keep confidential partner workbooks local; the directory is ignored by Git.
| Variable | Default | Purpose |
|---|---|---|
LUCRUM_RAW_DIR | <repository>/data/raw/ | Directory containing partner XLSX workbooks |
LUCRUM_DB_PATH | <repository>/data/lucrum.sqlite3 | SQLite persistence path |
VITE_API_BASE_URL | Set in frontend/.env.local to http://127.0.0.1:8000 | Backend origin used as Vite proxy target in development; its presence also enables live API mode in the frontend |
VITE_API_PROXY | true in development | Keep /api requests on Vite's proxy; set to false only when intentionally making direct browser requests to the backend |
The supplied IEK and SystemElectric books do not include a separate legal supplier directory or explicit lead times. The loader uses provisional IEK and SYSTEMELECTRIC range keys and defaults missing lead times to 30 days. These supplier keys are not verified 1C directory codes; provide an authoritative supplier crosswalk before using the CSV export as a production 1C import.
Successful XLSX uploads reload the complete raw-data directory and invalidate existing recommendations. Run a fresh calculation after an upload before approving or exporting positions.
API and calculation documentation
Авторы коммитов
История коммитов
- 2026-09-23 17:53Merge pull request #1 from BAITC-Hacks/full-stack-integrationlapisUbi
- 2026-09-23 17:511meinetwegen
- 2026-09-23 16:51frontendlapisUbi
- 2026-09-23 16:16v2-backmeinetwegen
- 2026-09-23 15:59Second + ui + featureslapisUbi
- 2026-09-23 14:41v1-backmeinetwegen
- 2026-09-23 14:37First commitlapisUbi
- 2026-09-22 23:13Expand README with detailed project informationlapisUbi
Все коммиты (9)
- 2026-09-22 17:06Update README.mdlapisUbi
Структура репозитория (36 файлов)
.gitignore README.md backend/__init__.py backend/app.py backend/db.py backend/engine.py backend/loader.py docs/API.md docs/METHODOLOGY.md frontend/.env.example frontend/.gitignore frontend/THIRD_PARTY_LICENSE_TREMOR_APACHE-2.0.txt frontend/index.html frontend/package-lock.json frontend/package.json frontend/skills-lock.json frontend/src/components/OrderApprovalDashboard.vue frontend/src/components/ui/Badge.tsx frontend/src/components/ui/BarList.tsx frontend/src/components/ui/Card.tsx frontend/src/data/api.ts frontend/src/data/mock.ts frontend/src/data/types.ts frontend/src/lib/utils.ts frontend/src/main.tsx frontend/src/ui/App.tsx frontend/src/ui/styles.css frontend/src/vite-env.d.ts frontend/tsconfig.json frontend/vite.config.ts requirements.txt scripts/generate_sample.py tests/test_api.py tests/test_db.py tests/test_engine.py tests/test_loader.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.