AAYMA
RU
Войти

ekt.kz AI assistant

Low-code чат-консультант для ekt.kz на n8n: поиск по каталогу, аналоги при нулевом остатке, условия доставки и оплаты, прототипная корзина с…

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

О проекте

Команда: BioGraph
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP

Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина

Суть

Low-code чат-консультант для ekt.kz на n8n: поиск по каталогу, аналоги при нулевом остатке, условия доставки и оплаты, прототипная корзина с подтверждением. Есть публичная демо-страница.

Как устроено

AI-агент в n8n workflow ekt_assistant (OpenAI Chat Model, Postgres Chat Memory) вызывает инструменты-ноды: search_products, get_product, find_analogs, purchase_terms, prepare_cart_intent, confirm_add_to_cart и get_cart. Каталог лежит в Postgres/Supabase: 40 реальных товаров импортированы из API ekt.kz через Basic Auth, плюс синтетические TEST-*. Поиск строится на русском полнотексте и pg_trgm word_similarity; pgvector подключён, но embeddings не рассчитаны. Корзина меняется только следующим сообщением-согласием с проверкой сессии, 15-минутного срока намерения и остатка.

Ключевые решения

  • n8n AI Agent с tool-нодами
  • PostgreSQL full-text search
  • pg_trgm
  • pgvector (без embeddings)
  • consent-gated cart
  • импорт каталога через Basic Auth API

Особенности

Решение почти без кода, на n8n workflows и SQL. README честно перечисляет ограничения: embeddings не рассчитаны, вложения не обрабатываются, корзина ekt.kz не меняется. Первые коммиты от 19.09 — это подготовка n8n-скаффолда, удалённая к старту.

Стек

n8n · PostgreSQL · Supabase · pgvector · Docker Compose · HTML · GitHub Actions

Модели

OpenAI Chat Model (n8n)


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-80d7035f-biograph.

README

README.md

