AAYMA
RU
Войти

EKT Match

Чат-консультант по каталогу электротехники ekt.kz.

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

О проекте

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

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

Суть

Чат-консультант по каталогу электротехники ekt.kz. Ищет товар по характеристикам или артикулу, показывает цену и остаток, предлагает аналоги и кладёт товар в корзину только после подтверждения пользователя.

Как устроено

Express-бэкенд валидирует каталог через Zod: в offline-режиме это 40 синтетических SKU, в live — API партнёра ekt.kz. Параметры подбирает детерминированный поиск с аналогами, например большая отключающая способность у автоматов. OpenAI gpt-4.1-mini со Structured Outputs извлекает параметры и ведёт диалог. Тексты о товарах, ценах и корзине собирает сервер из данных, и модель не может менять корзину. Фронтенд — React/Vite-виджет в стиле витрины EKT. Есть rate limit, кеш ответов и Docker Compose с nginx.

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

  • structured extraction
  • rule-based analog matching
  • grounded responses
  • explicit cart confirmation
  • rate limiting and response cache

Особенности

Жёсткое разделение: LLM только понимает запрос, а цены, остатки и корзину формирует сервер. Модель не может добавить товар текстом, у неподтверждённых фактов стоит фильтр. Запуск одной кнопкой через start.cmd и Docker Compose, в репозитории есть подробные аудиты устойчивости.

Стек

JavaScript · Node.js · Express · Zod · React · TypeScript · Vite · Vitest · Docker Compose · Nginx

Модели

OpenAI gpt-4.1-mini


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

README

README.md

EKT Match — SAQ Digital

Помощник для подбора электротехники: принимает запрос по характеристикам или артикулу, показывает цену и остаток, предлагает кандидатов в аналоги и добавляет товар в корзину после явного подтверждения.

Проект объединяет React-интерфейс, Express API и каталог: в offline это 40 синтетических SKU, а в live с доступом партнёра — товары из API ekt.kz. Основной offline-сценарий работает локально без интернета, аккаунтов и API-ключей после установки зависимостей или сборки Docker-образа.

Запуск одной кнопкой через Docker

Установите и запустите Docker Desktop с Linux-контейнерами и Docker Compose v2+. В Windows откройте start.cmd двойным кликом: он соберёт приложение, запустит его в фоне и дождётся успешной проверки готовности. Локальные Node.js и npm для этого не нужны. Первый запуск загружает образ Node.js и зависимости.

Та же команда для Windows, macOS, Linux и сервера:

docker compose up --build --wait --remove-orphans

Откройте http://localhost:8080. В Docker Desktop появится проект ekt-match с двумя сервисами: frontend (Nginx и интерфейс) и backend (Express, каталог, OpenAI и корзина). Backend доступен внутри сети Docker; Frontend передаёт ему запросы /api. Повторный запуск применяет изменения к тому же проекту и удаляет прежний общий контейнер app. После первой сборки запускать и останавливать проект можно кнопками Docker Desktop.

docker compose logs -f frontend backend
docker compose down

Если порт занят, измените APP_PORT в корневом .env и повторите запуск. Есть эквивалентные команды npm: docker:up, docker:logs, docker:down. Подробности образа, окружения и размещения на сервере: docs/deployment.md.

Разработка без Docker

Требуется Node.js 22.10+ и npm. Проверено на Node.js 24.11.1 и npm 11.6.2. Команды выполняются из корня репозитория в Windows, macOS или Linux:

npm run setup
npm run dev

Откройте http://localhost:5173. Команда запускает Backend и Vite вместе; запросы /api проксируются на Backend. Остановка — Ctrl+C. Frontend обновляется через Vite; после изменения Backend перезапустите общую команду. Отдельный режим watch Backend: npm --prefix backend run dev.

setup устанавливает Frontend через существующий lock-файл, а Backend — без создания lock-файла, согласно правилам репозитория. Backend нужен также для интеграционных тестов Frontend.

Собранное приложение

npm run build
npm start

