AAYMA
RU
Войти

EKT AI / EKT Assist

Витрина ekt.kz с ИИ-консультантом: поиск и фильтры по каталогу, сравнение, подбор аналогов, корзина с подтверждением каждого изменения…

Доведённый продукт
Команда «Ctrl-Z» 17💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Ctrl-Z
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Доведённый продукт

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

Суть

Витрина ekt.kz с ИИ-консультантом: поиск и фильтры по каталогу, сравнение, подбор аналогов, корзина с подтверждением каждого изменения, демо-оформление заявки, экспорт подборки в XLSX/PDF, интерфейс на RU/KZ/EN.

Как устроено

Снимок из 100 реальных карточек (data/catalog.json, скрипт sync-catalog.mjs) плюс свежая проверка карточки через API ekt.kz (/api/products/detail) на сервере Vinext/Cloudflare Worker. Модель через Chat Completions-совместимый endpoint с function tools читает каталог. Изменения корзины идут двумя шагами: серверное предложение с токеном и сроком 5 минут, затем подтверждение с повторной проверкой цены и остатка; запись в D1 защищена сравнением revision. Аналог выдаётся только при совпадении группы и минимум двух критических параметров.

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

  • function calling
  • двухэтапное подтверждение корзины (токен + TTL)
  • optimistic concurrency (revision) в D1
  • правила подбора аналогов по критическим параметрам
  • разбор спецификаций из вложений
  • экспорт XLSX/PDF

Особенности

Серьёзная защита корзины: HttpOnly-сессия, проверка Origin, одноразовое предложение с TTL, повторное чтение API перед записью и revision-сравнение от гонок. Честная обработка неизвестных значений: при противоречии номинала аналоги не выдаются, нули вместо пропусков не подставляются. Много тестов, в том числе адаптера ИИ на подставных ответах.

Стек

TypeScript · React · Vinext · Cloudflare Workers · Cloudflare D1 · Drizzle ORM · shadcn/ui · Node.js


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

README

README.md

Электрокомплект — консультант по каталогу

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

В текущей версии это витрина с ИИ-консультантом, пошаговым оформлением демо-заявки и инструментами для закупщика: фильтры каталога, избранное, история просмотров, разбор спецификаций, русский, казахский и английский интерфейс, пересчёт цен и выгрузка подборки в Excel/PDF. Покупатель может пройти путь от поиска товара до подборки и демо-заявки с контактами, адресом, желаемой датой доставки и способом оплаты.

Основной принцип: сведения о товаре берутся из каталога, а решение об изменении корзины остаётся за пользователем. Объяснение задачи — в CASE.md, подготовка выступления — в сценарии защиты.

Возможности и статус

ВозможностьТекущая реализация
КаталогПоиск, фильтры, сравнение, избранное и история; снимок из 100 товаров
EKT AIГенерация ответов и инструменты чтения каталога; требуется ключ провайдера
КорзинаПроверка живых цен и остатков, отдельное подтверждение изменений
ОформлениеКонтакты, доставка или самовывоз, адрес, дата, интервал, способ оплаты, история демо-заявок
ДокументыРазбор спецификаций, экспорт подборки в XLSX/PDF, квитанция заявки в TXT
ЯзыкиРусский, казахский и английский; цены отображаются в RUB/KZT/USD

Заказ не отправляется в EKT, товар не резервируется, деньги не списываются. Интеграции с API заказов и платёжным сервисом пока нет.

Презентации и демонстрация

HTML-демонстрация показывает сценарий на сохранённых данных. Для работы с серверной сессией и живым API нужно запустить приложение. Презентации отражают разные этапы проекта; актуальные возможности описаны ниже.

Запуск

Нужен Node.js 24 и npm. В каталоге проекта:

npm ci

Скопируйте .env.example в .env.local и заполните выданные организатором EKT_API_USER, EKT_API_PASSWORD. Они используются только сервером. В архиве пароля нет. Без доступов EKT поиск по сохранённой выборке доступен, а добавление и изменение количества блокируются, поскольку проверить свежий остаток невозможно. Для просмотра каталога ключ ИИ не требуется. Для диалога с EKT AI обязательны серверные настройки LLM_URL, LLM_API_KEY и LLM_MODEL; без них чат показывает статус отключённого ИИ. Заполненный .env.local не нужно загружать в GitHub.

npm run build
node scripts/migrate-local.mjs
npm run dev

