О проекте
Команда: ATKS
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Система анализа запасов и рекомендаций по закупкам на данных Systeme Electric. В неё входят веб-панель, мобильное складское приложение и Python-сервис прогнозов. Заказы группируются по поставщикам, заказ создаётся только после подтверждения менеджера.
Как устроено
Excel-файлы (продажи, остатки, сезонность, MOQ, товар в пути) обрабатываются Python-модулем intelligence. Он выявляет выбросы от крупных разовых продаж, stockout и потерянный спрос и строит скорректированный спрос. Прогноз строит сезонный метод с годовым ростом и модель CatBoost, модуль reorder формирует рекомендации по закупкам. Результаты отдаёт FastAPI через PHP REST API с MySQL в веб-панель и мобильное приложение на React Native (Expo). Ассистент на OpenAI выбирает инструменты над проверенными результатами и не меняет остатки.
Ключевые решения
- CatBoost
- сезонный прогноз с годовым ростом
- детекция выбросов
- stockout / lost demand коррекция
- reorder с учётом MOQ и товара в пути
- LLM tool selection
Особенности
Кроме расчёта закупок есть мобильное приложение для складских операций: приёмка, выдача, перемещение, списание, инвентаризация, сканирование Barcode/QR. Сохранены аудиторские артефакты обработки данных: коррекции, выбросы, сверка знаков транзакций. Ограничения данных, например отсутствие client_id, описаны в README.
Стек
Python · FastAPI · CatBoost · PHP · MySQL · Composer · React Native · Expo · JavaScript
Модели
OpenAI
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-87882dff-atks.
README
README.mdQoyma
Система анализа запасов, рекомендаций по закупкам и мобильных складских операций. Веб-панель и приложение на русском языке. Qoyma используется как название и визуальный бренд, SupplyMind AI как название хакатонного проекта.
Инструкция предназначена для запуска на новом компьютере. Для первой проверки достаточно браузера: телефон, OpenAI-ключ и обучение модели не обязательны.
Содержание
- Что работает и какие есть ограничения
- Требования
- Установка на Windows
- Запуск: три терминала
- Адреса и логины
- Проверка через интерфейс
- Проверка REST API
- Запуск на телефоне
- Подключение OpenAI
- Деморежим подтверждения заказов
- Автоматические тесты
- Пересчёт Python-модели
- Linux и macOS
- Частые ошибки
- Структура и передача проекта
1. Что работает сейчас
В проекте два разных источника данных. Их важно не путать при проверке.
| Часть | Источник | Возможности |
|---|---|---|
| Рабочий склад | MySQL | Товары, склады, продажи, поставщики, операции, история и подтверждённые заказы |
| План Systeme Electric | Python, Excel и CSV | Каталог, прогнозы, объяснения, фильтры, экспорт CSV; пока только просмотр |
| Ассистент | Проверенные результаты Python | Локальный разбор без ключа или выбор инструментов через OpenAI; не изменяет остатки и не утверждает заказы |
| Демо закупочного процесса | Mock на товарах MySQL, включается отдельно | Расчёт, группировка по поставщикам, изменение количества, подтверждение менеджером и приёмка |
Мобильные вкладки: Операции, Склад, Прогнозы, История, Профиль. Поддерживаются приёмка, выдача, перемещение, списание и инвентаризация, Barcode/QR и ручной ввод кода.
Веб-разделы: Обзор, Остатки, Товары, Продажи, Поставщики, Прогноз, Закупки, Заказы поставщикам, AI-агент.
Заказы не отправляются поставщикам автоматически. В операционном деморежиме только подтверждение менеджера создаёт заказ и ожидаемую поставку. Фактический остаток меняется при складской операции, не при расчёте закупки.
Ограничения текущей версии
- Исторические остатки Systeme Electric пока не синхронизированы с текущими остатками MySQL.
- У внешних рекомендаций нет согласованной привязки к складам, поставщикам и срокам поставки. Их подтверждение отключено, отображается «Поставщик не указан».
- Нет полной интеграции категорий и отдельного внешнего прогноза роста. В прогнозе используется история спроса, включая сезонный метод с годовым ростом.
- Месячные всплески определяются автоматически, но без
client_idнельзя подтвердить разовую крупную покупку конкретного клиента. - Месячные снимки остатков не дают точного числа дней stockout. Неизвестные данные не подменяются нулями.
- Jetson/hardware, Figma и публикация в магазинах приложений не входят в текущую поставку.
Подробный аудит: docs/HACKATHON-READINESS.md.
Веб-панель / React Native (Expo)
|
v
PHP REST API :8000 <----> MySQL :3306
|
v
Python FastAPI :8004 <---- Excel / CSV / модель
|
+---- OpenAI (необязательно, по запросу ассистента)
PHP проверяет авторизацию. Python слушает только 127.0.0.1; телефон и браузер получают его результаты через PHP, не обращаются к FastAPI напрямую.
2. Что установить заранее
| Программа | Версия / требование | Назначение |
|---|---|---|
| PHP | 8.1+, расширения pdo_mysql, curl, openssl | Backend и REST API |
| Composer | 2.x | PHP-зависимости |
| MySQL | 8.x, запущен на 3306 | База данных |
| Node.js и npm | Рекомендуется Node 24 LTS; для Node 22 нужна версия не ниже 22.13 | Expo, веб-иконки и тесты |
| Python | Для воспроизводимого запуска используйте Python 3.13, 64-bit | FastAPI, обработка данных, CatBoost |
| Браузер | Современный Chrome, Edge, Firefox или Safari | Веб и мобильная веб-версия |
| Expo Go | Только для телефона; совместимый с SDK 57 | Нативное приложение |
Ссылки: Node.js, Python, Composer, MySQL Community Server, PHP для Windows.
Проект использует Expo SDK 57, React Native 0.86 и React 19.2.3. Минимальная версия Node 22.13.x указана в документации SDK 57. Не устанавливайте глобальный старый expo-cli и не обновляйте SDK при первоначальном запуске.
Если используете OSPanel или другой серверный комплект, запустите в нём MySQL и используйте его PHP. PHP, Composer, Node и Python должны быть доступны через PATH. После установки программ откройте новый терминал.
Проверка в PowerShell:
php -v
php --ini
php -m
composer --version
node --version
npm.cmd --version
python --version
mysql --version
В php -m должны быть PDO, pdo_mysql, curl, openssl. Если расширение выключено, включите его в php.ini, который показывает php --ini, и перезапустите PHP.
Если mysql не найден в PATH, SQL ниже можно выполнить в MySQL Workbench или SQL-консоли серверного комплекта. Сам MySQL-сервис должен быть запущен.
3. Первоначальная установка на Windows
Команды выполняются в PowerShell. Не вводите префиксы PS ...>, >> и текст сообщений терминала.
3.1. Получить проект
Скачайте архив от команды или клонируйте переданный командой репозиторий. Распакуйте в отдельную папку. Одной папки smartstock-mobile недостаточно.
Далее используется пример D:\Projects\smartstock-hackathon. Если путь другой, замените его во всех командах.
cd D:\Projects\smartstock-hackathon
Get-ChildItem
В корне должны быть README.md, composer.json, composer.lock, config.php, router.php, setup.php, папки src, api, web, smartstock-mobile, intelligence, tests.
Для демонстрации нужны intelligence/data/raw и intelligence/data/processed. Если их нет в репозитории, получите у команды комплект данных отдельно. Не переименовывайте Excel: имена заданы в intelligence/loader.py.
3.2. Создать пустую базу
Запустите MySQL и подключитесь с вашей локальной административной учётной записью:
mysql -u root -p
Введите пароль MySQL. В появившейся SQL-консоли, не в PowerShell:
CREATE DATABASE IF NOT EXISTS smartstock
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
SHOW DATABASES LIKE 'smartstock';
EXIT;
Пароль MySQL не является паролем менеджера приложения. База не создаётся командой setup.php: сначала выполните SQL выше.
Для локального демо можно использовать локального администратора. Для общего сервера нужен отдельный пользователь с правами на выделенную базу. Не подключайте демонстрацию к производственной БД.
3.3. Настроить PHP .env
В корне проекта:
if (-not (Test-Path -LiteralPath '.env')) {
Copy-Item -LiteralPath '.env.example' -Destination '.env'
}
notepad .env
Пример содержимого для основного режима с Python:
DB_HOST=127.0.0.1
DB_NAME=smartstock
DB_USER=root
DB_PASSWORD=ваш_пароль_MySQL
INTELLIGENCE_API_URL=http://127.0.0.1:8004
ML_API_URL=
ML_API_KEY=
Укажите свои host/user/password. Если у локального MySQL действительно нет пароля, оставьте [скрыто]. Не используйте пример ваш_пароль_MySQL как настоящий пароль. Сохраните файл как .env, не .env.txt, в UTF-8 без BOM.
INTELLIGENCE_API_URL указывает на новый FastAPI. Не записывайте его в ML_API_URL: это старый, другой контракт. DB_PORT в текущем конфиге не используется; инструкция рассчитана на MySQL 3306.
3.4. Установить зависимости
В корне проекта:
composer install
npm.cmd ci --prefix web
npm.cmd ci --prefix smartstock-mobile
python -m venv .venv-intelligence
.\.venv-intelligence\Scripts\python.exe -m pip install --disable-pip-version-check -r intelligence/requirements.txt
Дождитесь завершения каждой команды. При ошибке сначала устраните её, затем продолжайте.
composer installсоздаётvendor/поcomposer.lock.npm ciиспользуетpackage-lock.json; lock-файлы обоих Node-проектов должны быть в архиве.- Python-окружение создаётся на вашем компьютере. Чужую
.venvс Windows/Linux переносить нельзя. - Активировать окружение не нужно: команды используют полный путь к его Python.
- Если
pythonоткрывает Microsoft Store, установите Python и настройтеPATH. При наличии Windows Launcher можно использоватьpy -3.13 -m venv .venv-intelligence.
3.5. Создать таблицы и учебный товар
```powershell
php setup.php
php demo-demand.php
```
Ожидаемый результат setup.php:
SupplyMind schema ready. Existing data preserved.
Команда создаёт таблицы и две демоучётные записи. Повторный запуск не очищает БД и не сбрасывает пароль существующего аккаунта.
demo-demand.php добавляет один учебный SKU SM-DEMO-OAT-06 с историей продаж. В пустой базе также создаются два склада и демонстрационный поставщик. Повторный запуск сообщает Demand demo already exists. и не добавляет товар повторно.
Не запускайте php seed.php. Это старый скрипт с очисткой данных, не часть текущей установки.
После чистой установки рабочий склад содержит один учебный товар, не 724 позиции. Каталог Systeme Electric показывается отдельно и не импортируется в текущие остатки.
4. Запуск: три отдельных терминала
MySQL должен оставаться включённым. Каждый сервер работает в своём окне. Пока сервер работает, приглашение ввода не возвращается. Это нормально.
Терминал 1: PHP и веб-панель
cd D:\Projects\smartstock-hackathon
php -S 0.0.0.0:8000 router.php
Ожидается PHP ... Development Server ... started.
Откройте http://localhost:8000/manager. Отдельный npm run dev для веб-панели не нужен: её обслуживает PHP.
Терминал 2: Python ML API
cd D:\Projects\smartstock-hackathon
.\.venv-intelligence\Scripts\python.exe -m uvicorn intelligence.api.main:app --host 127.0.0.1 --port 8004
Ожидаются Application startup complete и Uvicorn running on http://127.0.0.1:8004.
Эквивалентный вариант через скрипт, вместо команды выше:
powershell -NoProfile -ExecutionPolicy Bypass -File tools/start-intelligence.ps1
Не запускайте оба варианта одновременно.
Проверьте http://127.0.0.1:8004/health: ожидается status: "ok", metadata.pipeline_ready: true. Swagger: http://127.0.0.1:8004/docs.
Для первого запуска подготовлены готовые прогнозы. Обучение при старте API не запускается.
Терминал 3: мобильная веб-версия
cd D:\Projects\smartstock-hackathon\smartstock-mobile
npx.cmd expo start --web --port 8081
Откройте http://localhost:8081. Это мобильное приложение в браузере; для проверки форм и операций телефон не нужен.
Expo запускается из smartstock-mobile, не из корня PHP-проекта. Если интерфейс не обновился, остановите Expo через Ctrl+C и повторите команду с --clear.
Если 8081 занят, сначала проверьте, не запущен ли уже ваш Expo. Для второй копии можно выбрать 8082:
npx.cmd expo start --web --port 8082
Тогда откройте http://localhost:8082. PHP остаётся на 8000, Python на 8004. Смена порта Expo не меняет адрес backend.
Остановка и повторный запуск
Ctrl+C останавливает сервер в его терминале. Не закрывайте PHP/Python во время демонстрации. При следующем запуске достаточно включить MySQL и повторить три команды серверов; установка зависимостей и создание учебного товара повторно не нужны.
5. Адреса и логины
| Что открыть | Адрес |
|---|---|
| Веб-панель менеджера | http://localhost:8000/manager |
| Мобильная веб-версия | http://localhost:8081 |
| Проверка PHP | http://localhost:8000/ |
| Проверка Python | http://127.0.0.1:8004/health |
| Swagger Python | http://127.0.0.1:8004/docs |
| MySQL | TCP 127.0.0.1:3306, база smartstock; не ссылка для браузера |
| Роль | Логин | Пароль |
|---|---|---|
| Менеджер | [email protected] | SupplyMind2026! |
| Сотрудник склада | [email protected] | SupplyMind2026! |
Веб-панель требует менеджера. В мобильном приложении используйте сотрудника склада. Пароль вводится без обратных кавычек, с большой S, большой M и ! в конце.
0.0.0.0 означает адрес прослушивания, не адрес страницы. На компьютере открывайте localhost, на телефоне используйте LAN IP компьютера.
Для просмотра MySQL подключите клиент БД с host/user/password/database из .env. phpMyAdmin в проект не входит, универсальной ссылки на него нет.
6. Проверка через интерфейс
6.1. Каталог и прогнозы
- Войдите менеджером в веб-панель и нажмите «Обновить результаты».
- В «Товары» выберите источник «Systeme Electric».
- Проверьте поиск по названию, коду и артикулу, например
IMT35180. - Откройте «Закупки», фильтр «К закупке» и подробный разбор товара.
- Нажмите значок скачивания: CSV должен содержать текущий поиск/фильтр, объяснение и статус данных.
- В мобильном приложении откройте «Прогнозы»: используется тот же PHP API.
Для поставляемого снимка от 23.09.2026 ожидаются:
| Показатель | Значение |
|---|---|
| Общий каталог | 724 SKU |
| Готовые прогнозы | 422 |
| Без прогноза | 302 |
| К пополнению | 21 позиция |
| С неполными входами | 25 позиций |
| Период прогноза | Октябрь 2026 |
Проверка арифметики IMT35180, код 030200203_:
Остаток по файлу: 4668
В пути: 0
Прогноз спроса: 4928
Не хватает: 260
Кратность: 900
К закупке: 900
Количество округляется вверх до кратности. Дата остатка взята из файла, не означает текущее состояние склада. После изменения данных/модели эти контрольные числа могут измениться.
6.2. Ассистент
В «AI-агент» задайте один из вопросов:
Какие товары нужно закупить?
Почему IMT35180 нужно закупить?
Какие товары требуют проверки данных?
Как товары в пути влияют на закупки?
Без ключа отображается «Локальный разбор, без OpenAI». Это ограниченный поиск фактов по коду/артикулу и типу запроса, не языковая модель. Ответ и этапы проверки показываются на русском. От вопроса заказы не создаются.
6.3. Складские операции
Эти проверки действительно изменяют данные. Выполняйте их только в своей тестовой БД. Нужен учебный товар MySQL, не внешний Python-каталог.
- В мобильной веб-версии войдите сотрудником склада.
- В «Операции» выберите Алматы и найдите
SM-DEMO-OAT-06ручным вводом. - Запишите исходный остаток
Q. В свежей базе послеdemo-demand.phpон равен 12. - «Приёмка» на 5 без привязки к заказу: остаток
Q + 5. - «Выдача» на 2: остаток
Q + 3. - «Перемещение» на 1 в Астану: на исходном складе
Q + 2, на складе назначения прибавится 1. - «Списание» на 1 с причиной
Учебная проверка: остаток исходного складаQ + 1. - «Инвентаризация» с фактическим количеством 10 и причиной
Учебный пересчёт: остаток ровно 10, не увеличение на 10. - Обновите «История», «Склад» и веб-раздел «Остатки». Операции должны быть видны в общей MySQL-базе.
- Попробуйте выдать больше доступного остатка. Ожидается ошибка без изменения остатка.
Для приёмки ожидаемого заказа явно выберите его в форме. Обычная приёмка не закрывает поставку. Для списания и инвентаризации обязательна причина.
7. Проверка REST API
В новом PowerShell, из корня:
Invoke-RestMethod -Uri 'http://localhost:8000/'
Invoke-RestMethod -Uri 'http://127.0.0.1:8004/health'
php tools/check-intelligence.php
Последняя команда должна показать reachable: true, healthy: true и маршруты. Она не вызывает OpenAI и не меняет остатки.
Проверка авторизованного запроса через PHP:
$base = 'http://localhost:8000/api/v1'
$loginBody = @{ email = '[email protected]'; password = '[скрыто]!' } | ConvertTo-Json
$session = Invoke-RestMethod -Method Post -Uri "$base/login" -ContentType 'application/json' -Body $loginBody
$headers = @{ Authorization = "Bearer $($session.token)" }
$snapshot = (Invoke-RestMethod -Uri "$base/intelligence/results?refresh=1" -Headers $headers).data
$snapshot.results.total
$snapshot.results.catalog.Count
$snapshot.stale
$null = Invoke-RestMethod -Method Post -Uri "$base/logout" -Headers $headers -ContentType 'application/json' -Body '{}'
Ожидается 422, 724, False для комплектного снимка. Не публикуйте $session.token: это токен доступа. После logout он больше не действует.
Основные маршруты PHP
Префикс /api/v1/. Кроме login, нужен Authorization: Bearer <token>.
| Метод | Маршрут | Назначение |
|---|---|---|
| POST | login, logout | Вход / выход |
| GET | session, catalog, inventory | Сессия, справочники, текущий склад |
| GET | lookup?code=SM-DEMO-OAT-06 | Поиск товара MySQL по SKU / штрихкоду |
| GET, POST | movements | История / проведение операции |
| GET | purchase-orders | Подтверждённые и полученные заказы |
| GET | intelligence/results?refresh=1 | Сотрудник и менеджер: снимок Python |
| GET | workspace, recommendations | Менеджер: операционные данные |
| GET | intelligence/health, intelligence/schema | Менеджер: состояние / схема Python |
| GET | intelligence/forecast?sku=030200203_ | Менеджер: прогноз SKU |
| GET | intelligence/recommendation?sku=030200203_ | Менеджер: рекомендация SKU |
| POST | intelligence/agent/run | Менеджер: разбор, тело {"message":"..."} |
| POST | procurement/run, procurement/approve | Операционный расчёт / подтверждение; не импорт Python-снимка |
| POST | products, suppliers, sales | Менеджер: товар, поставщик, продажи за день |
Операции: receive, issue, transfer, writeoff, count. Используются product_id, warehouse_id, quantity, уникальный request_id; для перемещения также destination_id, для инвентаризации expected_version, для списания/инвентаризации note. ID получайте из API, не копируйте из чужой базы.
Повтор после потери ответа отправляйте с тем же request_id и телом: это предотвращает дублирование. История продаж редактируется отдельно и не проводит физическую выдачу.
Контракты: Python-интеграция, старый контракт расчёта.
8. Запуск на телефоне
Сначала проверьте работу в браузере компьютера.
Одна локальная сеть
- Установите Expo Go, совместимый с SDK 57. Не создавайте новый Expo-проект вместо существующего.
- Подключите телефон к Wi-Fi сети компьютера. ПК может использовать кабель, если маршрутизатор разрешает обмен между устройствами.
- Выполните
ipconfig, найдите IPv4 активного адаптера. Не используйте адрес Docker, VPN или127.0.0.1. - На телефоне откройте
http://IP-КОМПЬЮТЕРА:8000/. Ожидается JSON PHP backend. - При необходимости разрешите входящие подключения PHP/Node в Windows Firewall только для доверенной частной сети. Не отключайте весь firewall.
- В
smartstock-mobile/.env.localукажите реальный адрес ПК, например:
EXPO_PUBLIC_API_URL=http://192.168.1.50:8000
IP здесь только пример. Адрес без /api/v1 в конце и без секретных ключей.
Остановите предыдущий Expo и запустите:
cd D:\Projects\smartstock-hackathon\smartstock-mobile
npx.cmd expo start --lan --clear --port 8081
Откройте QR в Expo Go, войдите сотрудником склада и разрешите камеру. Для проверки нужен QR с точным SKU SM-DEMO-OAT-06 или штрихкод товара 200000000006. Сканируется товар MySQL, не произвольный внешний артикул.
Если Expo Go несовместим с SDK, не меняйте зависимости наугад: сначала используйте Expo Web, затем согласуйте совместимый клиент. Проверка форм в браузере не заменяет проверку камеры на телефоне.
Телефон на мобильном интернете
Локальный 192.168.* / 10.* обычно недоступен из другой сети. Проще использовать общую Wi-Fi-сеть либо мобильную веб-версию на ПК.
Для разных сетей нужны отдельно доступный HTTPS backend и доступный Expo/сборка. Expo --tunnel относится к Metro и не открывает PHP на 8000. EXPO_PUBLIC_API_URL должен указывать на доступный HTTPS-адрес PHP, не Swagger и не туннель Metro. Публичную публикацию development-серверов с демопаролями эта инструкция не предусматривает.
9. OpenAI: необязательное подключение
Прогнозы, каталог, склад и локальный разбор работают без OpenAI. Ключ нужен только для выбора инструментов языковой моделью при отправке вопроса менеджером.
В корне проекта:
if (-not (Test-Path -LiteralPath 'intelligence/.env')) {
Copy-Item -LiteralPath 'intelligence/.env.example' -Destination 'intelligence/.env'
}
notepad intelligence/.env
Содержимое:
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4.1-mini
После OPENAI_API_KEY= укажите новый ключ с доступом к выбранной модели. Не отправляйте его в чат. Ранее опубликованные в сообщениях или архиве ключи отзовите.
- Файл
intelligence/.envчитается при каждом запросе. После изменения обновите результаты в панели; перезапуск Python для замены ключа не требуется. - Корневой PHP
.env, мобильный.env.localи унаследованные переменные сторонних процессов для OpenAI не используются. - Отправка вопроса с настроенным ключом может вызвать платный запрос; сообщение и выбранные данные инструментов передаются OpenAI.
- Health, просмотр прогнозов и обновление результатов OpenAI не вызывают.
metadata.agent_mode: "openai"означает наличие ключа, не гарантирует его действительность, доступ к модели или наличие средств.- При отказе провайдера интерфейс явно показывает локальный разбор. Модель не меняет числовые результаты.
Режим виден в /health, без вывода ключа. Официальная справка: OpenAI API quickstart.
10. Отдельный деморежим подтверждения заказов
Нужен для проверки полного процесса на учебных товарах MySQL. Это mock, не прогноз Systeme Electric. Для основной демонстрации Python включать его не требуется.
- Остановите PHP через
Ctrl+C. - Запомните текущее значение
INTELLIGENCE_API_URLв корневом.env. - Временно оставьте пустыми оба адреса:
INTELLIGENCE_API_URL=
ML_API_URL=
- Если эти переменные заданы в окружении терминала, уберите именно эти переопределения или откройте терминал без них: процессные переменные имеют приоритет над
.env. - Запустите PHP и обновите панель. Источник должен быть явно обозначен как mock.
- Нажмите «Рассчитать закупки», откройте «Закупки» и разбор
SM-DEMO-OAT-06. - Проверьте поставщика, измените количество с учётом минимальной партии, выберите позиции, откройте проверку заказа и подтвердите в отдельном диалоге.
- В «Заказы поставщикам» появится заказ. Остаток не изменится, количество в пути увеличится.
- В мобилке выполните приёмку товара, выбрав этот заказ. Частичная приёмка уменьшает ожидание, полная закрывает поставку.
- Восстановите
INTELLIGENCE_API_URL=http://127.0.0.1:8004, оставьтеML_API_URL=пустым, перезапустите PHP и обновите панель.
Изменение входных данных между расчётом и подтверждением может сделать рекомендацию устаревшей. Сервер отклонит её: пересчитайте закупки. В деморежиме мобильная вкладка внешних прогнозов может сообщать об отключённом Intelligence Service; складские операции продолжают работать.
11. Автоматические тесты
Установите зависимости и включите MySQL. Основные серверы можно оставить работающими: тесты создают собственные временные серверы на свободных портах.
Backend и Python: из корня
php tests/supplymind-workflow.php
php tests/intelligence-api.php
php tests/ai-explainer.php
node tests/intelligence-ui.mjs
.\.venv-intelligence\Scripts\python.exe -m unittest discover -s intelligence/tests -v
node --check web/app.js
Ожидаются PASS, итоговое checks passed или Python OK, код завершения 0. На версии от 23.09.2026: 131 проверка основного PHP workflow, 40 проверок транспорта Intelligence API и 45 Python-тестов.
Изоляция БД: основной PHP-тест создаёт отдельную случайно названную базу supplymind_test_* и удаляет только её. Рабочая база не очищается. MySQL-пользователю из .env нужны права CREATE/DROP DATABASE. Не используйте производственные учётные данные.
Проверяются роли, миграции, транзакции, отрицательные остатки, повторные запросы, устаревшие рекомендации, подтверждение, группировка, приёмка, Python-контракт, сезонность, stockout, фильтры и CSV. Автотесты ассистента используют локальные данные/заглушки и не требуют платных OpenAI-запросов.
Мобильная часть
cd D:\Projects\smartstock-hackathon\smartstock-mobile
npx.cmd tsc --noEmit
npx.cmd expo lint
npx.cmd expo export --platform all --output-dir .expo/verification-export
Ожидается отсутствие ошибок TypeScript/lint и успешный export Android, iOS, Web. Это проверка JS/asset-сборок, не создание APK или IPA. Она не заменяет проверку камеры и интерфейса на реальном телефоне.
12. Пересчёт модели из исходных Excel
Для первого просмотра не нужен. Используйте при изменении данных или для воспроизводимости.
Остановите Python API, чтобы он не загрузил частично обновлённые CSV. При необходимости сохраните копию intelligence/data/processed и intelligence/models: команды перезаписывают производные результаты и модель, но не исходные Excel и не MySQL.
Из корня, последовательно; при ошибке остановитесь:
.\.venv-intelligence\Scripts\python.exe -m intelligence
.\.venv-intelligence\Scripts\python.exe -m intelligence.demand
.\.venv-intelligence\Scripts\python.exe -m intelligence.forecast
intelligenceнормализует Excel в CSV и формирует отчёты качества.intelligence.demandобрабатывает месячные выбросы, проверяет stockout и оценивает поддержанную историей потерю спроса.intelligence.forecastиспользует скорректированный спрос, проводит хронологическую проверку методов, выбирает метод по SKU и рассчитывает закупку по остатку, транзиту и кратности.
Результаты: intelligence/data/processed/forecasts.csv, procurement_recommendations.csv, forecast_metrics.json. Модель и схема признаков: intelligence/models/.
Перезапустите Python API и нажмите «Обновить результаты» в вебе/мобилке. Обновление интерфейса не обучает модель. FastAPI держит снимок в памяти: изменения CSV без перезапуска не подхватятся.
Проверка методов на шести хронологических месяцах не является независимым финальным тестом или гарантией точности. Методология: intelligence/README.md.
13. Linux и macOS
Порядок тот же: программы, пустая MySQL-база, PHP .env, зависимости, схема, три сервера. Используйте содержимое конфигов, логины и проверки из разделов выше. Нужны те же PHP-расширения и Python 3.13 с venv.
Из корня распакованного проекта:
composer install
npm ci --prefix web
npm ci --prefix smartstock-mobile
python3.13 -m venv .venv-intelligence
.venv-intelligence/bin/python -m pip install --disable-pip-version-check -r intelligence/requirements.txt
Если .env отсутствует, создайте его из .env.example, заполните MySQL и INTELLIGENCE_API_URL. Не заменяйте существующие рабочие настройки. Создайте базу SQL-командой из раздела 3.2.
php setup.php
php demo-demand.php
Терминал PHP, из корня:
php -S 0.0.0.0:8000 router.php
Терминал Python, из корня:
.venv-intelligence/bin/python -m uvicorn intelligence.api.main:app --host 127.0.0.1 --port 8004
Терминал Expo, из корня:
cd smartstock-mobile
npx expo start --web --port 8081
В тестовых командах Windows замените .\.venv-intelligence\Scripts\python.exe на .venv-intelligence/bin/python, npm.cmd / npx.cmd на npm / npx. Если системный Python другой версии, используйте именно установленный Python 3.13.
14. Частые ошибки
| Ошибка / симптом | Что проверить |
|---|---|
Unable to find expo in this project | Перейдите в smartstock-mobile, выполните npm.cmd ci, запускайте локальный npx.cmd expo start --web |
Legacy expo-cli | Не используйте глобальный expo. Установите локальные зависимости и запускайте npx.cmd expo из мобильной папки |
npm.ps1 cannot be loaded | Используйте npm.cmd / npx.cmd; глобально отключать политику безопасности не нужно |
No module named uvicorn / dotenv / catboost | Установите requirements через .venv-intelligence и запускайте Python именно из неё |
Нет vendor/autoload.php | composer install в корне |
| Пропали иконки веба | npm.cmd ci --prefix web; проверьте /manager/icons.js на PHP-сервере |
could not find driver | Включите pdo_mysql в PHP, путь показывает php --ini |
Не найдена curl_init() | Включите PHP cURL, перезапустите PHP |
Unknown database | Создайте БД SQL-командой, сверьте DB_NAME |
MySQL Access denied | Проверьте MySQL-логин/пароль, права и адрес в корневом .env |
MySQL Connection refused | Запустите MySQL на 127.0.0.1:3306 |
| Таблица не найдена | php setup.php для выбранной базы; не seed.php |
| «Неверная почта или пароль» | Регистр и !, правильная БД, выполнен ли setup.php. Он не сбрасывает пароль существующего аккаунта |
Python /health недоступен | Оставьте Uvicorn открытым, проверьте порт 8004 и traceback в его терминале |
Python degraded / нет pipeline data | Проверьте комплект intelligence/data/processed; восстановите файлы или выполните раздел 12 |
| «Сохранённая копия» | Кэш устарел или PHP не получил новый снимок. Проверьте Python и обновите результаты |
| Ассистент локальный после добавления ключа | Нужен intelligence/.env, точное OPENAI_API_KEY, UTF-8, не .env.txt. Обновите результаты |
| OpenAI настроен, но ответ локальный | Проверьте доступ к модели, ключ, лимиты и соединение. Интерфейс показывает предупреждение провайдера |
| На складе нет 724 товаров | «Склад» показывает MySQL, «Прогнозы» и внешний каталог показывают файлы. Автоимпорт отключён |
| Нельзя подтвердить внешнюю рекомендацию | Не согласованы поставщик, склад и текущий остаток. Approval проверяется в отдельном деморежиме |
| Телефон не видит backend | Проверьте http://IP-ПК:8000/, сеть, firewall, EXPO_PUBLIC_API_URL. localhost на телефоне означает телефон |
| UI не обновляется | Жёсткое обновление страницы или перезапуск Expo с --clear. После .env.local перезапустите Metro |
| Инвентаризация возвращает 409 | Остаток изменился после загрузки формы; обновите товар и повторите |
| Workflow-тест не создаёт БД | Нужны права CREATE/DROP DATABASE для тестовой БД |
Занят порт
Посмотреть слушающие порты:
Get-NetTCPConnection -State Listen -LocalPort 8000,8004,8081,8082 -ErrorAction SilentlyContinue
Не завершайте неизвестные процессы наугад. Свой предыдущий сервер можно использовать или остановить из его терминала. Если меняете порт:
- PHP: обновите URL веб-панели и
EXPO_PUBLIC_API_URLв мобилке. - Python: обновите
INTELLIGENCE_API_URLв корневом.env, перезапустите PHP. - Expo: открывайте URL, выданный Expo; адрес PHP не меняется.
PHP и Python не могут занимать один и тот же адрес/порт. Поэтому здесь используются 8000 и 8004.
15. Структура и передача проекта
api/ PHP REST-маршруты
src/ Авторизация, склад, закупки, адаптер Python, кэш
web/ Веб-панель и логотип
smartstock-mobile/ Expo / React Native
src/app/ Мобильные экраны
src/components/ Общие компоненты
src/lib/ API-клиенты и сессия
intelligence/
api/ FastAPI
agent/ Инструменты, OpenAI и локальный режим
data/raw/ Исходные Excel
data/processed/ Подготовленные CSV и отчёты
models/ CatBoost и схема признаков
tests/ Python-тесты
tests/ PHP / JS проверки
tools/ Запуск и диагностика
contracts/ Контракты интеграции
docs/HACKATHON-READINESS.md Аудит требований
setup.php Создание/обновление схемы без очистки
demo-demand.php Один учебный товар
router.php Точка входа PHP-сервера
Основные MySQL-таблицы: product, category, warehouse, stock, movement, saleshistory, supplier, supplierproduct, intransit, forecastrun, forecast, recommendation, purchaseorder, useraccount, apitoken, approvalrequest, intelligencecache.
Что передать проверяющим
- Исходники, README,
composer.lock, обаpackage-lock.json,intelligence/requirements.txtи.env.exampleфайлы. - Согласованный комплект Excel/CSV и модель. Приложение не скачивает их автоматически; данные партнёра передавайте только разрешённым получателям.
- Не включайте реальные
.env, ключи, токены, приватные дампы БД,.venv-intelligence,vendor,node_modules,.tmp,.expoи логи. Зависимости устанавливаются по инструкции. - Убедитесь, что архив сохраняет кириллические имена Excel и включает весь backend, не только мобильную папку.
- Дамп личной рабочей БД не нужен: для чистой проверки достаточно пустой базы,
setup.phpиdemo-demand.php.
Критерий успешного запуска
- PHP, MySQL, Python и Expo работают без ошибок.
- Вход менеджера и сотрудника склада работает.
- Внешний каталог и прогнозы доступны в вебе и мобилке.
- Ассистент отвечает с явно указанным режимом.
- CSV скачивается, неизвестные поставщики не подменены фиктивными.
- Учебная операция видна в остатках и истории.
- Автотесты проходят, ограничения внешнего подтверждения понятны.
Это локальный хакатонный стенд, не production-развёртывание. Перед внешней публикацией нужны HTTPS, смена демопаролей, ограничение CORS, защита входа и закрытые сетевые порты MySQL/FastAPI. Не публикуйте PHP development server с открытым доступом к учебным аккаунтам.