ekt.kz AI assistant (https://ekt-assistant-hackalem-2026.koncevojdanila10.chatgpt.site/)

Открыть публичное демо · Каталог товаров · Результаты проверок

Чат-консультант для ekt.kz: поиск товаров, характеристики, остатки по складам, сертификаты, аналоги и условия покупки. Цена и наличие берутся только из базы каталога.

Быстрый запуск

Нужны Docker с Docker Compose и доступ к OpenAI API. Команда docker compose up -d запускает Postgres и n8n; при первом запуске затем нужно вручную создать credentials, импортировать и опубликовать workflows по шагам ниже. Credentials из облачного экземпляра не переносятся с JSON. Статическая страница site/demo/index.html разворачивается отдельно; сервис сайта в Compose пока не включён.

  1. Скопируйте шаблон окружения:

    Copy-Item .env.example .env
    
  2. Замените POSTGRES_PASSWORD и N8N_ENCRYPTION_KEY в .env на собственные секретные значения. Файл .env не коммитится.

  3. Запустите локальный стек:

    docker compose up -d
    
  4. Откройте n8n: http://localhost:5678. При первом запуске создайте владельца n8n.

  5. Создайте credential типа Postgres с параметрами из .env:

    • Host: postgres (если n8n запущен через этот Docker Compose);
    • Port: 5432;
    • Database: значение POSTGRES_DB;
    • User: значение POSTGRES_USER;
    • Password: значение POSTGRES_PASSWORD;
    • SSL: выключен для локального Docker.
  6. Создайте credential типа OpenAI со своим API-ключом. Импортируйте n8n/workflows/ekt_assistant.json и назначьте локальный Postgres credential нодам Guard chat and cart confirmation, Postgres Chat Memory, catalog_overview, search_products, get_product, find_analogs, purchase_terms, prepare_cart_intent, confirm_add_to_cart и get_cart. Выберите созданный OpenAI credential в OpenAI Chat Model; при необходимости выберите модель, доступную вашему API-аккаунту.

  7. Импортируйте и опубликуйте n8n/workflows/ekt_cart_view.json, назначив Postgres credential ноде Load cart. В confirm_add_to_cart и get_cart замените базовый URL https://marindsain8n.ru/webhook/ekt-cart на http://localhost:5678/webhook/ekt-cart, затем опубликуйте ekt_assistant. Для уже существующей локальной БД (том Docker создан раньше) импортируйте n8n/workflows/ekt_cart_schema.json, назначьте локальный Postgres credential нодам Install cart schema и Sync verified purchase terms и выполните workflow вручную. Новые init-скрипты выполняются автоматически только при создании пустого тома; установочный workflow публиковать не нужно.

  8. Откройте production Chat URL из Chat Trigger и выполните локальные проверки ниже. Сразу после установки доступны только синтетические артикулы TEST-*. Для реального каталога дополнительно импортируйте n8n/workflows/ekt_catalog_import.json, создайте HTTP Basic Auth credential с данными, полученными от партнёра, назначьте его ноде Fetch product details, а локальный Postgres credential — нодам Existing catalog coverage, Upsert products и Verify PDF catalog coverage. Затем нажмите Execute workflow. Артикул 200300273_ используйте в проверках только после успешного импорта.

Уже работающий облачный вариант

На https://marindsain8n.ru создан и опубликован workflow ekt_assistant. Его Postgres credential подключён к Supabase через Session pooler (порт 5432). SQL из db/init.sql, db/cart.sql и db/terms.sql выполнен в Supabase. Повторные проверки 23 сентября 2026 года подтвердили товар по артикулу, аналог при нулевом остатке, составной вопрос о доставке/оплате/минимальной партии, отказ от добавления и запрет количества сверх остатка.

Для загрузки репрезентативной выборки реального каталога используйте n8n/workflows/ekt_catalog_import.json (workflow ekt_catalog_import). Он по нажатию Execute workflow запрашивает детальные данные 40 товаров из предоставленных PDF через Basic Auth API ekt.kz и обновляет products в Supabase по артикулу. Импорт проверен: 40 товаров получили реальные цены и остатки; повторный запуск обновит те же строки. Логин и пароль API хранятся только в HTTP Basic Auth credential n8n. Идентификаторы товаров для выборки находятся в ноде Sample product IDs; для расширения выборки потребуется согласованно обновить ID в Sample product IDs, Existing catalog coverage и Verify PDF catalog coverage. Перед защитой этот список и рабочий импорт не изменяйте.

В API списка есть id, article, name, price и URL карточки. Надёжный остаток по складам и характеристики берутся из /api/products/detail?id=.... Если сертификат в детальном ответе отсутствует, поле сертификата остаётся пустым. Категория для импортируемых товаров выводится из пути URL карточки. Поле embedding у этих 40 товаров пока пустое; find_analogs использует сходство названий через pg_trgm, когда векторов нет. Синтетические записи TEST-* остаются в базе для демонстрационных проверок. Семантические embeddings реального каталога не рассчитаны: search_products выполняет точный/частичный поиск по артикулу и имени, русский полнотекстовый поиск по имени/категории и приблизительное сравнение через word_similarity, а векторное сравнение в find_analogs используется только при наличии совместимых векторов. Установленный pgvector сам по себе не означает, что полноценный семантический поиск уже реализован.

Прототипная корзина

На хостинговом n8n опубликованы ekt_cart_view и обновлённый ekt_assistant. Корзина хранится в нашей БД, не в корзине сайта ekt.kz: предоставленный партнёром API содержит только чтение каталога, без метода изменения корзины. В чат сначала отправляют, например, «Добавь 1 штуку артикула 200300273_». Инструмент prepare_cart_intent проверяет товар и остаток, сохраняет намерение и просит отдельное подтверждение. Лишь на следующем сообщении «Да, добавь» / «Иә, қос» инструмент confirm_add_to_cart сверяет исходный текст клиента, сессию, срок намерения (15 минут), отдельное выполнение и текущий остаток, затем атомарно меняет корзину. При успехе выдаётся ссылка на актуальное состояние корзины. Перед AI узел Guard chat and cart confirmation проверяет формат sessionId и отменяет прежнее неподтверждённое намерение, если текущее сообщение не является явным согласием. После отказа или другого вопроса нужно заново попросить добавить товар. Без согласия и при превышении остатка корзина не меняется. Ссылка содержит случайный токен доступа; не публикуйте её публично. Заказ и оплата в прототипе недоступны.

Локально db/cart.sql и db/terms.sql выполняются при первом запуске пустого Postgres-тома. Скрипты db/cart.sql и db/terms.sql идемпотентны. Не запускайте повторно целиком db/init.sql поверх существующей БД: его исходные демонстрационные записи terms могут дублироваться. На уже созданной БД запустите workflow ekt_cart_schema вручную после db/init.sql: он также обновит проверенные условия покупки и уберёт демонстрационные ссылки на сертификаты. Этот workflow предназначен только для установки схемы и не публикуется. Секреты остаются в credentials n8n и .env.

Данные

При первом создании локальной БД Docker последовательно выполняет db/init.sql, db/cart.sql и db/terms.sql. Они создают и заполняют:

  • products с ценой, остатками, характеристиками, сертификатом, ссылкой на карточку и embedding;
  • terms для доставки, оплаты и минимальной партии; содержимое db/terms.sql сверено с публичными страницами ekt.kz;
  • n8n_chat_histories для истории чата по sessionId;
  • cart_sessions, cart_pending, cart_items для прототипной корзины;
  • синтетические записи TEST-001, TEST-000, TEST-002 и TEST-003.

TEST-000 имеет нулевой остаток, а TEST-002 и TEST-003 пригодны для проверки аналогов. Все TEST-* — синтетические записи, не реальные карточки ekt.kz; фальшивые ссылки на сертификаты удалены. На облачном демо рядом с тестовыми строками уже загружены 40 реальных товаров; тестовые строки оставлены для воспроизводимых проверок. Basic Auth API-данные хранятся только в credentials n8n или .env.

Проверка

В чате workflow отправляйте запросы ниже по одному. «Да, добавь» отправьте отдельным сообщением только после того, как ассистент повторит артикул и количество и попросит подтверждение. Этот набор работает на свежей локальной БД без доступа к API партнёра:

Покажите товар по артикулу TEST-001
У товара TEST-000 нулевой остаток, предложите аналог
Какие условия доставки, оплаты и минимальной партии?
Добавь 1 штуку по артикулу TEST-001
Да, добавь

Ожидается: ответ с данными из БД и явной пометкой тестовых товаров, аналоги при нулевом остатке, условия доставки из terms и добавление в прототипную корзину только после отдельного подтверждения. Откройте полученную ссылку и проверьте товар и количество. Также проверьте отказ («нет») и количество больше остатка — корзина не должна меняться.

Подключение к сайту

Проверен публичный сайт ekt.kz; подготовлены инструкция для владельца сайта и фрагмент для встраивания. У команды пока нет доступа к шаблону/админке, поэтому чат не установлен на ekt.kz. Предоставленный API позволяет только читать каталог, поэтому настоящая корзина ekt.kz не изменяется. Для установки и подключения настоящей корзины нужны доступ владельца сайта и документированный серверный метод добавления товара. Вложения (фото, PDF, Excel, Word) пока не обрабатываются; не заявляйте эту возможность на демонстрации.

Отдельный публичный демо-сайт

Рабочая страница: ekt-assistant-hackalem-2026.koncevojdanila10.chatgpt.site. Исходник: site/demo/index.html, сведения о публикации: site/demo/README.md. Страница использует собственный адаптивный интерфейс чата без iframe. Браузер отправляет в опубликованный Chat Trigger n8n POST JSON с полями action: "sendMessage", sessionId и chatInput; ответ отображается в том же окне. История интерфейса и случайный идентификатор сессии хранятся в sessionStorage этой вкладки, кнопка «Новый диалог» создаёт новый sessionId. Серверный контекст диалога хранится отдельно в Postgres Chat Memory. В интерфейсе предусмотрены ожидание ответа, ошибка соединения и ручное повторение запроса; автоматического повторного добавления в корзину после сетевой ошибки нет.

Товары, цены и остатки приходят из Postgres/Supabase через workflow, а не зашиты в страницу. API-ключи и пароль БД в HTML отсутствуют. Для размещения этой страницы с собственным n8n замените ENDPOINT в site/demo/index.html на production Chat URL своего экземпляра, опубликуйте workflow и разрешите origin сайта в настройках CORS Chat Trigger. По умолчанию исходник обращается к облачному n8n, а не к БД, поднятой локальным Compose.

Сайт публичен по ссылке, но не установлен на ekt.kz; корзина остаётся прототипной без оформления заказа. Полноценный семантический поиск по реальному каталогу и обработка вложений (фото, PDF, Excel, Word) пока не реализованы. Ссылку на сертификат ассистент может вернуть только для товара, у которого она действительно есть в БД.

Импорт всех товаров из предоставленных PDF

23.09.2026 выполнен импорт №3191: до запуска в БД были 8 из 40 выбранных товаров, после — 40/40, список отсутствующих ID пуст. Добавлены 32 товара, прежние 8 обновлены. Подробная карточка ID 515291 входит в эти 40 и не создаёт дубль. Это все товары из двух PDF-страниц списка, а не весь каталог ekt.kz.

Импорт загружает детальные ответы API группами по 5, проверяет полноту/уникальность, сохраняет цены, остатки по складам, свойства, описание, изображение, варианты и URL. Все upsert-запросы идут в одной транзакции. Пустая цена/остаток не преобразуются в ноль. Корзины и TEST-* не изменяются. Basic Auth остаётся в существующем credential n8n.

Назначьте Postgres credential также нодам проверки покрытия до/после импорта. Подробности и перечень всех 40 артикулов: CATALOG_IMPORT_REPORT.md. Для карточки 200300285_ отдельно проверено предупреждение ассистента о противоречии 160 A / 250 A в исходных данных.

Витрина товаров из БД и фотографии

Отдельный демонстрационный сайт показывает каталог под чатом: карточки с фото, названием, артикулом, ценой и остатком; поиск по названию/артикулу, категории и фильтр «Только в наличии». Кнопка «Спросить о товаре» отправляет вопрос в текущий диалог и не добавляет товар в корзину.

Источник витрины — публичный read-only GET https://marindsain8n.ru/webhook/ekt-catalog, workflow ekt_catalog_view (экспорт n8n/workflows/ekt_catalog_view.json). Импортируйте его в n8n, выберите существующий Postgres credential в Read public catalogue и опубликуйте. Запрос читает только импортированные нетестовые строки products: публичные поля карточки, категории и агрегированные счётчики. История диалогов, сессии, корзины и credentials наружу не передаются. Ошибка БД возвращает безопасный HTTP 503, не пустой каталог. Для своего n8n измените CATALOG_ENDPOINT и ENDPOINT в site/demo/index.html; новых переменных окружения нет.

Чат использует catalog_overview для «сколько товаров?»/«что есть?» и отделяет этот запрос от get_cart. Поиск учитывает русские словоформы, нормализованные категории и приблизительное совпадение; синтетические TEST-* не попадают в обычный обзор. Фото передаются в поле image_url и отображаются безопасно, только с HTTPS-домена ekt.kz. Если фото нет или оно не загрузилось, показывается явный текст, без подмены изображением другого товара.

На контрольном снимке: 40 реальных товаров, 22 позиции с положительным остатком, 39 URL фотографий; это выборка из PDF, не весь каталог ekt.kz. Кабелей в ней нет. Цены и остатки читаются из БД и являются снимком последнего импорта, не обещанием наличия в реальном времени.

Финальная проверка и воспроизведение

Для локального запуска сначала скачайте/клонируйте этот репозиторий и откройте терминал в его корневой папке (где лежит docker-compose.yml). Доступ к приватному репозиторию необходимо заранее выдать проверяющему; публичное демо доступно без доступа к GitHub.

После настройки .env и запуска из раздела «Быстрый запуск» проверьте:

docker compose config --quiet
docker compose ps
docker compose exec postgres sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT count(*) AS products FROM products;"'

Postgres должен быть healthy, n8n — running. На свежей БД ожидаются 4 синтетических товара TEST-. После описанного импорта добавятся 40 реальных товаров. Публичная витрина и catalog_overview намеренно исключают TEST-, поэтому до импорта они показывают 0 — это не ошибка подключения.

Для отдельной страницы после настройки обоих URL и публикации workflows (включая ekt_catalog_view) запустите из корня репозитория:

# Требуется установленный Python 3; на macOS/Linux команда может называться python3.
python -m http.server 8080 --bind 127.0.0.1 --directory site/demo

Откройте http://localhost:8080. Для локального запуска используйте production Chat URL локального n8n в ENDPOINT, http://localhost:5678/webhook/ekt-catalog в CATALOG_ENDPOINT; разрешите origin http://localhost:8080 в CORS Chat Trigger. Не открывайте страницу через file://. Иначе при неизменённых URL она продолжит обращаться к облачному демо, а не к вашей локальной БД.

Необязательные автоматические тесты интерфейса (Node.js 18+):

node site/demo/tests.cjs

Статус проверки запуска: облачный опубликованный сценарий и тесты интерфейса выполнены. Полный fresh-install через Docker на машине проверки не выполнен: Docker CLI/Desktop отсутствуют. Compose, переменные и порядок SQL проверены статически. Образ n8n пока указан как latest; его воспроизведение в будущую дату не гарантирует тот же runtime. Перед защитой не обновляйте рабочий инстанс и не удаляйте Docker volumes. Пароли/ключи, случайные ссылки доступа к корзинам и реальные .env не прикладывайте к отчётам.

Звёзды
⭐ 0
Форки
0
Язык
HTML
Последний push
в прошлом месяце
Коммиты
59
Авторы
3
Файлы
29
Ветки
1

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

koncevojdanila10-source 30MarFedorovna 27mrqey-cmyk 3

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

  • 2026-09-23 17:49fix: use high detail for product photo OCRMarFedorovna
  • 2026-09-23 17:48test: add portable synthetic attachment smoke checksMarFedorovna
  • 2026-09-23 17:45feat: enable safe attachments in public demoMarFedorovna
  • 2026-09-23 17:44feat: add validated document and image extraction workflowMarFedorovna
  • 2026-09-23 17:39Create smoke.ymlci: verify clean Docker startup and workflow importsMarFedorovna
  • 2026-09-23 17:29Update README.mdMarFedorovna
  • 2026-09-23 17:28Update README.mdMarFedorovna
  • 2026-09-23 17:26docs: final smoke checks and reproducible setupMarFedorovna
Все коммиты (59)
  • 2026-09-23 17:25Update README.mdMarFedorovna
  • 2026-09-23 17:18docs: record catalogue and photo regression checksMarFedorovna
  • 2026-09-23 17:18feat: visible database catalogue with photos and filtersMarFedorovna
  • 2026-09-23 17:06fix: catalogue answers, product photos and read-only catalogue APIMarFedorovna
  • 2026-09-23 16:57Update README.mdMarFedorovna
  • 2026-09-23 16:57docs: record complete PDF catalog importMarFedorovna
  • 2026-09-23 16:56feat: import all 40 PDF catalog productsMarFedorovna
  • 2026-09-23 16:44feat: responsive public assistant chatMarFedorovna
  • 2026-09-23 16:43docs: record demo verification and setupMarFedorovna
  • 2026-09-23 16:42fix: guard cart consent and export verified assistantMarFedorovna
  • 2026-09-23 16:12docs: link public ekt assistant demo siteMarFedorovna
  • 2026-09-23 16:10Checkpoint standalone public demo deployment and API evidencekoncevojdanila10-source
  • 2026-09-23 16:10Document public standalone assistant demo deploymentkoncevojdanila10-source
  • 2026-09-23 16:08Add standalone public demo page for ekt assistantkoncevojdanila10-source
  • 2026-09-23 15:55docs: record 15:55 acceptance test resultskoncevojdanila10-source
  • 2026-09-23 15:54docs: update setup, verified tests, and site limitationskoncevojdanila10-source
  • 2026-09-23 15:54docs: document safe ekt.kz integration handoffkoncevojdanila10-source
  • 2026-09-23 15:54feat(site): prepare official n8n chat embed fragmentkoncevojdanila10-source
  • 2026-09-23 15:53fix(n8n): include catalog currency in product toolskoncevojdanila10-source
  • 2026-09-23 15:52fix(db): do not seed fake certificate URLskoncevojdanila10-source
  • 2026-09-23 15:52build: seed verified terms in fresh local databasekoncevojdanila10-source
  • 2026-09-23 15:51feat(db): add verified purchase terms and remove demo certificate linkskoncevojdanila10-source
  • 2026-09-23 15:51feat(n8n): sync verified purchase termskoncevojdanila10-source
  • 2026-09-23 15:51fix(n8n): repair analog and purchase terms toolskoncevojdanila10-source
  • 2026-09-23 15:37docs: explain prototype cart setup and testsmrqey-cmyk
  • 2026-09-23 15:36feat(n8n): add consent-gated cart workflowsmrqey-cmyk
  • 2026-09-23 15:35feat(db): add consent-gated prototype cartmrqey-cmyk
  • 2026-09-23 15:23docs: clarify catalog sample and analog fallbackkoncevojdanila10-source
  • 2026-09-23 15:22fix(n8n): search real analogs by name when embeddings absentkoncevojdanila10-source
  • 2026-09-23 15:22docs: document verified real catalog importkoncevojdanila10-source
  • 2026-09-23 15:22chore(n8n): remove superseded catalog preview exportkoncevojdanila10-source
  • 2026-09-23 15:12feat(n8n): export verified ekt catalog importerkoncevojdanila10-source
  • 2026-09-23 15:02docs: describe hosted Supabase setup and catalog previewkoncevojdanila10-source
  • 2026-09-23 15:01feat(n8n): add credential-safe ekt catalog API previewkoncevojdanila10-source
  • 2026-09-23 14:57chore(n8n): export published ekt assistant statekoncevojdanila10-source
  • 2026-09-23 14:57fix(n8n): connect Supabase Postgres and verify assistant chatkoncevojdanila10-source
  • 2026-09-23 14:31chore(n8n): export analog explanation updatekoncevojdanila10-source
  • 2026-09-23 14:30chore(n8n): export updated ekt assistant tool guidancekoncevojdanila10-source
  • 2026-09-23 14:29docs: add local setup and ekt assistant test guidekoncevojdanila10-source
  • 2026-09-23 14:29docs(config): add local stack environment templatekoncevojdanila10-source
  • 2026-09-23 14:29feat(docker): add local n8n and pgvector stackkoncevojdanila10-source
  • 2026-09-23 14:29fix(db): enable trigram extension before search indexeskoncevojdanila10-source
  • 2026-09-23 14:28feat(db): add ekt assistant schema and demo cataloguekoncevojdanila10-source
  • 2026-09-23 14:21checkpoint 15:00: add ekt_assistant n8n workflowkoncevojdanila10-source
  • 2026-09-23 14:15checkpoint 14:00: track 10 ekt.kz — TZ, plan, scaffoldMarFedorovna
  • 2026-09-22 18:32chore: remove pre-hackathon setupMarFedorovna
  • 2026-09-19 21:50fix: place n8n workflow in workflows directoryMarFedorovna
  • 2026-09-19 21:50Delete workflows/biograph-healthcheck.json/biograph-healthcheck.jsonMarFedorovna
  • 2026-09-19 21:43feat: add n8n health check workflowMarFedorovna
  • 2026-09-19 21:42feat: add self-hosted n8n scaffoldMarFedorovna
  • 2026-09-19 20:54Create CODEX_ACCESS_TEST.mdMarFedorovna
Структура репозитория (29 файлов)
.env.example
.github/workflows/smoke.yml
.gitignore
AGENTS.md
CATALOG_IMPORT_REPORT.md
PROGRESS.md
README.md
TEST_REPORT.md
data/.gitkeep
db/.gitkeep
db/cart.sql
db/init.sql
db/terms.sql
docker-compose.yml
docs/SITE_INTEGRATION.md
docs/TZ.md
n8n/workflows/.gitkeep
n8n/workflows/ekt_assistant.json
n8n/workflows/ekt_attachment_extract.json
n8n/workflows/ekt_cart_schema.json
n8n/workflows/ekt_cart_view.json
n8n/workflows/ekt_catalog_import.json
n8n/workflows/ekt_catalog_view.json
site/demo/README.md
site/demo/index.html
site/demo/tests.cjs
site/ekt-chat-embed.html
tests/attachment-smoke.py
tests/attachment-validation.py

Обсуждение 0 комментариев

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

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