Откройте адрес, напечатанный сервером, обычно http://localhost:5173. Миграцию выполняйте один раз для новой локальной базы. Для локальной проверки собранного Worker используйте npm start и адрес из его вывода. Эта команда не публикует приложение. Локальная D1 хранится в .wrangler/state. Повторно запускать миграционный скрипт на уже созданной базе не требуется.

npm test
npm run test:currency
npm run test:exports
npm run test:ai
npm run test:checkout
npx tsc --noEmit

Эти проверки запускаются без работающего сервера. npm test проверяет логику корзины на контролируемых данных, test:currency — курсы, округление и языковые сценарии, test:exports — состав подборки и генерацию документов. test:ai проверяет адаптер на подставных ответах провайдера без платных запросов. test:checkout проверяет поля формы, наличие, цены, срок предложения и защиту от повторного создания заявки.

Для HTTP-проверок сначала запустите приложение и подготовьте D1:

npm run test:catalog
npm run test:workflows
node scripts/test-localization-export.mjs --http
node scripts/test-ai-consultant.mjs --http
node scripts/test-checkout.mjs --http

test:catalog проверяет и фильтры, и серверный /api/catalog, поэтому для завершения всей команды нужен сервер. Живые сценарии EKT запускаются отдельно:

npm run test:integration
node scripts/test-workflows.mjs --live

Для них нужны настроенные доступы EKT, доступный API и подходящие актуальные остатки. Тесты создают отдельные сессии демонстрационной корзины и не оформляют реальных заказов. HTTP-проверки используют http://localhost:5173; другой адрес задаётся переменной TEST_URL.

Архитектура

Интерфейс React → серверные маршруты Vinext/Cloudflare Worker → API ekt.kz + D1. Клиент не получает BasicAuth и не может самостоятельно задать цену. Данные каталога импортированы в data/catalog.json; lib/domain.ts отвечает за нормализацию, поиск, правила подбора и количества. app/api/assistant/route.ts обрабатывает диалог и двухэтапное добавление. lib/store.ts отвечает за работу с D1. lib/ai-consultant.ts реализует обращения к модели и инструменты чтения каталога, lib/ekt.ts — запрос актуальной карточки товара. Форма оформления находится в app/checkout.tsx, серверные правила — в lib/checkout.ts, маршрут — в app/api/checkout/route.ts.

Витрина и её фильтры находятся в app/storefront.tsx и lib/catalog-browser.ts. lib/workflows.ts описывает операции корзины, местные остатки и разбор спецификаций. lib/i18n.ts, lib/english.ts и lib/ai-copy.ts содержат переводы интерфейса и вспомогательную обработку поисковых запросов. lib/currency.ts и /api/rates отвечают за валютное отображение, а lib/selection.ts и lib/export-selection.ts — за состав и выгрузку подборки.

Публичный /api/catalog отдаёт снимок товаров, /api/assistant обслуживает диалог и действия текущей сессии, /api/attachment извлекает текст вложений, /api/selection возвращает данные для экспорта, /api/checkout проверяет и сохраняет демо-заявки текущей сессии. Учётные данные внешнего API не передаются браузеру.

Сессия идентифицируется случайной HttpOnly cookie с SameSite=Strict и Secure на HTTPS. Запросы изменения требуют совпадения Origin. Серверное предложение содержит ID товара, количество, цену, случайный токен и срок пять минут. Подтверждение повторно читает API, проверяет доступное количество вместе с уже добавленным. Изменившаяся цена требует нового согласия. Обновление строки D1 использует сравнение revision: конкурентные подтверждения не могут оба записать одну версию состояния.

Диалог, корзина, оценки и демо-заявки с контактами доступны в пределах 24-часовой сессии. Просроченные записи удаляются при создании новых сессий; отдельного планировщика очистки нет. Для настоящего магазина нужны его авторизация, согласованная политика хранения, лимиты на уровне инфраструктуры, мониторинг и нагрузочное тестирование.

Данные и достоверность

Выборка: 100 реальных карточек с первых пяти страниц, полученных 2026-09-23. В неё входят цены, остатки по складам, свойства, описания, URL и изображения. Публичные изображения загружаются напрямую с ekt.kz. Открытие карточки, сравнение, подготовка и подтверждение добавления запрашивают детали через /api/products/detail?id=.... При недоступности API карточка и сравнение могут показать отмеченный снимок, но добавление и изменение количества требуют успешной свежей проверки. Поиск остаётся по выборке, поэтому «не найден» не означает «нет в магазине». В API нет найденного товара — неизвестные значения не подменяются нулями.

