О проекте
Команда: Paradox
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
Чат-консультант по каталогу ekt.kz: ищет товары по названию и артикулу, показывает цены и остатки по городам, подбирает аналоги с таблицей сравнения параметров и добавляет товар в демо-корзину только после явного подтверждения.
Как устроено
При старте backend строит поисковый индекс по страницам EKT API (Basic Auth) и подтягивает детали товаров. AssistantRunner через OpenAI Responses API вызывает ограниченный набор инструментов: поиск, характеристики, аналоги, условия покупки, подготовка предложения. Вложения PDF/DOCX/XLSX/JPEG разбираются структурированным ответом в черновик позиций. Предложение не меняет корзину: после клика «Да, добавить» сервер заново проверяет цену, остаток и кратность, защищён cookie-сессией и CSRF.
Ключевые решения
- function calling
- OpenAI Responses API
- structured output extraction from attachments
- analog matching with parameter diff
- confirmation-gated cart
- CSRF protection
Особенности
Подготовка предложения и изменение корзины разделены: запись в корзину идёт только после отдельного подтверждения с повторной проверкой цены и остатка. Кандидат-аналог показывается с таблицей совпадающих, отличающихся и неизвестных параметров, а не объявляется гарантированной заменой.
Стек
Node.js · TypeScript · Fastify · Zod · Vitest · JavaScript · HTML/CSS
Модели
OpenAI Responses API (по умолчанию gpt-6-sol, OPENAI_MODEL)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-ca5ddf34-paradox.
README
README.mdEKT AI — консультант по электротехнике
Проект команды Paradox для HackAlem AI, трек «Торговля». Покупателю ekt.kz бывает трудно самостоятельно проверить характеристики и наличие электротоваров или подобрать замену позиции без остатка. EKT AI помогает пройти этот путь в чате: находит товары в каталоге, показывает проверяемые сведения и готовит добавление в демонстрационную корзину только после явного подтверждения человека.
Что реализовано
- Поиск по названию и артикулу, карточки товаров с ценой, характеристиками и остатками по городам из API EKT.
- Подбор кандидата-аналога с таблицей совпадающих, отличающихся и неизвестных параметров. Кандидат не объявляется гарантированно совместимой заменой.
- Ответы на вопросы об условиях покупки из ограниченного набора сведений с указанием источника.
- Загрузка PDF, DOCX, XLSX и JPEG до 10 МБ: модель извлекает товарные позиции в черновик для проверки и отправки пользователем.
- Подготовка предложения с товаром, артикулом, количеством, городом, ценой и сроком действия. Подготовка не меняет корзину; для добавления нужен отдельный клик «Да, добавить в корзину».
- Демо-корзина с повторной проверкой цены, остатка и кратности при подтверждении; cookie-сессия, проверка CSRF и защита от повторного подтверждения одного предложения.
- Адаптивный чат, локальные история запросов и избранное. Сохранённые ответы служат справкой, а не подтверждением актуальной цены или наличия.
- Отдельный
ekt-ai-frontend/demo.htmlдля офлайн-показа на образцовых, а не на живых данных.
Как работает основной сценарий
- Покупатель пишет запрос — например, артикул товара, которого нет в наличии, и нужный город.
- Backend ищет товар в предварительно построенном индексе EKT, затем получает актуальные детали из API каталога. AI-ассистент вызывает ограниченные инструменты поиска, получения характеристик и подбора кандидатов.
- Интерфейс показывает исходный товар, одного или нескольких кандидатов, городской остаток, цену и сравнение. Противоречия в источнике и недостающие параметры остаются видимыми.
- Покупатель выбирает товар, количество и город. Backend создаёт предложение, но корзина пока не меняется.
- После просмотра предложения покупатель нажимает «Да, добавить в корзину». Backend повторно проверяет условия и обновляет демо-корзину; результат доступен по ссылке
/cart.
Решение не оформляет реальный заказ на ekt.kz.
Технологии
| Часть | Используется |
|---|---|
| Backend | Node.js, TypeScript, Fastify, Zod, @fastify/cookie, @fastify/multipart |
| AI | OpenAI SDK и Responses API: вызовы инструментов для чата, структурированный ответ для извлечения позиций из вложений; модель по умолчанию gpt-6-sol, задаётся через OPENAI_MODEL |
| Frontend | JavaScript, HTML, CSS без UI-фреймворка; сборка автономного index.html скриптом Node.js; локальный HTTP proxy |
| Тесты и запуск | Vitest для backend, Node.js Test Runner и LinkeDOM для frontend, tsx для запуска TypeScript |
| Данные | Каталог ekt.kz через защищённые Basic Auth запросы к API; сведения об условиях покупки в src/knowledge/ekt-terms.ts |
Архитектура
Браузер: чат, карточки, сравнение, история, подтверждение
│ /api/* и /cart через same-origin proxy при локальной разработке
▼
Fastify API: сессия, CSRF, маршруты чата, вложений и корзины
├── AssistantRunner ──► OpenAI Responses API
│ └── инструменты: поиск, детали, аналоги, условия, предложение
├── EktCatalogReader ─► поисковый индекс + EKT API (Basic Auth)
├── AttachmentExtractor ─► OpenAI Responses API
└── DemoCartProvider ─► корзина в памяти; запись только по подтверждению
Секреты EKT и OpenAI используются только на backend. Frontend обращается к своему origin, а сервер разработки проксирует API-запросы на порт 3000. Формат запросов и ответов описан в docs/API.md; особенности интерфейса — в ekt-ai-frontend/README.md.
Установка и запуск
Нужны Node.js 20.19+, npm, доступ к EKT API и действующий ключ OpenAI API. При старте backend загружает страницы каталога в индекс, поэтому первый запуск может занять время. Для локального запуска используйте 127.0.0.1 и не смешивайте его с localhost в адресах браузера.
-
Склонируйте репозиторий и настройте backend:
git clone https://github.com/BAITC-Hacks/hack-ca5ddf34-paradox.git cd hack-ca5ddf34-paradox npm ci cp .env.example .env -
В локальном
.envзаполнитеEKT_API_PASSWORDиOPENAI_API_KEY. При необходимости изменитеEKT_API_USERиOPENAI_MODEL. Для запуска ниже оставьтеPUBLIC_APP_URL=http://127.0.0.1:5173. Не публикуйте.envи ключи: этот файл исключён из Git. -
В первом терминале соберите, проверьте и запустите backend:
npm run build npm test npm run dev -
Во втором терминале, из корня того же репозитория, запустите frontend:
cd ekt-ai-frontend npm ci npm run build npm test npm run check npm run dev -
Откройте http://127.0.0.1:5173. Для быстрой проверки backend: http://127.0.0.1:3000/health должен вернуть
{"status":"ok"}.
npm run build в корне проверяет TypeScript; запуск backend в режиме разработки выполняет tsx. Сборка frontend обновляет отслеживаемый ekt-ai-frontend/index.html из исходников. Чтобы изменить число индексируемых страниц каталога, задайте EKT_INDEX_MAX_PAGES в .env (по умолчанию 20).
Как проверить решение жюри
- Откройте локальный интерфейс и отправьте: «Подбери один кандидат-аналог с наличием в Алматы для Legrand DPX3 160, артикул
310100077_. Покажи совпадения, противоречия и что нужно проверить». - Выберите Алматы в верхнем меню. У исходной позиции проверьте остаток, у кандидата — артикул, цену, доступное количество и таблицу сравнения. Данные каталога меняются: конкретные остаток, цена и найденный кандидат не гарантированы в будущий момент.
- На карточке доступного кандидата нажмите «Выбрать количество», укажите количество и город, затем «Проверить наличие и цену». Убедитесь, что предложение показано, а корзина ещё не изменилась.
- Нажмите «Проверить и подтвердить», просмотрите поля предложения и только затем «Да, добавить в корзину». Проверьте строку товара в
/cart.
Если нет доступа к внешним API, отдельный ekt-ai-frontend/demo.html можно открыть локально для показа интерфейса. Его товары, ответы и корзина — офлайн-образцы, не доказательство работы живых интеграций.
Данные и интеграции
- EKT API: список
GET /api/products?page=Nи деталиGET /api/products/detail?id=...; серверная авторизация Basic Auth. По умолчанию индексируются первые 20 страниц, подробности товаров запрашиваются отдельно. - OpenAI API: Responses API для ответов с ограниченными вызовами инструментов и структурированного извлечения позиций из вложений. Ключ хранится на backend.
- Условия покупки: конечный набор утверждений и ссылок на страницы ekt.kz находится в исходном коде; он не заменяет проверку актуальных условий у продавца.
- Локальные данные: история и избранное хранятся в браузере; сессии, предложения и демо-корзина — в памяти процесса backend.
Ограничения текущей версии
- Индекс ограничен числом страниц: отсутствие товара в поиске не означает отсутствие товара во всём каталоге.
- Кандидат в аналоги требует проверки электрической и механической совместимости. Если характеристики источника противоречат друг другу, система не считает их совпадением.
- Демо-корзина не связана с настоящей корзиной или оплатой ekt.kz; данные в памяти исчезают после перезапуска backend.
- Для живого сценария нужны доступные EKT API и OpenAI API. Локальный офлайн-показ использует образцовые данные.
- Публичная развёрнутая версия не указана в репозитории. GitHub-репозиторий содержит исходный код, но не является ссылкой на deployed-приложение.
Авторы коммитов
История коммитов
- 2026-09-23 17:25docs: prepare judge-ready README and align live catalog UItimur
- 2026-09-23 17:08feat(frontend): update sidebar navigation, local saved store, and offline demobossmerej-ship-it
- 2026-09-23 17:02perf: keep assistant replies concisetimur
- 2026-09-23 16:46fix: broaden safe alternative searchtimur
- 2026-09-23 15:39fix: align frontend integration and demo claimstimur
- 2026-09-23 15:28feat(frontend): integrate EKT AI chat frontend, safe cart flow and presentation deckbossmerej-ship-it
- 2026-09-23 14:41fix: require in-stock alternatives and catalog order multiplestimur
- 2026-09-23 14:38chore: merge team repository historytimur
Все коммиты (11)
- 2026-09-23 14:37feat: expose EKT assistant HTTP API and safe cart flowtimur
- 2026-09-23 13:58feat: add catalog tools and confirmation-safe backendtimur
- 2026-09-23 13:47chore: scaffold ekt assistant backendtimur
Структура репозитория (60 файлов)
.env.example .gitignore README.md docs/API.md docs/presentation.html docs/presentation.md ekt-ai-frontend/.gitignore ekt-ai-frontend/README.md ekt-ai-frontend/api.js ekt-ai-frontend/app.js ekt-ai-frontend/build.mjs ekt-ai-frontend/demo.html ekt-ai-frontend/dev-server.mjs ekt-ai-frontend/index.html ekt-ai-frontend/package-lock.json ekt-ai-frontend/package.json ekt-ai-frontend/saved-store.js ekt-ai-frontend/src/index.template.html ekt-ai-frontend/styles.css ekt-ai-frontend/tests/api.test.cjs ekt-ai-frontend/tests/build.test.cjs ekt-ai-frontend/tests/proxy.test.cjs ekt-ai-frontend/tests/ui.test.cjs ekt-ai-frontend/tests/view-model.test.cjs ekt-ai-frontend/view-model.js package-lock.json package.json src/agent/instructions.ts src/agent/runner.ts src/agent/schemas.ts src/agent/tools.ts src/app/ekt-assistant.ts src/app/presenter.ts src/attachments/extract.ts src/attachments/index.ts src/cart/confirmation.ts src/cart/demo-provider.ts src/cart/provider.ts src/catalog/ekt-client.ts src/catalog/index.ts src/catalog/normalize.ts src/catalog/search.ts src/catalog/types.ts src/http/app.ts src/http/server.ts src/index.ts src/integration/ekt-reader.ts src/knowledge/ekt-terms.ts src/knowledge/purchase-terms.ts tests/agent/runner.test.ts tests/agent/tools.test.ts tests/app/presenter.test.ts tests/attachments/extract.test.ts tests/cart/demo-provider.test.ts tests/catalog/catalog.test.ts tests/catalog/index.test.ts tests/http/app.test.ts tests/integration/ekt-reader.test.ts tsconfig.json vitest.config.ts
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.