Откройте http://localhost:3001. Express раздаёт API и готовый Frontend, включая /cart. Vite для этого режима не требуется. npm run preview запускает тот же режим. Открывайте сборку через сервер, а не как локальный HTML-файл: интерфейс обращается к API.

Структура проекта

frontend/                 React + TypeScript + Vite
  src/components/         Чат, карточка товара, страница корзины
  src/lib/                Клиент API и форматирование
  src/test/               Подключение Backend для тестов интерфейса
  config.json             Порт UI, адрес API и demo-запрос
  package-lock.json       Существующий lock-файл Frontend
backend/                  Express + Zod, JavaScript ESM
  src/                    API, каталог, подбор, сессии, корзина, адаптеры
  test/                   Тесты Backend и интеграция с demo-данными
  config.json             Порт, пути данных, настройки адаптеров
  purchase-terms.json     Локальный снимок условий со ссылкой на источник
data/catalog.json         Общий каталог: 40 синтетических SKU
docs/                     Контракты, сценарии, описание интеграции
deploy/Dockerfile          Отдельные образы Frontend и Backend
deploy/nginx.conf.template Раздача UI и proxy /api к Backend
scripts/dev.mjs           Общий запуск приложения в разработке
compose.yaml              Запуск Docker, порт, окружение, перезапуск
start.cmd                 Запуск Docker двойным кликом в Windows
package.json              Команды разработки, проверок и Docker
.env.example              Необязательные настройки окружения
Браузер → frontend (Nginx) → /api → backend (Express)
                                      ├── data/catalog.json и правила подбора
                                      ├── OpenAI: вопросы о сайте и диалог
                                      └── сессии и корзины в памяти

Backend валидирует каталог через Zod и преобразует price → priceKzt, breakingCapacity → breakingCapacityKa. Frontend получает товары только от API и переводит числовые параметры в подписи карточек. Отдельного каталога заглушек в интерфейсе нет.

Проверка демо

В live можно начать с «что по товарам есть», «Как выбрать товар на сайте?» или «Чем отличаются характеристики B и C?». Помощник получает факты каталога и историю диалога, отвечает на вопросы магазина и отклоняет посторонние темы. Для подбора можно написать «Нужны трёхполюсные автоматы C16 на десять килоампер», затем ответить «восемь штук» на вопрос о количестве. Сначала проверяются известные локальные сценарии, остальные вопросы понимает OpenAI.

  1. Введите в помощнике запрос Нужен автомат 3P C16, 10 kA, 8 штук. Если нет — совместимый аналог. и нажмите Отправить.
  2. Точный товар DEMO-MCB-001 имеет остаток 3 штуки и недоступен для этого количества. Есть два кандидата с 15 kA: DEMO-MCB-003 и DEMO-MCB-004.
  3. Выберите DEMO-MCB-003. До подтверждения корзина остаётся пустой; Отмена также ничего в неё не добавляет.
  4. Нажмите Да, добавить. После подтверждения сервером откроется корзина.
  5. На /cart проверьте SKU DEMO-MCB-003, 8 штук, цену 7 900 ₸ и сумму 63 200 ₸.
  6. Обновление страницы в той же вкладке сохраняет корзину, пока работает Backend. После перезапуска Backend создаётся новая пустая сессия.

Дополнительные запросы: Есть DEMO-MCB-013, 4 штуки?, Какие условия доставки и оплаты?, 4P D63, 15 kA, 1 штука. Все десять сценариев: docs/demo-catalog.md.

Для отсутствующего автомата подбор учитывает и другие SKU с такими же номиналами, и варианты с большей отключающей способностью. Для ламп, светильников и кабелей используются параметры соответствующей категории; помощник не требует у светильника параметры автомата. Результаты — кандидаты из каталога с объяснением совпадений, требующие проверки совместимости, монтажа и единицы продажи. Произвольный кабель не считается безопасной заменой только по совпадению названия категории.

Настройки

Файл .env необязателен. При необходимости скопируйте .env.example в .env в корне. Команды dev, start и Docker Compose читают настройки из него. Существующий .env обновляйте вручную, чтобы сохранить свои значения.

