Black Time — ekt.kz сатушы-кеңесшісі
Чат-консультант по каталогу ekt.kz на казахском и русском: поиск по ID, артикулу и названию, цены, остатки по складам, сертификаты, аналоги.
О проекте
Команда: Black Time
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
Чат-консультант по каталогу ekt.kz на казахском и русском: поиск по ID, артикулу и названию, цены, остатки по складам, сертификаты, аналоги. Добавление в тестовую корзину через предложение и подтверждение, разбор вложений XLSX/DOCX/PDF/JPEG.
Как устроено
FastAPI ходит в каталог ekt.kz по BasicAuth (кэш 120 с) и нормализует поля: id, sku, stock, warehouse_stocks, minimum_order. Диалог ведёт JS-модуль на правилах (nlu.js распознаёт запрос, dialogue.js хранит состояние) через Node-bridge, LLM не вызывается. Корзина работает в два шага, proposal и confirm, с confirmation_id и идемпотентным request_id; при подтверждении цена и остаток перезапрашиваются. Аналоги ищутся по категории, техническим характеристикам и положительному остатку, файлы разбираются, для JPEG используется Windows OCR.
Ключевые решения
- rule-based NLU и диалоговый автомат
- интеграция с API каталога ekt.kz
- двухшаговое подтверждение корзины с идемпотентностью
- подбор аналогов по характеристикам
- OCR и парсинг вложений
Особенности
Бот не выдумывает данные: неизвестный остаток или валюта остаются null, аналог не подбирается без достаточных оснований. Замечает противоречия в карточке (160 А в названии против 250 А в NOMINALNYY_TOK). README на казахском честно перечисляет невыполненные требования.
Стек
Python · FastAPI · Node.js · JavaScript · HTML · Playwright · PowerShell (Windows OCR)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-010f81b0-black-time.
README
README.mdBlack Time — ekt.kz сатушы-кеңесшісі
Frontend, FastAPI backend және команданың JavaScript диалог модулі бір қолданбаға біріктірілді. Браузердегі каталог пен чат ekt.kz-тен алынған деректермен жұмыс істейді; тауарды таңдау, санын ұсыну, растау және жергілікті себетті ашу бір интерфейсте орындалады.
Себет — тестілік прототип. Бұл нұсқа ekt.kz сайтындағы себетті өзгертпейді, тапсырыс жасамайды және төлем қабылдамайды. Нақты себет API-і мен клиент сессиясын байланыстыру тәсілі берілмеген. Ұйымдастырушылардың тестілік себетті толық талаптың орнына қабылдайтыны туралы растау да жоқ. Сондықтан барлық хакатон шарттары толық орындалды деп айтуға болмайды; төмендегі тексеру кестесі қалған шектеулерді көрсетеді.
1. Бір рет дайындау
Қажет: Python 3.10+, Node.js 20+ және VS Code/PowerShell. JPEG мәтінін тану Windows-та орнатылған ағылшын немесе орыс OCR тілімен жұмыс істейді. Қалған файлдар Windows OCR-ге тәуелді емес.
VS Code терминалын осы README.md тұрған жоба қалтасында ашыңыз. Бұрынғы .env және .venv бар болса, оларды сақтаңыз.
Жобаны басқа компьютерге алғаш көшіргенде:
git clone --branch integration https://github.com/BAITC-Hacks/hack-010f81b0-black-time.git
cd hack-010f81b0-black-time
Орнатылған нұсқаларды тексеріп, Python кітапханаларын дайындаңыз:
node --version
py -3 --version
if (-not (Test-Path -LiteralPath .venv)) {
py -3 -m venv .venv
}
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.env файлын тек ол жоқ болса жасаңыз:
if (-not (Test-Path -LiteralPath .env)) {
Copy-Item -LiteralPath .env.example -Destination .env
}
.env ішінде берілген EKT_LOGIN және EKT_PASSWORD мәндерін енгізіп, Ctrl+S басыңыз. Құпиясөзді чатқа, frontend-ке немесе GitHub-қа көшірмеңіз. .env Git-тен шығарылған. Жүйеде бұрын орнатылған орта айнымалылары .env мәндерінен басым болады.
| Айнымалы | Мағынасы |
|---|---|
EKT_LOGIN | ekt.kz каталог API логині. |
EKT_PASSWORD | ekt.kz каталог API құпиясөзі. |
CATALOG_MAX_PAGES=3 | Іздеу қарайтын алғашқы беттер саны; 1–20 аралығы. Әдепкісі — 3. |
CATALOG_CURRENCY="" | API иесі валютаны растағанша бос қалдырыңыз. Бос мән — валюта белгісіз. |
Бар .env ішінде соңғы екі айнымалы болмаса, әдепкі баптаулар қолданылады. Диалог модулі ережелерге негізделген: src/nlu.js сұранысты таниды, src/dialogue.js диалог күйін басқарады. LLM немесе сыртқы ЖИ провайдері шақырылмайды; ЖИ API кілті қажет емес.
2. Үш бөлікті бірге іске қосу
Жоба түбірінен:
.\.venv\Scripts\python.exe -m uvicorn main:app --app-dir backend --reload --host 127.0.0.1 --port 8000
Терминалды ашық қалдырып, браузерде http://127.0.0.1:8000/ ашыңыз. Бұл мекенжай frontend-ті де, API-ді де бір серверден береді. Live Server ашу немесе үш бөлек сервер іске қосу қажет емес. .env өзгерсе, Ctrl+C басып, осы командамен қайта іске қосыңыз.
127.0.0.1 тек өз компьютеріңізді білдіреді. Басқа командалас осы нұсқаулықпен өз компьютерінде іске қосады. Қоғамдық серверге орналастыру бұл нұсқада жасалған жоқ.
Қосымша мекенжайлар:
- Себет: /cart — осы браузер сессиясының тестілік себеті.
- Сервер күйі: /health —
{"status":"ok"}; сыртқы API-ді тексермейді. - Swagger: /docs — маршруттар мен параметрлер.
- Каталог: /products?page=1 және екінші бет.
- ID 515291 мәліметі.
3. Демонстрация сценарийі
- Чатқа
ID 515291жазыңыз. Тауардың нақты атауын, бағасын, қалдығын және сипаттамаларын қараңыз. Сертификаты бар ма?немесеҚоймада қанша бар?деп сұраңыз. Жауап алдыңғы тауарға қатысты болуы керек. Дерек жоқ болса, ол белгісіз деп айтылады.Одан 2 дана қосжазыңыз немесе тауар карточкасынан санын таңдаңыз. Бұл қадам тек ұсыныс жасайды; себет өзгермейді. Нақты қалдық аз немесе ең аз партия үлкен болса, басқа жарамды сан таңдаңыз.- Ұсыныстағы тауар мен санды қарап, растау батырмасын басыңыз. Сервер осы сәтте баға мен қалдықты қайта сұратады. Өзгеріс болса, жаңа ұсынысқа қайта келісу қажет.
- «Себетке өту» арқылы қосылған тауарды және санын қараңыз. Бұл тек тестілік себет екенін интерфейс көрсетеді.
- XLSX/XLS, DOCX, мәтінді PDF немесе JPEG тіркеңіз. Алынған мәтінді алдын ала қарап, түзетіп, чатқа өзіңіз жіберіңіз. Файлдағы «иә» немесе «қос» сөзі себетті автоматты өзгертпейді.
Төлем шарттарыжәнеЖеткізу шарттарыдеп сұраңыз. Белгілі мәлімет пен дереккөз беріледі; нақты тариф пен мерзімге кепілдік берілмейді.
Атау мен артикул бойынша іздеу де бар. ID 515291 — нақты ID іздеуі, ал артикул 200300285_ — артикул іздеуі. Бұлар бөлек өрістер. Іздеу алғашқы CATALOG_MAX_PAGES бетімен шектеледі; осы іріктемеде табылмауы бүкіл дүкенде тауар жоқ дегенді білдірмейді.
4. Архитектура және деректер
Браузер: index.html + frontend/
│ бір origin, сессия cookie-і
▼
FastAPI: backend/main.py + integration.py
├─ dialogue.py ── Node src/bridge.js ── src/dialogue.js + nlu.js
├─ shop.py ── ekt_client.py ── HTTPS/BasicAuth ── ekt.kz каталогы
├─ attachments.py ── Office/PDF оқу, Windows JPEG OCR
└─ жедел жадтағы сессия және тестілік себет
Браузер ekt.kz BasicAuth құпияларын алмайды. Каталогқа тек сервер қосылады. Тізім беттерінің кэші — 120 секунд; себетке растау кезінде тауардың толық мәліметі қайта алынады. Сыртқы қосылу таймауты — 5 секунд, жауап оқу таймауты — 15 секунд. Алғашқы іздеу мен OCR бірнеше секундтан ұзаққа созылуы мүмкін; тұрақты жауап кідірісіне кепілдік берілмейді.
| ekt.kz өрісі | Біріктірілген модель | Ереже |
|---|---|---|
id | id | Тауар идентификаторы; артикулмен алмастырылмайды. |
article | sku | Артикулды дәл іздеуге және көрсетуге арналған. |
quantity | stock | null мәні белгісіз қалдық болып қалады. |
price | price | Жоқ баға нөлге айналмайды. |
currency немесе расталған орта баптауы | currency | Екеуі де жоқ болса null; теңге автоматты қосылмайды. |
properties | attributes | Сыртқы сипаттамалар сақталады. |
stores | warehouse_stocks | Қойма атауы мен қалдығы көрсетіледі. |
properties.KRATNOST_MIN | minimum_order | Тауардың ең аз саны; бүкіл тапсырыстың ең аз сомасы емес. |
certificate_url | certificate_url | Тек нақты берілген қауіпсіз HTTP(S) сілтемесі. |
Пайдаланушы бұрын жіберген нақты жауаптар /products?page=1, page=2 және /products/515291 байланысының жұмыс істегенін көрсетті. Автоматты тесттердегі каталог деректері жасанды және нақты дүкендегі қорды дәлелдемейді. Қазіргі API қолжетімділігін өз ортаңызда жоғарыдағы маршруттармен тексеріңіз.
Нақты 515291 тауарының бұрынғы жауабында атау/сипаттама 160 А, ал NOMINALNYY_TOK 250 А болған. Модель мұндай қайшылықты ескертеді. Қайшы сипаттамалары бар тауарға автоматты сәйкестік уәдесі берілмейді.
Аналогтар іріктемедегі тауарлардан алынады: санат, қолда бар негізгі техникалық сипаттамалар және белгілі оң қалдық салыстырылады. Дәлел жеткіліксіз болса немесе сәйкес тауар табылмаса, балама ойдан шығарылмайды. Сондықтан «әрбір жоқ тауарға кемінде бір аналог» талабы барлық каталог үшін кепілденбеген.
Төлем/жеткізу мәтіндері backend/purchase_terms.json ішінде сақталған. Дереккөз — ekt.kz ресми бетінің іздеу индексінде көрінген үзіндісі; тікелей бетті алу таймаутпен аяқталған. Нақты пайдалану алдында дүкен иесімен қайта растау қажет. Белгіленген тариф, жеткізу күні немесе бүкіл тапсырысқа ортақ ең аз сома ойдан қосылмайды.
5. Чат пен себет API келісімі
Алдымен GET /api/session шақырылады. Сервер HttpOnly, SameSite=Strict cookie береді; HTTPS ортада Secure де қосылады. Браузердің келесі сұраныстары сол cookie-ді жібереді. Сессия/себет жедел жадта сақталады: сессия белсенді емес 1 сағаттан кейін немесе сервер қайта іске қосылғанда жоғалады. Бұл авторизацияланған клиент тарихы емес; бірнеше worker немесе production үшін ортақ сақтау қабаты қажет.
| Маршрут | Мақсаты |
|---|---|
GET /api/session | Сессия, прототип режимі, файл мүмкіндіктері және баптаулар. |
GET /api/search?q=... | Сәйкестендірілген тауарлар және іздеудің coverage шегі. |
POST /api/chat | {message, request_id, confirmation_id?}; контексті диалог. |
POST /api/cart/proposal | {product_id, quantity, request_id}; тек ұсыныс жасайды. |
POST /api/cart/confirm | {confirmation_id, request_id}; дәл ұсынысты растайды. |
POST /api/cart/cancel | {}; ұсынысты жояды. |
GET /api/cart | Осы сессияның тестілік себеті. |
DELETE /api/cart/items/{product_id} | Осы сессияның себетінен тауарды алып тастайды. |
POST /api/attachments | Multipart file; өңдеуге арналған жоба мәтінін қайтарады. |
GET /products?page=N, GET /products/{id} | Бастапқы {source:"ekt.kz", data:...} келісімі сақталған. |
Чат/ұсыныс/растау жауаптарының негізгі пішімі:
{
reply: { message, locale, cards: [product, ...] },
confirmation: null | { id, product_id, quantity, product },
cart: {
mode: "prototype", items: [{ product, quantity, line_total }],
total, currency, cart_url: "/cart"
}
}
Әр жаңа әрекетке жаңа request_id (UUID) жіберіледі. Желілік қайталауда сол ID мен сол денені қайталау себетке қайта қоспайды. Бір ID-мен басқа дене жіберу — 409. Растау токені нақты сессияға және соңғы ұсынысқа тиесілі; ескі немесе бөтен токен қабылданбайды. Чатта «иә» деп растағанда да интерфейс ағымдағы confirmation_id жібереді. Жай «маған 5 дана керек» деген сұраныс растау саналмайды.
6. Файлдарды қолдау шегі
| Пішім | Қолдау |
|---|---|
Excel .xlsx, .xls | Алғашқы 5 парақ, әрқайсысында 200 жол және 20 баған. Формула орындалмайды. |
Word .docx | Мәтін және кестелер; ескі .doc файлын .docx етіп сақтау керек. |
| Алғашқы 10 беттің мәтін қабаты; құпиясөзбен жабылған PDF оқылмайды. | |
JPEG .jpg, .jpeg | Windows OCR арқылы көрінетін жазу. Тауарды фотосынан модель ретінде тану жоқ. |
Файл шегі — 10 МБ, нәтиже — алғашқы 10 000 таңба. Office архивтері ашылғандағы көлемі де шектеледі. Мәтінсіз скан PDF-ке OCR жасалмайды; мәтіні бар JPEG немесе қолмен енгізу қажет. PNG қолдау көрсетілетін тізімге кірмейді. Тіркеме ескі растау ұсынысын жояды, бірақ себеттегі тауарларды өзгертпейді.
7. Тесттер және қабылдау шарттары
Бөлек терминалда, жоба түбірінен:
.\.venv\Scripts\python.exe -m pytest -q
npm.cmd test
Node диалогына runtime пакет орнату қажет емес. Қосымша әзірлеуші құралдарын орнату үшін npm.cmd install қолданылады. Windows PowerShell npm.ps1 орындауын шектесе, көрсетілген npm.cmd командасын пайдаланыңыз.
Нақты сервер мен ekt.kz кіру деректері бапталған кезде ғана орындалатын қосымша тексерулер:
.\.venv\Scripts\python.exe scripts/smoke_live.py
npm.cmd ci
npx.cmd playwright install chromium
$env:LIVE_EKT="1"
npm.cmd run test:e2e
Remove-Item Env:LIVE_EKT
Бұл тексерулер нақты каталогты оқып, тек тестілік себетті өзгертеді. Нақты ekt.kz тапсырысы жасалмайды. Браузер тесттері desktop және mobile өлшемдерінде орындалады; суреттері Git-ке қосылмайтын artifacts/ қалтасында сақталады.
Python тесттері API, HTTP арқылы толық диалог/растау, сессиялардың оқшаулануы, қайталанған сұраныстар, қор/баға өзгерісі және файлдарды тексереді. Каталог сұраныстары жасанды деректермен алмастырылады, Requests арқылы нақты желіге шығу бұғатталған. Windows-та JPEG тесті нақты жергілікті OCR-ді қолданады; басқа жүйеде сол тест өткізіледі. Node тесттері диалог, көпмәнді сұраулар, аналогтар және frontend келісімін тексереді. Тесттердің өтуі нақты ekt.kz себетінің қосылғанын білдірмейді.
2026-09-23 күнгі интеграция тексерісі:
- 151 Python тест өтті (каталог, диалог, растау, қор/баға, файлдар және нақты Windows OCR). Бір Starlette/httpx deprecation ескертуі бар.
- 98 Node тест өтті (диалог пен frontend).
pip checkтәуелділік қайшылығын таппады. - Нақты API арқылы
515291тауары,200300285_артикулын іздеу, дереккөзді жеткізу жауабы, растау және қайталауда санның өзгермеуі тексерілді.scripts/smoke_live.pyосы бірнеше қадамды 7,22 секундта аяқтады; бұл әр сұранысқа арналған SLA емес. - Chromium-да 2 толық сценарий өтті: desktop 1365×900 және mobile 390×844. Нақты тауарды чатта алу → сан ұсыну → растау →
/cartарқылы осы сессияның себетін ашу тексерілді. JavaScript қатесі мен көлденең асып кету табылмады. - Барлық қосу әрекеті тек жергілікті прототип себетінде орындалды; нақты ekt.kz себеті немесе тапсырысы өзгерген жоқ.
| Талап | Күйі | Шекарасы |
|---|---|---|
| Тауар, сипаттама, баға, қойма қалдығы | Іске асқан | Сыртқы API мен іріктеме көлеміне тәуелді; белгісіз дерек ойдан толтырылмайды. |
| Сертификат | Ішінара | API-де нақты certificate_url болса көрсетіледі; барлық тауарға сертификат берілмеген. |
| Қолда жоқ тауарға аналог | Ішінара | Дәлелденген техникалық сәйкестік табылғанда ұсынылады; кей сұрауларда нәтиже болмауы мүмкін. |
| Төлем, жеткізу, ең аз партия | Ішінара | Дереккөзді жалпы шарттар бар; production алдында растау, жалпы ең аз сома белгісіз. |
| Растаудан кейін және қалдықтан аспай қосу | Прототипте іске асқан | Ескі токен, қосарланған сұраныс, өзгерген баға/қалдық тексеріледі. |
| Өз себетіне сілтеме | Прототипте іске асқан | /cart жергілікті себетті ашады; нақты ekt.kz checkout емес. |
| Нақты ekt.kz себетімен интеграция | Сыртқы ақпарат қажет | Себет API-і, клиент сессиясы және ресми келісім берілмеген. |
| Excel, Word, PDF, JPEG кірісі | Көрсетілген пішімдерде іске асқан | Жоғарыдағы файл/мәтін/OCR шектері қолданылады. |
| Әңгіме контексі | Бір сессияда іске асқан | Тарих пен себет қайта іске қосқанда жоғалады. |
| Мобильді/компьютер интерфейсі | Бейімделетін интерфейс бар | Нақты құрылғыда төмендегі сценариймен тексеріңіз. |
| Бірнеше секундтық жауап | Кепілденбеген | Суық кэш, сыртқы API және OCR уақытына тәуелді. |
Қолмен тексеру: десктопта және тар экранда каталогты ашу → чатта тауар іздеу → мәлімет/сертификат сұрау → сан ұсыну → растау → себетке өту → файлды алдын ала қарау. Нақты сыртқы қорды өзгертетін тапсырыс жасалмайды.
8. Қателер мен негізгі файлдар
| Код | Не істеу керек |
|---|---|
401 | Сессия аяқталған; бетті жаңартыңыз. |
403 | Сұраныс origin-і рұқсат етілмеген; frontend-ті сервердің / бетінен ашыңыз. |
409 | Ұсыныс ескірген, сан/қор сәйкес емес немесе баға белгісіз; хабарлама бойынша қайта таңдаңыз. |
413 / 415 / 422 | Файл тым үлкен / пішім қолдау таппайды / дерек жарамсыз. |
502 / 504 | Сыртқы API немесе диалог қатесі / күту уақыты бітті. detail мәтінін қараңыз. |
503 | API кіру деректері, Node.js немесе JPEG үшін Windows OCR баптауын тексеріңіз. |
«Address already in use» болса, ескі сервердің терминалында Ctrl+C басып тоқтатыңыз. Қате туралы көмек сұрағанда HTTP кодын және detail мәтінін жіберіңіз; .env мазмұнын жібермеңіз.
| Файл/қалта | Мақсаты |
|---|---|
index.html, frontend/ | Біріккен интерфейс, каталог және HTTP клиенті. |
backend/main.py, backend/integration.py | FastAPI, frontend беру, сессия және API маршруттары. |
backend/ekt_client.py, backend/shop.py | BasicAuth, нақты деректерді бейімдеу, кэш, іздеу және аналогтар. |
backend/dialogue.py | Node диалогын шақыру, растау, тестілік себет. |
src/ | Команданың ережелерге негізделген диалогы және JSON bridge. |
backend/attachments.py, backend/ocr.ps1 | Файл мәтінін алу және Windows OCR. |
backend/purchase_terms.json | Дереккөз көрсетілген сатып алу шарттары. |
tests/ | Python және Node автоматты тексерулері. |
| INTEGRATION.md | Командаға арналған қысқа техникалық келісім. |
docs/*-original.md | Үш бөлімнің бұрынғы README нұсқалары және бастапқы команда жоспары. |
Авторы коммитов
История коммитов
- 2026-09-23 17:36Integrate frontend, catalog, dialogue and confirmed prototype cartErmek
- 2026-09-23 17:00Merge team documentation history into integrationErmek
- 2026-09-23 16:59Merge AI dialogue module into integrationErmek
- 2026-09-23 16:58Merge frontend into integration and preserve component documentationErmek
- 2026-09-23 16:22Update README.mdklmnve
- 2026-09-23 16:05Prepare catalog API integration with pagination and product detailsberikmuratuly702-cmyk
- 2026-09-23 15:58Complete AI requirements: bilingual replies, alternatives, contracts and testsRamazan
- 2026-09-23 15:46Add FastAPI backend for ekt.kz catalogErmek
Все коммиты (10)
- 2026-09-23 15:36Add Kazakh ekt.kz frontend prototypeberikmuratuly702-cmyk
- 2026-09-23 15:04AI layer: dialogue logic, NLU, prompts, testsRamazan
Структура репозитория (41 файлов)
.env.example .gitignore INTEGRATION.md README.md backend/attachments.py backend/dialogue.py backend/ekt_client.py backend/integration.py backend/main.py backend/ocr.ps1 backend/purchase_terms.json backend/shop.py contracts/dialogue.schema.json docs/ai-original.md docs/backend-original.md docs/frontend-original.md docs/team-plan-original.md e2e/integration.spec.js examples/dialogue.js frontend/app.js frontend/catalog.js index.html package-lock.json package.json playwright.config.js requirements.txt scripts/smoke_live.py src/bridge.js src/dialogue.js src/i18n.js src/nlu.js src/prompts.js tests/bridge.test.js tests/catalog.test.cjs tests/dialogue.test.js tests/frontend.test.cjs tests/must-have.test.js tests/test_api.py tests/test_attachments.py tests/test_integration.py tests/test_search.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.