О проекте
Команда: FruktAi
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Доведённый продукт
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Рабочее место закупщика: таблица рекомендаций по SKU с объяснением расчёта, загрузка своих данных, what-if пересчёт остатка и товаров в пути, проверка менеджером и экспорт заказа поставщику в CSV/XLSX.
Как устроено
Данные из CSV или LOGISTIQ Excel (продажи, остатки, stockouts, товары в пути, поставщики) нормализуются и проверяются. Выбросы в дневных продажах отсекаются по IQR (порог Q3 + 1.5×IQR, отдельно одиночные клиентские пики). Упущенный спрос за дни stockout восстанавливается от базового уровня, сезонность (clamp 0.75–1.5) и рост (clamp 1.0–1.3) считаются по 28-дневному окну. Прогноз × срок поставки плюс страховой запас минус остаток и товары в пути дают количество заказа и уровень срочности. Оркестратор проводит семь шагов, результат сохраняется в SQLite с run_id. OpenAI опционально добавляет пояснение, но числа не меняет.
Ключевые решения
- IQR outlier detection
- lost-demand estimation
- seasonality/growth heuristics
- safety stock
- reorder quantity formula
- what-if recalculation
Особенности
Все формулы расписаны с граничными случаями (например, нулевой IQR даёт порог 3×Q3, при нехватке истории коэффициент 1.0). Каждый запуск прослеживается по run_id, поэтому экспорт прошлого расчёта не меняется после пересчёта. Контракты API оформлены как JSON Schema. What-if поправки идут через настоящий серверный пересчёт.
Стек
Python · FastAPI · SQLite · React · TypeScript · Vite · Tailwind CSS · Recharts · Docker · nginx · Playwright · ruff
Модели
OpenAI
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-392ab0c0-fruktai.
README
README.mdFruktAI — интегрированный предфинальный MVP
Ветка main содержит интегрированную версию: frontend команды, FastAPI,
детерминированный workflow и SQLite. Интеграционная ветка — test-main.
Пользователь открывает таблицу рекомендаций, видит причины и историю продаж,
загружает собственные данные, изменяет остаток / товар в пути, получает пересчёт
и экспортирует CSV/XLSX из сохранённого расчёта после проверки.
Число заказа рассчитывает алгоритм:
ceil(max(0, forecast_demand + safety_stock - on_hand - in_transit))
OpenAI может добавить пояснение. Ошибка OpenAI не отменяет расчёт. Все экранные рекомендации загружаются из API. Файл mock используется только тестами.
Навигация по проекту
Запуск · Загрузка файлов · Интерфейс · Формулы · Frontend · Backend · API · БД и интеграция · Карта кода · Тесты
Разделы интерфейса
| Раздел | Что находится внутри |
|---|---|
| Обзор запасов | KPI, распределение рисков и график доступного запаса до/после закупки. Без таблицы товаров. |
| Рекомендации | Таблица SKU, поиск, фильтры, сортировка, выбор позиций, карточка расчёта и экспорт. Без дублирования дашборда. |
| Поставщики | Отдельные карточки групп поставки: товары, потребность, высокий риск, сроки; переход к товарам и проверка заказа группы. |
| Источники данных | Загрузка, предупреждения, предпросмотр и сведения об используемом наборе. |
| Ход анализа | Семь шагов последнего расчёта и технические подробности. Не трансляция выполнения в реальном времени. |
| Профиль | Сведения о локальном рабочем месте и быстрые переходы. Это не авторизация. |
Frontend: React + TypeScript, Vite, Tailwind CSS и стили по компонентам, Recharts. Оболочка, состояние и запросы, экраны, сводка поставщиков. Данные приходят из API; сумма заказа не рассчитывается заново на клиенте.
Визуальные ориентиры проекта, не подключённые сервисы и не скопированные компоненты: Linear — оболочка; Netstock — складской обзор; Confido — закупочная очередь; IBM Planning Analytics — аналитика и what-if; Maersk Design System — организация таблиц.
Frontend: рабочее место принятия решений
Интерфейс построен вокруг последовательного раскрытия информации: менеджер сначала оценивает ситуацию на дашборде, затем выбирает позиции в таблице и открывает детали только для проверки конкретного решения. Обзор, закупочная очередь и сводка поставщиков решают разные задачи, поэтому не дублируют один и тот же экран.
- Контрактное взаимодействие. Типизированный клиент получает данные по единому API-контракту; представление отделено от сетевых запросов и серверной бизнес-логики.
- Единое управление состоянием. useWorkspace координирует загрузку, фильтры, выбор позиций и сценарные поправки. Устаревший ответ запроса не заменяет более свежий результат.
- Проверка гипотез через what-if. Изменение остатка или количества в пути запускает настоящий серверный пересчёт. Значения «до / после» позволяют оценить последствия поправки, не изменяя исходные CSV.
- Проверка человеком перед экспортом. Менеджер выбирает позиции, проверяет объёмы и подтверждает выгрузку. Кнопка экспорта не отправляет заказ поставщику и не проводит документ в 1С.
- Работа с плотными данными. Закреплённые заголовки, сортировка, фильтры и числовое выравнивание облегчают сравнение SKU; на мобильном экране таблица заменяется карточками.
- Явные состояния интерфейса. Загрузка, ошибка, отсутствие результатов и предупреждения качества данных отображаются отдельно. Неуспешный запрос не выдаётся за выполненный расчёт.
Точка входа — App.tsx, сетевой слой — client.ts, визуальные компоненты — components/, тематические стили — styles/. Это позволяет менять представление, не затрагивая формулу потребности и серверный контракт.
Backend: проверяемый расчёт и сохранение результатов
Backend реализует разделение транспорта, прикладного сценария и расчётного ядра. FastAPI принимает запрос, сервис координирует обработку, оркестратор выполняет последовательность шагов, а слой хранения сохраняет результат. Такое разделение позволяет тестировать алгоритм независимо от HTTP и UI.
| Слой | Ответственность | Реализация |
|---|---|---|
| HTTP | Валидация запросов, маршруты, коды ошибок, загрузка и экспорт | backend/main.py |
| Прикладной сервис | Набор данных, overrides, запуск workflow и сохранение | agent/service.py |
| Расчётное ядро | Аномалии, потерянный спрос, прогноз, количество и срочность | agent/workflow/ |
| Оркестрация | Порядок шагов, проверки и журнал выполнения | agent/orchestrator.py |
| Хранение | Источники, запуски, рекомендации и история SKU | database/ |
Воспроизводимость: одинаковые валидные входные данные, overrides и настройки дают одинаковые числовые рекомендации. Идентификатор и время нового запуска при этом различаются; текст необязательного AI-пояснения не является частью детерминированной гарантии.
Прослеживаемость: run_id связывает рекомендации, историю товара и экспорт
с конкретным сохранённым запуском. Последующий пересчёт не меняет экспорт
предыдущего запуска. Входные нормализованные данные и поправки доступны для аудита.
Контролируемая деградация: нехватка сезонной истории приводит к коэффициенту
1.0, отсутствие строки поставки — к нулю с пояснением. Отрицательный остаток
является ошибкой данных, а не поводом незаметно подменять значение.
Граница ответственности: сервис поддерживает решение менеджера, но не принимает коммерческое обязательство от его имени. Текущий MVP — однопроцессное приложение с SQLite, а не распределённая production-платформа. Промышленное развёртывание потребует отдельной проработки доступа, резервного копирования, наблюдаемости и конкурентного выполнения.
Коротко для презентации
FruktAI превращает разрозненные складские данные в проверяемую очередь закупок: от очистки истории спроса до объяснимой рекомендации и экспорта. Прозрачный алгоритм отвечает за количество, интерфейс — за проверку решения, а сохранённый запуск — за возможность восстановить контекст расчёта.
Формулы активного расчёта
Источник истины: спрос и аномалии, количество и срочность. Это прозрачные эвристики MVP, а не обученная модель прогнозирования.
- Выбросы. Для дневных продаж
IQR = Q3 − Q1; порогQ3 + 1.5 × IQR. Если IQR равен нулю, порог —3 × Q3. Проверка требует минимум 4 наблюдения и положительный Q3. При наличии минимум 8 групп клиент/день сначала исключаются одиночные клиентские пики вышеmax(Q3 + 3 × IQR, 5 × median). - Окно спроса. Последние максимум 28 календарных дней относительно последней
даты продаж/stockout в источнике.
U— сумма пригодных продаж,N— число календарных дней. Пропущенный день даёт нулевые продажи; выбросы и stockout не добавляют продажи, но дни остаются в знаменателе. - Упущенный спрос.
baseline = U / N;lost = baseline × stockout_days;avg_daily_demand = (U + lost) / N. Это оценка, не известные фактические продажи. - Сезонность. При 28 днях:
seasonality = clamp(mean_7 / baseline, 0.75, 1.50). При нехватке истории или нулевой базе —1.0. Это недельная эвристика, не годовая модель. - Рост.
growth = clamp(mean_last_14 / mean_previous_14, 1.0, 1.30): нужны 28 дней, минимум 7 пригодных дней в каждом окне и положительная предыдущая средняя. Обе суммы делятся на 14; иначе коэффициент —1.0. - Прогноз.
forecast_demand = avg_daily_demand × lead_time_days × seasonality × growth. - Страховой запас.
safety_stock = avg_daily_demand × safety_stock_days; по умолчанию 7 дней, настройкаFRUKTAI_SAFETY_STOCK_DAYS. - Заказ. Прогноз и страховой запас округляются до двух знаков, затем
recommended_qty = ceil(max(0, forecast_demand + safety_stock − on_hand − in_transit)). - Покрытие.
(on_hand + in_transit) / avg_daily_demand; при нулевом спросе возвращается0.0с пояснением, не бесконечность.
Пример: спрос 10 ед./день, срок поставки 7 дней, оба коэффициента 1,
страховой запас 70, остаток 25, в пути 20 → ceil(max(0, 70 + 70 − 25 − 20)) = 95.
При замене остатка на 125 рекомендация станет нулевой.
Срочность: high, если остаток равен нулю или остаток + поставки меньше прогноза;
medium, если их хватает на прогноз, но не на прогноз + страховой запас;
иначе low. AI не меняет эти числа и статусы.
MOQ, кратность упаковок, backorders и задержки ETA не входят в формулу. Для LOGISTIQ Excel импортируются реальные входные строки; лист Expected Results не становится готовым ответом API.
Быстрый запуск на Windows
Нужны Python 3.10+ и Node.js 22+. Команды выполнять из корня репозитория:
git fetch origin
git switch main
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r backend/requirements-dev.txt
npm --prefix frontend ci
.\.venv\Scripts\python.exe scripts/run_local.py
Оставьте терминал открытым. Остановка обоих серверов — Ctrl+C.
- Интерфейс: http://127.0.0.1:5173
- Swagger: http://127.0.0.1:8000/docs
- Health: http://127.0.0.1:8000/health
run_local.py запускает оба процесса и по умолчанию отключает платные AI-вызовы.
Существующий .env перезаписывать не нужно. SQLite создаётся автоматически.
Для macOS/Linux: вместо .\.venv\Scripts\python.exe используйте .venv/bin/python.
Первый прогон: ваши файлы → рекомендации → экспорт
После обновления кода обязательно повторите установку зависимостей из команды выше: для загрузки добавлены multipart, openpyxl, xlrd и pdfplumber. Каждая команда — отдельная строка; не склеивайте run_local.py и smoke_test.py.
- Откройте интерфейс → «Загрузить данные / выгрузку 1С».
- Скачайте Excel-шаблон. Для проверки можно сразу загрузить его обратно: это явно синтетический набор, а не данные партнёра.
- Для настоящего расчёта замените строки своими: продажи (дата, артикул, количество, обезличенный клиент, цена), справочник товаров/поставщиков, остатки по складу, stockout, товары в пути. Материальная ведомость 1С может заменить таблицу остатков. Если предоставлены обе, остатки сверяются.
- Выберите XLSX/XLS, CSV/TSV, JSON или текстовый табличный PDF. Для отдельных файлов/листов обязательны имена и заголовки из шаблона. Если складов несколько — укажите его код. Подтвердите обезличивание.
- Нажмите «Загрузить и проверить»: проверьте строки, склад, предупреждения и предпросмотр. Загрузка сама по себе не запускает расчёт.
- Нажмите «Рассчитать загруженные данные». Получите рекомендации, причины, срочность, график и группировку по поставщикам. Пересчёт использует этот же набор; обновление страницы его не заменяет на demo.
- Измените остаток / товар в пути в карточке и пересчитайте.
- «Проверить заказ» → CSV или Excel → подтвердить проверку → скачать. Экспорт содержит именно сохранённый run_id, даже если позже был другой расчёт. В 1С и поставщикам автоматически ничего не отправляется.
Граница интеграции 1С: реализован файловый обмен и сверка ведомости, а не прямое подключение к вашей базе. Для OData/HTTP нужны конфигурация, доступный интерфейс и реальный пример структуры данных. PDF-сканы/фото требуют OCR и сейчас отклоняются с понятной ошибкой; произвольные печатные формы не угадываются.
Полные форматы, обязательные колонки и ограничения: Вход/выход и 1С. Для backend/frontend: HTTP-контракт, структура входов, JSON Schema.
Запуск с OpenAI
Ключ должен быть только в корневом .env:
OPENAI_API_KEY=ваш_ключ
OPENAI_MODEL=gpt-6-astra
OPENAI_EXPLANATIONS_ENABLED=true
После остановки обычного запуска:
.\.venv\Scripts\python.exe scripts/run_local.py --ai
Один пересчёт вызывает одну пакетную AI-операцию с ограниченными повторами.
При отказе провайдера сохраняются детерминированные причины; подробности видны
в серверном логе. Наличие ответа HTTP 200 само по себе не доказывает работу LLM.
Успешное AI-пояснение начинается с AI-пояснение:.
Полный live-тест AI → HTTP → SQLite на временной БД (один платный пакетный
запрос по учебным данным): python scripts/test_ai_integration.py.
Тест требует корневой .env с ключом и явно завершается ошибкой при fallback.
Настройки лимитов и fallback: OpenAI integration. Описание входа и выхода: AI contract.
Полный автоматический прогон
В отдельном терминале из корня:
.\.venv\Scripts\python.exe -m pytest tests -q
.\.venv\Scripts\python.exe scripts/test_full_stack.py
.\.venv\Scripts\python.exe scripts/validate_api_contracts.py
.\.venv\Scripts\python.exe scripts/test_agent_workflow.py
.\.venv\Scripts\python.exe scripts/test_database.py
.\.venv\Scripts\python.exe scripts/test_workflow_service.py
.\.venv\Scripts\python.exe scripts/test_openai_explainer.py
npm --prefix frontend test
npm --prefix frontend run build
test_full_stack.py сам запускает настоящий HTTP-сервер на свободном порту,
выполняет health → расчёт → изменение остатка → историю товара, затем перезапускает
сервер и проверяет сохранность результата в SQLite. Использует временную БД,
не меняет рабочую БД и не вызывает OpenAI.
Если сервер не стартует, тест выводит код завершения, путь к Python и исходный
лог Uvicorn. Проверяйте зависимости тем же интерпретатором из .venv, которым
запускаете тест. test_full_stack.py запускает свой сервер автоматически;
smoke_test.py требует уже запущенного приложения.
Для проверки уже запущенного приложения, включая Vite-прокси:
.\.venv\Scripts\python.exe scripts/smoke_test.py --base-url http://127.0.0.1:5173
Smoke-test создаёт два настоящих расчёта в рабочей БД; последний содержит override. Нажмите «Обновить данные» в UI, чтобы вернуться к исходным CSV.
Браузерный прогон при работающем run_local.py:
cd frontend
npx playwright install chromium
npm run test:e2e
cd ..
Проверяет таблицу, открытие товара и графика, пересчёт, чтение из API/БД и
скачивание CSV, а также Excel-шаблон → загрузку → предпросмотр → расчёт →
историю конкретного run_id → экспорт XLSX. Для установленного Chrome можно задать
$env:PLAYWRIGHT_CHANNEL = "chrome" и пропустить загрузку Chromium.
Демонстрация за две минуты
- Откройте http://127.0.0.1:5173 — загрузятся 6 SKU.
- Откройте «Рекомендации» и любой товар с ненулевым заказом.
- Посмотрите формулу, причины и график истории.
- Введите остаток
10000, нажмите «Пересчитать через API». Рекомендация станет нулевой, отобразятся значения до / после. - Закройте карточку и откройте «Ход анализа» в отдельном разделе слева:
там настоящий
run_idи семь выполненных шагов. - Нажмите «Проверить заказ», подтвердите проверку, скачайте CSV. Отправка поставщику не выполняется.
- «Обновить данные» сбрасывает поправки и заново считает исходный набор.
Данные и БД
data/demo/README.md описывает синтетический учебный набор: 56 дней, стабильный спрос, недельный рисунок, рост, stockout, выброс и поставка в пути. Это не данные партнёра и не готовый расчёт.
Источники: data/demo/{sales,inventory,stockouts,suppliers,in_transit,products}.csv.
CSV не изменяются при пересчёте; override относится только к текущему запуску.
Внутри UI поправки нескольких SKU накапливаются до «Обновить данные».
artifacts/fruktai.sqlite— SQLite с расчётами, причинами, историей и журналом.artifacts/imports/upload_*/— нормализованные входы и manifest; оригиналы документов не сохраняются.source_importsв SQLite — снимок нормализованных таблиц, включая цену и обезличенный ID.artifacts/runs/— JSON исходного детерминированного этапа, до AI-обогащения.- Структура: database/schema.sql.
- Для VS Code откройте SQLite через SQLite Viewer; полезны
latest_recommendations,supplier_order_summary,calculation_runs. - Ключи, БД, журналы, виртуальное окружение и node_modules исключены из Git.
Docker Compose
Альтернатива локальному запуску, когда работает Docker Desktop:
docker compose up --build -d
docker compose ps
python scripts/smoke_test.py --base-url http://127.0.0.1:5173
docker compose logs --tail=100 backend
docker compose down
Те же адреса: UI 5173, API 8000. Не запускайте локальные процессы одновременно
на этих портах. Каталог ./artifacts примонтирован: БД остаётся после остановки.
Compose читает корневой .env. Для прогона без OpenAI:
$env:OPENAI_EXPLANATIONS_ENABLED = "false" перед docker compose up.
Для включения задайте true и выполните docker compose up -d --force-recreate backend.
Ключ передаётся только backend и не попадает в frontend build.
Архитектура и границы интеграции
React :5173 -> Vite/nginx proxy -> FastAPI :8000
|
WorkflowService
/ \
CSV + алгоритм OpenAI (optional)
\ /
SQLite
Публичные маршруты: GET /health, POST /api/v1/recalculate,
GET /api/v1/items/{sku} плюс загрузка/метаданные/шаблон в
/api/v1/datasets/ и экспорт /api/v1/runs/{run_id}/export.
Существующие поля рекомендаций не переименованы:
API, CSV, JSON Schema.
В API работает только agent/orchestrator.py. Исходные
backend/calculation.py и backend/services/ сохранены вместе с тестами как
наработка backend-участника; HTTP их не использует. Для запуска достаточно
backend/requirements.txt; pandas/NumPy нужны только для тестов этих наработок.
Происхождение: AI/БД — 83e19ff, frontend/main — 35ee99e
(frontend 0c53176), исходники backend — 9e9aa6c.
Backend перенесён выборочно: его .venv, pycache и конфликтующая реализация
database/ не включались. Общая БД сохранена из AI-ветки.
Предфинальные ограничения: один процесс API, файловый обмен с 1С, выбор одного склада на набор, целочисленные остатки/заказ в базовой единице товара. Сезонность оценивается по неделям, а не полноценной годовой модели. Выбросы анализируются по SKU/дню и, при наличии, обезличенному клиенту. Категория и единица берутся только из метаданных входа; ETA в рекомендации не добавляется. Все товары в пути вычитаются по исходной MVP-формуле без моделирования задержек. Автоматическая отправка/проведение заказов отсутствует.
Проверено для файлового обмена: 47 pytest-тестов, HTTP-прогон с перезапуском SQLite,
8 JSON Schema, script-тесты workflow/БД/AI-fallback, frontend unit/build,
семь браузерных E2E через установленный Chrome: импорт/экспорт, пересчёт,
раздельные экраны, профиль, навигация и сортировки, мобильный экран,
восстановление после ошибки API. Дополнительный тест локального LOGISTIQ-файла
включается через E2E_LOGISTIQ_FILE; без этого пути он пропускается.
В этом прогоне платные AI-запросы не выполнялись.
Compose ранее прошёл проверку конфигурации; повторная проверка в текущей
среде ограничена доступом к Docker config. Запуск контейнеров не проверен.
Читаемость и структура кода
Карта модулей и команды проверки. Исходники разделены по ответственности; каждый файл кода — не более 350 строк. Публичные импорты agent и database сохранены, API и формула не изменились.
После обновления зависимостей доступны npm --prefix frontend run format:check
и Ruff из backend/requirements-dev.txt.
Проверка лимита: python scripts/check_code_size.py.
Frontend: App → useWorkspace → оболочка / экраны / диалоги. Стили разбиты по разделам в frontend/src/styles. Обзор, рекомендации, поставщики, источники и журнал открываются в боковой навигации.
Документация backend-участника
Исходное описание backend и формул сохранено из main. Оно описывает отдельную реализацию; активный HTTP-путь использует agent/orchestrator.py.
Авторы коммитов
История коммитов
- 2026-09-23 17:58docs: explain frontend architecture backend guarantees and project pitchDmitribear
- 2026-09-23 17:56fix: separate dashboard recommendations and supplier workspaceDmitribear
- 2026-09-23 17:54merge: integrate main and preserve backend reference documentationDmitribear
- 2026-09-23 17:53fix: support LOGISTIQ uploads and repair workspace navigationDmitribear
- 2026-09-23 17:52chore(frontend): empty checkpoint before hackathon submissionDoumalini
- 2026-09-23 17:34refactor: separate workspace state views and themed stylesDmitribear
- 2026-09-23 17:34docs: describe module boundaries and code quality checksDmitribear
- 2026-09-23 17:33refactor: split workflow storage and file parsing into focused modulesDmitribear
Все коммиты (41)
- 2026-09-23 17:23feat: redesign procurement workspace and scenario reviewDmitribear
- 2026-09-23 17:02feat: validate uploaded sources and export persisted supplier ordersDmitribear
- 2026-09-23 17:02feat: connect upload preview and Excel export to dashboardDmitribear
- 2026-09-23 17:02docs: define file exchange and persisted export contractsDmitribear
- 2026-09-23 16:35fix: expose HTTP test startup errors and use fresh restart portDmitribear
- 2026-09-23 16:32Merge pull request #8 from BAITC-Hacks/Frontend_BaimuratDoumalini
- 2026-09-23 16:30feat: integrate frontend API AI and SQLite on test-mainDmitribear
- 2026-09-23 16:30docs: document backend and forecastingdisappointtt
- 2026-09-23 16:29feat: integrate OpenAI explanations into the supplier replenishment APIdisappointtt
- 2026-09-23 16:17chore(frontend): checkpoint with no code changesDoumalini
- 2026-09-23 16:08Merge pull request #7 from BAITC-Hacks/Frontend_BaimuratDoumalini
- 2026-09-23 15:53style(frontend): simplify dashboard and adopt IBM Plex typographyDoumalini
- 2026-09-23 15:51feat: complete validated OpenAI explanation funnelDmitribear
- 2026-09-23 15:42Implement SQLite database for transactional persistence of source snapshots and recommendationsdisappointtt
- 2026-09-23 15:39Merge pull request #6 from BAITC-Hacks/Frontend_BaimuratDoumalini
- 2026-09-23 15:33fix(frontend): polish responsive layout labels and error controlsDoumalini
- 2026-09-23 15:27Merge pull request #5 from BAITC-Hacks/Frontend_BaimuratDoumalini
- 2026-09-23 15:25feat: add optional OpenAI explanation layerDmitribear
- 2026-09-23 15:24feat(frontend): redesign procurement workspace and review flowDoumalini
- 2026-09-23 14:58docs: prepare backend database integration handoffDmitribear
- 2026-09-23 14:43feat: integrate workflow persistence and item detailsDmitribear
- 2026-09-23 14:42second commitdisappointtt
- 2026-09-23 14:32Merge pull request #2 from BAITC-Hacks/Frontend_BaimuratDoumalini
- 2026-09-23 14:29feat: add SQLite import and inspection toolsDmitribear
- 2026-09-23 14:26feat(frontend): add procurement dashboard demo based on design referenceDoumalini
- 2026-09-23 14:18Merge pull request #1 from BAITC-Hacks/Frontend_BaimuratDoumalini
- 2026-09-23 14:13first commitdisappointtt
- 2026-09-23 14:12feat: formalize and validate API contractsDmitribear
- 2026-09-23 14:06docs: add API contract placeholderDoumalini
- 2026-09-23 14:00docs: add optional SQLite data modelDmitribear
- 2026-09-23 13:52test: add API smoke test and integration handoffDmitribear
- 2026-09-23 13:49feat: add deterministic replenishment workflowDmitribear
- 2026-09-23 13:42docs: define MVP and data contractsDmitribear
Структура репозитория (162 файлов)
.dockerignore .env.example .gitignore .prettierrc.json MVP_SPEC.md README.md agent/__init__.py agent/api_client.py agent/explanation_contract.py agent/openai_client.py agent/openai_explainer.py agent/orchestrator.py agent/service.py agent/workflow/__init__.py agent/workflow/data.py agent/workflow/demand.py agent/workflow/models.py agent/workflow/primitives.py agent/workflow/recommendations.py agent/workflow/results.py backend/Dockerfile backend/__init__.py backend/calculation.py backend/exports.py backend/file_exchange/__init__.py backend/file_exchange/logistiq.py backend/file_exchange/normalization.py backend/file_exchange/parsers.py backend/imports.py backend/main.py backend/requirements-dev.txt backend/requirements.txt backend/schemas.py backend/services/__init__.py backend/services/data_processing.py backend/services/forecasting.py backend/services/replenishment.py contracts/README.md contracts/ai-explanation.input.schema.json contracts/ai-explanation.output.schema.json contracts/error.response.schema.json contracts/health.response.schema.json contracts/import.response.schema.json contracts/item.response.schema.json contracts/recalculate.request.schema.json contracts/recommendation.schema.json data/demo/README.md data/demo/in_transit.csv data/demo/inventory.csv data/demo/products.csv data/demo/sales.csv data/demo/stockouts.csv data/demo/suppliers.csv data/inventory_demo.csv data/sales_demo.csv database/ER_DIAGRAM.md database/__init__.py database/calculations.py database/connection.py database/queries.py database/repository.py database/schema.sql database/sources.py database/validation.py docker-compose.yml docs/AI_API_CONTRACT.md docs/API_CONTRACT.md docs/BACKEND_BRANCH_REFERENCE.md docs/BACKEND_DATABASE_INTEGRATION.md docs/CODE_STRUCTURE.md docs/DATA_CONTRACT.md docs/INPUT_OUTPUT.md docs/INTEGRATION.md docs/OPENAI_INTEGRATION.md frontend/.env.example frontend/.gitignore frontend/Dockerfile frontend/README.md frontend/e2e/logistiq.spec.ts frontend/e2e/navigation.spec.ts frontend/e2e/workflow.spec.ts frontend/index.html frontend/nginx.conf frontend/package-lock.json frontend/package.json frontend/playwright.config.ts frontend/public/fonts/IBMPlexSans-Bold.woff2 frontend/public/fonts/IBMPlexSans-Medium.woff2 frontend/public/fonts/IBMPlexSans-Regular.woff2 frontend/public/fonts/IBMPlexSans-SemiBold.woff2 frontend/public/fonts/LICENSE.txt frontend/public/fonts/SOURCES.md frontend/scripts/test-ui.mjs frontend/src/App.tsx frontend/src/api/client.ts frontend/src/api/presentation.ts frontend/src/components/AgentRunPanel.tsx frontend/src/components/Analytics.tsx frontend/src/components/DataView.tsx frontend/src/components/Drawer.tsx frontend/src/components/FiltersBar.tsx frontend/src/components/ImportPanel.tsx frontend/src/components/KpiCards.tsx frontend/src/components/LoadingState.tsx frontend/src/components/ProductArt.tsx frontend/src/components/RecommendationDetails.tsx frontend/src/components/RecommendationsTable.tsx frontend/src/components/ReviewOrder.tsx frontend/src/components/StatusBadge.tsx frontend/src/components/item/SalesHistory.tsx frontend/src/components/workspace/ProcurementQueue.tsx frontend/src/components/workspace/SuppliersView.tsx frontend/src/components/workspace/WorkspaceDialogs.tsx frontend/src/components/workspace/WorkspaceHeader.tsx frontend/src/components/workspace/WorkspaceShell.tsx frontend/src/components/workspace/WorkspaceViews.tsx frontend/src/hooks/useWorkspace.ts frontend/src/index.css frontend/src/main.tsx frontend/src/mocks/demo.json frontend/src/styles/analytics.css frontend/src/styles/drawer.css frontend/src/styles/foundation.css frontend/src/styles/mobile.css frontend/src/styles/queue-controls.css frontend/src/styles/responsive.css frontend/src/styles/review.css frontend/src/styles/scenario.css frontend/src/styles/shell.css frontend/src/styles/sidebar.css frontend/src/styles/sources.css frontend/src/styles/states.css frontend/src/styles/suppliers.css frontend/src/styles/table.css frontend/src/styles/workflow.css frontend/src/types/api.ts frontend/src/types/demo.ts frontend/src/utils/csv.ts frontend/src/utils/presentation.ts frontend/src/vite-env.d.ts frontend/tsconfig.json frontend/vite.config.ts ruff.toml scripts/check_backend_readiness.py scripts/check_code_size.py scripts/check_openai_connection.py scripts/database_cli.py scripts/run_local.py scripts/smoke_test.py scripts/test_agent_workflow.py scripts/test_ai_integration.py scripts/test_database.py scripts/test_full_stack.py scripts/test_openai_explainer.py scripts/test_workflow_service.py scripts/validate_api_contracts.py tests/test_calculation.py tests/test_file_exchange.py tests/test_full_stack_runner.py tests/test_integrated_api.py tests/test_logistiq_import.py tests/test_services.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.