Пересоздать выборку можно скриптом ниже, передав доступ через переменные окружения оболочки. CATALOG_PAGES по умолчанию равен 30; значение all обходит страницы до пустого ответа. CATALOG_MAX_PRODUCTS ограничивает размер (по умолчанию 10000). Скрипт последовательно перебирает страницы и загружает карточки с параллелизмом четыре.

node --env-file=.env.local scripts/sync-catalog.mjs

Команда выше загружает переменные из .env.local. Параметр --resume продолжает сохранённый прогресс. Есть повторные попытки, тайм-ауты и защита от повторяющихся страниц. При ошибке прежний каталог сохраняется; новый файл заменяется атомарно. Ограничение встроенного снимка — 12 МБ, для большего каталога нужен индекс в базе. После обновления пересоберите приложение. Автоматическое расписание не настроено. В переданной версии снимок содержит 100 товаров. Число товаров и дату загрузки нужно проверять в data/catalog.json: настройки загрузчика сами по себе не означают, что весь каталог уже получен.

Подбор аналога требует совпадения группы каталога и минимум двух известных критических параметров; несовпадающий известный параметр исключает кандидата. Отсутствие противоречий не доказывает совместимость. Полная электробезопасность требует инженерной проверки. При противоречии номинала между названием и полями автоматические аналоги не выдаются.

ИИ не должен придумывать условия покупки. Реальные сроки, тарифы доставки, адрес самовывоза и доступность способов оплаты требуют подтверждения менеджером; выбранные в демо-форме значения являются пожеланиями покупателя. Сертификаты не выдумываются: при отсутствии ссылки в API пользователь направляется к менеджеру.

Подключение EKT AI

Сценарный обработчик диалога заменён генерацией ответов через модель. Задайте в серверном окружении:

LLM_URL=https://your-provider.example/v1/chat/completions
LLM_API_KEY=your-server-secret
LLM_MODEL=your-supported-model

Нужен полный HTTPS endpoint, совместимый с Chat Completions, function tools и параметром max_completion_tokens. Ключ не передаётся браузеру и не хранится в Git. После изменения настроек перезапустите приложение.

Без настроек чат показывает статус отключённого ИИ; прежние шаблонные консультации не включаются. Поиск через каталог, карточки, корзина и её подтверждения продолжают работать при доступности нужных данных.

Модель получает последние 8 сообщений, текущий вопрос, город, выбранный товар, ID и количества корзины и ограниченные данные каталога. Инструменты search_catalog и product_details только читают данные. ИИ не может менять корзину или оформлять заказ: покупатель использует карточку товара и отдельное подтверждение. Ответ формируется на языке интерфейса. При сбое провайдера показывается ошибка, историю и корзину не подменяют выдуманным результатом.

Ограничения адаптера: до 4 обращений к модели, до 4 инструментов за шаг и общий сигнал тайм-аута запросов модели 45 секунд. Качество ответов конкретного провайдера нужно проверить отдельно. Реальная генерация без ключа не проверена; автоматические тесты используют подставные ответы.

Для JPEG дополнительно нужна поддержка image_url с data URL. Сообщения и распознаваемые фотографии передаются настроенному провайдеру; контакты и адрес из формы заказа в историю ИИ не попадают. Не отправляйте платёжные данные в чат.

Вложения

До 4 МБ: DOCX, XLSX, текстовый PDF до 25 страниц, TXT, CSV; JPEG после подключения модели. DOCX/XLSX разбираются как ограниченный ZIP/XML без выполнения макросов, формул и инструкций. Старые бинарные .doc/.xls не поддерживаются: сохраните как DOCX/XLSX. PDF-сканы без текстового слоя автоматически не распознаются: можно ввести артикул вручную или подготовить JPEG для подключённой модели. Распознанный текст ограничен 12000 символами. Исходные файлы не сохраняются как отдельные вложения; извлечённый текст открывается в таблице спецификации (до 60 непустых строк). Пользователь проверяет артикул, соответствие товара и количество; неоднозначные позиции требуют ручного выбора. До 20 выбранных строк товаров можно добавить одним подтверждением после проверки API. Повторы одного товара объединяются по ID, а количества суммируются. Пример формата: 200300285_;2; файл — public/example-spec.csv. Последний разбор строк хранится в сессии для обращения менеджеру и экспорта. Загрузка и разбор файла сами по себе не меняют корзину.

