О проекте
Команда: Ketnavr
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Сервис рекомендаций пополнения склада: из Excel-выгрузок двух поставщиков считает количество к заказу, срочность и обоснование. Менеджер проверяет позиции и выгружает CSV/XLSX.
Как устроено
Backend читает ZIP с XLSX (pandas/openpyxl) и сопоставляет товары по коду 1С. Спрос считается по последним 6 месяцам: выбросы обрезаются по медиане и MAD, затем применяются поправки на тренд (0.85–1.25) и сезонность (0.8–1.2). Потребность = спрос × (срок поставки + страховой запас) − (остаток + в пути), округляется вверх до MOQ; приоритеты critical/soon/normal по покрытию в днях. LLM (OpenAI или NVIDIA) только переписывает объяснения и работает в чате-помощнике, числа считает Python.
Ключевые решения
- median/MAD outlier capping
- trend and seasonality factors
- safety stock
- lead time horizon
- MOQ rounding
- coverage days prioritization
- template fallback explanations
Особенности
Прозрачная эвристика вместо ML с явными ограничителями коэффициентов. Отдельный share-сервер отдаёт закэшированный снимок расчёта через Cloudflare Tunnel, так что посетители не тратят платные API. Экспорт всей отфильтрованной выборки в настоящий XLSX.
Стек
Python · FastAPI · Uvicorn · Pydantic · pandas · openpyxl · NumPy · React 19 · Vite 6 · ExcelJS · Cloudflare Tunnel
Модели
OpenAI gpt-5.6-luna · NVIDIA meta/llama-3.1-8b-instruct
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-f8b85cde-ketnavr.
README
README.mdKetnavr: рекомендации по закупкам
От Excel-выгрузок склада к объяснимому списку пополнения для менеджера по закупкам.
Ketnavr обрабатывает данные поставщиков ИЭК и SystemElectric: продажи, остатки, товары в пути и кратность заказа. Менеджер получает рекомендуемое количество, срочность и обоснование, проверяет позиции в интерфейсе и выгружает результат в CSV или Excel.
Проект решает задачу подготовки закупок по разрозненным таблицам. Это хакатонный прототип поддержки решения, не система автоматической отправки заказов. Количества рассчитываются в Python; OpenAI или NVIDIA могут улучшать текст объяснения, но не управляют числовым расчётом.
Быстрые ссылки: запуск · сценарий для жюри · ограничения · общая версия.
Для запуска после git clone деплой не нужен. Backend и frontend работают
локально. Нужен исходный ZIP из материалов задачи, а для живого чата также
свой API-ключ OpenAI или NVIDIA. Архив и секреты передаются отдельно от Git.
Без ключа доступны полный расчёт, фильтры, карточки и экспорт.
Что реализовано
- Чтение локального ZIP-архива с Excel-таблицами двух поставщиков и сопоставление товаров по коду 1С.
- Расчёт прогнозного дневного спроса с ограничением месячных выбросов, поправками на тренд и сезонность.
- Учёт остатка, количества в пути, срока поставки, страхового запаса и округление заказа до кратности MOQ.
- Приоритеты «Критично», «Заказать скоро» и «Планово».
- Два списка: «К закупке» и «Весь расчёт», включая товары с нулевым заказом.
- Поиск по названию и артикулу; совместные фильтры по поставщику, категории и срочности.
- Сортировки по приоритету, количеству к заказу и «Рекомендуемый порядок», сохраняющий порядок API.
- Карточка товара с объяснением, спросом, покрытием, остатками и параметрами заказа.
- Сводка по всей текущей выборке; неизвестные цены не заменяются нулями, неполная сумма помечается явно.
- Пагинация по 50 строк с прокруткой внутри таблицы и закреплёнными заголовками.
- Экспорт всей отфильтрованной выборки, а не только открытой страницы, в CSV и настоящий XLSX.
- Необязательные AI-объяснения через OpenAI или NVIDIA, с возвратом к расчётным шаблонам при сбое.
- Отдельно помеченный режим синтетического демо; ошибки API не подменяются демо автоматически.
- Сервер показа сохранённого снимка для временной публикации через Cloudflare Tunnel.
- Чат-помощник по всему расчёту с историей диалога: требует настроенного AI-провайдера; на необязательном сервере показа включается через
SHARE_CHAT_ENABLED=true.
Как работает решение
- Оператор получает исходный Excel-архив и задаёт его путь и дату расчёта в настройках backend.
- Backend читает таблицы, объединяет позиции по коду 1С и рассчитывает потребность.
- Для каждой рассчитанной позиции формируются количество, приоритет и шаблонное объяснение. Если ИИ включён, часть объяснений может быть заменена ответом модели.
- Frontend получает JSON, проверяет его формат и показывает список «К закупке».
- Менеджер фильтрует товары, открывает карточки и проверяет основания заказа. Выбор «Планово» переключает интерфейс на полный расчёт с нулевой потребностью.
- Менеджер выгружает выбранные позиции в CSV/XLSX. Дальнейшее согласование и отправка заказа выполняются вне приложения.
Метод расчёта
Реализация находится в backend/app/calculator.py.
Используются до шести последних доступных месяцев продаж не позднее месяца
AS_OF_DATE. Верхние выбросы ограничиваются на основе медианы и медианного
абсолютного отклонения. Среднемесячный объём делится на 30,4, затем применяются
поправки на тренд и сезонность, если истории достаточно.
Прогнозный дневной спрос = средний дневной спрос × тренд × сезонность
Доступное количество = остаток + товар в пути
Горизонт = срок поставки + дни страхового запаса
Потребность = max(прогнозный дневной спрос × горизонт - доступное количество, 0)
Заказ = потребность, округлённая вверх до кратности MOQ
Покрытие, дней = доступное количество / прогнозный дневной спрос
Тренд ограничен диапазоном 0,85–1,25, сезонный коэффициент: 0,8–1,2. Это эвристический расчёт, а не обученная модель прогнозирования.
| Приоритет | Условие |
|---|---|
critical / «Критично» | Покрытие меньше срока поставки. |
soon / «Заказать скоро» | Покрытие не меньше срока поставки, но меньше горизонта со страховым запасом. |
normal / «Планово» | Покрытие не меньше горизонта; дополнительный заказ равен 0. |
Позиции без пригодной положительной истории спроса в расчёт не включаются. «Весь расчёт» поэтому не означает весь ассортимент исходных файлов.
Технологии
| Компонент | Технологии в репозитории |
|---|---|
| Backend | Python, FastAPI, Uvicorn, Pydantic. |
| Обработка Excel | pandas, openpyxl; NumPy указан в зависимостях backend. |
| Расчёт | Python: statistics, math, datetime; собственные правила расчёта. |
| Frontend | JavaScript, React 19, Vite 6, CSS, иконки Lucide React. |
| Выгрузка | ExcelJS для XLSX; формирование CSV в браузере. |
| OpenAI | Responses API: POST https://api.openai.com/v1/responses. |
| NVIDIA | Chat Completions: POST https://integrate.api.nvidia.com/v1/chat/completions. |
| HTTP к моделям | Стандартная библиотека Python urllib.request, без SDK OpenAI. |
| Временная публикация | Отдельное приложение FastAPI и Cloudflare Tunnel (cloudflared). |
| Тесты | Python unittest, FastAPI TestClient/httpx, встроенный Node.js test runner. |
В backend/.env.example и конфигурации заданы
OPENAI_MODEL=gpt-5.6-luna и NVIDIA_MODEL=meta/llama-3.1-8b-instruct.
Это настраиваемые идентификаторы из кода, не гарантия доступа к модели
для любого API-аккаунта. Доступность зависит от используемого провайдера и ключа.
Зависимости: backend/requirements.txt,
backend/requirements-dev.txt,
frontend/package.json.
Архитектура
Локальная разработка
Локальный ZIP с XLSX
-> data_loader.py: чтение и объединение таблиц
-> calculator.py: числовые рекомендации и шаблонные объяснения
-> ai_client.py: необязательное обогащение reason через OpenAI/NVIDIA
-> main.py: FastAPI, порт 8000, JSON
-> Vite proxy: /api/* -> backend /*
-> React, порт 5173: проверка контракта, таблица, фильтры, карточки
-> CSV / XLSX в браузере
API-ключи хранятся только на backend. Браузер не обращается к моделям напрямую. Базы данных нет: исходные таблицы и снимок для показа кэшируются в памяти процессов.
Общая версия для показа
main.py:8000 -> share.py:8010: снимок расчёта в памяти
frontend/dist -> share.py:8010: статическая сборка интерфейса
браузер посетителя -> Cloudflare Tunnel -> share.py:8010
При запуске share.py получает полный расчёт без ИИ, затем запрашивает
AI-объяснения для первых трёх позиций к заказу. Посетители читают уже сохранённый
снимок: обновление страницы не вызывает платные API. При недоступности ИИ остаются
расчётные объяснения. Недоступный основной backend не заменяется демо.
Структура репозитория
backend/
app/data_loader.py загрузка Excel из ZIP
app/calculator.py спрос, потребность, MOQ и срочность
app/ai_client.py OpenAI/NVIDIA и резервные объяснения
app/assistant.py контекст чат-помощника и ограничение запросов
app/config.py настройки backend
app/models.py модели ответов
app/main.py основной HTTP API
app/share.py сервер статической сборки и снимка
tests/ тесты backend
frontend/
src/App.jsx интерфейс и пользовательские состояния
src/AssistantChat.jsx виджет диалога с ИИ
src/lib/api.js HTTP-запрос и таймаут 45 секунд
src/lib/contract.js проверка и нормализация JSON
src/lib/data.js фильтрация, сортировка, сводка, пагинация
src/lib/export.js CSV и XLSX
src/lib/back-front-errors.js журнал ошибок подключения
src/data/demo.js синтетический пример
tests/ модульные и вспомогательные проверки
outputs/API_CONTRACT.md контракт frontend/backend
QUICKSTART.md краткий запуск
SHARING.md публикация временной версии
FRONTEND_HANDOFF.md подключение и контрольные числа
Установка и запуск
Команды ниже предназначены для Windows PowerShell. Сервисы запускаются в отдельных терминалах. Для первого запуска платные API и ключи не нужны.
Требования
- Git и доступ к командному репозиторию, если код получается через
git clone. - Python 3.12+ с
venvиpip. - Node.js 22+ и npm.
- Исходный ZIP с Excel для работы на реальных данных. Он не входит в Git и передаётся командой отдельно.
Шаг 1. Получить проект
git clone https://github.com/BAITC-Hacks/hack-f8b85cde-ketnavr.git
cd hack-f8b85cde-ketnavr
Если проект уже скачан, откройте терминал в его корне.
Шаг 2. Установить и настроить backend
cd backend
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
if (-not (Test-Path .env)) { Copy-Item .env.example .env }
New-Item -ItemType Directory -Path data -Force
Copy-Item -LiteralPath "$env:USERPROFILE\Downloads\Excel_IEK_Systeme_Electric_оформленные.zip" -Destination data/source.zip
Последняя команда копирует предоставленный архив из «Загрузок»; если он лежит
в другом месте, замените только исходный путь. Не распаковывайте и не меняйте
структуру ZIP. В backend/.env задайте следующие настройки:
DATA_ZIP_PATH=data/source.zip
AS_OF_DATE=2026-09-22
MAX_RECOMMENDATIONS=0
SAFETY_STOCK_DAYS=14
IEK_LEAD_TIME_DAYS=18
SYSTEME_LEAD_TIME_DAYS=14
AI_PROVIDER=template
Относительный DATA_ZIP_PATH считается от папки backend, независимо от
рабочего каталога терминала. Можно вместо копирования указать свой абсолютный
путь к исходному ZIP. Архив должен существовать. AS_OF_DATE задаётся явно,
а не обновляется автоматически. MAX_RECOMMENDATIONS=0 снимает ограничение
числа рекомендаций. Существующий .env и его ключи не перезаписывайте.
Запустите backend из каталога backend:
.\.venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
Оставьте этот терминал открытым. В другом терминале проверьте:
Invoke-RestMethod 'http://127.0.0.1:8000/health'
Invoke-RestMethod 'http://127.0.0.1:8000/data/summary'
Invoke-RestMethod 'http://127.0.0.1:8000/recommendations?ai=false&limit=5'
$full = Invoke-RestMethod 'http://127.0.0.1:8000/recommendations?ai=false&include_no_order=true&limit=0'
$full.recommendations.Count
data_zip_exists должен быть true. Документация основного API:
Swagger UI.
Для предоставленного архива полный запрос возвращает 2144, а не 120 строк.
limit=5 выше служит только короткой проверкой, не настройкой интерфейса.
Шаг 3. Запустить frontend
В новом терминале из корня проекта:
cd frontend
npm install
if (-not (Test-Path .env.local)) { Copy-Item .env.example .env.local }
Проверьте настройки frontend/.env.local:
BACKEND_URL=http://127.0.0.1:8000
VITE_API_BASE_URL=/api
VITE_RECOMMENDATIONS_PATH=/recommendations?ai=false
VITE_DATA_MODE=api
npm run dev:local
Откройте локальный сайт. Frontend сам добавляет
include_no_order=true&limit=0, чтобы получить весь доступный расчёт.
dev:local принудительно использует backend 127.0.0.1:8000, реальные данные
и ai=false для таблицы, даже если в старом .env.local осталась ссылка туннеля.
Чат остаётся доступен отдельно. Если порт занят, используйте
npm run dev:local -- --port 5174 и адрес, который напечатает сервер.
Для собственных настроек .env.local, другого backend или демо запускайте
обычный npm run dev; после изменения настроек перезапустите Vite.
Шаг 4. Необязательно: включить AI-объяснения
В backend/.env выберите провайдера и добавьте его ключ. Не вставляйте ключи
в README, Git, JavaScript или переменные VITE_*.
Режим AI_PROVIDER | Что требуется и что происходит |
|---|---|
template | Ключ не нужен, внешних вызовов нет. |
openai | OPENAI_API_KEY; модель задаётся через OPENAI_MODEL. |
nvidia | NVIDIA_API_KEY; модель через NVIDIA_MODEL, адрес через NVIDIA_BASE_URL. |
auto | Пробует настроенный OpenAI, затем настроенный NVIDIA при отсутствии результата; без успешного ответа остаются шаблоны. |
AI_MAX_ROWS=8 по умолчанию ограничивает число строк, отправляемых модели.
Запросы к провайдерам имеют таймаут 12 секунд и лимит выходного текста 900 токенов.
Внешнему сервису передаются названия и показатели выбранных товаров, поэтому
AI следует включать только при разрешении на такую обработку данных.
Перезапустите backend. Для прямого локального подключения замените настройку
frontend на VITE_RECOMMENDATIONS_PATH=/recommendations?ai=true и запустите
обычный npm run dev вместо dev:local. Проверить конфигурацию без раскрытия ключа можно через
GET /ai/status, но наличие ключа не доказывает успешный вызов модели.
Прямые запросы к основному backend с ai=true могут каждый раз расходовать токены.
Шаг 5. Включить чат-помощник
В backend/.env добавьте свой действующий ключ, например:
AI_PROVIDER=openai
OPENAI_API_KEY=YOUR_OPENAI_API_KEY
OPENAI_MODEL=gpt-5.6-luna
YOUR_OPENAI_API_KEY заменяется только в локальном .env, а не в этом README.
При необходимости укажите доступную вашему аккаунту модель. Для NVIDIA
используйте AI_PROVIDER=nvidia, NVIDIA_API_KEY и NVIDIA_MODEL.
Перезапустите backend. В локальном режиме портов 8000 + 5173
SHARE_CHAT_ENABLED не нужен: он относится только к app.share на порту 8010.
Откройте сайт, дождитесь таблицы, нажмите «Спросить ИИ» и отправьте: «Сколько позиций всего, сколько нужно заказать и сколько критичных?». Ожидаемые факты для исходного архива: 2144 / 221 / 177. Формулировка ответа модели может отличаться.
Чат работает через POST /api/assistant/chat во frontend и
POST /assistant/chat на основном backend. Пример тела:
{"question":"Почему нужен заказ?","history":[]}
Ответ: {"answer":"Текст ответа модели"}. Каждый отправленный вопрос может
расходовать токены; ключ остаётся на backend. Для экономии можно оставить
VITE_RECOMMENDATIONS_PATH=/recommendations?ai=false: таблица будет без
вызовов модели, а чат продолжит работать через отдельный POST.
Помощник получает сводку всего расчёта, до 18 подходящих товаров и до 10 сообщений истории. Он не видит только текущие фильтры и не отправляет заказы. Без ключа или при сбое API отображается ошибка, а не выдуманный ответ. Лимит: 10 вопросов в минуту и 2 одновременно на процесс, не денежный лимит. Настройка для готовой сборки на 8010: SHARING.md.
Запуск без исходного архива
Для демонстрации только интерфейса задайте в frontend/.env.local
VITE_DATA_MODE=demo и запустите обычный npm run dev, не dev:local. Backend в этом режиме не требуется.
Данные вымышлены и помечены как синтетические, в том числе в выгрузке.
Это не проверка расчёта по Excel. Кнопки входа в демо в рабочем интерфейсе нет.
Как проверить решение жюри
Пользовательский сценарий на реальных данных
- Запустите проект с исходным архивом, указанной выше датой и
ai=false, либо откройте общую версию из раздела «Развёрнутая версия». - В «К закупке» проверьте таблицу, наличие обоих поставщиков и показатели сводки.
- Выберите
SystemElectricи «Заказать скоро». Откройте любой товар и сопоставьте остаток, путь, спрос, MOQ и объяснение с количеством к заказу. - Скачайте CSV и Excel. Количество строк должно соответствовать всей выборке по фильтрам, а неизвестная цена не должна превращаться в ноль.
- Сбросьте фильтры и выберите «Планово». Интерфейс перейдёт во «Весь расчёт»; в карточках будет объяснение, почему дополнительный заказ не требуется.
- Вернитесь в «К закупке», выберите «Критично» и переключите страницы 2, 3 и 4. Панель пагинации должна оставаться на месте.
- Выберите «Рекомендуемый порядок»: это порядок ответа API, без изменения количеств и приоритетов.
- При настроенном AI задайте помощнику вопрос из шага 5. Без ключа этот шаг пропускается; расчёт и экспорт от AI не зависят.
Для набора и настроек на 22.09.2026 в
FRONTEND_HANDOFF.md зафиксированы контрольные значения:
| Выборка | Количество позиций |
|---|---|
| К закупке | 221 |
| ИЭК / SystemElectric в списке к закупке | 205 / 16 |
| Критично / Заказать скоро | 177 / 44 |
| SystemElectric + Заказать скоро | 8 |
| Весь расчёт | 2144 |
| Планово, заказ 0 | 1923 |
Это контроль конкретного набора, не оценка точности прогноза. При замене файлов, даты или параметров числа могут измениться. Без исходного архива репозиторий сам по себе не позволяет воспроизвести эти результаты.
Автоматические проверки
Из корня проекта:
cd backend
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
.\.venv\Scripts\python.exe -m unittest discover -s tests
cd ..\frontend
npm test
npm run build
Модульные тесты не требуют реальных API-ключей. Они проверяют расчёт, контракт, резервные AI-объяснения, сервер снимка, фильтры, сортировку, пагинацию, ошибки и экспорт. Исходные Excel и платные провайдеры этими тестами не валидируются.
При проверке текущей версии 23.09.2026 прошли 27 тестов backend и 29 тестов frontend.
node tests/live-check.mjs из frontend выполняет отдельную проверку
согласованного снимка 221/177/44 через работающий порт 5173. Скрипт запрашивает
ai=true: используйте его с сервером снимка через BACKEND_URL=http://127.0.0.1:8010,
если не хотите повторных вызовов моделей. Перед запуском перезапустите Vite
после изменения этой настройки.
Данные и интеграции
Excel
Загрузчик рассчитан на предоставленный архив
Excel_IEK_Systeme_Electric_оформленные.zip, содержащий папки IEK/ и
Systeme electric/ непосредственно внутри ZIP. Для каждого поставщика
используются XLSX-файлы, найденные по словам в имени:
| Таблица | Слова в имени | Назначение |
|---|---|---|
| MOQ | MOQ | Код товара, артикул, название и кратность. |
| Продажи | Ежемесячные, продажи | История продаж по месяцам. |
| Остатки | Ежемесячные, остатки | Количество из последнего распознанного месячного столбца. |
| В пути, ИЭК | Путь | Количество поставок в пути. |
| В пути, SystemElectric | Товар в пути | Количество в пути, доступные категории и цены. |
Распознавание колонок и структуры описано кодом
data_loader.py. Это адаптер заданных выгрузок,
не универсальный импорт произвольного Excel. Загрузка файла через сайт и
прямое подключение к 1С или API поставщиков не реализованы.
HTTP API
Основной backend на порту 8000:
| Метод и путь | Назначение |
|---|---|
GET /health | Состояние, наличие ZIP и настройка AI. |
GET /data/summary | Число загруженных товаров и позиций к заказу по поставщикам. |
GET /ai/status | Провайдеры, модели и наличие ключей без их значений. |
GET /recommendations | JSON: schema_version, as_of, recommendations. |
POST /assistant/chat | Вопрос и история диалога; ответ модели в поле answer. |
Параметры /recommendations: ai=false отключает AI для запроса;
include_no_order=true включает рассчитанные строки с нулевым заказом;
limit=0 возвращает весь выбранный набор, limit=1..500 ограничивает число строк.
Если limit не передан, используется MAX_RECOMMENDATIONS.
По умолчанию include_no_order=false, ai=true.
Сервер показа на порту 8010 отдаёт /api/recommendations и /api/health
(также доступны пути без /api). Его /health показывает дату снимка,
число рекомендаций, размер полного расчёта и число изменённых AI-объяснений.
Swagger и диагностические маршруты основного backend в нём не опубликованы.
Полный формат ответа: контракт API.
Ограничения текущей версии
- Нет подтверждения или отправки заказов, личных кабинетов, авторизации и разграничения доступа. CSV/XLSX передаются в дальнейший процесс вручную. Чат-помощник не оформляет заказы и требует действующего ключа провайдера.
- Прогноз эвристический. Нет оценки точности на отложенной выборке, доказанного экономического эффекта или обучения модели спроса.
- Детальная клиентская динамика и отдельные таблицы сезонности загрузчиком не читаются. Клиентские разовые закупки и упущенный спрос в периоды отсутствия товара отдельно не моделируются.
- Дата ограничивает выбор недавних месяцев продаж, но остаток берётся из последнего столбца файла, а сезонный расчёт использует всю доступную месячную историю. Это не механизм корректного исторического тестирования на любую дату.
- Количество в пути учитывается целиком, без проверки дат прибытия. Срок поставки общий для поставщика, по умолчанию 18 дней для ИЭК и 14 для SystemElectric.
- При недостающем MOQ используется 1, при отсутствующей единице измерения
шт., категория может определяться по названию. Эти допущения требуют проверки владельцем данных. - Отсутствующие или неположительные цены из Excel становятся
null; сумма считается только по известным ценам. Это не полный бюджет при наличии пропусков. - AI не меняет числовые поля, но текст модели не проходит проверку всех фактов. Ответ следует проверять; в контракте нет поля
reason_sourceдля определения источника каждого объяснения. - Основной backend кэширует загруженные таблицы. После замены ZIP по тому же пути перезапустите backend; для новой общей версии также перезапустите сервер снимка. Кнопка «Обновить» не загружает новый файл.
- Пагинация только клиентская: весь расчёт передаётся браузеру. Нагрузочные гарантии для больших наборов не заявляются.
- Публичный снимок доступен без пароля всем, у кого есть ссылка. Нужны разрешение владельца данных и отдельная доработка защиты для производственного использования.
Сборка и публикация
Этот раздел необязателен: для проверки проекта из Git достаточно шагов запуска backend и frontend выше. Аккаунты хостинга и туннель не требуются.
npm run build из frontend создаёт frontend/dist. Для готовой сборки
Vite dev proxy не работает: нужен общий origin с API или отдельно настроенные
серверный proxy/CORS. Основной backend разрешает CORS только локальному
frontend на порту 5173.
В репозитории реализован вариант публикации через app.share:app. После
настройки и запуска основного backend, сборки frontend с /api и VITE_DATA_MODE=api
сервер снимка запускается из backend:
.\.venv\Scripts\python.exe -m uvicorn app.share:app --host 127.0.0.1 --port 8010
Локальная собранная версия: http://127.0.0.1:8010/.
Полная последовательность сборки, запуска туннеля и остановки:
SHARING.md. Публиковать следует порт 8010, не Vite и не
основной диагностический API. Ключи и исходный архив не входят в статическую
сборку, но показанные товарные данные посетители смогут скачать.
Развёрнутая версия
Открыть временную общую версию Ketnavr
Этот адрес указан в FRONTEND_HANDOFF.md. Он зависит
от включённого ноутбука, запущенных процессов и интернет-соединения. После
перезапуска Cloudflare Tunnel адрес может измениться. Это временный показ,
не постоянный production-хостинг. Если ссылка недоступна, используйте
инструкцию локального запуска или запросите актуальный адрес у команды.
Если не запускается
| Проблема | Что проверить |
|---|---|
data_zip_exists=false, Excel не найден | Поместите исходный архив в backend/data/source.zip или исправьте DATA_ZIP_PATH, затем перезапустите backend. |
| API вернул HTML или соединение отсутствует | Backend должен работать на 8000; BACKEND_URL=http://127.0.0.1:8000, VITE_API_BASE_URL=/api. После правки перезапустите Vite. |
| Мало строк, не виден второй поставщик | Используйте актуальный main, MAX_RECOMMENDATIONS=0; полный API-запрос содержит include_no_order=true&limit=0. В ZIP должны быть обе папки поставщиков. |
| «Планово» пусто | Сбросьте остальные фильтры и выберите «Весь расчёт». На исходном наборе доступно 1923 позиции с нулевым заказом. |
| Чат сообщает, что AI не настроен | Провайдер не должен быть template; ключ хранится в backend/.env. Перезапустите backend. Для 8010 дополнительно включите SHARE_CHAT_ENABLED=true и перезапустите app.share. |
| Временная ошибка AI или HTTP 429 | Проверьте доступ к модели, лимиты аккаунта и сеть; при 429 подождите минуту. Не делайте частых повторов платных запросов. |
| Порт 5173 занят | Остановите старый Vite через Ctrl+C или используйте npm run dev -- --port 5174. |
При обновлении кода выполните git pull --ff-only, повторите установку
зависимостей и перезапустите backend/frontend. Не перезаписывайте существующие
.env файлами примеров. Для режима показа дополнительно выполните
npm run build и перезапустите app.share; работающий туннель не трогайте,
если необходимо сохранить текущую временную ссылку.
Документация
- Краткий запуск
- Контракт API
- Подключение frontend и контрольные значения
- Временная публикация
- Подключение чат-помощника
- Проверка пагинации
README описывает реализованное поведение кода. Планы развития, неподтверждённые показатели точности и функции будущей версии не выдаются за готовый результат.
Авторы коммитов
История коммитов
- 2026-09-23 17:58Merge remote-tracking branch 'origin/main' into codex/publish-backend8zellorr8
- 2026-09-23 17:57docs: align README with verified localhost launch and chat setup8zellorr8
- 2026-09-23 17:57Merge remote-tracking branch 'origin/main' into codex/publish-backend8zellorr8
- 2026-09-23 17:56fix: make clone setup portable and document full calculation and AI chat8zellorr8
- 2026-09-23 17:56Add files via upload8zellorr8
- 2026-09-23 17:52feat: add explicit localhost mode for frontend and assistantABA-coder
- 2026-09-23 17:47Merge remote-tracking branch 'origin/main' into codex/publish-backend8zellorr8
- 2026-09-23 17:46feat: deploy isolated cloud calculation API with Vercel frontend8zellorr8
Все коммиты (54)
- 2026-09-23 17:44feat: integrate procurement assistant into current appABA-coder
- 2026-09-23 17:39chore: checkpoint laptop-independent deployment discussion8zellorr8
- 2026-09-23 17:36chore: checkpoint Vercel deployment assessment8zellorr8
- 2026-09-23 17:33chore: checkpoint asynchronous online evaluation requirements8zellorr8
- 2026-09-23 17:32chore: checkpoint final hackathon preparation discussion8zellorr8
- 2026-09-23 17:31chore: checkpoint architecture diagram discussion8zellorr8
- 2026-09-23 17:29docs: write complete Russian README for hackathon jury8zellorr8
- 2026-09-23 17:16Merge remote-tracking branch 'origin/main' into codex/publish-backend8zellorr8
- 2026-09-23 17:16fix(frontend): keep page position stable during table pagination8zellorr8
- 2026-09-23 17:15Add files via uploadABA-coder
- 2026-09-23 17:10merge: preserve frontend QA updates with full stock calculation8zellorr8
- 2026-09-23 17:07fix(frontend): show planned stock in full calculation view8zellorr8
- 2026-09-23 17:00feat: include sufficient-stock products in full calculation8zellorr8
- 2026-09-23 16:59fix(frontend): clarify sorting and coverage, export error logs; verify full recommendationsjjestar
- 2026-09-23 16:52chore: checkpoint after export verification8zellorr8
- 2026-09-23 16:51chore: checkpoint after normal-priority review8zellorr8
- 2026-09-23 16:47docs: add frontend integration handoff8zellorr8
- 2026-09-23 16:45chore: checkpoint per user request8zellorr8
- 2026-09-23 16:44fix: return all procurement recommendations by default8zellorr8
- 2026-09-23 16:33ui: светлая шапка с узором, демо только через настройку, мобильная прокруткаjjestar
- 2026-09-23 16:12feat: add cached shared preview for hackathon8zellorr8
- 2026-09-23 16:04fix: allow 45 seconds for AI recommendations8zellorr8
- 2026-09-23 15:53ui: warm header, shift logo left, add table help tooltip and patterned backgroundjjestar
- 2026-09-23 15:50feat: add supplier backend with OpenAI and NVIDIA integration8zellorr8
- 2026-09-23 15:33brand: sharpen transparent wordmark assetjjestar
- 2026-09-23 15:33ui: center error actions and refine herojjestar
- 2026-09-23 15:33ui: clean up recommendation error statejjestar
- 2026-09-23 15:23brand: remove opaque wordmark cropjjestar
- 2026-09-23 15:23brand: preserve transparent logo proportionsjjestar
- 2026-09-23 15:23brand: switch navigation to transparent wordmarkjjestar
- 2026-09-23 15:23brand: add transparent cropped wordmarkjjestar
- 2026-09-23 15:17brand: refresh page metadatajjestar
- 2026-09-23 15:17ui: refine background spacing and responsive logojjestar
- 2026-09-23 15:17ui: apply review fixes and simplify error statejjestar
- 2026-09-23 15:17error: add back-front error loggerjjestar
- 2026-09-23 15:16brand: remove placeholder SVG wordmarkjjestar
- 2026-09-23 15:16brand: use source PNG wordmark from concept 02jjestar
- 2026-09-23 15:04brand: size Ketnavr wordmark responsivelyjjestar
- 2026-09-23 15:04brand: wire Ketnavr wordmark into navigationjjestar
- 2026-09-23 15:04brand: set Ketnavr document identityjjestar
- 2026-09-23 15:04brand: replace favicon with star markjjestar
- 2026-09-23 15:04brand: add Ketnavr wordmark assetjjestar
- 2026-09-23 14:40design: add editorial procurement herojjestar
- 2026-09-23 14:39design: apply Ventriloc-inspired visual systemjjestar
- 2026-09-23 14:25docs: fix frontend install commandjjestar
- 2026-09-23 14:24frontend: add procurement dashboard and API contractjjestar
Структура репозитория (55 файлов)
.gitignore FRONTEND_HANDOFF.md QUICKSTART.md README (1).md README (2).md README.md SHARING.md backend/.env.example backend/README.md backend/app/__init__.py backend/app/ai_client.py backend/app/assistant.py backend/app/calculator.py backend/app/config.py backend/app/data_loader.py backend/app/main.py backend/app/models.py backend/app/share.py backend/requirements-dev.txt backend/requirements.txt backend/tests/test_ai_client.py backend/tests/test_assistant.py backend/tests/test_calculator.py backend/tests/test_config.py backend/tests/test_recommendations.py backend/tests/test_share.py frontend/.env.example frontend/.gitignore frontend/index.html frontend/package.json frontend/public/favicon.svg frontend/public/header-contours.svg frontend/public/ketnavr-wordmark-transparent.png frontend/public/procurement-pattern.svg frontend/src/App.jsx frontend/src/AssistantChat.jsx frontend/src/data/demo.js frontend/src/lib/api.js frontend/src/lib/back-front-errors.js frontend/src/lib/contract.js frontend/src/lib/data.js frontend/src/lib/export.js frontend/src/main.jsx frontend/src/styles.css frontend/tests/assistant.test.js frontend/tests/core.test.js frontend/tests/errors.test.js frontend/tests/live-check.mjs frontend/tests/local-config.test.js frontend/tests/qa-server.mjs frontend/vite.config.js outputs/API_CONTRACT.md outputs/CHAT_HANDOFF.md outputs/FRONTEND_QA.md outputs/PAGINATION_QA.md
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.