EduVibe
Платформа, где AI задаёт бизнесу уточняющие вопросы, а бизнес редактирует и подтверждает карточку задачи с рейтингом готовности и публикует её.
О проекте
Команда: EduVibe
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Рабочий MVP
Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд
Суть
Платформа, где AI задаёт бизнесу уточняющие вопросы, а бизнес редактирует и подтверждает карточку задачи с рейтингом готовности и публикует её. Студенческие команды отправляют приватные отклики, бизнес вручную выбирает исполнителей.
Как устроено
Бэкенд на FastAPI с MySQL (SQLAlchemy 2, Alembic) и фронт на React+Vite, всё в Docker Compose. gpt-4.1-mini получает тему, описание и текущую карточку и возвращает JSON из 3–7 вопросов по пробелам. Сервер проверяет поля и отсекает дубли, при ошибке работает шаблонный фолбэк. Рейтинг — сумма весов непустых полей (0–100) с уровнями «черновик», «рабочая», «готовая», «приоритетная». Каталог сортируется по баллу, бизнес вручную выбирает команды и начисляет баллы за этап.
Ключевые решения
- валидация JSON-ответа LLM
- весовой рейтинг заполненности
- резервный режим без AI
- ролевой доступ и проверка владельца
Особенности
LLM не заполняет карточку выдуманными фактами, а только задаёт вопросы; ответы вводит сам пользователь. Формула рейтинга прозрачна. Опубликованная карточка версионируется: до повторного подтверждения студенты видят прежнюю версию.
Стек
Python · FastAPI · SQLAlchemy · Alembic · MySQL · React · TypeScript · Vite · Docker Compose · pytest
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-31e4e4c0-eduvibe.
README
README.mdEduVibe
MVP для кейса AI Sana «Рейтинг качества бизнес-задач и открытый выбор команд». Платформа помогает бизнесу превратить краткую потребность в понятное студентам ТЗ. AI задаёт уточняющие вопросы, бизнес редактирует и подтверждает карточку, а система рассчитывает её готовность и публикует в каталоге. Команды отправляют приватные предложения; бизнес вручную выбирает одну, несколько или ни одной команды.
Запуск
Нужны Git, Docker с Docker Compose и свободные порты 5173 и 8000.
git clone [email protected]:BAITC-Hacks/hack-31e4e4c0-eduvibe.git
cd hack-31e4e4c0-eduvibe
cp .env.example .env
# Укажите OPENAI_API_KEY в .env для вопросов от модели.
docker compose up --build -d
docker compose ps
curl http://localhost:5173/api/v1/health
- Приложение: http://localhost:5173
- API и схемы запросов: http://localhost:8000/docs
- Исправный health:
{"status":"ok","database":"ok"}.
Миграции и синтетические данные загружаются автоматически. Без ключа OpenAI вопросы работают в явно обозначенном резервном режиме.
Для доступа из той же локальной сети откройте http://IP_КОМПЬЮТЕРА:5173. Запросы к /api/v1 проходят через frontend к backend; менять адрес API не нужно.
Обновление: git pull, затем docker compose up --build -d. Данные MySQL сохраняются в volume. Остановка — docker compose down; добавление -v удалит данные.
Конфигурация
Все переменные и значения по умолчанию — в .env.example. Для обычного запуска достаточно добавить ключ; остальные настройки можно оставить без изменений.
| Настройка | Назначение |
|---|---|
OPENAI_API_KEY, OPENAI_MODEL | Ключ backend и модель; по умолчанию gpt-4.1-mini |
OPENAI_TIMEOUT_SECONDS, AI_FALLBACK_ENABLED | Таймаут 20 секунд; резервный режим включён |
MYSQL_* | База, пользователь и пароли MySQL |
DATABASE_URL | Подключение для локального backend; Compose формирует его из MYSQL_* |
VITE_API_URL | /api/v1; изменение требует пересборки frontend |
CORS_ORIGINS | Разрешённые origin для прямого доступа браузера к API |
Сценарий демонстрации
Пример для выступления до пяти минут:
- Войти как бизнес, создать тему «Доставка выпечки» и описание: «В пекарне диспетчер вручную распределяет доставки между курьерами. Адреса ведём в таблице, заказы опаздывают». Показать исходный рейтинг.
- Получить минимум три AI-вопроса. Ответить известными фактами: пользователи — диспетчер и пять курьеров; данные — 20 тестовых заказов; результат — веб-прототип распределения; критерий — распределить 20 заказов за пять минут.
- Перенести ответы в карточку, отредактировать, сохранить. Показать рост рейтинга, расшифровку и оставшиеся пробелы. Подтвердить и опубликовать.
- В отдельной вкладке войти как студенческая команда, найти кейс в каталоге и отправить идею решения, план, срок и ссылку, например
https://example.com/prototype. - Вернуться к бизнесу, обновить отклики и вручную выбрать или отклонить предложение. У студента обновить статусы.
- Для выбранной команды подтвердить выполненный этап и начислить баллы.
Бизнес может редактировать и удалять свои кейсы. До нового подтверждения студенты видят прежнюю опубликованную версию; после удаления у авторов сохраняется история откликов. Другие команды не видят чужие предложения.
Архитектура
Браузер → frontend: React + TypeScript + Vite (:5173)
↓ /api/v1
backend: FastAPI, Python 3.11 (:8000) → OpenAI API
↓ SQLAlchemy 2 / Alembic
db: MySQL 8.4
Три сервиса запускаются через docker-compose.yml.
- backend/app — API, схемы валидации, модели, бизнес-логика и AI-сервис.
- backend/migrations — миграции БД.
- frontend/src — интерфейс и API-клиент.
- backend/tests — автоматические проверки.
API использует префикс /api/v1 и JSON. После демонстрационного входа запросы передают Authorization: Bearer <token>. Доступ к изменениям кейса и списку его откликов проверяется на сервере по роли и владельцу. Полные схемы доступны в Swagger.
Рейтинг и каталог
Рейтинг — сумма весов непустых полей, от 0 до 100. Формула находится в rating.py.
| Поле | Баллы |
|---|---|
| Контекст | 10 |
| Потребность | 10 |
| Данные и материалы | 20 |
| Ожидаемый результат | 15 |
| Критерии успеха | 15 |
| Ограничения | 10 |
| Пользователи | 10 |
| Контакт бизнеса | 5 |
| Формат взаимодействия | 5 |
Название и тема в баллы не входят. До подтверждения показан предварительный расчёт; каталог использует последнюю подтверждённую карточку. Неизвестные сведения остаются пустыми. Интерфейс показывает баллы по каждому полю, недостающую информацию и рекомендации.
Уровни: 0–39 — черновик, 40–69 — рабочая, 70–89 — готовая, 90–100 — приоритетная.
Все опубликованные кейсы доступны всем командам, включая задачи с низким рейтингом. Каталог сортируется по убыванию баллов, при равенстве — по ID; доступны фильтры по теме и уровню готовности. Число откликов не ограничено. Автоматического назначения команды нет.
Рейтинг оценивает заполненность, а не достоверность текста. Командные баллы считаются отдельно: бизнес однократно назначает 1–100 баллов за подтверждённый этап выбранного отклика.
Демонстрационные данные
Синтетический набор находится в seed.py. На чистой базе создаются:
| Набор | Количество | Состав |
|---|---|---|
| Черновики | 5 | Описание, отрасль/тема, сведения разной полноты |
| Опубликованные карточки | 5 | Все поля карточки, рейтинг, разные уровни готовности |
| Команды | 5 | Название, интересы, навыки, технологии |
| Отклики | 5 | Команда, идея, план, срок, ссылка |
Пустое значение поля означает неизвестные сведения. Повторный запуск не дублирует набор. Ссылки на доменах example.com и example.test — демонстрационные.
AI
Промпт, вход и обработка ответа находятся в clarifications.py. Модель получает topic, initial_description и current_card — значения всех полей текущей карточки — и возвращает JSON:
{"questions":[
{"id":"q1","field":"users","text":"Кто будет пользоваться результатом?"},
{"id":"q2","field":"data_materials","text":"Какие данные доступны команде?"},
{"id":"q3","field":"success_criteria","text":"Как вы проверите успешность решения?"}
]}
Сервер проверяет 3–7 вопросов, допустимые и неповторяющиеся поля, непустой текст. Если пробелов меньше трёх, AI уточняет детали заполненных полей. Модель не заполняет карточку выдуманными фактами: ответы вводит пользователь, затем редактирует и подтверждает их.
ai_mode: live означает ответ модели; fallback — шаблонные вопросы при отсутствии ключа, таймауте, ошибке API или некорректном ответе. При AI_FALLBACK_ENABLED=false API возвращает контролируемую ошибку 502/503/504. Режим относится к последней генерации вопросов; для новой попытки обновите их в интерфейсе.
Описание и карточка передаются OpenAI. Используйте синтетические данные без секретов: автоматического удаления чувствительных сведений из текста нет.
Проверки
Из корня репозитория:
# Все backend-тесты; образ пересобирается из текущего кода.
docker compose run --build --rm --no-deps --entrypoint python backend -m pytest -q
# Только минимальные наборы данных и повторный запуск seed.
docker compose run --build --rm --no-deps --entrypoint python backend -m pytest tests/test_seed.py -v
# Сборка frontend, локально нужен Node.js 22.
npm --prefix frontend ci
npm --prefix frontend run build
# Диагностика работающего приложения.
curl http://localhost:5173/api/v1/health
docker compose logs --tail=100 backend
Тесты используют отдельную SQLite в памяти и не подключаются к рабочей MySQL. Проверяются сессии, роли и владение, приватность откликов, жизненный цикл кейса, рейтинг и каталог, решения бизнеса, однократное начисление баллов, валидация, ошибки AI и наборы данных. Ответы OpenAI в тестах имитируются; реальный вызов проверяется через интерфейс по ai_mode: live.
Для ручной проверки пройдите сценарий выше, затем отправьте отклики от двух команд, выберите несколько или отклоните все. Проверьте, что студент видит только свои отклики, неподтверждённые правки публикации скрыты, а удалённый кейс исчезает из каталога. Без ключа должен явно отображаться резервный режим.
Ограничения и материалы
Вход демонстрационный: любой посетитель может выбрать любой тестовый профиль. Проверка прав работает в пределах выбранной сессии; полноценной проверки личности нет. Регистрация, чат, загрузка файлов и полный проектный трекер в MVP не входят. Vite preview используется для демонстрации, промышленный деплой не заявляется.
Команда: Dexarim — backend, AI, БД, Docker и интеграция; B_l_a_c_kS_u_n — frontend и интерфейс.
Кейс предоставлен AI Sana; данные созданы командой. До старта были подготовлены контекстные шаблоны документации. При разработке использовался OpenAI Codex. Сторонние библиотеки и версии зафиксированы в requirements.txt и package-lock.json; инфраструктура использует Docker и MySQL.
Авторы коммитов
История коммитов
- 2026-09-23 17:57Merge remote-tracking branch 'origin/main'Dima Schmidt
- 2026-09-23 17:57Исправить запуск backend после Windows checkoutDima Schmidt
- 2026-09-23 17:38Update README.mdDima Schmidt
- 2026-09-23 17:33Проверить исходные данные, исправить seed и сократить READMEDima Schmidt
- 2026-09-23 17:19Подготовить v2: интегрировать интерфейс, закрыть сценарий ТЗ и очистить релизDima Schmidt
- 2026-09-23 16:56Объединить frontend v2 с backend и ролевой модельюDima Schmidt
- 2026-09-23 16:56Сохранить актуальную историю main в релизе v2Dima Schmidt
- 2026-09-23 16:56Сохранить локальные настройки перед интеграцией v2Dima Schmidt
Все коммиты (20)
- 2026-09-23 16:50feat: синхронизировать frontend с ролевым backend1BlackSun1
- 2026-09-23 16:17merge: обновить backend до v21BlackSun1
- 2026-09-23 16:11feat: добавить функциональную карту кейса1BlackSun1
- 2026-09-23 15:53Разделить кабинеты бизнеса и студентов и закрыть чужие откликиDima Schmidt
- 2026-09-23 15:40Merge pull request #1 from BAITC-Hacks/version-0.1Dima Schmidt
- 2026-09-23 15:19docs: подтвердить live AI и чистый запуск version 0.1Dima Schmidt
- 2026-09-23 15:09feat: интегрировать frontend и backend в version 0.1Dima Schmidt
- 2026-09-23 15:00merge: объединить backend и frontend в version 0.1Dima Schmidt
- 2026-09-23 14:56Front1BlackSun1
- 2026-09-23 14:54feat: add EduVibe frontend MVP1BlackSun1
- 2026-09-23 14:09docs: зафиксировать первый backend milestoneDima Schmidt
- 2026-09-23 14:09feat: реализовать backend MVP EduVibeDima Schmidt
Структура репозитория (57 файлов)
.env.example .gitattributes .github/workflows/release.yml .gitignore README.md backend/.dockerignore backend/Dockerfile backend/alembic.ini backend/app/__init__.py backend/app/api/__init__.py backend/app/api/routes.py backend/app/core/__init__.py backend/app/core/config.py backend/app/core/errors.py backend/app/db/__init__.py backend/app/db/base.py backend/app/db/session.py backend/app/main.py backend/app/models/__init__.py backend/app/models/entities.py backend/app/schemas/__init__.py backend/app/schemas/api.py backend/app/seed.py backend/app/services/__init__.py backend/app/services/access.py backend/app/services/ai/__init__.py backend/app/services/ai/clarifications.py backend/app/services/rating.py backend/app/services/tasks.py backend/entrypoint.sh backend/migrations/env.py backend/migrations/script.py.mako backend/migrations/versions/0001_initial.py backend/migrations/versions/0002_roles.py backend/requirements.txt backend/tests/conftest.py backend/tests/test_ai.py backend/tests/test_api.py backend/tests/test_seed.py docker-compose.yml frontend/.dockerignore frontend/.env.example frontend/.gitignore frontend/Dockerfile frontend/index.html frontend/package-lock.json frontend/package.json frontend/src/App.tsx frontend/src/CaseWorkspace.tsx frontend/src/Views.tsx frontend/src/api.ts frontend/src/main.tsx frontend/src/styles.css frontend/src/ui.ts frontend/src/vite-env.d.ts frontend/tsconfig.json frontend/vite.config.ts
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.