Границы прототипа

  • Корзина собственная, не интегрирована в ekt.kz: предоставлены только методы чтения товаров. Ссылка /#cart открывает актуальную демонстрационную корзину той же сессии. Нет оплаты, реального заказа или резервирования.
  • Работа модели и распознавание JPEG требуют настройки провайдера. Без неё ИИ-чат отключён, а каталог остаётся доступным.
  • Есть адаптивная страница и виджет /widget-demo. На реальный сайт он пока не установлен.
  • Сертификат выводится только при наличии данных. Производственные правила доставки, кратности и допустимых складов нужно согласовать с владельцем каталога.
  • Валютный пересчёт предназначен для отображения. Исходные цены и серверные проверки остаются в KZT; оплата в RUB/USD не реализована.
  • Избранное хранится в браузере, а диалог, оценки и корзина ограничены сроком сессии. Постоянного личного кабинета, совместных подборок и общей аналитической панели пока нет.
  • Автоматические тесты покрывают основной цикл корзины, но не являются аудитом безопасности и нагрузочным испытанием.

Проверяемые сценарии

Тесты проверяют поиск по артикулу, противоречивые характеристики, количество и остаток, явное подтверждение, отмену, конкурентную запись, сохранение корзины, изоляцию сессий и отклонение чужого Origin. Отдельные наборы покрывают ИИ-инструменты, оформление заявки, валюты и экспорт. Проверки вспомогательных функций прежнего диалога не означают, что сценарный чат по-прежнему используется.

Фронтенд предоставляет WebMCP search_catalog только для поиска: инструмент не меняет корзину.

Диалог и карточки

История до 60 сообщений и последняя выдача восстанавливаются с сервера в пределах 24-часовой сессии. Модель использует последние 8 сообщений для контекста. Уточнения обрабатываются подключённым ИИ; фразы в чате сами по себе не дают модели права менять корзину. При ошибке отправки вопрос возвращается в поле ввода.

Предупреждения о противоречивых характеристиках видны в карточках и перед подтверждением. Ссылки на сертификаты извлекаются только из соответствующих полей и только с HTTPS-доменов EKT; фотография товара не считается сертификатом. Отсутствие конфликтов характеристик не гарантирует безопасную замену.

Обновлённый интерфейс

На широком экране чат и каталог видны рядом. В узком окне используются вкладки «Диалог» и «Товары» со счётчиком результатов. На компьютере доступно «Развернуть чат», чтобы сосредоточиться на диалоге. Добавление открывает выбор количества, а затем отдельную панель подтверждения. Карточки выделяют производителя, стоимость за единицу и наличие; служебные детали остаются в раскрываемой карточке. Загрузка файла находится на панели ввода. Пустая выдача сопровождается пояснением и кнопкой возврата к диалогу.

У товара доступны «О товаре» и «Добавить». Панель количества показывает остаток в выбранном городе, уже добавленные единицы, кратность и предварительную сумму. После «Проверить и добавить» сервер готовит предложение. Только отдельное подтверждение записывает изменение. При успехе появляется уведомление «Корзина обновлена» с переходом к её содержимому.

Новые сценарии

  • Выбор города показывает местные остатки; Астана учитывает склад «Нур-Султан». Изменение города отменяет ожидающее подтверждение, но само по себе не меняет корзину.
  • Сравнение 2–3 товаров: цена, местный остаток, характеристики и выделение различий. Если API недоступен, таблица и карточка показывают сохранённые данные с предупреждением и датой. Для добавления и изменения количества нужна успешная актуальная проверка.
  • Изменение количества и удаление из корзины требуют отдельного подтверждения. Пакетное добавление выполняется целиком либо не выполняется; повторы одного товара объединяются, количества суммируются. Изменение цены требует нового согласия.
  • «Вопрос менеджеру» собирает редактируемый текст из города, корзины, истории и последнего разбора спецификации. Его можно скачать; автоматической отправки нет.

Виджет

Демонстрация: /widget-demo; компактный интерфейс: /widget. Подключение на том же домене:

<script src="/widget.js" defer></script>