ПеременнаяПо умолчаниюНазначение
APP_MODEofflinelive разрешает настроенные внешние адаптеры
PORT3001Порт Backend внутри контейнера и в локальной разработке
APP_PORT8080Опубликованный порт Docker на хосте
FRONTEND_PORT5173Порт Vite
CATALOG_PATHdata/catalog.jsonАбсолютный путь или путь относительно рабочей директории процесса
FRONTEND_DIST_PATHfrontend/distПуть для общего сервера без Docker, относительно backend/
CART_URL/cartПуть страницы корзины Frontend
VITE_API_BASE_URL/apiАдрес API для отдельно размещённого Frontend при локальной сборке; Docker использует общий /api
OPENAI_API_KEYНе заданНеобязательный ключ OpenAI в live
OPENAI_MODELgpt-4.1-miniМодель диалога и извлечения параметров с Structured Outputs
OPENAI_RESPONSES_URLИз backend/config.jsonEndpoint OpenAI Responses API
FRONTEND_IMAGEekt-match-frontend:localОбраз интерфейса
BACKEND_IMAGEekt-match-backend:localОбраз API; старый APP_IMAGE принимается как fallback
BACKEND_ORIGINhttp://backend:3001Адрес API для Nginx в Docker; порт берётся из PORT
EKT_API_USERNAME, EKT_API_PASSWORDНе заданыBasic Auth для загрузки каталога ekt.kz в live
EKT_PRODUCT_DETAIL_URLИз backend/config.jsonEndpoint карточки партнёра

Для OpenAI укажите в .env:

APP_MODE=live
OPENAI_API_KEY=ваш_ключ_OpenAI

Повторите docker compose up --build --wait --remove-orphans после изменения .env. Ранее использовавшиеся NVIDIA_* больше не нужны. OPENAI_MODEL и endpoint можно не задавать: значения по умолчанию находятся в backend/config.json. Ключ передаётся только Backend во время запуска и не попадает в Docker-образ или JavaScript интерфейса.

В offline работают локальные подбор, вопросы по артикулу и условиям покупки. В live свободные вопросы классифицирует OpenAI: получает текущий каталог, условия покупки, состояние корзины текущей сессии, последние 8 сообщений и уже уточнённые параметры. Формулировки о товарах, ценах, корзине и проверенных технических сведениях сервер строит из этих данных; неподтверждённые факты из свободного текста модели не показываются покупателю. Это диалог по данным сайта, без перебора заранее записанных вопросов. Посторонние темы перенаправляются к магазину и не попадают в дальнейшую историю модели. При подборе неизвестные характеристики остаются null; помощник спрашивает только о недостающих данных. Карточки и цены формирует поиск Backend. Модель не может изменять корзину текстовым ответом. Подбор использует только характеристики, которые пользователь явно назвал в текущем запросе или сохранил при уточнении; новый подбор сбрасывает прежние параметры.

В backend/config.json → openai настроены 60 попыток за скользящие 60 секунд (maxCalls, windowMs), до 4 одновременных вызовов (maxConcurrent), 768 выходных токенов и таймаут 15 секунд для чата. Кеш ответов учитывает контекст, использует хеши ключей и ограничен 200 записями на 5 минут (maxCacheEntries, cacheTtlMs). Одинаковые одновременные запросы используют один вызов. Ошибки расходуют квоту окна; автоматических повторов нет. Квота возобновляется без перезапуска сервера, общая для чата и распознавания файлов. При временном ограничении чат указывает время повтора; локальный поиск продолжает работать. Денежный бюджет отдельно не рассчитывается.

действуют лимиты на сессию и источник запроса: 6 AI-вызовов на сессию и 10 на IP за минуту, для анонимного поиска — 2 на IP. Параметры находятся в backend/config.json и имеют значения по умолчанию в коде. Денежный бюджет

Создание ограничено 30 запросами в минуту на IP, заполненная ёмкость отвечает SESSION_CAPACITY без удаления активной корзины. В Docker Backend принимает X-Forwarded-For только от адреса сервиса frontend, определённого через DNS по trustedProxyHost; адрес обновляется каждые 30 секунд. При ошибке DNS доверие отключается. Для дополнительного внешнего прокси настройте его цепочку доверия и подходящие лимиты в backend/config.json. При недоступности AI локальный поиск по артикулу и параметрам продолжает работать.

