EventMatch
Веб-сервис подбирает до трёх подрядчиков для мероприятия (ведущий, флорист, площадка и др.) по городу, дате, формату, категории и бюджету.
О проекте
Команда: requiem
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Рабочий MVP
Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор
Суть
Веб-сервис подбирает до трёх подрядчиков для мероприятия (ведущий, флорист, площадка и др.) по городу, дате, формату, категории и бюджету. Для каждого варианта показывается объяснение с цитатой из описания и причины отсева остальных.
Как устроено
CSV-каталог при старте загружается в память. Правила фильтрации применяются по порядку: город и категория, занятость на дату, бюджет, формат, язык, длительность. Прошедшие фильтр сортируются по цене, затем по ID, выдаётся топ-3. Отдельно различаются два случая пустого результата: категории нет в городе или кандидаты не прошли условия. Опционально OpenAI Responses API со строгой JSON Schema выбирает характерный фрагмент описания для каждой карточки. Сервер проверяет ID в ответе и при ошибке или тайм-ауте переходит на объяснения из каталога.
Ключевые решения
- rule-based filtering
- deterministic ranking
- OpenAI Responses strict JSON Schema
- safe fallback
- node:test
Особенности
AI не влияет на подбор и порядок, он только выбирает цитату-объяснение из уже имеющегося текста, так что результат воспроизводим. Пустые выдачи объясняются по-разному.
Стек
Node.js 22 · Express 5 · vanilla HTML/CSS/JS · csv-parse
Модели
OpenAI (модель через OPENAI_MODEL)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-510e990a-requiem.
README
README.mdEventMatch — объяснимый подбор подрядчиков для мероприятий
EventMatch — MVP для HackAlem. Он помогает организатору быстро найти до трёх подходящих подрядчиков из каталога: ведущего, флориста, площадку и другие категории.
Приложение принимает город, дату, формат события, категорию и бюджет; язык и длительность — дополнительные фильтры. Для каждого варианта оно показывает начальную цену, признаки профиля, причину соответствия и точный фрагмент описания. Подбор не является бронированием или рейтингом качества: это прозрачная фильтрация по данным каталога.
Что решает продукт
Организатору не нужно вручную просматривать весь каталог и отдельно проверять условия каждого исполнителя. EventMatch:
- исключает подрядчиков, занятых на выбранную дату;
- учитывает город, категорию, стартовую цену, формат, язык и длительность;
- сортирует подходящие варианты по возрастанию начальной цены, а при равенстве — по ID;
- возвращает максимум три результата и объясняет, почему остальные не попали в выдачу;
- различает две ситуации без результатов: категории нет в городе или кандидаты есть, но не проходят условия;
- работает и без AI: в этом случае берёт релевантный фрагмент из описания по правилам каталога.
AI подключается опционально. Он выбирает один характерный фрагмент из уже предоставленных описаний максимум для трёх кандидатов. Он не влияет на доступность, цену, фильтрацию или порядок карточек; сервер проверяет все ID и использует безопасный резервный режим при ошибке, тайм-ауте или некорректном ответе.
Исходный каталог содержит 66 анонимизированных профилей, 17 категорий и данные о доступности в период с 23 сентября по 31 декабря 2026 года включительно.
Технологии
| Область | Используется |
|---|---|
| Сервер | Node.js 22.12+ и Express 5 |
| Клиент | HTML, CSS и современный JavaScript без фреймворка и сборщика |
| Данные | Локальный CSV, разобранный с csv-parse и загружаемый в память при старте |
| AI, необязательно | OpenAI Responses API со строгой JSON Schema |
| Тесты | Встроенный раннер node:test |
База данных, авторизация и сторонние CDN не используются. Один Express-сервер обслуживает и страницу, и JSON API.
Запуск
Нужны Node.js 22.12 или новее и npm. Команды выполняются из папки приложения:
cd contractor-picker
npm ci
npm start
Откройте http://127.0.0.1:3000. После установки зависимостей базовый режим не требует доступа к интернету и API-ключа.
Для разработки с автоматическим перезапуском сервера используйте:
npm run dev
На Windows, если PowerShell блокирует npm.ps1, запускайте те же команды через npm.cmd, например npm.cmd start.
Настройки
Пример переменных находится в .env.example. Можно создать локальный .env и при необходимости изменить PORT или HOST.
Чтобы включить AI-выбор фрагментов, добавьте в .env свой OPENAI_API_KEY и доступную модель в OPENAI_MODEL, затем перезапустите сервер. Не коммитьте .env и не передавайте ключ в браузер: запрос к API выполняется только сервером. Без ключа подбор остаётся полностью рабочим, а интерфейс показывает режим «AI не подключён».
Как работает решение
Браузер → POST /api/recommend → проверка входных данных
↓
фильтры каталога и сортировка
↓
до 3 карточек + проверяемые объяснения
↓
OpenAI выбирает фрагмент описания (опционально)
Порядок проверок: город и категория → занятость на дату → бюджет → формат → язык → длительность. У прошедших фильтры кандидатов проверяется цена, затем ID. Поэтому повторный запрос к одной версии CSV возвращает один и тот же порядок.
Публичные методы API:
GET /api/meta— справочники для формы и границы календаря;POST /api/recommend— подбор подрядчиков;GET /api/health— статус сервера и версия датасета.
Полная схема запросов и ответов описана в контракте API.
Проверка решения
-
Установите зависимости и запустите полный набор проверок:
cd contractor-picker npm run checkКоманда проверяет синтаксис клиента и сервера, затем запускает 18 тестов: данные CSV, фильтрацию, стабильный порядок, календарь, границы бюджета, язык, длительность, API, тайм-аут и безопасный fallback AI.
-
Запустите приложение (
npm start) и откройте страницу. Начальный пример «Корпоратив в Алматы» должен показать три карточки: Куррапика (HK-88430), Аня Форджер (HK-29829) и Сон Гоку (HK-27222). Под карточками без ключа должна быть надпись, что объяснения составлены по каталогу. -
Проверьте демонстрационные пресеты в интерфейсе:
- «Флорист на свадьбу» — один результат;
- «Банкетный зал» — два результата;
- «Нет категории в городе» — отдельный сценарий отсутствующей категории;
- «Не проходит бюджет» — отдельный сценарий, когда категория есть, но условия слишком строгие.
-
Измените только дату основного примера с 10 на 11 октября 2026 года. Интерфейс должен показать, что ранее подобранные Куррапика и Аня Форджер заняты на новую дату.
-
При необходимости проверьте API напрямую:
curl http://127.0.0.1:3000/api/healthОжидаемый ответ содержит
status: "ok", число профилей и версию датасета. -
Если настроен
OPENAI_API_KEY, выполните любой успешный подбор. Под карточками должно появиться сообщение «AI выбрал особенности из описаний». При ошибке API приложение не должно ломать подбор: режим сменится на резервный с объяснениями из каталога.
Подробные ожидаемые результаты для демонстрации находятся в сценариях, а сведения о выполненной проверке — в verification.md.
Структура репозитория
contractor-picker/
├── data/ # исходный каталог подрядчиков
├── public/ # интерфейс в браузере
├── server/ # Express API, загрузка данных, подбор и AI-объяснения
├── tests/ # автоматические проверки
└── docs/ # API-контракт, демонстрационные сценарии и верификация
Инструкция по работе команды и зонам ответственности: TEAM.md.
Авторы коммитов
История коммитов
- 2026-09-23 17:57аштфдn1sbala
- 2026-09-23 17:53ааааааааn1sbala
- 2026-09-23 17:36ffn1sbala
- 2026-09-23 17:36fffn1sbala
- 2026-09-23 17:34ddn1sbala
- 2026-09-23 17:34ddddn1sbala
- 2026-09-23 17:34coden1sbala
- 2026-09-23 16:40Merge branch 'main' of https://github.com/BAITC-Hacks/hack-510e990a-requiemn1sbala
Все коммиты (18)
- 2026-09-23 16:37updaten1sbala
- 2026-09-23 16:13Merge pull request #1 from BAITC-Hacks/backendtrezviz
- 2026-09-23 16:11ReadmeNurlat
- 2026-09-23 15:26Merge branch 'main' of https://github.com/BAITC-Hacks/hack-510e990a-requiemn1sbala
- 2026-09-23 15:26frontendn1sbala
- 2026-09-23 14:38Document frontend and backend team workflowolimpiyskiy mishka
- 2026-09-23 14:36aaan1sbala
- 2026-09-23 14:28sigma1Nurlat
- 2026-09-23 14:22Add EventMatch contractor picker MVPolimpiyskiy mishka
- 2026-09-23 11:54sigmaNurlat
Структура репозитория (32 файлов)
.env README.md TEAM.md contractor-picker/.env.example contractor-picker/.gitignore contractor-picker/README.md contractor-picker/data/contractors.csv contractor-picker/docs/api-contract.md contractor-picker/docs/demo-scenarios.md contractor-picker/docs/verification.md contractor-picker/package-lock.json contractor-picker/package.json contractor-picker/public/app.js contractor-picker/public/catalog.html contractor-picker/public/catalog.js contractor-picker/public/favicon.svg contractor-picker/public/i18n.js contractor-picker/public/index.html contractor-picker/public/styles.css contractor-picker/server/ai.js contractor-picker/server/assistant.js contractor-picker/server/dataset.js contractor-picker/server/explanations.js contractor-picker/server/index.js contractor-picker/server/locales.js contractor-picker/server/matching.js contractor-picker/server/recommendations.js contractor-picker/tests/assistant.test.js contractor-picker/tests/matching.test.js contractor-picker/tools/check-assistant.mjs contractor-picker/tools/check-openai-key.mjs package-lock.json
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.