При reverse proxy нужно направить /widget, /widget.js, /api/assistant, /api/attachment, /api/selection, /api/checkout, /api/rates, ресурсы приложения и шрифт /fonts/DejaVuSans.ttf на этот сервис. Для полной витрины нужен также /api/catalog. Маршруты нужно согласовать с существующим сайтом. Скрипт использует Shadow DOM для оболочки и iframe для приложения. При подключении с другого домена кнопка открывает консультанта в отдельной вкладке: это сохраняет работу сессии без ослабления cookie-защиты. Реальная корзина EKT требует отдельной интеграции. Внешняя оболочка виджета содержит русские и казахские подписи; сам консультант поддерживает также английский.

Витрина и каталог

Главная страница объединяет категории, бренды, товарные карточки, подборки и ответы на частые вопросы. Каталог доступен по /#catalog, избранное — /#favorites, консультант — /#assistant, корзина текущей сессии — /#cart.

Покупатель может искать по артикулу и названию, выбирать категорию и производителя, задавать диапазон цены и номинальный ток, оставлять только товары с местным остатком. Доступны сортировка и страницы по 12 товаров. Пошаговый подбор предлагает выбрать известные параметры и применяет те же фильтры. Категории вычисляются по разделам исходных ссылок EKT.

Избранное сохраняется в текущем браузере и обновляется между его вкладками. История хранит последние 8 просмотренных товаров, из которых блок «Вы недавно смотрели» показывает до 4. Эти данные не синхронизируются между устройствами. Карточки витрины используют датированный снимок; открытие подробностей запрашивает API.

Русский, казахский и английский

Переключатель «Рус / Қаз / Eng» меняет интерфейс, подписи экспорта и сообщения проверки; форма оформления также переведена. Выбор хранится в браузере и синхронизируется между вкладками. Названия, описания и характеристики товаров остаются на языке исходного каталога.

Подключённая модель получает инструкцию отвечать на выбранном языке. Без модели диалог недоступен; поиск по каталогу работает отдельно. Изменения корзины подтверждаются через интерфейс, а не обещаниями модели в тексте ответа.

Валюты и курс

Язык связан с валютой отображения: «Рус» показывает RUB, «Қаз» — KZT, «Eng» — USD. Независимого переключателя валюты пока нет. Исходные цены и серверная проверка корзины всегда остаются в тенге.

/api/rates запрашивает датированный XML Национального банка Казахстана на текущую дату по времени Asia/Almaty. Проверяются дата ответа, положительные значения USD/RUB и количество единиц валюты. Интерфейс показывает источник и дату курса, поэтому пользователь видит, на каких данных основан пересчёт.

Браузер обновляет запрос при открытии, каждые 5 минут и при возврате фокуса окна. Сервер хранит успешный ответ в памяти и обычно обновляет его раз в час, если дата не изменилась. При сбое остаётся последнее доступное значение с предупреждением. После перезапуска используется резервный снимок из lib/currency.ts, датированный 23.09.2026; постоянного хранилища курсов нет.

Карточки, сравнение, корзина и Excel/PDF используют общую логику пересчёта. Цена единицы округляется до двух знаков, затем умножается на количество. Фильтр цены учитывает выбранную валюту, а при смене языка его границы очищаются. Пересчёт помогает сравнивать суммы и не означает, что магазин принимает оплату в выбранной валюте.

Оценка ответов

Под ответами ассистента есть «Помогло / Не помогло». Оценка привязана к стабильному ID ответа, хранится в текущей серверной сессии и восстанавливается после перезагрузки. Повторное нажатие снимает оценку, противоположное заменяет её.

Оценить чужой ответ или сообщение покупателя нельзя. Данные живут вместе с историей до 24 часов. В текущей версии реализован сбор оценки конкретного ответа; общей статистики качества и панели аналитики пока нет.

Excel и PDF

Кнопки экспорта доступны в панели инструментов консультанта и в корзине. Выгружаются подтверждённые позиции: артикул, исходное название, количество, сохранённая цена, сумма, город и ссылка на товар. Подписи соответствуют выбранному языку, цены — его валюте. Для RUB/USD в документе указывается дата и значение курса.

Экспорт не обновляет цену через EKT API, не подтверждает ожидающее действие и не создаёт заказ. Для пересчёта сохранённой цены KZT используется курс, доступный интерфейсу при выгрузке. Файл не является счётом и не подтверждает резервирование.

Отдельный блок содержит строки последней спецификации, которые ещё не покрыты количеством в корзине. Эти строки не входят в итог. Если спецификацию меняли только на экране, сначала повторите разбор, чтобы обновить серверные данные для выгрузки.

