О проекте
Команда: IT Accelerator NX
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
Чат-консультант по синтетическому каталогу ekt.kz: поиск по артикулу и описанию, наличие по складам, аналоги, условия покупки, корзина с отдельным подтверждением, обработка вложений (XLS/DOC/PDF/фото) и встраиваемый виджет.
Как устроено
Spring Boot backend с ограниченным tool-loop агентом на Spring AI (OpenAI) вызывает сервисы каталога, аналогов, остатков, базы знаний и корзины. Каталог версионируется при импорте и индексируется в PostgreSQL + pgvector; база знаний с версионным ингестом и scoped retrieval. Вложения извлекаются через Tesseract OCR и OpenAI Vision с отсевом размытых фото и ручным ревью. Корзина через Confirm Gate: предложение → отдельное согласие → снимок; чат по SSE с replay, visitor JWT, embed-скрипт и iframe-виджет.
Ключевые решения
- tool-loop агент
- pgvector
- RAG по базе знаний
- Confirm Gate корзины
- Tesseract OCR
- vision-извлечение
- SSE replay
- OpenAPI-генерация клиента
Особенности
Серьёзная инженерия для 5 часов: версионированный каталог, контрактный офлайн-режим без LLM, изолированные compose-слоты для параллельных AI-агентов разработки, повторная проверка доступа к источникам при replay инструментов.
Стек
Java 21 · Spring Boot 3 · Spring AI · Flyway · PostgreSQL 16 · pgvector · Redis 7 · React 19 · Vite · TypeScript · TanStack Query · Tailwind · Docker Compose
Модели
OpenAI (Spring AI)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-9dc7559b-it-accelerator-nx.
README
README.mdHackAlem AI
B2B-консультант для электротехнического каталога ekt.kz — подбор по артикулу и описанию, наличие и аналоги, условия покупки, безопасное подтверждение состава перед корзиной.
| Команда | TechnoHorizon · хакатон BAITC |
| Репозиторий | Monorepo: Spring Boot API + React SPA + Docker Compose |
| Статус | Активная разработка (hackathon demo), не production-release |
| Контракт | OpenAPI · Swagger после локального старта |
Синтетические каталог, остатки и корзина — учебные данные. Они не являются офертой ekt.kz и не заменяют партнёрские adapters.
Содержание
- Возможности
- Архитектура
- Быстрый старт
- Режимы запуска
- Конфигурация
- Структура репозитория
- API и клиент
- Разработка
- Проверки качества
- Устранение неисправностей
- Документация
- Правила работы с репозиторием
Возможности
| Область | Реализация |
|---|---|
| Чат и сессии | Visitor JWT, диалоги, история, идемпотентная отправка, SSE replay |
| Агент | Ограниченный tool-loop, типизированные события ответа |
| Каталог | Версионированный импорт, поиск, pgvector, синтетический seed |
| Корзина | Confirm Gate: предложение → отдельное согласие → снимок корзины |
| Вложения | Upload / review UI (XLS, DOC, PDF, JPEG) с серверным контуром |
| Embed | Script + iframe /widget, host-demo на отдельном origin |
| Платформа | PostgreSQL + pgvector, Redis, Flyway, Docker Compose profiles |
Архитектура
┌─────────────┐ ┌──────────────┐ ┌──────────────────────────┐
│ Browser │────▶│ Frontend │────▶│ Backend (Spring Boot) │
│ :5173 │ │ React/Vite │ │ :8080 │
│ host-demo │ │ OpenAPI SDK │ │ JWT · Chat · Catalog │
│ :5180 │ └──────────────┘ │ Cart · Attachments │
└─────────────┘ └────────────┬─────────────┘
│
┌────────────┴────────────┐
│ PostgreSQL :5432 │
│ Redis :6379 │
└─────────────────────────┘
| Слой | Стек |
|---|---|
| Backend | Java 21, Spring Boot 3.x, Spring AI (OpenAI), Flyway, Jdbc/JPA |
| Frontend | React 19, Vite, TypeScript, TanStack Query, Tailwind |
| Data | PostgreSQL 16 + pgvector, Redis 7 |
| Ops | Docker Compose (db/redis always; backend/frontend/host-demo · profile full) |
Правило адресов:
- Браузер →
localhost:8080(не DNS-имяbackend). - Backend в Compose → БД
db:5432, Redisredis. - Backend на хосте (
bootRun) → БДlocalhost:5432, Redislocalhost:6379.
Быстрый старт
Рекомендуемый путь для ежедневной работы: инфраструктура в Docker, API и UI на хосте.
Требования: Docker Compose v2, Java 21, Node.js 20+, свободные порты 5432, 6379, 8080, 5173.
git clone https://github.com/BAITC-Hacks/hack-9dc7559b-it-accelerator-nx.git
cd hack-9dc7559b-it-accelerator-nx
cp .env.example .env
# Укажите OPENAI_API_KEY=sk-... (не коммитьте .env)
docker compose up -d
docker compose ps # db и redis → healthy
# Терминал 1
cd backend && ./gradlew bootRun # http://localhost:8080
# Терминал 2
cd frontend && npm ci && npm run gen && npm run dev
# http://localhost:5173
Проверка:
curl --fail http://localhost:8080/actuator/health
curl --fail -X POST http://localhost:8080/auth/visitor-session
Полный стек «как на проде» (нужен ключ OpenAI):
docker compose --profile full up -d --build
| Сервис | URL |
|---|---|
| Чат | http://localhost:5173 |
| Embed demo | http://localhost:5180 |
| Swagger | http://localhost:8080/swagger-ui.html |
| OpenAPI | http://localhost:8080/v3/api-docs |
| Health | http://localhost:8080/actuator/health |
Режимы запуска
Выберите один режим. Не смешивайте порты без смены POSTGRES_PORT / COMPOSE_PROJECT_NAME.
| Режим | Назначение | OpenAI | Порты |
|---|---|---|---|
| Dev | Hot reload, повседневная разработка | Для live-чата | 5432 · 6379 · 8080 · 5173 |
| Full | Demo / compose-образцы frontend+embed | Обязателен | + host-demo 5180 |
| Contract | Offline API без LLM-сети | Не нужен | 55432 · 56379 · 18080 |
Dev (детально)
cp .env.example .env→ задатьOPENAI_API_KEY.- Если
5432занят: в.envпоставитьPOSTGRES_PORT=5433и тот же порт вSPRING_DATASOURCE_URL. docker compose up -d→ дождаться(healthy).cd backend && ./gradlew bootRun.cd frontend && npm ci && npm run gen && npm run dev.
Учебный UI без живого chat-backend: cd frontend && npm run dev:mock → http://localhost:5174.
Full Compose
cp .env.example .env # OPENAI_API_KEY обязателен
docker compose --profile full up -d --build
docker compose ps
Smoke:
curl --fail http://localhost:8080/actuator/health
curl --fail -o /dev/null -w "%{http_code}\n" http://localhost:5173/
curl --fail -o /dev/null -w "%{http_code}\n" http://localhost:5180/
curl --fail http://localhost:5173/embed/v1/widget.js | head -c 80
VITE_* запекаются при сборке образа. После смены VITE_API_URL / VITE_EMBED_ALLOWED_ORIGINS:
docker compose up -d --build frontend
Contract (offline)
Изолированный проект — не использует общий volume hackalem_pgdata.
docker compose -p hackalem-d1 -f scripts/d1-compose.yml up -d --wait
cd backend
SPRING_PROFILES_ACTIVE=contract \
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:55432/hackalem \
REDIS_PORT=56379 \
PORT=18080 \
./gradlew bootRun
curl --fail http://localhost:18080/actuator/health
curl --fail -X POST http://localhost:18080/auth/visitor-session
Остановка: docker compose -p hackalem-d1 -f scripts/d1-compose.yml down.
Остановка и изоляция
| Действие | Команда | Данные |
|---|---|---|
| Стоп сервисов | docker compose down | Volume сохранён |
| Полный сброс своей БД | docker compose down -v && docker compose up -d | Volume удалён |
| Логи | docker compose logs -f backend | — |
| psql | docker compose exec db psql -U hackalem -d hackalem | — |
down -v на общем demo-окружении команды не выполнять без явного согласования.
Параллельный worktree / CI-слот:
sh scripts/isolated-compose.sh my-agent-slot1 1 up
sh scripts/isolated-compose.sh my-agent-slot1 1 ps
sh scripts/isolated-compose.sh my-agent-slot1 1 down
Имя проекта ≠ hackalem. Слот 1…9 задаёт сдвинутые порты.
Конфигурация
Единый шаблон: .env.example → локальный .env (в git не коммитится).
| Переменная | Назначение | Default |
|---|---|---|
POSTGRES_* | Учётные данные БД | hackalem |
POSTGRES_PORT / REDIS_PORT | Порты на хосте | 5432 / 6379 |
BACKEND_PORT / FRONTEND_PORT | Проброс Compose | 8080 / 5173 |
HOST_DEMO_PORT | Embed host page | 5180 |
OPENAI_API_KEY | Live LLM / embeddings | обязателен для live |
SPRING_PROFILES_ACTIVE | live | contract | test | live |
VITE_API_URL | API из браузера (build-time) | http://localhost:8080 |
VITE_EMBED_ALLOWED_ORIGINS | Parent origins postMessage | 5180, 5173 |
EMBED_FRAME_ANCESTORS | CSP frame-ancestors (runtime) | 'self' + demo origins |
CORS_ALLOWED_ORIGINS | CORS backend | UI + host-demo |
CART_MODE | Корзина | sample |
Новая переменная → сразу в .env.example и docker-compose.yml.
Структура репозитория
backend/ Spring Boot API, Flyway, domain, security, workers
frontend/ React SPA, generated OpenAPI client, embed script
host-demo/ Статическая страница для cross-origin iframe
data/ Синтетический каталог, FAQ, fixtures, evaluation sets
docs/ ТЗ, API handoff, performance, architecture
scripts/ Compose helpers, smoke, data validators
tasks/ Функциональный backlog и DoD
tests/ Evaluation / load сценарии
docker-compose.yml
docker-compose.test.yml
.env.example
AGENTS.md Инженерный контракт monorepo
API и клиент
Контракт ведётся на backend (springdoc). После старта API:
cd frontend
npm run gen
npm run gen:check
Источник по умолчанию: http://localhost:8080/v3/api-docs.
Для contract: npm run gen -- --input http://localhost:18080/v3/api-docs.
Каталог frontend/src/client/** — только генерация, ручные правки запрещены.
| Метод | Путь | Назначение |
|---|---|---|
GET | /actuator/health | Liveness |
GET | /v3/api-docs | OpenAPI JSON |
POST | /auth/visitor-session | Выдача visitor-сессии |
UI: http://localhost:8080/swagger-ui.html
Разработка
Backend
docker compose up -d
cd backend
./gradlew bootRun # :8080
./gradlew test
./gradlew build
Frontend
cd frontend
npm ci
npm run gen # backend должен отвечать на :8080
npm run dev # :5173
npm run build && npm run lint && npm run test
API-first workflow
- Изменить контракт / контроллеры на backend.
- Убедиться, что
/v3/api-docsактуален. cd frontend && npm run gen.- Потреблять только сгенерированные типы и SDK.
Проверки качества
Перед merge / демо:
cd backend && ./gradlew build
cd ../frontend && npm run build && npm run lint && npm run test
cd ..
./scripts/validate-demo-data.sh
Контейнерный smoke:
docker compose --profile full up -d --build
curl --fail http://localhost:8080/actuator/health
docker compose down
Устранение неисправностей
| Симптом | Действие |
|---|---|
port is already allocated | Сменить POSTGRES_PORT / REDIS_PORT / BACKEND_PORT / FRONTEND_PORT в .env и синхронно URL-ы |
| Backend не видит БД | docker compose up -d && docker compose ps; в Compose хост БД — db, не localhost |
| Flyway checksum mismatch | Не править применённую миграцию; добавить V{n}__…sql. Сброс только своей БД: down -v |
npm run gen падает | curl http://localhost:8080/v3/api-docs — backend ещё не готов |
| Frontend в Docker «старый» | docker compose up -d --build frontend (особенно после смены VITE_*) |
| Старт падает без OpenAI | Задать OPENAI_API_KEY или использовать Contract |
| Embed не открывается | Проверить /embed/v1/widget.js на :5173, host-demo :5180, allowlist origins в env |
Документация
| Документ | Содержание |
|---|---|
| AGENTS.md | Контракт monorepo, Compose, env, DoD |
| backend/AGENTS.md | Backend-конвенции, Flyway, security |
| frontend/AGENTS.md | Frontend-конвенции, генерация клиента |
| docs/ekt-assistant-spec.md | Единое ТЗ и архитектура |
| docs/api/README.md | API v1, границы D1/D2 |
| docs/api/d1-handoff.md | Offline demo-path и evidence |
| host-demo/README.md | Embed host page |
| tasks/README.md | Backlog и зависимости задач |
| data/README.md | Синтетические данные |
Правила работы с репозиторием
- Не ломать воспроизводимый demo-path и Compose-контракт.
- API: backend → OpenAPI →
npm run gen→ frontend. - Секреты только в локальном
.env; в репозитории —.env.example. - Применённые Flyway-миграции не редактировать.
- Новые env — сразу в
.env.exampleиdocker-compose.yml. - Перед PR: backend
build, frontendbuild/lint/test, health smoke. - Trunk-based: короткие ветки, Conventional Commits (
feat:,fix:,docs:, …).
Инженерный источник правил: AGENTS.md.
Ограничения текущей поставки
Не считаются закрытыми без отдельной приёмки:
- боевые adapters каталога / identity / partner cart;
- полный embed/mobile acceptance (QA-01);
- live OpenAI evaluation и cost-control;
- нагрузка 1–5k суммарных API RPS;
- production secrets, observability и disaster recovery.
Валидация синтетических fixtures:
./scripts/validate-demo-data.sh
Авторы коммитов
История коммитов
- 2026-09-23 18:01chore: regenerate client for dialogue parameter resetsZhubanyshZh
- 2026-09-23 17:59Merge pull request #5Zhubanysh Zharylkassyn
- 2026-09-23 17:59Merge remote-tracking branch 'origin/main'damirablahat
- 2026-09-23 17:59feat: add editable dialogue parameters panelZhubanyshZh
- 2026-09-23 17:59fix: sync commerce context and resolve reviewed attachment articlesZhubanyshZh
- 2026-09-23 17:59fix: wrote new name of team and added tzdamirablahat
- 2026-09-23 17:59fix: synchronize dialogue parameters across live frontendZhubanyshZh
- 2026-09-23 17:58fix: preserve dialogue selections and support parameter resetsZhubanyshZh
Все коммиты (55)
- 2026-09-23 17:55docs: restructure README around clearer demo-patharemakk
- 2026-09-23 17:49fix: wrote new name of team and added tzdamirablahat
- 2026-09-23 17:42docs: expand local startup guide and align UI with EKT palettearemakk
- 2026-09-23 17:37Merge pull request #4Zhubanysh Zharylkassyn
- 2026-09-23 17:35feat: connect all frontend workflows to live APIZhubanyshZh
- 2026-09-23 17:32fix: display scale-six catalog prices and quantity stepsZhubanyshZh
- 2026-09-23 17:26feat: connect catalog and cart UI to live APIZhubanyshZh
- 2026-09-23 17:24feat: connect attachment upload and review UI to live APIZhubanyshZh
- 2026-09-23 17:24feat: connect knowledge sources and administration screens to APIZhubanyshZh
- 2026-09-23 17:17fix: expose correct knowledge and SSE schemas in OpenAPIZhubanyshZh
- 2026-09-23 17:12fix: restore nginx startup and refresh API clientZhubanyshZh
- 2026-09-23 17:01Merge branch 'codex/d2-remaining-services'ZhubanyshZh
- 2026-09-23 16:57fix: integrate latest main and verify final D2 regressionsZhubanyshZh
- 2026-09-23 16:57Merge branch 'codex/ui-01-client-transport'aremakk
- 2026-09-23 16:55feat(ui): add embed script, host-demo and mobile widget shellaremakk
- 2026-09-23 16:53feat: isolate compose test projects and offline startuparemakk
- 2026-09-23 16:53Merge remote-tracking branch 'origin/main' into codex/d2-remaining-servicesZhubanyshZh
- 2026-09-23 16:52fix: normalize knowledge request words without dropping factsZhubanyshZh
- 2026-09-23 16:52feat: integrate D2 services and publish quality evaluation evidenceZhubanyshZh
- 2026-09-23 16:47fix: reject unreadable blurred photos before visual inferenceZhubanyshZh
- 2026-09-23 16:37feat: add fenced attachment reprocessing and OCR word provenanceZhubanyshZh
- 2026-09-23 16:36fix: publish stock atomically and serve catalog certificatesZhubanyshZh
- 2026-09-23 16:33test: verify source revocation on repeated tool callsZhubanyshZh
- 2026-09-23 16:33fix: fence knowledge reindex and expose fixture source keysZhubanyshZh
- 2026-09-23 16:31fix: recheck source access on tool replay and enforce upload limitsZhubanyshZh
- 2026-09-23 16:31feat: add catalog search authoritative offers and fulfillment alternativesZhubanyshZh
- 2026-09-23 16:29Merge branch 'main' of https://github.com/BAITC-Hacks/hack-9dc7559b-it-accelerator-nxaremakk
- 2026-09-23 16:29Merge branch 'codex/ui-01-client-transport'aremakk
- 2026-09-23 16:29feat(ui): add commerce proposals, cart and attachments reviewaremakk
- 2026-09-23 16:28feat: wire D2 runtime, migration and reproducible quality evaluationZhubanyshZh
- 2026-09-23 16:28feat: add versioned knowledge ingestion and scoped retrievalZhubanyshZh
- 2026-09-23 16:28feat: add private attachment extraction and reviewed catalog selectionsZhubanyshZh
- 2026-09-23 16:12fix: merge catalog with D1 contracts and preserve both schema historiesZhubanyshZh
- 2026-09-23 16:00feat(catalog): versioned catalog, safe admin import and indexingZhubanyshZh
- 2026-09-23 15:54Merge pull request #2 from BAITC-Hacks/codex/ui-01-client-transportaremakk
- 2026-09-23 15:52Merge branch 'main' into codex/ui-01-client-transportaremakk
- 2026-09-23 15:52feat(ui): add chat transport, fixtures and streaming workspacearemakk
- 2026-09-23 15:51Merge branch 'refs/heads/codex/d1-chat-cart'damirablahat
- 2026-09-23 15:47feat: implement durable chat and confirmed cart backenddamirablahat
- 2026-09-23 15:22Merge pull request #1Zhubanysh Zharylkassyn
- 2026-09-23 15:21feat(data): add synthetic catalog, document fixtures and scenario validationZhubanyshZh
- 2026-09-23 14:54docs: map task dependencies and developer execution orderZhubanyshZh
- 2026-09-23 14:42docs: unify ekt requirements and split parallel implementation tasksZhubanyshZh
- 2026-09-23 14:07docs: plan AI chat RAG architecture and capacity roadmapZhubanyshZh
- 2026-09-23 14:04fix: wrote new name of team and added tzdamirablahat
- 2026-09-23 13:59feat: add vector db and did mugrationaremakk
- 2026-09-23 13:49init projectZhubanyshZh
Структура репозитория (414 файлов)
.claude/launch.json .env.example .gitignore AGENTS.md CLAUDE.md README.md backend/.dockerignore backend/AGENTS.md backend/CLAUDE.md backend/Dockerfile backend/build.gradle backend/gradle/wrapper/gradle-wrapper.jar backend/gradle/wrapper/gradle-wrapper.properties backend/gradlew backend/gradlew.bat backend/settings.gradle backend/src/main/java/com/hackalem/HackalemApplication.java backend/src/main/java/com/hackalem/ai/.gitkeep backend/src/main/java/com/hackalem/ai/agent/AgentTools.java backend/src/main/java/com/hackalem/ai/agent/AgentWorker.java backend/src/main/java/com/hackalem/ai/agent/Limits.java backend/src/main/java/com/hackalem/ai/agent/ModelUsage.java backend/src/main/java/com/hackalem/ai/attachments/AttachmentExtractor.java backend/src/main/java/com/hackalem/ai/attachments/AttachmentValidator.java backend/src/main/java/com/hackalem/ai/attachments/AttachmentWorker.java backend/src/main/java/com/hackalem/ai/attachments/DocumentRows.java backend/src/main/java/com/hackalem/ai/attachments/ImageQualityGate.java backend/src/main/java/com/hackalem/ai/attachments/OcrGateway.java backend/src/main/java/com/hackalem/ai/attachments/OpenAiVisionGateway.java backend/src/main/java/com/hackalem/ai/attachments/TesseractOcrGateway.java backend/src/main/java/com/hackalem/ai/attachments/VisionGateway.java backend/src/main/java/com/hackalem/ai/catalog/BoundedCatalogQueryEmbedding.java backend/src/main/java/com/hackalem/ai/catalog/CatalogEmbeddingProvider.java backend/src/main/java/com/hackalem/ai/catalog/DeterministicCatalogEmbeddingProvider.java backend/src/main/java/com/hackalem/ai/catalog/OpenAiCatalogEmbeddingProvider.java backend/src/main/java/com/hackalem/ai/catalog/ProductEmbeddingText.java backend/src/main/java/com/hackalem/ai/gateway/ContractLlm.java backend/src/main/java/com/hackalem/ai/gateway/OpenAiGateway.java backend/src/main/java/com/hackalem/config/CatalogConfig.java backend/src/main/java/com/hackalem/config/CatalogProperties.java backend/src/main/java/com/hackalem/config/ContractData.java backend/src/main/java/com/hackalem/config/OpenApiConfig.java backend/src/main/java/com/hackalem/config/SchemaLineageConfig.java backend/src/main/java/com/hackalem/config/WorkerConfig.java backend/src/main/java/com/hackalem/domain/.gitkeep backend/src/main/java/com/hackalem/domain/Json.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentCatalog.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentException.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentLimits.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentMatcher.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentModels.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentRepository.java backend/src/main/java/com/hackalem/domain/attachments/AttachmentService.java backend/src/main/java/com/hackalem/domain/attachments/CatalogAttachmentAdapter.java backend/src/main/java/com/hackalem/domain/attachments/ReviewedAttachmentPort.java backend/src/main/java/com/hackalem/domain/cart/CartService.java backend/src/main/java/com/hackalem/domain/catalog/ArticleNormalizer.java backend/src/main/java/com/hackalem/domain/catalog/CatalogAnalogsService.java backend/src/main/java/com/hackalem/domain/catalog/CatalogCertificates.java backend/src/main/java/com/hackalem/domain/catalog/CatalogConflictException.java backend/src/main/java/com/hackalem/domain/catalog/CatalogImportDocument.java backend/src/main/java/com/hackalem/domain/catalog/CatalogImportError.java backend/src/main/java/com/hackalem/domain/catalog/CatalogImportJob.java backend/src/main/java/com/hackalem/domain/catalog/CatalogImportJobRepository.java backend/src/main/java/com/hackalem/domain/catalog/CatalogImportService.java backend/src/main/java/com/hackalem/domain/catalog/CatalogImportValidator.java backend/src/main/java/com/hackalem/domain/catalog/CatalogIndexNotReadyException.java backend/src/main/java/com/hackalem/domain/catalog/CatalogOfferService.java backend/src/main/java/com/hackalem/domain/catalog/CatalogProduct.java backend/src/main/java/com/hackalem/domain/catalog/CatalogQueryService.java backend/src/main/java/com/hackalem/domain/catalog/CatalogReadSnapshots.java backend/src/main/java/com/hackalem/domain/catalog/CatalogRepository.java backend/src/main/java/com/hackalem/domain/catalog/CatalogSearchService.java backend/src/main/java/com/hackalem/domain/catalog/CatalogValidationException.java backend/src/main/java/com/hackalem/domain/catalog/CatalogVersion.java backend/src/main/java/com/hackalem/domain/catalog/CatalogVersionStatus.java backend/src/main/java/com/hackalem/domain/catalog/CompatibilityRules.java backend/src/main/java/com/hackalem/domain/catalog/Decimals.java backend/src/main/java/com/hackalem/domain/catalog/EmbeddingStatus.java backend/src/main/java/com/hackalem/domain/catalog/ImportJobStatus.java backend/src/main/java/com/hackalem/domain/catalog/ProductCertificate.java backend/src/main/java/com/hackalem/domain/catalog/ProductNotFoundException.java backend/src/main/java/com/hackalem/domain/catalog/ProductOffer.java backend/src/main/java/com/hackalem/domain/catalog/ProductStock.java backend/src/main/java/com/hackalem/domain/catalog/QuantityBasis.java backend/src/main/java/com/hackalem/domain/catalog/SampleCatalogInitializer.java backend/src/main/java/com/hackalem/domain/catalog/SearchCriteria.java backend/src/main/java/com/hackalem/domain/catalog/StagedProduct.java backend/src/main/java/com/hackalem/domain/catalog/StockStatus.java backend/src/main/java/com/hackalem/domain/catalog/WarehouseAvailability.java backend/src/main/java/com/hackalem/domain/chat/ChatService.java backend/src/main/java/com/hackalem/domain/chat/DialogueSelectionBridge.java backend/src/main/java/com/hackalem/domain/chat/EventJournal.java backend/src/main/java/com/hackalem/domain/knowledge/KnowledgeEvidence.java backend/src/main/java/com/hackalem/domain/knowledge/KnowledgeIngestionWorker.java backend/src/main/java/com/hackalem/domain/knowledge/KnowledgeRepository.java backend/src/main/java/com/hackalem/domain/knowledge/KnowledgeSeed.java backend/src/main/java/com/hackalem/domain/knowledge/KnowledgeService.java backend/src/main/java/com/hackalem/domain/knowledge/KnowledgeText.java backend/src/main/java/com/hackalem/domain/port/AnalogsPort.java backend/src/main/java/com/hackalem/domain/port/AttachmentPort.java backend/src/main/java/com/hackalem/domain/port/CartPort.java backend/src/main/java/com/hackalem/domain/port/CatalogPort.java backend/src/main/java/com/hackalem/domain/port/Contracts.java backend/src/main/java/com/hackalem/domain/port/KnowledgePort.java backend/src/main/java/com/hackalem/domain/port/LlmGateway.java backend/src/main/java/com/hackalem/domain/port/PartnerIdentityPort.java backend/src/main/java/com/hackalem/domain/port/StockPort.java backend/src/main/java/com/hackalem/integration/cart/HttpCartAdapter.java backend/src/main/java/com/hackalem/integration/cart/SampleCartAdapter.java backend/src/main/java/com/hackalem/integration/catalog/CatalogDataAdapter.java backend/src/main/java/com/hackalem/integration/catalog/PartnerOfferClient.java backend/src/main/java/com/hackalem/security/AdminAccessException.java backend/src/main/java/com/hackalem/security/AuthenticatedTrustedScopeResolver.java backend/src/main/java/com/hackalem/security/CatalogAdminScope.java backend/src/main/java/com/hackalem/security/JwtFilter.java backend/src/main/java/com/hackalem/security/SecurityConfig.java backend/src/main/java/com/hackalem/security/SessionService.java backend/src/main/java/com/hackalem/security/TrustedScopeResolver.java backend/src/main/java/com/hackalem/web/.gitkeep backend/src/main/java/com/hackalem/web/ApiErrors.java backend/src/main/java/com/hackalem/web/ApiException.java backend/src/main/java/com/hackalem/web/AuthController.java backend/src/main/java/com/hackalem/web/CartController.java backend/src/main/java/com/hackalem/web/ChatController.java backend/src/main/java/com/hackalem/web/EventController.java backend/src/main/java/com/hackalem/web/ModelUsageController.java backend/src/main/java/com/hackalem/web/PingController.java backend/src/main/java/com/hackalem/web/attachments/AttachmentController.java backend/src/main/java/com/hackalem/web/catalog/CatalogAdminController.java backend/src/main/java/com/hackalem/web/catalog/CatalogExceptionHandler.java backend/src/main/java/com/hackalem/web/catalog/CatalogImportMapper.java backend/src/main/java/com/hackalem/web/catalog/CatalogImportRequest.java backend/src/main/java/com/hackalem/web/catalog/CatalogReadController.java backend/src/main/java/com/hackalem/web/catalog/CatalogResponseMapper.java backend/src/main/java/com/hackalem/web/catalog/CatalogResponses.java backend/src/main/java/com/hackalem/web/catalog/ProductCatalogController.java backend/src/main/java/com/hackalem/web/sources/KnowledgeController.java backend/src/main/java/com/hackalem/web/sources/KnowledgeResponseMapper.java backend/src/main/java/com/hackalem/web/sources/KnowledgeResponses.java backend/src/main/resources/application-contract.yml backend/src/main/resources/application-d2.yml backend/src/main/resources/application-test.yml backend/src/main/resources/application.yml backend/src/main/resources/db/baseline-catalog/V3__catalog_versions_offers_stock.sql backend/src/main/resources/db/baseline-catalog/V4__identity_chat_cart.sql backend/src/main/resources/db/baseline-identity/V3__identity_chat_cart.sql backend/src/main/resources/db/baseline-identity/V4__catalog_versions_offers_stock.sql backend/src/main/resources/db/drafts/attachments.sql backend/src/main/resources/db/drafts/catalog.sql backend/src/main/resources/db/drafts/knowledge.sql backend/src/main/resources/db/migration/V1__init.sql backend/src/main/resources/db/migration/V2__products_vector_search.sql backend/src/main/resources/db/migration/V5__catalog_knowledge_attachments.sql backend/src/test/java/com/hackalem/CoreIntegrationTest.java backend/src/test/java/com/hackalem/attachments/AttachmentExtractionTest.java backend/src/test/java/com/hackalem/attachments/AttachmentHttpIntegrationTest.java backend/src/test/java/com/hackalem/attachments/AttachmentMatchingTest.java backend/src/test/java/com/hackalem/catalog/ArticleNormalizerTest.java backend/src/test/java/com/hackalem/catalog/CatalogImportValidatorTest.java backend/src/test/java/com/hackalem/catalog/CatalogServicesIntegrationTest.java backend/src/test/java/com/hackalem/catalog/CompatibilityRulesTest.java backend/src/test/java/com/hackalem/catalog/DeterministicCatalogEmbeddingProviderTest.java backend/src/test/java/com/hackalem/catalog/ProductStockTest.java backend/src/test/java/com/hackalem/config/SchemaLineageConfigTest.java backend/src/test/java/com/hackalem/integration/cart/HttpCartAdapterTest.java backend/src/test/java/com/hackalem/knowledge/KnowledgeIntegrationTest.java backend/src/test/java/com/hackalem/knowledge/KnowledgeTextTest.java backend/src/test/resources/docker-java.properties data/.gitattributes data/README.md data/attachments/images/blurred.jpg data/attachments/images/label.jpg data/attachments/images/product-only.jpg data/attachments/images/rotated.jpg data/attachments/invalid/corrupt.pdf data/attachments/invalid/renamed-executable.jpg data/attachments/manifest.json data/attachments/office/specification.doc data/attachments/office/specification.docx data/attachments/office/specification.xls data/attachments/office/specification.xlsx data/attachments/pdf/mixed.pdf data/attachments/pdf/scan.pdf data/attachments/pdf/text.pdf data/evaluation/README.md data/evaluation/questions.json data/expected/attachment-rows.json data/expected/cart-snapshots.json data/expected/offer-snapshots.json data/expected/questions.json data/expected/scenarios.json data/expected/terms-answers.json data/purchase_terms/adversarial.json data/purchase_terms/terms.json data/sample_catalog/catalog.schema.json data/sample_catalog/certificates/synthetic-certificate.pdf data/sample_catalog/compatibility-rules.json data/sample_catalog/invalid/duplicate-article.json data/sample_catalog/invalid/negative-quantity.json data/sample_catalog/products.json docker-compose.test.yml docker-compose.yml docs/ai-chat-architecture.md docs/ai-chat-backlog.md docs/api/README.md docs/api/attachments-handoff.md docs/api/catalog-merge.md docs/api/d1-handoff.md docs/api/fixtures/accepted.json docs/api/fixtures/conflict.json docs/api/fixtures/delta.json docs/api/fixtures/products.json docs/api/fixtures/proposal.json docs/api/fixtures/terminal.json docs/api/openapi.json docs/api/partner-cart.md docs/catalog/services-handoff.md docs/ekt-assistant-spec.md docs/frontend-manual-check.md docs/knowledge/rag-handoff.md docs/performance/workload.md docs/reports/d2-integration.md docs/reports/qa02-blur-regression.json docs/reports/qa02-live.json docs/reports/qa02-offline.json docs/reports/qa02-rag-regression.json docs/ТЗ_ИИ-ассистент_ekt.kz.md frontend/.dockerignore frontend/.prettierignore frontend/.prettierrc frontend/AGENTS.md frontend/CLAUDE.md frontend/Dockerfile frontend/README.md frontend/components.json frontend/eslint.config.js frontend/index.html frontend/nginx.conf frontend/openapi-ts.config.ts frontend/package-lock.json frontend/package.json frontend/public/catalog/breaker.svg frontend/public/catalog/cable.svg frontend/public/catalog/generic.svg frontend/public/catalog/lamp.svg frontend/public/embed/v1/widget.js frontend/scripts/check-generated.mjs frontend/src/App.tsx frontend/src/client/client.gen.ts frontend/src/client/client/client.gen.ts frontend/src/client/client/index.ts frontend/src/client/client/types.gen.ts frontend/src/client/client/utils.gen.ts frontend/src/client/core/auth.gen.ts frontend/src/client/core/bodySerializer.gen.ts frontend/src/client/core/params.gen.ts frontend/src/client/core/pathSerializer.gen.ts frontend/src/client/core/queryKeySerializer.gen.ts frontend/src/client/core/serverSentEvents.gen.ts frontend/src/client/core/types.gen.ts frontend/src/client/core/utils.gen.ts frontend/src/client/index.ts frontend/src/client/sdk.gen.ts frontend/src/client/types.gen.ts frontend/src/components/.gitkeep frontend/src/components/FeatureNav.tsx frontend/src/components/SessionBoundary.tsx frontend/src/components/attachments/AttachmentPanel.tsx frontend/src/components/attachments/AttachmentProvider.tsx frontend/src/components/attachments/attachments.css frontend/src/components/attachments/context.ts frontend/src/components/attachments/model.ts frontend/src/components/cart/CommerceProvider.tsx frontend/src/components/cart/LineItems.tsx frontend/src/components/cart/ProposalCard.tsx frontend/src/components/cart/commerce.css frontend/src/components/cart/context.ts frontend/src/components/cart/model.ts frontend/src/components/catalog/CommercePanel.tsx frontend/src/components/catalog/LiveCatalogPanel.tsx frontend/src/components/catalog/ProductCard.tsx frontend/src/components/catalog/decimal.ts frontend/src/components/catalog/productImage.ts frontend/src/components/chat/Composer.tsx frontend/src/components/chat/ContextPanel.tsx frontend/src/components/chat/ConversationSidebar.tsx frontend/src/components/chat/DialogueEditor.tsx frontend/src/components/chat/MessageTimeline.tsx frontend/src/components/chat/ReplyStatus.tsx frontend/src/components/chat/RunDetails.tsx frontend/src/components/chat/Welcome.tsx frontend/src/components/chat/chat.css frontend/src/components/chat/model.ts frontend/src/components/chat/parameters.css frontend/src/components/chat/reducer.ts frontend/src/components/live.css frontend/src/components/sources/SafeMarkdown.tsx frontend/src/components/ui/.gitkeep frontend/src/hooks/useApiSession.ts frontend/src/hooks/useAttachments.ts frontend/src/hooks/useChatWorkspace.ts frontend/src/hooks/useCommerce.ts frontend/src/index.css frontend/src/lib/api-errors.ts frontend/src/lib/api.ts frontend/src/lib/attachments-live.ts frontend/src/lib/chat-live.ts frontend/src/lib/chat-query-keys.ts frontend/src/lib/commerce-live.ts frontend/src/lib/dialogue-form.ts frontend/src/lib/dialogue-state.ts frontend/src/lib/knowledge.ts frontend/src/lib/live-session.ts frontend/src/lib/query.ts frontend/src/lib/retry.ts frontend/src/lib/session.ts frontend/src/lib/stream.ts frontend/src/lib/transport.ts frontend/src/lib/utils.ts frontend/src/main.tsx frontend/src/mocks/attachment-demo.ts frontend/src/mocks/browser.ts frontend/src/mocks/chat-demo.ts frontend/src/mocks/commerce-data.ts frontend/src/mocks/commerce-demo.ts frontend/src/mocks/fixtures.ts frontend/src/mocks/handlers.ts frontend/src/mocks/sse.ts frontend/src/pages/AdminPage.tsx frontend/src/pages/AttachmentsPage.tsx frontend/src/pages/CartPage.tsx frontend/src/pages/CatalogPage.tsx frontend/src/pages/ChatPage.tsx frontend/src/pages/HomePage.tsx frontend/src/pages/KnowledgePage.tsx frontend/src/pages/SessionPage.tsx frontend/src/pages/SourcePage.tsx frontend/src/pages/WidgetPage.tsx frontend/src/pages/service-ui.tsx frontend/src/pages/services.css frontend/src/vite-env.d.ts frontend/src/widget/bridge.ts frontend/src/widget/useEmbedBridge.ts frontend/src/widget/useVisualViewport.ts frontend/tests/attachments-live.test.ts frontend/tests/chat-live.test.ts frontend/tests/chat-restore.test.ts frontend/tests/commerce-demo.test.ts frontend/tests/commerce-live.test.ts frontend/tests/decimal.test.ts frontend/tests/dialogue-form.test.ts frontend/tests/dialogue-state.test.ts frontend/tests/embed-bridge.test.ts frontend/tests/knowledge-admin.test.ts frontend/tests/setup.ts frontend/tests/transport.test.ts frontend/tsconfig.app.json frontend/tsconfig.json frontend/tsconfig.node.json frontend/vite.config.ts frontend/vitest.config.ts host-demo/README.md host-demo/index.html scripts/d1-compose.yml scripts/d1-smoke.py scripts/d2-quality-compose.yml scripts/evaluate.py scripts/evaluation.Dockerfile scripts/generate-attachment-fixtures.py scripts/generate-demo-data.py scripts/generate-workbook-fixture.mjs scripts/isolated-compose.sh scripts/update-fixture-manifest.py scripts/validate-demo-data.py scripts/validate-demo-data.sh tasks/00-foundation/DATA-01-sample-data-contract.md tasks/00-foundation/FOUND-01-contracts-and-ports.md tasks/00-foundation/NFR-01-workload-and-release-gates.md tasks/01-identity/AUTH-01-session-and-ownership.md tasks/02-chat/CHAT-01-history-and-runs.md tasks/02-chat/CHAT-02-agent-tools.md tasks/02-chat/CHAT-03-sse-recovery.md tasks/02-chat/CHAT-04-dialogue-context.md tasks/03-catalog/CAT-01-import-and-schema.md tasks/03-catalog/CAT-02-search-and-comparison.md tasks/03-catalog/CAT-03-offers-and-stock.md tasks/03-catalog/CAT-04-analogs-and-fulfillment.md tasks/04-knowledge/RAG-01-terms-and-sources.md tasks/05-cart/CART-01-immutable-proposals.md tasks/05-cart/CART-02-confirmation-gate.md tasks/05-cart/CART-03-cart-adapters-and-reconciliation.md tasks/06-attachments/ATT-01-upload-and-jobs.md tasks/06-attachments/ATT-02-office-extraction.md tasks/06-attachments/ATT-03-pdf-ocr-and-photo.md tasks/06-attachments/ATT-04-matching-and-review.md tasks/07-widget/UI-01-client-and-fixtures.md tasks/07-widget/UI-02-chat-and-streaming.md tasks/07-widget/UI-03-products-proposals-and-cart.md tasks/07-widget/UI-04-attachments-review.md tasks/07-widget/UI-05-embed-and-mobile.md tasks/08-platform/OPS-01-compose-foundation.md tasks/08-platform/OPS-02-complete-product-compose.md tasks/08-platform/PERF-01-limits-events-and-metrics.md tasks/08-platform/PERF-02-load-and-failure-tests.md tasks/09-quality/QA-01-end-to-end-acceptance.md tasks/09-quality/QA-02-rag-and-recognition-evaluation.md tasks/09-quality/REL-01-release-handoff.md tasks/DEPENDENCIES.md tasks/README.md tests/evaluation/test_report.py tests/load/profiles/1000.json tests/load/profiles/3000.json tests/load/profiles/5000.json
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.