Реальный каталог ekt.kz

Для загрузки укажите APP_MODE=live, EKT_API_USERNAME и EKT_API_PASSWORD в локальном .env или окружении Backend и перезапустите приложение. Доступ к каталогу не требует ключа OpenAI. Значения учётных данных не коммитьте.

Backend читает /api/products?page=1, затем следующие страницы и получает подробности каждого товара через /api/products/detail?id=.... Остаток берётся только из quantity подробной карточки: в списке товаров его нет. Конец списка определяется по неполной/пустой странице или повтору первой страницы — так API ekt.kz отвечает на запрос за пределами каталога. Локальные DEMO-* позиции в реальный каталог не добавляются, CATALOG_PATH в этом режиме не используется.

Первая загрузка без сохранённого каталога по-прежнему занимает время: контрольный импорт примерно 15 тысяч товаров занял около 12 минут. После успешного импорта Backend атомарно сохраняет каталог в backend/.cache/ekt-catalog.json. При повторном запуске данные читаются с диска и поиск доступен сразу после запуска сервера. Свежий кэш не вызывает повторного импорта. По умолчанию через час каталог обновляется в фоне; устаревший кэш при запуске обновляется сразу, также в фоне. Во время обновления остаётся доступен предыдущий снимок; при ошибке он сохраняется. Если при обновлении часть карточек недоступна или не прошла проверку, рабочий снимок также сохраняется целиком, чтобы временный сбой не удалил товары из поиска.

Даже при первом запуске без кэша доступны создание сессии, чтение корзины, приветствие и условия оплаты/доставки. Запрос товара в режиме диалога получает понятный ответ о загрузке; классический поиск, добавление в корзину и загрузка файлов ждут готовности каталога (CATALOG_LOADING / CATALOG_UNAVAILABLE). При недоступном каталоге AI-диалог продолжает отвечать на вопросы о сайте, корзине и условиях покупки; сведения о товарах, ценах и остатках остаются недоступными до загрузки. Сессии продолжают работать после её завершения. Демо-цены не подставляются.

После ошибки импорта первая повторная попытка выполняется через 30 секунд (partner.retryDelayMs); дальнейшие интервалы удваиваются до пяти минут. Успешная загрузка возвращает обычный интервал обновления. /api/health показывает catalog.upstreamStatus при HTTP-ошибке поставщика и время catalog.nextRetryAt.

GET /api/health → catalog показывает status, loadedAt, cached, stale, refreshing, прогресс и необязательный refreshError. Ответ по устаревшему снимку содержит дату данных. Настройки: backend/config.json → partner.cache.path (относительно backend) и maxAgeMs (3600000). EKT_CATALOG_CACHE_PATH заменяет путь к файлу. Кэш проверяется на соответствие источнику API и учётной записи; пароль в него не записывается, файл исключён из Git. Повреждённый кэш приводит к новой загрузке. Ошибка сохранения не мешает работе, но видна как cacheSaved: false.

Для запуска через npm кэш сохраняется между перезапусками. В текущем Docker постоянное хранилище кэша не настроено: при пересоздании контейнера файл теряется. Production требует постоянного хранилища каталога; текущая реализация предназначена для одного процесса Backend. Для нескольких экземпляров нужна общая синхронизация.

Карточки с ошибками загрузки/валидации и товары с неоднозначным одинаковым SKU исключаются; их количество отражается в catalog.failed и логах. Цены и остатки являются снимком на время импорта (catalog.loadedAt), обновляются фоновым импортом. Перед новым подтверждённым добавлением в live Backend запрашивает актуальную карточку партнёра и проверяет цену, количество и кратность. Frontend передаёт цену выбранной карточки через expectedUnitPriceKzt. При изменении цены возвращается PRODUCT_PRICE_CHANGED (409): нужно повторить поиск и подтвердить новую цену. При недоступности API возвращается PRODUCT_VERIFICATION_UNAVAILABLE (503). Обе ошибки оставляют корзину без изменений. Повтор уже успешного подтверждения не добавляет товар второй раз и не вызывает API повторно. Корзина остаётся локальной: API партнёра используется только для чтения, резервирования и оформления заказа на ekt.kz нет.