Excel создаётся как настоящий OOXML .xlsx: артикулы записываются текстом с сохранением ведущих нулей, количество и деньги — числами, суммы строк и итог — формулами с сохранёнными результатами. Пользовательский текст не исполняется как формула.

PDF создаётся в браузере со встроенным DejaVu Sans, переносами строк, ссылками и нумерацией страниц. Поддерживаются кириллица и казахские буквы. Лицензия шрифта находится в public/fonts/LICENSE-DejaVu.txt. Генерация документов не использует сторонний сервис.

Проверка текущей версии

В репозитории предусмотрены проверки логики корзины, валют, локализации, витрины, документов и HTTP-сценариев. Команды и условия запуска приведены в разделе «Запуск». Результаты предыдущей сборки не гарантируют успешную проверку после новых изменений: перед защитой тесты нужно запускать на той версии, которую показываете.

test:currency проверяет дату и единицы курса, отклонение некорректных значений, округление, английский поиск и фильтр цены в выбранной валюте. test:exports проверяет RU/KK/EN, числовые значения и формулы XLSX, текстовые артикулы, защиту от исполнения пользовательских формул и создание PDF. Образцы сохраняются в .sites-runtime/export-tests/.

HTTP-проверки охватывают восстановление сессии, оценки и их изоляцию, спецификации, сравнение и черновик менеджеру. Сценарии с живым EKT дополнительно проверяют добавление, изменение количества и удаление через отдельное подтверждение. Изменение актуальных остатков или исходных характеристик может потребовать пересмотра ожидаемых значений тестов.

Что показать на защите

  1. Витрина, фильтры и поиск по артикулу; при подключённой модели — уточнение параметров в чате.
  2. Характеристики, остатки в городе, предупреждение о противоречиях и обоснование предварительного аналога.
  3. Ссылка на исходную карточку и сертификат, если данные действительно содержат документ.
  4. Выбор количества, подготовка предложения и отмена без изменения корзины.
  5. Повторное действие с явным подтверждением, открытие корзины и отказ при превышении остатка.
  6. Сравнение товаров, избранное и разбор спецификации с ручной проверкой строк.
  7. Переключение «Рус / Қаз / Eng», изменение валюты и дата курса.
  8. Выгрузка Excel/PDF, итоговая сумма и отдельные позиции для уточнения.
  9. При подключённой модели — оценка ответа; восстановление сессии, черновик менеджеру и виджет.
  10. Корзина → «Оформить заказ»: контакты, адрес, желаемая дата и интервал, проверка суммы, подтверждение демо-заявки, её номер и скачивание квитанции.

Успешное добавление показывайте при работающем API. Если внешний сервис недоступен, объясните режим сохранённых данных и используйте HTML-сценарий как резервную демонстрацию. Не выдавайте его за живую проверку.

Оформление демонстрационной заявки

Кнопка «Оформить заказ» в корзине открывает контакты (фамилия, имя, необязательное отчество/email, телефон), курьера или самовывоз, город/адрес, желаемую дату и интервал, способ оплаты и комментарий. Дата выбирается с завтра на 30 дней вперёд по времени Казахстана; интервалы не являются бронированием. Адрес пункта самовывоза и стоимость доставки требуют согласования.

POST /api/checkout сначала создаёт пятиминутное предложение с проверенными ценами и наличием в выбранном городе, затем отдельно подтверждает его. Изменение корзины или цены требует повторной проверки. Токен защищает от повторного создания заявки. Данные формы разрешены по белому списку; номер карты/CVV не сохраняются. Контакты и адрес не попадают в историю ИИ. До 5 заявок доступны только своей HttpOnly-сессии до её истечения (24 часа); GET защищён сессией, запись — Origin и CAS revision. Заявку можно скачать как TXT.

Статус DEMO означает: не отправлено в EKT, не оплачено, товар не зарезервирован. Корзина сохраняется. «Картой при получении», «наличными», «счёт» — пожелания, а не гарантированные условия. Онлайн-эквайринг, реальный API заказов и бронирование доставки не подключены. Для приёма карты нужен hosted checkout платёжного провайдера и подтверждение оплаты через серверный webhook; поля PAN/CVV в приложении отсутствуют.

Проверки: npm run test:checkout и node scripts/test-checkout.mjs --http.

Если что-то не работает

