О проекте
Команда: just student
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
Чат-консультант по каталогу ekt.kz: поиск товаров по тексту, артикулу, спецификации (XLSX, DOCX, PDF) и фото маркировки, карточки с ценой, остатками и сертификатами, аналоги при нулевом остатке и локальная корзина с добавлением только после явного подтверждения.
Как устроено
FastAPI с сессиями и CSRF: модуль Dialogue определяет намерение с учётом контекста и направляет запрос в разговор, поиск, условия покупки или к менеджеру. CatalogService обращается к API EKT (Basic Auth) или к демо-каталогу, каталог фоново подгружается в JSON-снимок. OpenAI Responses API разбирает запросы, документы и изображения (OCR через vision), результат приходит структурированным JSON. Аналоги подбираются сравнением категории и технических параметров. Перед добавлением в корзину сервер заново берёт карточку и проверяет цену, остаток, минимум и кратность. Подтверждение одноразовое и действует 120 секунд.
Ключевые решения
- intent detection
- структурированный JSON
- vision-OCR спецификаций
- парсинг XLSX/DOCX/PDF
- подбор аналогов по параметрам
- одноразовое подтверждение корзины
Особенности
В README есть подробная таблица соответствия каждому пункту ТЗ со статусами «реализовано», «частично» и «внешний шаг». У модели нет инструментов менять корзину: все изменения идут через сервер после явного «да, добавь» или «иә, қос». Есть фильтр номеров карт и API-ключей в чате. Поддерживаются RU и KK.
Стек
Python · FastAPI · Uvicorn · Pydantic · httpx · SQLite · pypdf · PyMuPDF · python-docx · openpyxl · Docker · Caddy · GitHub Actions · vanilla JS
Модели
gpt-5.6-luna (OpenAI)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-63a0da97-just-student.
README
README.mdEKT Assistant — ИИ-консультант для покупателей ekt.kz
Проект для HackAlem AI, кейс ТОО «Электрокомплект»: единое окно чата помогает частным покупателям и закупщикам разобраться в задаче, найти электротехническую продукцию, проверить наличие и параметры, посмотреть фотографии, сравнить аналоги и подготовить корзину после явного согласия.
Решение предназначено для сокращения ожидания консультации и повторяющихся вопросов менеджерам. Изменение конверсии, оттока и нагрузки менеджеров пока не измерялось.
Статус: работающий локальный прототип с реальным каталогом EKT и отдельным демо-режимом. Корзина сохраняется в проекте, но не подключена к покупательской корзине ekt.kz. Оформления заказа и оплаты нет. Публичная версия не опубликована.
Документация сверена с кодом и тремя предоставленными PDF 23 сентября 2026 года. Повторная автоматическая проверка: 47 тестов, все прошли.
Содержание
- Возможности и пользовательский сценарий
- Соответствие требованиям кейса
- Технологии и архитектура
- Установка и локальный запуск
- Настройки
- Данные и внешние сервисы
- Проверка для жюри
- API
- Тестирование
- Безопасность и хранение данных
- Ограничения
- Развёртывание
- Готовность к сдаче
Возможности и пользовательский сценарий
Ассистент поддерживает обычный разговор: объясняет понятия, задаёт уточняющие вопросы, учитывает контекст и помогает сформулировать задачу клиента. Поиск товаров вызывается для товарных запросов; благодарность или вопрос «чем отличается автомат от УЗО?» не должны превращаться в бессмысленный поиск по каталогу.
Основной путь пользователя:
- Открыть чат и написать вопрос, артикул, название либо загрузить спецификацию или фото маркировки.
- Получить ответ и карточки: фотография, название, артикул, цена, общий остаток, характеристики, склады, сертификаты и ссылка на товар — если эти данные есть в источнике. Фото открывается крупнее по нажатию; при отсутствии или ошибке загрузки отображается заглушка.
- При нулевом остатке посмотреть найденные аналоги с объяснением совпадения параметров. При неоднозначности уточнить выбор.
- Выбрать товар и количество. На этом этапе корзина ещё не меняется.
- Подтвердить предложение кнопкой или точным сообщением
да, добавь/иә, қос. Сервер повторно получает карточку и проверяет цену, остаток, суммарное количество, минимум и кратность. - Перейти по ссылке
/cartи увидеть локальную корзину своей сессии. Заказ на ekt.kz при этом не создаётся.
Дополнительно доступны русский и казахский интерфейсы, условия покупки со ссылкой на источник, локальные аккаунты, сохранение/очистка истории, удаление аккаунта, контакты менеджера и скачивание текста запроса с контекстом разговора и корзиной. Гостевая сессия и корзина переживают перезапуск сервера в пределах срока действия сессии.
Соответствие требованиям кейса
Статусы означают: реализовано — функция есть в коде; частично — ограничения перечислены; внешний шаг — необходимы действия или данные партнёра/команды. Наличие механизма не означает завершённую интеграцию с production-сайтом.
Обязательные функции — пункт 7 PDF
| № | Требование | Реализация и статус |
|---|---|---|
| 7.1 | Наличие, технические характеристики, сертификат для существующего артикула | Реализовано. Данные из каталога; сертификат показывается при наличии ссылки. DEMO-001 демонстрирует все поля; demo-сертификат явно обозначен как образец. Отсутствующий реальный документ не выдумывается. |
| 7.2 | Минимум один обоснованный аналог при нулевом остатке | Частично. Демо-сценарий DEMO-001 → DEMO-002 и тесты проходят. В live сравниваются категория и известные технические параметры, проверяется остаток. При недостаточных или противоречивых данных замена не предлагается; аналог для каждой отсутствующей позиции не гарантируется. |
| 7.3 | Оплата, доставка, минимальная партия | Реализовано с ограничениями источника. Справка RU/KK, ссылка и дата проверки; минимум из карточки проверяется сервером. Спорные условия доставки требуют подтверждения менеджера. |
| 7.4 | Добавление только после явного согласия с учётом количества и остатка | Реализовано для локальной корзины. Отказ и предложение не добавляют товар; подтверждение одноразовое, действует 120 секунд. Проверяются свежие цена/остаток, уже добавленное количество, минимум и кратность. |
| 7.5 | Прямая ссылка на актуальное состояние корзины | Реализовано для /cart. Показывает состав корзины текущей cookie-сессии. Внешняя корзина и переход к оформлению ekt.kz требуют API партнёра. Цены в локальной корзине — снимок на момент добавления, не резерв. |
Остальные пункты кейса
| Пункт | Требование | Состояние |
|---|---|---|
| 1–4 | Консультант для частного покупателя/закупщика; единое окно; каталог, условия, выбор и подтверждение | Реализован локальный сценарий. Встраивание в CMS ekt.kz и бизнес-эффект не подтверждены. |
| 5 | Свободный текст, контекст диалога | AI определяет намерение и уточняет запрос с учётом последних сообщений. Точные цифровые артикулы и demo-артикулы работают без AI. |
| 5 | Excel, Word, PDF, JPEG | XLS/XLSX, DOCX, текстовый PDF, PDF со сканами, JPEG/PNG. Legacy DOC не поддерживается; лимиты приведены ниже. |
| 5 | Текстовый ответ, обновлённая корзина и ссылка | Реализовано в пределах локального прототипа. |
| 5 | Ответ за единицы секунд | Кэш и фоновая загрузка предусмотрены; отдельные прогретые запросы ранее проверены. Нагрузочная гарантия и SLA отсутствуют, OCR/большие файлы/холодная загрузка могут занимать дольше. |
| 6 | Артикул, название, категория, параметры, сертификаты, цена, остатки по складам | Модель данных поддерживает поля. Категория может выводиться из пути карточки с указанием источника. Неизвестные значения не заменяются вымышленными. |
| 6 | Репрезентативная выборка; разрешены синтетические данные | Есть live-снимок и отдельный синтетический demo-каталог. Полнота live проверяется через coverage.complete, размер выборки показывается в чате. |
| 8 | Казахский язык — опционально | Переключатель RU/KK, ответы и подтверждения; AI переводит поисковый запрос. Названия и значения характеристик сохраняются как в каталоге. |
| 8 | Сопутствующие товары — опционально | Механизм явных связей и demo-пример DEMO-004. Файл реальных связей пока пуст. |
| 8 | История авторизованного пользователя — опционально | Локальная регистрация/вход, SQLite, до 100 сообщений, очистка/удаление. Это отдельная авторизация, не SSO ekt.kz. |
| 8 | Эскалация менеджеру — опционально | Контакты и скачиваемый файл запроса. Автоматической отправки в CRM или создания обращения нет. |
| 9 | Не менять корзину/заказ без согласия | Модель не имеет инструментов изменения корзины; мутации контролирует сервер. Оформление заказа не реализовано. |
| 9 | Достоверные цена и наличие | Карточки основаны на API; перед добавлением свежая проверка. Демо помечено. Абсолютная достоверность свободного текста модели не гарантируется; необходимо проверять ответы и качество источника. |
| 9 | Не запрашивать/хранить платёжные данные; приватность | Платёжных полей нет. В чате есть фильтр сообщений, похожих на номера карт и API-ключи; это не полная DLP-защита произвольного текста/вложений. Подробности ниже. |
| 9 | Защита корзины, объяснимость, совместимость, desktop/mobile | Cookie/CSRF, одноразовые подтверждения, лимиты; объяснения аналогов; адаптивный интерфейс. Совместимость с production-CMS и покупательской сессией требует интеграционной проверки. |
| 10 | Репозиторий, README, архитектура, запуск, данные | Подготовлены локально. Публикация последней версии и сдача на платформе отдельно не подтверждены. |
Полная поэлементная сверка трёх документов: docs/REQUIREMENTS.md. Контракт недостающей внешней интеграции: docs/EKT_INTEGRATION.md.
Технологии и архитектура
- Backend: Python, FastAPI, Uvicorn, Pydantic/Pydantic Settings, httpx.
- Frontend: HTML, CSS, JavaScript без сборщика; находится в
ekt-ai-assistant/backend/app/static/. Отдельный frontend-сервер, Node.js иnpm installдля запуска сайта не нужны. - AI: OpenAI Python SDK, Responses API, структурированный JSON и обработка изображений. Модель задаётся
OPENAI_MODEL; значение по умолчанию в коде —gpt-5.6-luna. Доступ к модели с нужными возможностями зависит от API-проекта. - Файлы: pypdf и PyMuPDF для PDF, python-docx, openpyxl, xlrd, Pillow; OCR через модель с поддержкой изображений.
- Хранение: SQLite для аккаунтов/истории и сессий/корзин; JSON-снимок каталога.
- Проверки: unittest, FastAPI TestClient, заглушки API; GitHub Actions.
- Размещение: Dockerfile, Docker Compose, Caddy для HTTPS — подготовлены, сборка здесь не проверена.
Браузер: чат / карточки / фото / локальная корзина
→ FastAPI: сессия + CSRF + валидация + ограничения запросов
→ Dialogue: контекст → намерение → разговор / поиск / условия / менеджер
→ CatalogService → EKT API (Basic Auth) или DemoClient
→ OpenAI: разбор запроса, документа, фото; объяснение фактов
→ Recommendations: сравнение параметров / заданные связи товаров
→ Cart: предложение → согласие → свежий detail → сохранение корзины
→ Accounts / SessionStore → SQLite
↔ Фоновая загрузка каталога → var/catalog.json
README.md
start.ps1 # запуск на Windows
compose.yaml, deploy/Caddyfile # подготовка размещения
.github/workflows/test.yml # CI
docs/ # требования, интеграция, размещение
ekt-ai-assistant/backend/
.env.example # образец настроек без секретов
requirements.txt, requirements.lock.txt
Dockerfile, .dockerignore
app/main.py # маршруты, middleware, фоновые задачи
app/core/config.py # настройки
app/api/chat.py, attachments.py # чат, корзина, аккаунты, файлы
app/models/ # схемы данных
app/services/ # каталог, AI, OCR, история, сессии
app/static/ # весь frontend
data/related_products.json # согласованные сопутствующие товары
tests/ # автоматические проверки
var/ # runtime-данные, исключены из Git
Установка и локальный запуск
Рекомендуется Python 3.12. Нужен интернет для установки зависимостей и внешних API; для синтетического поиска/корзины после установки ключи не обязательны. Команды ниже выполняются из корня репозитория.
Windows / PowerShell
# Создать конфигурацию, не перезаписывая существующую:
if (-not (Test-Path ekt-ai-assistant/backend/.env)) {
Copy-Item ekt-ai-assistant/backend/.env.example ekt-ai-assistant/backend/.env
}
# Демо-каталог, порт 8000:
.\start.ps1 -Demo
Открыть http://127.0.0.1:8000. Скрипт создаёт .runtime, проверяет доступность основных библиотек и при необходимости устанавливает зависимости. Для воспроизводимой установки всех закреплённых версий используйте ручной вариант ниже.
# Запуск с настройками .env:
.\start.ps1
# Если порт занят:
.\start.ps1 -Port 8010
Во втором случае сайт доступен по http://127.0.0.1:8010. Остановить сервер: Ctrl+C. После изменения .env перезапустить; после изменения frontend при необходимости обновить страницу через Ctrl+F5.
Ручная установка и запуск:
python -m venv .runtime
.\.runtime\Scripts\python.exe -m pip install -r ekt-ai-assistant/backend/requirements.lock.txt
cd ekt-ai-assistant/backend
..\..\.runtime\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1
Если политика PowerShell запрещает запуск скрипта, используйте ручные команды. Старую .venv, перенесённую с другого компьютера, не используйте.
Linux / macOS
python3 -m venv .runtime
.runtime/bin/python -m pip install -r ekt-ai-assistant/backend/requirements.lock.txt
test -f ekt-ai-assistant/backend/.env || cp ekt-ai-assistant/backend/.env.example ekt-ai-assistant/backend/.env
cd ekt-ai-assistant/backend
../../.runtime/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1
Этот путь предусмотрен структурой проекта; текущие локальные проверки выполнялись на Windows.
Реальный каталог и AI
В ekt-ai-assistant/backend/.env установить DEMO_MODE=false, заполнить EKT_API_USER и EKT_API_PASSWORD доступами партнёра, OPENAI_API_KEY — своим ключом. Выбрать доступную модель в OPENAI_MODEL. Секреты не вставлять в код, README или frontend.
Демо-режим заменяет источник товаров и условия, но сам по себе не отключает платные AI-запросы при наличии ключа. Для проверки без AI задайте AI_DIALOGUE=false и оставьте OPENAI_API_KEY пустым. Разбор спецификаций в чате и распознавание изображений требуют OpenAI даже в демо.
Настройки
Источник: app/core/config.py. .env загружается из backend, переменные окружения имеют приоритет. Ниже перечислены все настройки приложения.
| Переменная | По умолчанию | Назначение |
|---|---|---|
APP_NAME | EKT AI Assistant | Название API |
APP_VERSION | 0.1.0 | Версия API |
DEMO_MODE | true | Синтетический каталог и demo-условия; false — EKT |
COOKIE_SECURE | false | Для локального HTTP; за HTTPS установить true |
PURCHASE_TERMS | пусто | Согласованный текст вместо встроенной справки; один текст для обоих языков |
MANAGER_URL | https://ekt.kz/about/contacts/ | Ссылка на контакты |
AI_DIALOGUE | true | AI-диалог при наличии ключа; не выключает AI-разбор загружаемых файлов |
OPENAI_TIMEOUT_SECONDS | 25 | Тайм-аут клиента OpenAI, не SLA всего запроса |
OPENAI_API_KEY | пусто | Серверный ключ OpenAI |
OPENAI_MODEL | gpt-5.6-luna | Модель для диалога, structured output и vision |
NVIDIA_API_KEY | пусто | Настройка зарезервирована; вызовов NVIDIA нет |
EKT_BASE_URL | https://ekt.kz | Адрес API партнёра |
EKT_API_USER / EKT_API_PASSWORD | пусто | Basic Auth каталога |
CATALOG_WARMUP | true | Фоновый обход/обновление каталога в live |
CATALOG_SEARCH_MAX_PAGES | 100 | Страниц за порцию live-загрузки, диапазон 1–1000 |
CATALOG_TOTAL_MAX_PAGES | 10000 | Защитный предел обхода, диапазон 1–50000 |
CATALOG_DETAIL_CANDIDATES | 5 | Максимум детальных кандидатов для сопоставления, диапазон 1–20 |
CATALOG_CACHE_TTL_SECONDS | 300 | Срок кэша, диапазон 0–86400 секунд |
DATA_DIR | backend/var | Базы SQLite и снимок каталога; путь относительно backend по умолчанию |
RELATED_PRODUCTS_FILE | backend/data/related_products.json | Файл подтверждённых связей товаров |
Дополнительно для Compose нужна переменная DOMAIN с реальным доменом. Это параметр размещения, не настройка FastAPI.
Данные и внешние сервисы
Каталог EKT
В документе с данными предоставлены только Basic Auth и методы чтения:
GET https://ekt.kz/api/products— первая страница;GET https://ekt.kz/api/products?page=2— последующие страницы;GET https://ekt.kz/api/products/detail?id=515291— детальная карточка.
Логин и пароль хранятся только в серверной конфигурации. Доступы каталога не дают методов изменения корзины, авторизации покупателя или CRM.
Live-каталог загружается порциями с параллелизмом до четырёх страниц. Снимок и курсор сохраняются в var/catalog.json; фон делает паузу 60 секунд между проходами. Полный снимок обновляется по TTL. Незавершённый обход возобновляется; после суток начинается заново. При сбое сохраняются доступные данные, при повторении страниц полнота не объявляется. Статус доступен в /api/health: products, complete, next_page, stale, limit_reached.
Количество товаров меняется во время обхода. Даже complete=true означает завершение пагинации, а не транзакционно согласованную выгрузку склада. Перед показом выбранной карточки и добавлением товара используется detail. Нулевой результат по неполной выборке не доказывает отсутствие товара во всём магазине.
Фотографии загружаются браузером по ссылкам каталога. Реальный товар 027228 / ID 515291 проверен: фото загружается; карточка имеет расхождение тока в названии и свойствах — 160 А и 250 А. Интерфейс показывает предупреждение, автоматический подбор аналога по такой карточке блокируется.
Демо и условия покупки
app/services/demo_catalog.py содержит четыре синтетических товара: отсутствующий DEMO-001, аналог DEMO-002 с остатком 12, кабель DEMO-003, аксессуар DEMO-004. Демо-цены, остатки, склады и условия не относятся к реальным предложениям EKT. demo-certificate.txt — образец для демонстрации.
Встроенная live-справка хранится в app/services/terms.py, основана на странице оплаты и доставки EKT; дата проверки в коде — 2026-09-23. Это сохранённая справка, не автоматическое ежедневное обновление. На странице были противоречивые пороги бесплатной доставки; окончательный тариф должен подтвердить менеджер. Согласованный текст можно внести в PURCHASE_TERMS.
Сопутствующие товары задаются в data/related_products.json: ключ — ID товара, значение — список объектов с product_id, reason и необязательным reason_kk. В live-файле сейчас {}; совместимость не генерируется без подтверждённых связей.
AI и передаваемые данные
OpenAI используется для определения намерения, ответа клиенту, структурирования спецификаций и распознавания маркировки/сканов. Для ответа передаются сообщение, ограниченный контекст истории и необходимые факты каталога; для файлов — извлечённый текст или изображение. Запросы используют store=False; это не обещание отсутствия обработки или любых журналов у внешнего провайдера.
Текст документов, карточек и истории обрабатывается как данные. Промпты запрещают выполнять встроенные команды и выдумывать цену/остаток. Модель не получает инструмента изменения корзины. NVIDIA в текущем приложении не используется; AI-агент Codex применялся при разработке.
Проверка для жюри
Сквозной обязательный сценарий без внешних ключей
- Запустить
start.ps1 -Demo; для полностью детерминированной проверки отключитьAI_DIALOGUEи оставить OpenAI-ключ пустым. - Ввести
DEMO-001: проверить нулевой остаток, технические характеристики, ссылку на demo-сертификат и аналогDEMO-002с объяснением. - У аналога указать количество 2 и нажать «Выбрать». Открытие
/cartдо подтверждения должно показать пустую корзину. - Вернуться в чат, подтвердить добавление. Корзина должна содержать 2 единицы. Повторное подтверждение не добавляет товар повторно.
- Попробовать добавить ещё 11: суммарно получилось бы 13 при остатке 12, поэтому сервер отказывает. Проверить и отказ от нового предложения.
- Спросить «Оплата и доставка»: получить содержательный ответ с явной пометкой демонстрационных условий.
- Открыть приложение в приватном окне: чужая корзина недоступна. Перезапустить сервер в том же режиме и вернуться в прежнем браузере: корзина сохраняется, если часовая сессия ещё действует.
Дополнительные сценарии
- AI-диалог: при настроенном ключе написать «Я делаю ремонт и не понимаю, с чего начать», затем уточнить вопрос. Ожидается разговор по задаче, без самовольного добавления товара.
- RU/KK: переключить язык, задать вопрос и уточнение, проверить подтверждение на казахском.
- Спецификация: загрузить небольшой DOCX/XLSX/PDF с артикулом и количеством. Проверить распознанные позиции и неопределённые строки; файл не меняет корзину автоматически.
- Фото/скан: загрузить чёткую маркировку JPEG/PNG или PDF со сканом. Нечитаемые символы нужно уточнить, результат проверить вручную.
- Live-карточка: включить live, дождаться загрузки нужной части каталога и найти
027228. Проверить фото, цену/остаток из текущего API и предупреждение о противоречии. Конкретные цена и остаток не фиксируются в сценарии, поскольку меняются. - История: зарегистрировать локальный аккаунт с паролем от 10 символов, отправить сообщение, выйти и войти; очистить историю или удалить аккаунт.
- Менеджер: открыть контакты и скачать текст запроса; скачивание не означает, что менеджер уже уведомлён.
- Сопутствующий товар: отдельный поиск
DEMO-002показывает заданный demo-аксессуар.
API
Документация: /docs, схема: /openapi.json. Swagger загружает ресурсы jsDelivr. Все URL ниже относятся к локальному приложению, а не к API сайта EKT.
| Метод и маршрут | Назначение |
|---|---|
GET /, GET /cart | Чат и локальная корзина |
GET /api/session | Создать/восстановить cookie-сессию, получить CSRF-токен и настройки UI |
DELETE /api/session | Отозвать сессию и удалить её корзину/гостевой диалог |
POST /api/chat | JSON: message, language (ru / kk) |
POST /api/chat/attachment | Multipart-поле file: распознавание и поиск |
GET /api/cart | Позиции текущей сессии |
POST /api/cart/propose | product_id, quantity: предложение, без добавления |
POST /api/cart/confirm | proposal_id, confirmed: подтверждение или отказ |
POST /api/language | Смена языка сессии |
POST /api/account/register, POST /api/account/login | Локальная регистрация/вход: username, password |
DELETE /api/account | Удаление аккаунта, истории и отзыв его сессий |
GET /api/history, DELETE /api/history | Чтение/очистка истории |
GET /api/handoff | Текстовый файл для передачи менеджеру вручную |
GET /api/health | Режим, состояние каталога, признаки настройки сервисов без значений секретов |
GET /api/ekt/products?page=N, GET /api/ekt/products/{id} | Чтение реального API через backend |
POST /api/attachments/extract | Извлечение содержимого файла |
POST /api/attachments/parse-specification | Структурированный разбор через AI |
POST /api/attachments/match-products | Сопоставление файла с реальным EKT, независимо от demo-режима |
Защищённые маршруты требуют cookie ekt_session; изменяющие запросы и все три API вложений — заголовок X-CSRF-Token из /api/session. При входе токен меняется. Ошибки: 400 — некорректный файл/запрос, 401 — нет действующей сессии, 403 — CSRF, 409 — конфликт подтверждения/цены/количества, 413 — размер, 422 — валидация, 429 — лимит, 502 — ошибка внешней интеграции. Точный контракт доступен в OpenAPI.
Тестирование
Из корня репозитория:
cd ekt-ai-assistant/backend
..\..\.runtime\Scripts\python.exe -m unittest discover -v
На Linux/macOS заменить путь интерпретатора на ../../.runtime/bin/python. Последний прогон при подготовке README: 47 тестов — OK.
Проверяются извлечение файлов и OCR-конвейер, точные/неоднозначные совпадения, аналоги, десятичные параметры, безопасные ссылки, диалог/контекст/сбой AI, согласие/отмена/повтор, свежая цена и остаток, минимум/кратность, CSRF, изоляция, RU/KK, история и аккаунты, лимиты, восстановление сессии из SQLite, её отзыв/истечение, продолжение каталога и поведение при сбоях/повторении страниц.
Тесты используют заглушки API и временные базы, поэтому не доказывают качество всех ответов настоящей модели. Проверка восстановления имитирует потерю памяти процесса и повторную загрузку сессии из БД. Отдельно в ходе разработки проверялись настоящие EKT/OpenAI-запросы и интерфейс в браузере, включая загрузку реального фото. Нагрузочные испытания, внешний CI и Docker-сборка здесь не подтверждены.
Workflow Backend checks подготовлен для push/pull request, Python 3.12 и запуска unittest на Ubuntu.
Безопасность и хранение данных
- Cookie: HttpOnly, SameSite=Strict; Secure включается настройкой для HTTPS. Токен CSRF проверяется сервером. Секреты API не передаются frontend.
- Подтверждение корзины одноразовое, TTL 120 секунд. Изменение цены или недостаточный остаток требуют нового предложения. Серверная блокировка сериализует операции корзины внутри одного процесса.
- Сессия действует 1 час с создания. Гостевой диалог, язык, корзина и ожидающее подтверждение сохраняются в
var/sessions.sqlite3; идентификатор сессии хранится в виде хеша. Фоновая очистка удаляет истёкшие записи. Удалённая сессия не восстанавливается последующим сохранением старого запроса. var/accounts.sqlite3хранит локальные аккаунты и историю до 100 сообщений. Пароль хешируется scrypt с солью. Вход меняет идентификатор и CSRF и создаёт пустую корзину. Выход удаляет сессию, но сохраняет аккаунтную историю до очистки/удаления аккаунта.- AI получает ограниченный контекст, обычно последние 8 записей; история не считается источником текущих цен/остатков.
- CSP, защита от MIME-sniffing, политика referrer, запрет кэширования ответов. Товарные тексты вставляются как текст, URL проверяются по протоколу.
- Лимиты: 30 запросов через защищённую mutation-зависимость в минуту на сессию, 120 API-запросов в минуту на адрес клиента. Это не защита от всех видов злоупотреблений.
- Полей оплаты нет. Сообщения, распознанные фильтром как платёжные данные или ключи, не передаются модели и не входят в историю. Фильтр не покрывает все формы персональных/платёжных данных, особенно внутри вложений.
- Приложение не создаёт постоянный архив загруженных файлов; multipart-обработка фреймворка может использовать временные файлы. Изображения перекодируются без EXIF перед отправкой AI. Пользователю показано уведомление о передаче данных провайдеру.
- Фото товара загружается с внешнего адреса каталога, поэтому браузер обращается к серверу изображения. Для фото установлен
no-referrer. .env,.runtime,var, временные файлы исключены из Git. Ранее отслеживаемая.venvостаётся в индексе:.gitignoreне удаляет уже отслеживаемые файлы и историю. Перед публикацией нужна проверка индекса и истории на секреты; раскрытые ключи следует отозвать и заменить.
Ограничения
| Область | Текущая граница |
|---|---|
| Внешняя корзина / CMS / SSO | Нет API покупательской сессии и изменения корзины; интеграция не выполнена. Локальная корзина не резервирует остаток. |
| Аналоги | Требуются одна категория и минимум два известных технических параметра; совпасть должны все распознанные параметры исходного товара. Проверяется ограниченное число кандидатов, выводится до 3 аналогов; инженерный допуск не выдаётся. |
| Каталог | Возможны неполнота выборки, сбой API, повтор страниц, предел обхода и изменения во время загрузки. Сертификаты/поля зависят от партнёра. |
| Условия покупки | Сохранённая справка; актуализация и согласование спорных тарифов — отдельная задача. |
| AI | Возможны ошибки интерпретации, OCR и текста ответа. При сбое пояснения сохраняются доступные карточки; при сбое понимания запроса предлагается повторить/указать артикул. Нужна проверка результатов человеком. |
| Файл | До 10 MiB; проверка Content-Length API-запроса — 11 MiB. Это не универсальный потоковый лимит всех возможных запросов. |
| До 50 страниц всего; до 5 страниц без текста для OCR. Большой скан нужно разделить. | |
| Word | DOCX поддерживается, старый DOC нужно предварительно сохранить как DOCX. |
| Excel | XLSX: до 5 листов, 1000 строк и 50 значимых столбцов на лист. XLS: до 1000 строк и 50 столбцов на лист. Формулы XLSX не вычисляются: читаются сохранённые результаты. |
| DOCX/XLSX | Суммарный объявленный распакованный размер ZIP — до 50 MiB. |
| Текст / позиции | Документ — до 50 000 символов, AI обрабатывает блоками до 20 000; чат принимает до 100 распознанных позиций на файл. Текст сообщения — до 2000 символов. |
| Изображения | JPEG/PNG до 20 мегапикселей. Результат vision ограничен 20 000 символов с признаком усечения. |
| Сопутствующие товары / менеджер | Live-связи пока отсутствуют; обращения в CRM не отправляются автоматически. |
| Масштабирование | Один worker и один экземпляр. SQLite обеспечивает сохранение, но блокировки и IP-лимиты локальны процессу. Для нескольких экземпляров нужны общее хранилище и координация. |
| Гарантии | Нет нагрузочного SLA, подтверждённого бизнес-эффекта или полной гарантии отсутствия ошибок модели. |
Развёртывание
Публичная deployed-версия отсутствует. Адреса 127.0.0.1 доступны только на компьютере, где запущен сервер, и не являются публичной ссылкой для жюри.
Подготовлены Dockerfile, compose.yaml, Caddyfile и инструкция размещения. Нужны сервер с Docker Compose, домен, DNS и доступные порты 80/443.
На сервере из корня проекта, после заполнения backend .env:
export DOMAIN=assistant.example.com # заменить своим доменом
docker compose up -d --build
docker compose ps
Compose включает Secure-cookie и постоянный том assistant_data; приложение запускается без root, его порт не публикуется наружу. Caddy обслуживает HTTPS. Docker в текущей среде отсутствует: сборка, сертификат и доступность домена не проверены.
Приложение не доверяет forwarded-заголовкам. За текущим proxy IP-лимит приложения общий для посетителей; перед публичной нагрузкой нужны ограничения на ingress и согласованная настройка доверенного proxy. Подробности резервного копирования и восстановления — в docs/DEPLOYMENT.md. Не удалять тома с данными командой docker compose down -v.
Готовность к сдаче
README покрывает все 11 разделов рекомендованной структуры организаторов: название, проблему/пользователя, функции, сценарий, технологии, архитектуру, запуск, проверку, данные/сервисы, ограничения и статус deployed-версии.
| Пункт инструкции участникам | Статус |
|---|---|
| 1. Доступы Codex/OpenAI/NVIDIA, не публиковать ключи | Codex использован, поддержка OpenAI есть. Активация личных доступов остаётся ответственностью команды. NVIDIA не интегрирована. Секреты в README не включены. |
| 2–3. Выбрать кейс, изучить требования | Выбран кейс EKT; требования отражены в README и матрице. Отдельная оценочная рубрика в предоставленных материалах не обнаружена. |
| 4. Распределить роли | Состав команды и распределение ролей не предоставлены; не выдумываются. |
| 5. AI-агент и командный репозиторий платформы | AI-агент применялся. Принадлежность remote репозиторию, выданному платформой, нужно подтвердить команде. |
| 6. Реализация за 5 часов и сквозная проверка | Прототип и проверки есть; соблюдение пятичасового интервала не подтверждено. Ограничения must-have явно перечислены выше. |
| 7–8. README и рекомендованная структура | Выполнено. Документы служат источником требований, а не разрешением на публикацию или передачу данных. |
| 9. Отправить последнюю версию в GitHub | Публикация финального состояния этой доработки не подтверждена. |
| 10. «Сдать решение», название/описание, обновления до дедлайна | Внешний шаг команды на платформе; здесь не выполнен. |
Перед сдачей:
- Подтвердить командный репозиторий, роли и дедлайн на платформе.
- Проверить Git-индекс и историю на секреты/окружения; заменить ранее раскрытые ключи.
- Повторить demo-сценарий и тесты на чистой установке; при live проверить доступность модели и каталога.
- Зафиксировать известные ограничения внешней корзины, аналогов, данных партнёра и менеджерской интеграции.
- При размещении проверить HTTPS, cookie, лимиты, сохранение данных и резервную копию; добавить фактический публичный URL в README.
- Отправить финальную версию в командный GitHub, дождаться CI и сдать решение на платформе с названием и описанием.
Исходные документы сверки: «Инструкция_для_участников_HackAlem_AI.pdf», «HackAlem AI_ ИИ-ассистент для чата на сайте ekt.kz.pdf», «ИИ-ассистент для чата на сайте ekt.kz ДАННЫЕ.docx.pdf». Они предоставлены отдельно; файл с доступами не следует публиковать в открытом репозитории.
Авторы коммитов
История коммитов
- 2026-09-23 17:25READMEAlihan
- 2026-09-23 17:14finalIslam
- 2026-09-23 17:02final touchesIslam
- 2026-09-23 16:29Front and AI responsesIslam
- 2026-09-23 15:26AlikhanAlihan
- 2026-09-23 15:15khamza half projectkhamza
- 2026-09-23 14:24POSTIslam
- 2026-09-23 13:58FirstIslam
Все коммиты (11)
- 2026-09-23 13:44Initial project structureIslam
- 2026-09-23 12:34tIslam
- 2026-09-23 12:26testingkhamza
Структура репозитория (44 файлов)
README.md ekt-ai-assistant/.gitignore ekt-ai-assistant/backend/.dockerignore ekt-ai-assistant/backend/.env.example ekt-ai-assistant/backend/Dockerfile ekt-ai-assistant/backend/app/__init__.py ekt-ai-assistant/backend/app/api/__init__.py ekt-ai-assistant/backend/app/api/attachments.py ekt-ai-assistant/backend/app/api/chat.py ekt-ai-assistant/backend/app/core/__init__.py ekt-ai-assistant/backend/app/core/config.py ekt-ai-assistant/backend/app/main.py ekt-ai-assistant/backend/app/models/__init__.py ekt-ai-assistant/backend/app/models/catalog.py ekt-ai-assistant/backend/app/models/specification.py ekt-ai-assistant/backend/app/services/__init__.py ekt-ai-assistant/backend/app/services/accounts.py ekt-ai-assistant/backend/app/services/attachment_service.py ekt-ai-assistant/backend/app/services/catalog_service.py ekt-ai-assistant/backend/app/services/demo_catalog.py ekt-ai-assistant/backend/app/services/dialogue.py ekt-ai-assistant/backend/app/services/ekt_client.py ekt-ai-assistant/backend/app/services/i18n.py ekt-ai-assistant/backend/app/services/pdf_ocr.py ekt-ai-assistant/backend/app/services/recommendations.py ekt-ai-assistant/backend/app/services/session_store.py ekt-ai-assistant/backend/app/services/specification_parser.py ekt-ai-assistant/backend/app/services/terms.py ekt-ai-assistant/backend/app/services/vision.py ekt-ai-assistant/backend/app/static/app.js ekt-ai-assistant/backend/app/static/demo-certificate.txt ekt-ai-assistant/backend/app/static/i18n.js ekt-ai-assistant/backend/app/static/index.html ekt-ai-assistant/backend/app/static/style.css ekt-ai-assistant/backend/data/related_products.json ekt-ai-assistant/backend/requirements.lock.txt ekt-ai-assistant/backend/requirements.txt ekt-ai-assistant/backend/tests/__init__.py ekt-ai-assistant/backend/tests/test_backend.py ekt-ai-assistant/backend/tests/test_catalog_sync.py ekt-ai-assistant/backend/tests/test_chat.py ekt-ai-assistant/backend/tests/test_conversation.py ekt-ai-assistant/backend/tests/test_features.py ekt-ai-assistant/backend/tests/test_persistence.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.