Дробные складские остатки сохраняются без округления. Нераспознанный или нулевой номинальный ток остаётся неизвестным: карточка доступна по артикулу, но не участвует в автоматическом подборе по току. Подробные свойства источника возвращаются вместе с предупреждением о необходимости проверки характеристик.

Лимит страниц, число параллельных запросов и таймаут находятся в backend/config.json → partner (2000, 4 и 5000 мс). Достижение лимита до конца списка считается ошибкой загрузки. URL списка выводится из адреса карточки; при нестандартной схеме адресов задайте partnerProductsUrl в том же JSON. AI получает размер всего каталога и ограниченный фрагмент, а поиск по артикулу и техническим параметрам работает по всем загруженным товарам.

Загрузка спецификаций и фотографий

Backend принимает PDF, Word (doc, docx), Excel (xls, xlsx), JPEG и PNG через POST /api/uploads. Нужны действующая сессия (X-Session-Id), APP_MODE=live и OPENAI_API_KEY. Файлы передаются в OpenAI для распознавания; цены и остатки берутся из загруженного каталога. В чате откройте Прикрепить файл: выберите файл, нажмите Распознать файл, проверьте позиции и количество. Добавление происходит только через отдельное явное подтверждение. В offline-режиме распознавание недоступно; текстовый поиск продолжает работать. Контракт API, сценарии проверки интерфейса.

Обработка асинхронная: отправка → опрос статуса → проверка извлечённых строк → отдельное подтверждение добавления в корзину. Повторная отправка с тем же requestId возвращает прежнее задание. Отмена доступна через DELETE. По умолчанию один файл до 900 КиБ, до 50 строк, два параллельных распознавания. Оригинал хранится в памяти до завершения обработки; результат — до 15 минут. Лимиты задаются в backend/config.json → uploads; вызовы делят общий бюджет openai.maxCalls с чатом. После перезапуска задания теряются.

Платёжные данные

Чат не запрашивает платёжные реквизиты. Обнаруженные номера карт/IBAN, CVV/CVC, PIN, коды подтверждения, срок действия карты и банковский пароль отклоняются с PAYMENT_DATA_NOT_ALLOWED (400) до записи в историю и отправки текстового запроса в AI. Проверяется также имя загружаемого файла. Обнаруженные значения в ответах модели, истории и извлечённых строках маскируются. Это проверка по шаблонам и контрольным суммам, она не гарантирует обнаружение всех способов записи. Не загружайте документы с платёжными реквизитами: исходный PDF, изображение или Office-файл передаётся провайдеру для распознавания.

Тесты

Последние изменения подбора, проверки корзины у партнёра, защиты платёжных данных и квот AI пока не проверены тестами или сборкой: запуск отложен до отдельного согласования. Ранее выполненные проверки их не подтверждают.

npm test
npm run build

Backend проверяется встроенным node:test, Frontend — Vitest и Testing Library. Тесты интерфейса поднимают настоящий Express API с общим каталогом. Проверяются все 10 demo-запросов в одной сессии, единицы измерения, изоляция корзин, явное подтверждение, отсутствие мутаций при отмене и ошибках, повтор после потери ответа, восстановление сессии и страница корзины. В обычный запуск включены регрессии из аудита; результаты исправлений описаны в проверке после исправлений.

Технологии и данные

КомпонентИспользование
React 19, TypeScript 5.7, Vite 6Интерфейс и сборка
Express 5, Zod 4HTTP API и валидация
Vitest 2, Testing Library, jsdom 25Проверки интерфейса
Node.js node:testПроверки Backend
Phosphor IconsИконки интерфейса
OpenAI Responses APIДиалог по сайту и извлечение параметров в live
Docker Compose, NginxОтдельные сервисы UI и API, запуск одним действием
data/catalog.jsonСинтетические данные команды, не выгрузка ekt.kz
backend/purchase-terms.jsonСнимок условий; ссылка на источник содержится в файле и ответе API