Если корзина недоступна, проверьте первую сборку, миграцию D1 и привязку DB. Если отсутствует dist/server/wrangler.json, сначала выполните npm run build.

Если товары находятся, но не добавляются, проверьте доступы EKT_API_USER и EKT_API_PASSWORD, соединение с API, местный остаток и кратность. Снимок позволяет искать без живого каталога, но не заменяет проверку перед добавлением. После изменения настроек перезапустите приложение.

Если ИИ отключён, заполните все три переменные LLM_URL, LLM_API_KEY и LLM_MODEL. При ошибке провайдера проверьте его доступность, формат endpoint и поддержку function calling. Старый шаблонный чат как запасной режим не используется.

Если заявка не подтверждается, завершите или отмените ожидающее изменение корзины, проверьте контакты и дату, затем повторите проверку цен. Предложение действует 5 минут; изменение корзины, цены или остатка может потребовать нового предложения.

Если цена показывается в рублях, выбран русский интерфейс. Для отображения тенге переключитесь на «Қаз». При предупреждении о курсе учитывайте дату последнего доступного значения.

Если экспорт пустой, подтвердите товары в корзине или разберите спецификацию. Ожидающее предложение ещё не входит в подборку. Если файл не читается, проверьте формат, размер и наличие текстового слоя в PDF.

Если HTTP-тест не соединяется с приложением, запустите сервер и задайте правильный TEST_URL. Сообщение об истёкшей сессии или конфликте записи требует обновить страницу, проверить текущее состояние и подготовить действие заново.

Дальнейшее развитие

Для внедрения нужны API реальных заказов, платёжный сервис с серверным подтверждением оплаты, расчёт доставки и бронирование интервалов, интеграция с реальной корзиной и сессией ekt.kz, расширение и регулярное обновление каталога, согласованные правила совместимости, доступ к сертификатам и проверенный провайдер модели. Отдельно требуется согласовать хранение данных и проверить нагрузку.

Перспективные дополнения — постоянные подборки по объектам, совместное согласование списка, история изменений и аналитика оценок. В текущей версии этих возможностей нет. На пилоте можно измерять время до готовой подборки, долю завершённых без менеджера заданий, ошибки подбора и оценки ответов. Бизнес-эффект пока не измерен.

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

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

DizzDer 10bahtiarabuzar 5zhasik6767 3

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

  • 2026-09-23 17:52Merge pull request #3 from BAITC-Hacks/feature/demo-checkoutDizzDer
  • 2026-09-23 17:52Update README for current AI consultant and checkoutDizzDer
  • 2026-09-23 17:44Add demo checkout with delivery, contacts and verified order confirmationDizzDer
  • 2026-09-23 17:29Merge pull request #2 from BAITC-Hacks/feature/ekt-ai-consultantDizzDer
  • 2026-09-23 17:25Merge latest README changes and retain AI setup documentationDizzDer
  • 2026-09-23 17:23Replace scripted replies with EKT AI consultant and catalog toolsDizzDer
  • 2026-09-23 17:18Update README.mdbahtiarabuzar
  • 2026-09-23 17:14Fix quick-add request races and refresh quantity constraintsDizzDer
Все коммиты (18)
  • 2026-09-23 17:11Update README.mdbahtiarabuzar
  • 2026-09-23 17:01Improve cart flow, expand assistant and add English with daily currency rateszhasik6767
  • 2026-09-23 16:27Add files via uploadbahtiarabuzar
  • 2026-09-23 16:18Add files via uploadbahtiarabuzar
  • 2026-09-23 16:10Update assistant with storefront, bilingual UI and selection exportsDizzDer
  • 2026-09-23 15:22Replace presentation with latest EKT Assist defense deckzhasik6767
  • 2026-09-23 15:20Add files via uploadbahtiarabuzar
  • 2026-09-23 15:15Update EKT assistant with comparison, city selection, batch cart and widgetDizzDer
  • 2026-09-23 14:29Add HackAlem AI presentation and README linkzhasik6767
  • 2026-09-23 14:18Import EKT catalog assistant prototypeDizzDer
