Rio
Сервис подбора до трёх подрядчиков для мероприятия (ведущие, коллективы, площадки).
О проекте
Команда: Rio
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Доведённый продукт
Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор
Суть
Сервис подбора до трёх подрядчиков для мероприятия (ведущие, коллективы, площадки). Объясняет выбор выполненными условиями и цитатой из профиля. Задеплоен на Vercel: карточки-пьедестал, портфолио и оценки 1–5★.
Как устроено
POST /api/v1/recommendations сначала валидирует запрос и выбирает пул по городу и категории. Затем жёсткие фильтры: занятость по календарю, бюджет по цене «от», формат, язык, часы. Пожелания лексически ранжируются: сумма ln(1+N/(1+df)) по совпавшим 6-буквенным основам, при равенстве сортировка по цене, затем по ID. Ответ содержит top-3 с фактами, цитатой до 240 символов, аудитом исключений и статусом matched/no_category/no_match. Бэкенд на стандартной библиотеке Python с SQLite, seed из CSV.
Ключевые решения
- жёсткие фильтры по условиям
- IDF-взвешенное лексическое ранжирование по 6-буквенным основам
- детерминированный tie-break
- извлечение цитаты-обоснования
- сравнение выдачи при смене даты
Особенности
Каталог расширен до 200 профилей, синтетические явно помечены (synthetic=True, price_imputed=True). Ранжирование полностью детерминированное, без LLM, численный балл и совпавшие основы видны в карточке. Отдельные состояния «категории нет» и «никто не проходит условия».
Стек
Python · http.server · SQLite · HTML · CSS · JavaScript · Vercel
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-009717fe-rio.
README
README.mdRio — умный подбор подрядчиков
Рабочее решение HackAlem AI, кейс #79-lite. Для заказчика мероприятия в Казахстане Rio сокращает каталог до трёх подходящих подрядчиков и объясняет выбор условиями запроса и цитатами из профилей. Поддерживаются люди, коллективы и площадки.
Цель и решаемая задача
Организатору события приходится вручную просматривать длинный каталог, сверять город, свободную дату, формат, бюджет, язык и длительность работы каждого подрядчика. Rio автоматизирует этот путь: принимает параметры события, проверяет каталог и возвращает до трёх наиболее подходящих вариантов.
Продукт помогает:
- сократить время от запроса до короткого списка подрядчиков;
- исключить занятые и не соответствующие условиям профили;
- понять причину каждой рекомендации по проверяемым фактам и цитате из описания;
- сравнить результаты при смене даты;
- изучить портфолио и оставить оценку работе подрядчика.
Что реализовано
- Город, дата, формат, категория и бюджет; необязательные язык, длительность и пожелания.
- Строгая проверка занятости, бюджета, формата, языка и часов.
- До трёх карточек с ценой, конкретными причинами, цитатой и полным описанием.
- Стабильное текстовое ранжирование, затем цена и ID.
- Три отдельных исхода: подобрали; категории в городе нет; кандидаты не проходят условия.
- Объяснение короткой выдачи, причины исключения каждого кандидата и сравнение двух дат.
- Пометки синтетических профилей и проставленных при подготовке цен и городов.
- Шесть демонстрационных сценариев и адаптивный русский интерфейс.
- SQLite-каталог, портфолио подрядчиков и клиентские оценки работ.
- Светлый фирменный стиль Rio, интерактивные 3D-карточки, favicon и метаданные для поисковой выдачи и превью ссылок.
Публичная демонстрация
| Параметр | Значение |
|---|---|
| URL | rio-hackalem-podium.vercel.app |
| Окружение | Vercel Production |
| Статус | READY |
| Стек | Static HTML/CSS/JS + Python Functions |
Проверено
- главная страница и API работают;
- поиск возвращает до трёх подходящих подрядчиков;
- первое место отображается по центру золотой карточкой;
- второе место — серебряной карточкой справа;
- третье место — бронзовой карточкой слева;
- портфолио и рейтинги отображаются;
- мобильная версия адаптирована;
- 17 автоматических тестов успешно пройдены;
- ошибок в консоли браузера нет.
Production deployment
| Параметр | Значение |
|---|---|
| URL | rio-hackalem-podium.vercel.app |
| Окружение | Vercel Production |
| Статус | READY |
| Стек | Static HTML/CSS/JS + Python Functions |
Контрольная проверка production от 23 сентября 2026:
- главная страница, favicon и description-метаданные загружаются;
/api/v1/healthвозвращает200,database: ok, 200 подрядчиков и схему002_portfolio_and_ratings.sql;- все шесть демонстрационных запросов возвращают ожидаемые состояния, не более трёх карточек и объяснение каждого результата;
- смена даты заменяет всю предыдущую тройку и показывает причину изменения;
- состояния
no_matchиno_categoryотображаются раздельно и предлагают релевантный следующий шаг; - оценка
1★–5★сохраняется через API и мгновенно обновляет рейтинг карточки; повторная оценка того же клиента меняет голос без увеличения счётчика; - при ширине 390 px горизонтальной прокрутки нет: форма, сценарии и колода карточек помещаются в viewport;
- ошибок и предупреждений в консоли браузера не обнаружено.
Сценарий пользователя
Укажите параметры события и нажмите «Подобрать подрядчиков». Сервис проверит обязательные условия и покажет до трёх карточек. Цитаты помогают увидеть отличия; раскрывающиеся секции показывают исходное описание и причины исключения альтернатив. Для сравнения дат измените только дату и повторите запрос: интерфейс объяснит, кто из прежней тройки теперь занят.
Как проверить решение
- Откройте production-сайт и дождитесь автоматической загрузки первого сценария.
- Убедитесь, что показаны три карточки с ценой, доступностью, объяснением и портфолио.
- Выберите «02 · Другая дата» и проверьте, что состав тройки меняется, а интерфейс объясняет замену.
- Выберите «04 · Бюджет не проходит» и проверьте состояние
no_matchс причинами исключения. - Выберите «05 · Нет категории» и проверьте отдельное состояние
no_category. - Поставьте оценку
1★–5★демонстрационной работе и убедитесь, что рейтинг обновился сразу. - Откройте сайт на телефоне или уменьшите окно до 390 px: форма, сценарии и карточки должны помещаться без горизонтальной прокрутки.
- Для полной локальной проверки запустите
python -m unittest discover -s tests -vиpython tools/audit_data.py --include-synthetic --markdown.
Все ручные запросы доступны кнопками над результатами:
| Сценарий | Параметры | Ожидаемое поведение |
|---|---|---|
| 01 · Осенний корпоратив | Алматы, ведущий, корпоратив, 04.10.2026, 1 500 000 ₸, 4 ч, русский; пожелания «интеллигентный юмор импровизация» | 4 подходящих профиля, показаны 3; ранжирование реально выбирает из большего пула |
| 02 · Другая дата | Тот же запрос, 01.10.2026 | Прошлая тройка занята; выдача меняется, причины видны над карточками |
| 03 · Редкая категория | Алматы, флорист, свадьба, 02.10.2026, 500 000 ₸, 8 ч | 1 карточка с объяснением, почему меньше трёх; max_hours=null не исключает флориста |
| 04 · Бюджет не проходит | Запрос 01, бюджет 10 000 ₸ | Кандидаты есть, но подходящих нет; перечислены причины |
| 05 · Нет категории | Зарубежье, флорист | Отдельное состояние отсутствующей категории |
| 06 · Банкетный зал | Алматы, корпоратив, 14.11.2026, 7 000 000 ₸ | Площадки проходят тот же календарь и фильтры |
Повторите запрос — порядок не изменится. Сравнение дат использует предыдущий успешный запрос с теми же остальными параметрами.
Технологии и архитектура
Backend: Python и стандартная библиотека (http.server, sqlite3, csv, json, unittest). Frontend: HTML, CSS, JavaScript без сборщика. Данные: CSV как seed-источник и SQLite во время работы. Подбор выполняется локально прозрачным детерминированным алгоритмом.
Браузер → POST /api/v1/recommendations → валидация
→ выбор города/категории → жёсткие фильтры
→ лексическое ранжирование → top-3 + факты + портфолио + аудит
| Компонент | Назначение |
|---|---|
app.py | Точка запуска HTTP-сервера и обратная совместимость API |
back/ | SQLite, репозиторий, REST API, фильтры, ранжирование, портфолио и оценки |
web/ | Форма, 3D-карточки, портфолио, рейтинги и адаптивный дизайн |
data/contractors.csv | Runtime-каталог на 200 профилей и 30 категорий; исходные 66 сохранены |
data/contractors.xlsx | Excel-копия расширенного каталога с фильтрами и закреплённой строкой |
data/synthetic_profiles.csv | Отдельный аудит-артефакт с 12 профилями команды, не добавляемый повторно в runtime |
tests/test_app.py | Исходный алгоритм подбора, правила фильтрации, детерминизм и демосценарии |
tests/test_backend.py | SQLite, портфолио, оценки и HTTP-контракты API v1 |
docs/ | Исходное задание, превью, инструкция, речь и текст для сдачи |
start.ps1 | Запуск на Windows |
Как принимается решение
- Проверяются обязательные поля, положительные бюджет и часы, известные форматы/языки и календарная дата. Вне 23.09–31.12.2026 запрос отклоняется: отсутствие данных нельзя считать свободным днём.
- Выбирается пул по точному городу и наличию категории в массиве. Упоминание поездок в описании не расширяет географию автоматически.
- Исключаются занятые, превышающие бюджет по цене «от», не берущие формат, не поддерживающие указанный язык или часы.
max_hours=nullозначает отсутствие привязки к присутствию. Все заданные условия применяются последовательно. - Пожелания разбиваются на слова;
ёзаменяется нае, короткие и служебные слова удаляются. Первые 6 букв используются для приблизительного сопоставления форм. Балл — суммаln(1 + N/(1 + df))по уникальным совпавшим основам, где N — размер загруженного каталога, df — число описаний с основой. Редкие совпадения весят больше. Затем меньшая цена, затем строковый ID. Суммирование идёт в отсортированном порядке. Случайности нет. - Первое предложение объяснения перечисляет выполненные условия. Затем идёт точная цитата из описания с наибольшим количеством текстовых совпадений, до 240 символов. Полный источник можно раскрыть.
- Возвращаются карточки и аудит исключений. Счётчики причин могут пересекаться: один профиль может одновременно быть занят и превышать бюджет.
Ранжирование детерминировано и проверяемо: пожелания используются как мягкий лексический сигнал, а в деталях карточки доступны численный балл и совпавшие основы слов.
API
GET /api/v1/meta — варианты полей, статистика, границы календаря и готовые запросы.
POST /api/v1/recommendations, Content-Type: application/json:
{
"city": "Алматы",
"date": "2026-10-04",
"event_format": "корпоратив",
"category": "Ведущий",
"budget": 1500000,
"hours": 4,
"language": "русский",
"preferences": "интеллигентный юмор импровизация"
}
Ответ: status (matched, no_category, no_match), message, cards (0–3), pool_count, eligible_count, rejected, exclusion_counts, elapsed_ms. Ошибка входных данных — HTTP 400 с error. Пустая выдача — штатный HTTP 200. Время измеряет серверный подбор, не сетевую задержку.
Полный контракт API, включая каталог, карточки подрядчиков, календарь, портфолио, оценки и OpenAPI, описан в docs/backend-api.ru.md.
В runtime-каталоге 200 профилей по 30 категориям, включая 147 синтетических. Исходные 66 записей сохранены без изменений; ещё 134 демонстрационные записи добавляют 13 категорий. Синтетические записи имеют synthetic=True, а подготовленные цены — price_imputed=True. Отдельный файл data/synthetic_profiles.csv сохраняется для аудита и не добавляется повторно.
Данные, источники и внешние сервисы
В исходном CSV и HTML-превью — 66 профилей организаторов. Расширенный runtime-каталог находится в data/contractors.csv; его локальная Excel-копия — в data/contractors.xlsx.
Подбор полностью локальный и не требует API-ключей. Для фирменной типографики браузер загружает Manrope через Google Fonts, а системный шрифт используется как автоматический fallback.
Проверки
Всего 17 автоматических тестов:
- 10 тестов исходного алгоритма: целостность датасета; 100 дней × 30 категорий; детерминизм; три состояния ответа; смена даты; граничный бюджет;
null-часы; дополнительные фильтры; неверные запросы; достоверность объяснений и быстродействие; - 7 backend-тестов: миграции и идемпотентный импорт SQLite; фильтры и календарь; сохранность портфолио при синхронизации; обновление оценки без дубля; рейтинг работ; HTTP-контракты; OpenAPI и обработка ошибок.
Контрольный запуск 23 сентября 2026: 17/17 тестов прошли со статусом OK примерно за 1,1 с. Аудит данных также завершился со статусом PASS: 212 проверенных записей с учётом отдельного synthetic-файла, 30 категорий, 8 008 записей занятости, ошибок нет. Production API обработал шесть демосценариев за 0,10–2,78 мс серверного времени.
Персональные чек-листы команды
| Участник | Зона ответственности | Чек-лист |
|---|---|---|
| Темирлан Досмухамбетов | Frontend, адаптивный интерфейс, 3D-карточки, портфолио и пользовательские сценарии | README Темирлана |
| Мирас Ринатулы | SQLite-бэкенд, API v1, фильтрация, ранжирование, портфолио и оценки | README Мираса |
| Айназ Абитай | Данные, аудит, тестовые сценарии, документация и воспроизводимость | README Айназ |
Дополнительные рабочие чек-листы: frontend, backend, данные и аудит.
Сдача на платформе
Инструкция требует разместить итоговый код в выданном командном GitHub-репозитории, затем выбрать кейс и нажать «Сдать решение». Готовые название и описание находятся в docs/submission.md. Публичный deployment не обязателен; ссылку на него указывают, только если он существует. Активация сторонних API не нужна текущей реализации и не выполняется проектом.
Англоязычная техническая спецификация: Rio Technical Specification.
Авторы коммитов
История коммитов
- 2026-09-23 17:38Update README.mdTemirlan
- 2026-09-23 17:33docs: finalize project readme and team checklistsJkooked
- 2026-09-23 17:29docs: polish project and participant readmesJkooked
- 2026-09-23 17:21Update README.temirlan.mdAinaz Abitay
- 2026-09-23 17:20docs: publish podium production demoTeacher
- 2026-09-23 17:16feat: add ranked podium and catalog searchTeacher
- 2026-09-23 16:56docs: point submission to final production demoTeacher
- 2026-09-23 16:51fix: include timing in serverless recommendationsTeacher
Все коммиты (43)
- 2026-09-23 16:45feat: integrate database backend and portfolio experienceTeacher
- 2026-09-23 16:22feat: add database-backed portfolio and ratings APIмирас
- 2026-09-23 16:21Standardize participant README templatesJkooked
- 2026-09-23 16:19Add checklists for all participantsJkooked
- 2026-09-23 16:18Update README.mdAinaz Abitay
- 2026-09-23 16:16Add Miras backend READMEJkooked
- 2026-09-23 16:14Translate participant three audit guide to RussianJkooked
- 2026-09-23 16:13Add Temirlan frontend READMEJkooked
- 2026-09-23 16:09Add Russian participant guides and jury defense materialsJkooked
- 2026-09-23 16:08feat: update frontendTeacher
- 2026-09-23 16:00Strengthen jury-focused README documentationJkooked
- 2026-09-23 15:57Document contributions of all three participantsJkooked
- 2026-09-23 15:53Document team roles and Rio screenshotsJkooked
- 2026-09-23 15:53Link live Rio demo in documentationJkooked
- 2026-09-23 15:46fix(vercel): include Python function data filesTeacher
- 2026-09-23 15:41Resolve README conflict in RussianJkooked
- 2026-09-23 15:41Make main README Russian and document participant threeJkooked
- 2026-09-23 15:39Document expanded catalog and data auditJkooked
- 2026-09-23 15:33feat(web): add light responsive Rio experienceTeacher
- 2026-09-23 15:25Merge remote-tracking branch 'origin/main'мирас
- 2026-09-23 15:22Merge remote-tracking branch 'origin/main'мирас
- 2026-09-23 15:21Expand runtime catalog with labelled synthetic profilesJkooked
- 2026-09-23 15:15Expand contractor catalog to 200 profiles and 30 categoriesмирас
- 2026-09-23 15:12Add catalog audit for participant threeJkooked
- 2026-09-23 15:09Add participant 3 data audit checklistJkooked
- 2026-09-23 15:02Restore Rio project with English documentation and Russian interfaceмирас
- 2026-09-23 14:07Delete start.ps1Miras123456
- 2026-09-23 14:07Delete app.pyMiras123456
- 2026-09-23 14:07Delete README.mdMiras123456
- 2026-09-23 14:07Delete .gitignoreMiras123456
- 2026-09-23 14:07Delete tests directoryMiras123456
- 2026-09-23 14:06Delete docs directoryMiras123456
- 2026-09-23 14:06Delete data directoryMiras123456
- 2026-09-23 14:06Delete web directoryMiras123456
- 2026-09-23 13:48Build Rio contractor recommendations with deterministic ranking and demosмирас
Структура репозитория (48 файлов)
.gitignore README.md api/meta.py api/recommend.py api/v1.py app.py back/README.md back/__init__.py back/catalog.py back/database.py back/demo.py back/http.py back/migrations/001_initial.sql back/migrations/002_portfolio_and_ratings.sql back/recommendations.py back/repository.py data/contractors.csv data/contractors.xlsx data/synthetic_profiles.csv docs/README.ainaz.md docs/README.miras.md docs/README.ru.md docs/README.temirlan.md docs/Rio_Technical_Specification_EN.md docs/backend-api.ru.md docs/backend-guide.md docs/brief.en.md docs/brief.md docs/dataset-preview.html docs/openapi.json docs/participant-instructions.en.md docs/participant-instructions.pdf docs/participant-instructions.txt docs/participant1-frontend.md docs/participant2-backend.md docs/participant3-data-audit.md docs/pitch.md docs/screenshots/README.md docs/screenshots/rio-ui-reference.png docs/submission.md start.ps1 tests/test_app.py tests/test_backend.py tools/audit_data.py vercel.json web/app.js web/index.html web/style.css
Ветки (2)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.