Границы демо

В offline товары, цены и остатки вымышлены; в live используются данные партнёра. Упрощённые правила подбора не устанавливают реальную техническую взаимозаменяемость оборудования. Корзина хранится в памяти Backend, не резервирует склад и не оформляет заказ на ekt.kz. Оплата, авторизация покупателя и сохранение в БД не реализованы. Окружение витрины служит контекстом для работающего помощника и локальной корзины.

Команда: SAQ Digital. Описание интеграции, контракт API.

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

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

Mudybluez 34hotcheetosss 24Yerkanat Malayev 20

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

  • 2026-09-23 17:55merge: restore catalog recovery and outage conversationsMudybluez
  • 2026-09-23 17:52fix: keep site assistant available during catalog outagesMudybluez
  • 2026-09-23 17:52fix: retry failed partner imports with bounded backoffMudybluez
  • 2026-09-23 17:47merge: integrate backend demo readiness with audited applicationMudybluez
  • 2026-09-23 17:42merge: integrate attachment UI with audited API protectionsMudybluez
  • 2026-09-23 17:38docs: describe catalog selection and confirmation safeguardshotcheetosss
  • 2026-09-23 17:38fix: verify live stock and confirmed price before cart writeshotcheetosss
  • 2026-09-23 17:38fix: select equivalent products and clarify by categoryhotcheetosss