Структура репозитория (158 файлов)
.env.example
.gitignore
.npmrc
.openai/hosting.json
CASE.md
EKT-demo.html
EKT_HackAlem_AI_Charts_Photos.pptx
EKT_Procurement_Studio_20.pptx
EKT_REIMAGINED_22.pptx
README.md
app/api/assistant/route.ts
app/api/attachment/route.ts
app/api/catalog/route.ts
app/api/checkout/route.ts
app/api/rates/route.ts
app/api/selection/route.ts
app/chatgpt-auth.ts
app/checkout.css
app/checkout.tsx
app/currency-context.tsx
app/features.css
app/features.tsx
app/globals.css
app/layout.tsx
app/locale.tsx
app/page.tsx
app/product.css
app/redesign.css
app/selection.tsx
app/shopping.css
app/storefront.css
app/storefront.tsx
app/widget-demo/page.tsx
app/widget/page.tsx
cloudflare-env.d.ts
components.json
components/ui/accordion.tsx
components/ui/alert-dialog.tsx
components/ui/alert.tsx
components/ui/aspect-ratio.tsx
components/ui/attachment.tsx
components/ui/avatar.tsx
components/ui/badge.tsx
components/ui/breadcrumb.tsx
components/ui/bubble.tsx
components/ui/button-group.tsx
components/ui/button.tsx
components/ui/calendar.tsx
components/ui/card.tsx
components/ui/carousel.tsx
components/ui/chart.tsx
components/ui/checkbox.tsx
components/ui/collapsible.tsx
components/ui/combobox.tsx
components/ui/command.tsx
components/ui/context-menu.tsx
components/ui/dialog.tsx
components/ui/direction.tsx
components/ui/drawer.tsx
components/ui/dropdown-menu.tsx
components/ui/empty.tsx
components/ui/field.tsx
components/ui/form.tsx
components/ui/hover-card.tsx
components/ui/input-group.tsx
components/ui/input-otp.tsx
components/ui/input.tsx
components/ui/item.tsx
components/ui/kbd.tsx
components/ui/label.tsx
components/ui/marker.tsx
components/ui/menubar.tsx
components/ui/message-scroller.tsx
components/ui/message.tsx
components/ui/native-select.tsx
components/ui/navigation-menu.tsx
components/ui/pagination.tsx
components/ui/popover.tsx
components/ui/progress.tsx
components/ui/radio-group.tsx
components/ui/resizable.tsx
components/ui/scroll-area.tsx
components/ui/select.tsx
components/ui/separator.tsx
components/ui/sheet.tsx
components/ui/sidebar.tsx
components/ui/skeleton.tsx
components/ui/slider.tsx
components/ui/sonner.tsx
components/ui/spinner.tsx
components/ui/switch.tsx
components/ui/table.tsx
components/ui/tabs.tsx
components/ui/textarea.tsx
components/ui/toggle-group.tsx
components/ui/toggle.tsx
components/ui/tooltip.tsx
data/catalog.json
db/index.ts
db/schema.ts
drizzle.config.ts
drizzle/0000_narrow_titanium_man.sql
drizzle/meta/0000_snapshot.json
drizzle/meta/_journal.json
eslint.config.mjs
examples/d1/app/api/notes/route.ts
examples/d1/db/schema.ts
hooks/use-mobile.ts
lib/ai-consultant.ts
lib/ai-copy.ts
lib/catalog-browser.ts
lib/checkout.ts
lib/currency.ts
lib/domain.ts
lib/ekt.ts
lib/english.ts
lib/export-selection.ts
lib/extract.ts
lib/feedback.ts
lib/i18n.ts
lib/selection.ts
lib/store.ts
lib/utils.ts
lib/workflows.ts
next.config.ts
package-lock.json
package.json
postcss.config.mjs
public/example-spec.csv
public/favicon.svg
public/file.svg
public/fonts/DejaVuSans.ttf
public/fonts/LICENSE-DejaVu.txt
public/globe.svg
public/widget.js
public/window.svg
scripts/build-verified.sh
scripts/execution-profile.mjs
scripts/install-ci.mjs
scripts/install-ci.sh
scripts/install-pnpm.sh
scripts/migrate-local.mjs
scripts/npm-install.mjs
scripts/pnpm-install.mjs
scripts/run-framework.mjs
scripts/sites-env.mjs
scripts/sites-env.sh
scripts/sync-catalog.mjs
scripts/test-ai-consultant.mjs
scripts/test-catalog-browser.mjs
scripts/test-checkout.mjs
scripts/test-currency.mjs
scripts/test-localization-export.mjs
scripts/test-workflows.mjs
scripts/test.mjs
tsconfig.json
vite.config.ts
Сценарий-защиты.md
Ветки (4)

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

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

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