AAYMA
RU
Войти

EKT AI

Чат-консультант по каталогу ekt.kz: ищет товары по названию и артикулу, показывает цены и остатки по городам, подбирает аналоги с таблицей сравнения…

Рабочий MVP
Команда «Paradox» 2💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: 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.md

EKT AI — консультант по электротехнике

Проект команды Paradox для HackAlem AI, трек «Торговля». Покупателю ekt.kz бывает трудно самостоятельно проверить характеристики и наличие электротоваров или подобрать замену позиции без остатка. EKT AI помогает пройти этот путь в чате: находит товары в каталоге, показывает проверяемые сведения и готовит добавление в демонстрационную корзину только после явного подтверждения человека.

Что реализовано

  • Поиск по названию и артикулу, карточки товаров с ценой, характеристиками и остатками по городам из API EKT.
  • Подбор кандидата-аналога с таблицей совпадающих, отличающихся и неизвестных параметров. Кандидат не объявляется гарантированно совместимой заменой.
  • Ответы на вопросы об условиях покупки из ограниченного набора сведений с указанием источника.
  • Загрузка PDF, DOCX, XLSX и JPEG до 10 МБ: модель извлекает товарные позиции в черновик для проверки и отправки пользователем.
  • Подготовка предложения с товаром, артикулом, количеством, городом, ценой и сроком действия. Подготовка не меняет корзину; для добавления нужен отдельный клик «Да, добавить в корзину».
  • Демо-корзина с повторной проверкой цены, остатка и кратности при подтверждении; cookie-сессия, проверка CSRF и защита от повторного подтверждения одного предложения.
  • Адаптивный чат, локальные история запросов и избранное. Сохранённые ответы служат справкой, а не подтверждением актуальной цены или наличия.
  • Отдельный ekt-ai-frontend/demo.html для офлайн-показа на образцовых, а не на живых данных.

Как работает основной сценарий

  1. Покупатель пишет запрос — например, артикул товара, которого нет в наличии, и нужный город.
  2. Backend ищет товар в предварительно построенном индексе EKT, затем получает актуальные детали из API каталога. AI-ассистент вызывает ограниченные инструменты поиска, получения характеристик и подбора кандидатов.
  3. Интерфейс показывает исходный товар, одного или нескольких кандидатов, городской остаток, цену и сравнение. Противоречия в источнике и недостающие параметры остаются видимыми.
  4. Покупатель выбирает товар, количество и город. Backend создаёт предложение, но корзина пока не меняется.
  5. После просмотра предложения покупатель нажимает «Да, добавить в корзину». Backend повторно проверяет условия и обновляет демо-корзину; результат доступен по ссылке /cart.

Решение не оформляет реальный заказ на ekt.kz.

Технологии

ЧастьИспользуется
BackendNode.js, TypeScript, Fastify, Zod, @fastify/cookie, @fastify/multipart
AIOpenAI SDK и Responses API: вызовы инструментов для чата, структурированный ответ для извлечения позиций из вложений; модель по умолчанию gpt-6-sol, задаётся через OPENAI_MODEL
FrontendJavaScript, 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 в адресах браузера.

  1. Склонируйте репозиторий и настройте backend:

    git clone https://github.com/BAITC-Hacks/hack-ca5ddf34-paradox.git
    cd hack-ca5ddf34-paradox
    npm ci
    cp .env.example .env
    
  2. В локальном .env заполните EKT_API_PASSWORD и OPENAI_API_KEY. При необходимости измените EKT_API_USER и OPENAI_MODEL. Для запуска ниже оставьте PUBLIC_APP_URL=http://127.0.0.1:5173. Не публикуйте .env и ключи: этот файл исключён из Git.

  3. В первом терминале соберите, проверьте и запустите backend:

    npm run build
    npm test
    npm run dev
    
  4. Во втором терминале, из корня того же репозитория, запустите frontend:

    cd ekt-ai-frontend
    npm ci
    npm run build
    npm test
    npm run check
    npm run dev
    
  5. Откройте 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).

Как проверить решение жюри

  1. Откройте локальный интерфейс и отправьте: «Подбери один кандидат-аналог с наличием в Алматы для Legrand DPX3 160, артикул 310100077_. Покажи совпадения, противоречия и что нужно проверить».
  2. Выберите Алматы в верхнем меню. У исходной позиции проверьте остаток, у кандидата — артикул, цену, доступное количество и таблицу сравнения. Данные каталога меняются: конкретные остаток, цена и найденный кандидат не гарантированы в будущий момент.
  3. На карточке доступного кандидата нажмите «Выбрать количество», укажите количество и город, затем «Проверить наличие и цену». Убедитесь, что предложение показано, а корзина ещё не изменилась.
  4. Нажмите «Проверить и подтвердить», просмотрите поля предложения и только затем «Да, добавить в корзину». Проверьте строку товара в /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-приложение.
Звёзды
⭐ 0
Форки
0
Язык
HTML
Последний push
в прошлом месяце
Коммиты
11
Авторы
2
Файлы
60
Ветки
1

Авторы коммитов

timur 9bossmerej-ship-it 2

История коммитов

  • 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 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.