Все коммиты (78)
  • 2026-09-23 17:37fix: renew AI quotas and protect payment datahotcheetosss
  • 2026-09-23 17:37merge: integrate audit fixes with catalog cache and uploadsMudybluez
  • 2026-09-23 17:36feat: integrate attachments and remove demo shortcutYerkanat Malayev
  • 2026-09-23 17:34docs: record audit fixes and targeted proxy verificationMudybluez
  • 2026-09-23 17:33fix: ground assistant answers in verified stateMudybluez
  • 2026-09-23 17:33fix: validate frontend API responses and preserve retriesMudybluez
  • 2026-09-23 17:33fix: update Vitest to patched releaseMudybluez
  • 2026-09-23 17:33fix: validate catalog quantities and partner unitsMudybluez
  • 2026-09-23 17:33fix: bound API resources and trust only frontend proxyMudybluez
  • 2026-09-23 17:20docs: explain catalog cache and startup behaviorhotcheetosss
  • 2026-09-23 17:20feat: serve cached catalog during background refreshhotcheetosss
  • 2026-09-23 17:20feat: persist validated partner catalog snapshotshotcheetosss
  • 2026-09-23 17:17feat: checkpoint chat history accessibility and purchase controlsYerkanat Malayev
  • 2026-09-23 17:02docs: publish upload API contract for frontend integrationhotcheetosss
  • 2026-09-23 17:01feat: add session-scoped asynchronous upload endpointshotcheetosss
  • 2026-09-23 17:01feat: extract product lines from document and image attachmentshotcheetosss
  • 2026-09-23 16:49docs: record assistant and project audit findingsMudybluez
  • 2026-09-23 16:48test: add adversarial assistant and resilience audit casesMudybluez
  • 2026-09-23 16:35fix: preserve fractional partner inventory and unknown ratingshotcheetosss
  • 2026-09-23 16:27docs: explain partner import configuration and readinesshotcheetosss
  • 2026-09-23 16:27fix: preserve offline dialogue and verify live startuphotcheetosss
  • 2026-09-23 16:19feat: serve live catalog with import status and bounded AI contexthotcheetosss
  • 2026-09-23 16:19feat: import paginated partner catalog with validated detailshotcheetosss
  • 2026-09-23 16:05feat: merge chat language and accessibility updatesMudybluez
  • 2026-09-23 16:05docs: describe merged chat and confirmation behaviorMudybluez
  • 2026-09-23 15:51feat: integrate OpenAI dialogue and separate Docker servicesMudybluez
  • 2026-09-23 15:48docs: explain site dialogue and separate service deploymentMudybluez
  • 2026-09-23 15:48feat: run frontend and backend as separate Docker servicesMudybluez
  • 2026-09-23 15:46fix: bound assistant API requests with timeoutsYerkanat Malayev
  • 2026-09-23 15:46fix: improve overlay accessibility and confirmation recoveryYerkanat Malayev
  • 2026-09-23 15:43fix: display assistant conversations and recover from failed requestsMudybluez
  • 2026-09-23 15:34fix: answer site questions with grounded OpenAI conversationsMudybluez
  • 2026-09-23 15:13feat: add editable chat starter suggestionsYerkanat Malayev
  • 2026-09-23 15:08feat: add chat language choice in welcome messageYerkanat Malayev
  • 2026-09-23 15:07feat: add one-click Docker startup for the integrated appMudybluez
  • 2026-09-23 15:07docs: document Docker deployment and OpenAI configurationMudybluez
  • 2026-09-23 14:59feat: replace NVIDIA parser with OpenAI structured extractionMudybluez
  • 2026-09-23 14:54fix: improve chat touch targets and contrastYerkanat Malayev
  • 2026-09-23 14:54fix: scope chat opening and error feedbackYerkanat Malayev
  • 2026-09-23 14:40feat: align chat overlay with EKT visual languageYerkanat Malayev
  • 2026-09-23 14:37feat: integrate backend frontend and demo catalogMudybluez
  • 2026-09-23 14:36feat: merge frontend API branch into unified projectMudybluez
  • 2026-09-23 14:31docs: document unified setup architecture and demo runbookMudybluez
  • 2026-09-23 14:22feat: connect storefront to catalog API and confirmed session cartMudybluez
  • 2026-09-23 14:16docs: explain frontend API run and demo flowYerkanat Malayev
  • 2026-09-23 14:16feat: connect assistant widget to search and cart APIYerkanat Malayev
  • 2026-09-23 14:11feat: assemble project folders and backend integrationMudybluez
  • 2026-09-23 14:07feat: add session-aware assistant API clientYerkanat Malayev
  • 2026-09-23 14:06feat: merge backend assistant implementationMudybluez
  • 2026-09-23 14:06feat: merge demo catalog and documentationMudybluez
  • 2026-09-23 13:54docs: align catalog contract with team datahotcheetosss
  • 2026-09-23 13:54test: cover team catalog mapping and cart linkhotcheetosss
  • 2026-09-23 13:54fix: accept team demo catalog and singular quantitieshotcheetosss
  • 2026-09-23 13:54style: recreate EKT storefront hero contextYerkanat Malayev
  • 2026-09-23 13:51docs: describe backend API and catalog contracthotcheetosss
  • 2026-09-23 13:50test: verify partner mapping and session isolationhotcheetosss
  • 2026-09-23 13:50feat: answer catalog and purchase questions with session contexthotcheetosss
  • 2026-09-23 13:50style: align demo shell with EKT storefrontYerkanat Malayev
  • 2026-09-23 13:47refactor: embed EKT assistant as chat widgetYerkanat Malayev
  • 2026-09-23 13:40docs: describe demo catalog format and verification scenariosMudybluez
  • 2026-09-23 13:36feat: add synthetic demo catalog with 40 breaker SKUsMudybluez
  • 2026-09-23 13:35feat: support EKT assistant case flowsYerkanat Malayev
  • 2026-09-23 13:34test: cover catalog search and cart confirmationhotcheetosss
  • 2026-09-23 13:34feat: expose search and cart APIhotcheetosss
  • 2026-09-23 13:34feat: add local catalog search and confirmed cart servicehotcheetosss
  • 2026-09-23 13:29refactor: embed assistant in EKT catalog contextYerkanat Malayev
  • 2026-09-23 13:24fix: support relative production asset pathsYerkanat Malayev
  • 2026-09-23 13:22test: cover cart confirmation flowYerkanat Malayev
  • 2026-09-23 13:17feat: add EKT Match frontend prototypeYerkanat Malayev
  • 2026-09-23 12:58added AGENTS.mdMudybluez