Авторы коммитов
История коммитов
- 2026-09-23 18:26finishedadilazimgereev
- 2026-09-23 18:24radilazimgereev
- 2026-09-23 18:23dadilazimgereev
- 2026-09-23 18:20add photoadilazimgereev
- 2026-09-23 18:18add photoadilazimgereev
- 2026-09-23 18:17dadilazimgereev
- 2026-09-23 18:14dadilazimgereev
- 2026-09-23 17:59fadilazimgereev
Все коммиты (20)
- 2026-09-23 17:58Merge remote repository with SmartStock projectadilazimgereev
- 2026-09-23 17:57Initial SmartStock projectadilazimgereev
- 2026-09-23 16:24changesysanszyz
- 2026-09-23 16:23test2ysanszyz
- 2026-09-23 16:22test1ysanszyz
- 2026-09-23 15:53upgradeysanszyz
- 2026-09-23 15:16corrected demandysanszyz
- 2026-09-23 14:46add ML environmentysanszyz
- 2026-09-23 14:31adding dastest for our ai modelysanszyz
- 2026-09-23 14:04upgrade READMEysanszyz
- 2026-09-23 13:49startysanszyz
- 2026-09-22 11:43testysanszyz
Структура репозитория (131 файлов)
.env.example .gitignore .htaccess 01.jpeg 02.jpeg 03.jpeg 04.jpeg 05.jpeg 06.jpeg 07.jpeg 08.jpeg 09.jpeg 10.jpeg README.md api/analyze_order.php api/approve_order.php api/dashboard_summary.php api/generate_order.php api/intelligence.php api/inventory.php api/orders.php api/stock_alerts.php api/v1.php composer.json composer.lock config.php contracts/README.md contracts/forecast-response.schema.json contracts/intelligence-integration.md demo-demand.php docs/HACKATHON-READINESS.md hack-87882dff-atks intelligence/.env.example intelligence/README.md intelligence/__init__.py intelligence/__main__.py intelligence/agent/__init__.py intelligence/agent/agent.py intelligence/agent/settings.py intelligence/agent/tools.py intelligence/api/__init__.py intelligence/api/main.py intelligence/api/schemas.py intelligence/baseline.py intelligence/catalog.py intelligence/cli.py intelligence/data/processed/api_demo.json intelligence/data/processed/bulk_outliers_audit.csv intelligence/data/processed/corrected_demand.csv intelligence/data/processed/corrections_audit.csv intelligence/data/processed/demand.csv intelligence/data/processed/demand_analysis.md intelligence/data/processed/demand_summary.json intelligence/data/processed/forecast_eligibility.csv intelligence/data/processed/forecast_metrics.json intelligence/data/processed/forecast_report.md intelligence/data/processed/forecasts.csv intelligence/data/processed/goods_in_transit.csv intelligence/data/processed/modeling_dataset.csv intelligence/data/processed/monthly_inventory.csv intelligence/data/processed/monthly_sales.csv intelligence/data/processed/moq.csv intelligence/data/processed/procurement_examples.csv intelligence/data/processed/procurement_recommendations.csv intelligence/data/processed/quality_report.json intelligence/data/processed/regular_demand.csv intelligence/data/processed/schema_report.json intelligence/data/processed/seasonality.csv intelligence/data/processed/sign_reconciliation_report.json intelligence/data/processed/stockouts.csv intelligence/data/processed/transaction_reconciliation.csv intelligence/data/processed/transaction_semantics_audit.csv intelligence/data/processed/transaction_sign_samples.csv intelligence/data/processed/transactions.csv intelligence/data/processed/validation_predictions.csv intelligence/data/processed/validation_report.json intelligence/data/raw/MOQ SystemElectric.xlsx intelligence/data/raw/Динамика продаж_Syseme Electric_2025-2026.xlsx intelligence/data/raw/Ежемесячные остатки SystemElectric 2024-2026.xlsx intelligence/data/raw/Ежемесячные продажи в кол-м выражении SystemElectric 2024-2026.xlsx intelligence/data/raw/Сезонность SystemElectric 2024-2026.xlsx intelligence/data/raw/Товар в пути_SystemElectric на 22.09.2026.xlsx intelligence/demand.py intelligence/features.py intelligence/forecast.py intelligence/loader.py intelligence/lost_demand.py intelligence/models/catboost.cbm intelligence/models/feature_schema.json intelligence/outliers.py intelligence/reconciliation.py intelligence/reorder.py intelligence/requirements.txt intelligence/stockout.py intelligence/tests/test_agent_settings.py intelligence/tests/test_api_agent.py intelligence/tests/test_demand.py intelligence/tests/test_forecasting.py intelligence/validate.py qoyma.jpeg router.php seed.php setup.php smartstock-mobile src/AiExplainer.php src/ApiException.php src/Auth.php src/ForecastService.php src/IntelligenceApiService.php src/IntelligenceResultsService.php src/InventoryService.php src/OrderService.php src/ReorderCalculator.php tests/FakeAiExplainer.php tests/ai-explainer.php tests/fixtures/intelligence-router.php tests/intelligence-api.php tests/intelligence-results-cases.php tests/intelligence-ui.mjs tests/supplymind-workflow.php tests/workflow.php tools/check-intelligence.php tools/check-openai.php tools/start-intelligence.ps1 web/app.js web/index.html web/intelligence.js web/package-lock.json web/package.json web/qoyma.png web/styles.css
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.