Структура репозитория (119 файлов)
.dockerignore
.env.example
.gitignore
AGENTS.md
README.md
backend/.gitignore
backend/audit/README.md
backend/audit/live.mjs
backend/audit/regressions.mjs
backend/audit/resilience.mjs
backend/config.json
backend/package.json
backend/purchase-terms.json
backend/src/ai.js
backend/src/app.js
backend/src/assistant.js
backend/src/attachments.js
backend/src/cart.js
backend/src/catalog-cache.js
backend/src/catalog.js
backend/src/errors.js
backend/src/index.js
backend/src/partner.js
backend/src/privacy.js
backend/src/product-kind.js
backend/src/search.js
backend/src/sessions.js
backend/src/trusted-proxy.js
backend/src/uploads.js
backend/test/ai.test.js
backend/test/api.test.js
backend/test/assistant.test.js
backend/test/attachments.test.js
backend/test/cart.test.js
backend/test/catalog-cache.test.js
backend/test/catalog.test.js
backend/test/fixtures.js
backend/test/partner.test.js
backend/test/resources.test.js
backend/test/search.test.js
backend/test/startup.test.js
backend/test/trusted-proxy.test.js
backend/test/uploads.test.js
compose.yaml
data/catalog.json
deploy/Dockerfile
deploy/nginx.conf.template
docs/audits/2026-09-23/evidence/browser.json
docs/audits/2026-09-23/evidence/dependencies-backend.json
docs/audits/2026-09-23/evidence/dependencies-frontend.json
docs/audits/2026-09-23/evidence/fixes/dependencies-frontend.json
docs/audits/2026-09-23/evidence/fixes/live.json
docs/audits/2026-09-23/evidence/fixes/resilience.json
docs/audits/2026-09-23/evidence/fixes/tests.json
docs/audits/2026-09-23/evidence/http.json
docs/audits/2026-09-23/evidence/live-verdicts.json
docs/audits/2026-09-23/evidence/live.json
docs/audits/2026-09-23/evidence/resilience.json
docs/audits/2026-09-23/evidence/tests.json
docs/audits/2026-09-23/fixes.md
docs/audits/2026-09-23/report.md
docs/backend-api.md
docs/demo-catalog.md
docs/deployment.md
docs/frontend-api.md
docs/integration.md
docs/plan.md
docs/uploads-api.md
frontend/config.json
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/src/App.test.tsx
frontend/src/App.tsx
frontend/src/ChatList.test.tsx
frontend/src/Conversation.test.tsx
frontend/src/FailureRecovery.test.tsx
frontend/src/ProductEvidence.test.tsx
frontend/src/ProductEvidence.tsx
frontend/src/Quantity.test.tsx
frontend/src/UploadIntegration.test.tsx
frontend/src/UploadPanel.test.tsx
frontend/src/UploadPanel.tsx
frontend/src/audit.test.tsx
frontend/src/components/CartPage.tsx
frontend/src/components/ErrorText.tsx
frontend/src/components/ProductCard.test.tsx
frontend/src/components/ProductCard.tsx
frontend/src/i18n.test.ts
frontend/src/i18n.ts
frontend/src/lib/api.test.ts
frontend/src/lib/api.ts
frontend/src/lib/api.unit.test.ts
frontend/src/lib/chatHistory.test.ts
frontend/src/lib/chatHistory.ts
frontend/src/lib/format.ts
frontend/src/lib/links.ts
frontend/src/lib/quantity.test.ts
frontend/src/lib/quantity.ts
frontend/src/lib/uploads.test.ts
frontend/src/lib/uploads.ts
frontend/src/main.tsx
frontend/src/overlay.test.tsx
frontend/src/styles.css
frontend/src/test/backend.ts
frontend/src/test/setup.ts
frontend/src/types.ts
frontend/src/uploadStyles.css
frontend/src/uploadText.ts
frontend/src/uploadTypes.ts
frontend/src/vite-env.d.ts
frontend/tsconfig.app.json
frontend/tsconfig.json
frontend/tsconfig.node.json
frontend/vite.config.ts
frontend/vitest.config.ts
package.json
scripts/dev.mjs
start.cmd
Ветки (15)

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

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

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