AAYMA
RU
Войти

AlemEdu

Площадка, где заказчик описывает проблему, уточняет её с AI-помощником и публикует структурированную задачу, а студенческие команды откликаются.

Доведённый продукт
Команда «1465» 14💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: 1465
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Доведённый продукт

Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд

Суть

Площадка, где заказчик описывает проблему, уточняет её с AI-помощником и публикует структурированную задачу, а студенческие команды откликаются. Заказчик вручную выбирает или отклоняет отклики.

Как устроено

Backend на Laravel (TaskEditor, TaskScorer) пересчитывает полноту описания 0–100 с разбивкой по критериям. AiQuestions генерирует 3–7 уточняющих вопросов через OpenAI Responses API с JSON Schema, в автономном режиме работает MockAiQuestions. Сущности Task / Team / Offer хранятся в SQLite. Фронтенд на Vue 3 отдаётся тем же сервером. Статус задачи не зависит от рейтинга, AI не назначает исполнителя.

Ключевые решения

  • Structured Outputs / JSON Schema
  • прозрачный скоринг полноты
  • детерминированный mock-режим AI
  • e2e-тесты Playwright

Особенности

Жюри получает рабочую демоверсию через Cloudflare Tunnel и запуск одной командой START.cmd. AI-режим (openai/mock/auto) явно помечен в интерфейсе, при ошибке OpenAI ответ не подменяется заглушкой молча. Открыто сказано, что Codex использовался для разработки.

Стек

PHP · Laravel 12 · SQLite · Vue 3 · Vite · Docker Compose · Render · Cloudflare Tunnel · PHPUnit · Vitest · Playwright

Модели

gpt-5.4-mini


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-c8a98f95-1465.

README

README.md

AlemEdu

Площадка образовательных задач для организаций и студенческих команд. Прототип для HackAlem AI.

Открыть сайт для жюри · Показ до 5 минут · Памятка жюри

Репозиторий: BAITC-Hacks/hack-c8a98f95-1465. Итоговая версия находится в ветке main.

Ссылка выше ведёт на работающую демоверсию через временный HTTPS-туннель. Компьютер организатора должен оставаться включённым и онлайн. На публичном показе используется явно обозначенный AI-деморежим, а не ответы внешней модели.

Краткое описание

Учебным организациям нужно понятно формулировать реальные потребности, а студенческим командам нужны задачи для практики. AlemEdu соединяет эти стороны: заказчик описывает проблему, уточняет её с помощником, публикует задачу и рассматривает предложения команд.

Проект предназначен для школ, колледжей, университетов и команд разработчиков. Рейтинг показывает полноту подтверждённого описания, а не качество будущего решения. Выбор исполнителя всегда остаётся за заказчиком.

Что реализовано

  • Создание и редактирование черновиков, подтверждение сведений и отдельное действие публикации.
  • Карточки с учреждением, регионом, охватом, категорией и готовностью описания.
  • Каталог опубликованных задач с поиском, фильтрами и сортировкой.
  • Прозрачная оценка полноты описания от 0 до 100 с разбивкой по критериям.
  • AI-помощник: 3–7 уточняющих вопросов; подключение OpenAI и отдельный автономный деморежим.
  • Отклики команд: идея, план, сроки и необязательная ссылка на прототип.
  • Панель заказчика со списком откликов, фильтрами и кнопками «Выбрать» / «Отклонить», отправляющими решение в API.
  • Кабинеты заказчика и команды; решения сохраняются после перезагрузки.
  • Проверки прав выбранного демопрофиля, валидация запросов, состояния загрузки, ошибки и повтор запросов.
  • Адаптивный интерфейс, синтетические демоданные, автоматические тесты и единый запуск сайта с API.

Правила, важные для кейса

Task.status принимает только draft или published и не зависит от рейтинга. Можно опубликовать задачу с 0 баллов, если заполнены необходимые основные реквизиты и заказчик подтвердил публикацию.

Охват institution означает задачу для своего учреждения, но не закрывает её от других команд. После публикации они тоже видят задачу и могут откликнуться.

Решение по отклику: pending, selected или rejected. Можно выбрать несколько команд и пересмотреть решение. Другие отклики не отклоняются автоматически. AI и рейтинг не назначают исполнителя.

Как работает решение

  1. Заказчик вводит название и описание проблемы, сохраняет черновик.
  2. Помощник предлагает уточняющие вопросы. Заказчик самостоятельно дополняет поля и подтверждает проверенные сведения.
  3. Backend пересчитывает полноту описания; заказчик отдельно подтверждает публикацию.
  4. Задача появляется в каталоге. Команда изучает её и отправляет предложение.
  5. Заказчик рассматривает отклики и вручную выбирает или отклоняет команды.
  6. Решение сохраняется через API и отображается в кабинете команды.

Вход: описание образовательной потребности и сведения заказчика.

Результат: опубликованная структурированная задача, предложения команд и сохранённое решение заказчика.

Технологии

ЧастьИспользуется
ИнтерфейсJavaScript, Vue 3, Vue Router, Vite, Axios, CSS, иконки @lucide/vue
BackendPHP 8.2+, Laravel 12, Eloquent, JSON REST API
ХранениеSQLite, миграции и сидеры Laravel
AIOpenAI Responses API, JSON Schema / Structured Outputs; модель по умолчанию gpt-5.4-mini, настраивается через OPENAI_MODEL
Автономный режимЛокальный детерминированный генератор вопросов
ТестированиеPHPUnit, Laravel Pint, Vitest, Vue Test Utils, Playwright
Запуск и размещениеPowerShell, Docker Compose, PHP/Apache в контейнере, конфигурация Render, Cloudflare Tunnel для текущего показа
РазработкаAI-агент Codex использовался для реализации, интеграции, тестов и документации

NVIDIA API, CUDA и GPU-инференс в текущей реализации не используются. Обучения собственной модели нет.

Архитектура проекта

Браузер: Vue
    |
    | HTTP JSON /api
    v
Laravel: проверка роли и входных данных
    |
    +-- TaskEditor / TaskScorer --> SQLite: Task, Team, Offer
    |
    +-- AiQuestions --> OpenAiQuestions --> OpenAI Responses API
                   \-> MockAiQuestions: автономный режим

В едином запуске Laravel отдаёт собранный frontend, а браузер обращается к API на том же домене. Отдельные адреса frontend/backend и настройка CORS жюри не нужны.

ПутьНазначение
frontend/src/views/Каталог, редактор, карточка задачи, кабинеты и панель откликов
frontend/src/lib/api.jsОбращения к backend и обработка ошибок
backend/routes/api.phpМаршруты JSON API
backend/routes/web.phpВыдача frontend и поддержка прямых ссылок
backend/app/Services/Рейтинг, публикация и AI-помощник
backend/resources/prompts/task-questions.txtГотовый промпт для OpenAI
backend/database/Миграции и синтетические демоданные
backend/tests/, frontend/e2e/Автоматические проверки
start.ps1, START.cmdЕдиный запуск на Windows
Dockerfile, compose.yaml, render.yaml, deploy/Контейнер и конфигурация размещения

Основные сущности: Task хранит задачу и полноту её описания; Team хранит команду и компетенции; Offer связывает задачу с командой и хранит предложение и решение. Полный состав полей и API описан в контракте.

Установка и запуск

Самый быстрый способ для жюри

Откройте демоверсию в браузере. Установка и регистрация не нужны: роль выбирается через демопрофиль в меню.

Windows: один запуск

Требуются Node.js 22.12+, npm, PHP 8.2+ и Composer 2. PHP-расширения: pdo_sqlite, mbstring, openssl, fileinfo, dom, xml, xmlwriter; curl и zip рекомендуются для установки зависимостей. Для первой установки нужен интернет.

git clone https://github.com/BAITC-Hacks/hack-c8a98f95-1465.git
cd hack-c8a98f95-1465
.\START.cmd

Если проект уже скачан, достаточно дважды нажать START.cmd. При закрытом репозитории для клонирования нужен доступ GitHub.

Скрипт находит PHP в PATH, локальной папке AlemEdu или XAMPP, при необходимости устанавливает зависимости, подготавливает SQLite и демоданные, собирает frontend и запускает один сервер.

Сайт: http://127.0.0.1:8080. Проверка API: http://127.0.0.1:8080/api/health. Оставьте терминал открытым; остановка через Ctrl+C. Обычный повторный запуск не сбрасывает базу.

Если порт занят:

powershell -NoProfile -ExecutionPolicy Bypass -File .\start.ps1 -Port 8085

Для отдельной демонстрационной базы и AI без внешних запросов:

powershell -NoProfile -ExecutionPolicy Bypass -File .\start.ps1 -Demo

Этот режим использует .run/jury.sqlite, не рабочую базу backend.

Linux / macOS

С теми же зависимостями, из корня репозитория:

cd backend
composer install
composer setup
cd ../frontend
npm ci
VITE_API_URL=/api npm run build:unified
cd ../backend
php artisan serve --host=127.0.0.1 --port=8080 --no-reload

Откройте http://127.0.0.1:8080. Режим разработки с Vite описан в frontend/README.md и backend/README.md.

Docker

Подготовлен единый контейнер; отдельно устанавливать PHP, Node.js и Composer не требуется:

docker compose up --build -d
docker compose logs --tail 50 app

Адрес: http://localhost:8080. SQLite и ключ приложения сохраняются в volume alemedu-data. Остановка без удаления данных:

docker compose down

Не используйте down -v для обычной остановки: этот параметр удаляет volume с базой. Контейнерная сборка пока не подтверждена запуском: локально Docker отсутствовал, а GitHub Actions не предоставил runner из-за ограничения аккаунта. Проверены единый Windows-запуск и опубликованная версия.

Подключение настоящего OpenAI

Не требуется для запуска демо. Из backend/:

php artisan ai:configure
php artisan ai:check

На Windows без PHP в PATH используйте & C:\xampp\php\php.exe вместо php.

Первая команда запрашивает ключ скрыто и сохраняет его в локальный backend/.env. Вторая отправляет один платный запрос с синтетическим описанием. После настройки перезапустите backend.

Режимы: auto выбирает OpenAI при наличии ключа, иначе демо; openai требует рабочий API; mock не обращается к внешним сервисам. При ошибке OpenAI ответ не подменяется заглушкой. Полная настройка и промпт.

Не публикуйте API-ключи в GitHub и не помещайте их в VITE_*. Файлы .env исключены из Git и Docker-контекста. Для публичного доступа с платным ключом сначала нужна настоящая защита доступа.

Как проверить решение

Полный сценарий для жюри

  1. Откройте сайт, выберите «Демо-заказчик 1», затем «Создать задачу».
  2. Название: «Разговорная практика первокурсников». Организация: оставить из профиля. Регион: Алматы. Тема: Языки. Охват: Одно учреждение.
  3. Описание: «Первокурсникам не хватает регулярной разговорной практики английского. Нужен простой тренажёр для занятий в парах».
  4. Сохраните черновик. Убедитесь, что появились уточняющие вопросы и отметка текущего AI-режима. Остальные содержательные поля можно оставить пустыми.
  5. Подтвердите публикацию. Ожидаемый результат: задача доступна в каталоге с низким рейтингом, который не блокирует публикацию.
  6. Переключитесь на Qadam из другого учреждения. Откройте задачу и отправьте отклик: идея «Веб-тренажёр парных диалогов», план «Уточнение сценария, прототип, тестирование», сроки «Три недели».
  7. Вернитесь к заказчику: «Мой кабинет» → отклики новой задачи → «Выбрать». Обновите страницу: решение должно сохраниться.
  8. Переключитесь на Qadam и откройте кабинет команды: ожидаемый статус отклика «Команда выбрана».
  9. Для проверки отклонения откройте от заказчика задачу «Расписание консультаций» (/tasks/2/offers), отклоните один из готовых откликов и обновите страницу.

Так проверяется полный путь: входные данные → публикация → доступ команды другого учреждения → отклик → решение заказчика. Сценарий показа на 4:45.

Автоматические проверки

Из backend/:

php artisan test
php vendor/bin/pint --test
composer validate --strict

Из frontend/:

npm test
npm run build
npx playwright install chromium
npm run test:e2e

На Windows допустимы npm.cmd и npx.cmd. По умолчанию Playwright запускает отдельный API на 18082, сайт на 5174 и временную SQLite, не меняя рабочую базу. Нужны установленные backend-зависимости и PHP; XAMPP находится автоматически, другой путь задаётся через E2E_PHP.

Тесты охватывают рейтинг и публикацию, права демопрофилей, каталог, отклики, решения, ошибки API, AI-контракт и адаптивность. Внешние AI-запросы имитируются: тесты не расходуют OpenAI-квоту. Браузерный отчёт создаётся в frontend/playwright-report/.

Данные и интеграции

Используются синтетические данные, включённые в репозиторий: исходные описания и сидер. Персональных данных реальных студентов в демонаборе нет. Упомянутые в описаниях CSV, планы корпусов и прототипы являются содержанием демонстрационных задач, а не реализованными внешними интеграциями.

На новой базе: 2 заказчика, 5 команд, 5 задач и 5 откликов.

IDЗадачаСтатусБаллы
1Разговорный английскийdraft20
2Расписание консультацийpublished60
3Поиск учебных книгpublished75
4Обратная связь по занятиямpublished90
5Навигация по кампусуpublished100

Команды: Steppe Coders, Qadam, Bilim Lab, Orken, Campus Makers. Qadam и Orken относятся к демо-колледжу «Самғау», остальные к демо-университету «Алем».

  • OpenAI: необязательная внешняя интеграция для уточняющих вопросов. Поле contact не отправляется модели; произвольный текст остальных полей автоматически не обезличивается.
  • Cloudflare Tunnel: HTTPS-доступ к текущей демоверсии.
  • GitHub: исходный код и конфигурации проверок.
  • Render: подготовлена конфигурация размещения, но постоянный сервис не развёрнут.
  • NVIDIA: интеграция в коде отсутствует.

Дополнительная документация: API и модели, REST-примеры, AI, размещение.

Известные ограничения

  • Демопрофили заменяют регистрацию и реальную аутентификацию. Проверка роли по демонстрационным заголовкам не является защитой для production.
  • На публичном показе и в Docker по умолчанию AI_PROVIDER=mock. Настоящее подключение требует ключа, доступа к модели, сети и квоты API; реальный ответ OpenAI не подтверждён текущими автоматическими тестами.
  • AI предлагает вопросы, а не готовое решение образовательной задачи. Он не редактирует карточку автоматически, не выставляет рейтинг и не выбирает команду.
  • Нет интеграции с информационными системами учреждений, загрузки файлов, чата, почтовых уведомлений и платежей.
  • SQLite и демонстрационный сервер не проверялись под промышленной нагрузкой. Демоданные общие: действия посетителей видны другим участникам показа.
  • Временная публичная ссылка перестанет работать при остановке сервера/туннеля или отключении компьютера.
  • Docker/Render-конфигурация подготовлена, но успешная контейнерная сборка не подтверждена. Наличие workflow в GitHub не означает, что облачные проверки прошли.

Развёрнутая версия

https://minute-wifi-reserves-throughout.trycloudflare.com

Это текущий доступный показ через временный туннель, а не постоянный независимый хостинг. Локальный запасной адрес после START.cmd: http://127.0.0.1:8080.

Для отдельного облачного сервиса подготовлена кнопка Deploy to Render. Нужны аккаунт, доступ Render к репозиторию и подтверждение деплоя. Конфигурация бесплатного демосервиса не включает постоянный диск; не рассчитывайте на сохранность пользовательских изменений SQLite после перезапуска. Подробности в инструкции размещения.

Звёзды
⭐ 0
Форки
0
Язык
Vue
Последний push
в прошлом месяце
Коммиты
8
Авторы
3
Файлы
150
Ветки
3

Авторы коммитов

Codex 4Yerassyl88 2Sabokanms 2

История коммитов

  • 2026-09-23 17:51Document HackAlem AI submission criteria for juryCodex
  • 2026-09-23 17:42Simplify jury launch and add single-container deploymentCodex
  • 2026-09-23 17:32Integrate OpenAI task assistant with secure setup and testsCodex
  • 2026-09-23 17:13Complete customer decisions and integrated demo workflowCodex
  • 2026-09-23 16:28Redesign frontend with guided SaaS experience for customers and teamsYerassyl88
  • 2026-09-23 16:05Add Vue frontend with API-connected task and team workflowsYerassyl88
  • 2026-09-23 15:19Document Windows startup with process-scoped script executionSabokanms
  • 2026-09-23 15:17Implement AlemEdu Laravel backend API and demo workflowSabokanms
Структура репозитория (150 файлов)
.dockerignore
.gitattributes
.github/workflows/backend.yml
.github/workflows/deploy-check.yml
.github/workflows/frontend.yml
.gitignore
Dockerfile
README.md
START.cmd
backend/.editorconfig
backend/.env.example
backend/.gitattributes
backend/.gitignore
backend/README.md
backend/app/Console/Commands/CheckAi.php
backend/app/Console/Commands/ConfigureAi.php
backend/app/Exceptions/AiUnavailable.php
backend/app/Http/Controllers/AiController.php
backend/app/Http/Controllers/Controller.php
backend/app/Http/Controllers/DemoController.php
backend/app/Http/Controllers/OfferController.php
backend/app/Http/Controllers/TaskController.php
backend/app/Http/Middleware/DemoIdentity.php
backend/app/Http/Middleware/JsonInput.php
backend/app/Http/Requests/TaskWriteRequest.php
backend/app/Http/Resources/OfferResource.php
backend/app/Http/Resources/TaskResource.php
backend/app/Http/Resources/TeamResource.php
backend/app/Models/Offer.php
backend/app/Models/Task.php
backend/app/Models/Team.php
backend/app/Providers/AppServiceProvider.php
backend/app/Services/AiQuestions.php
backend/app/Services/MockAiQuestions.php
backend/app/Services/OpenAiQuestions.php
backend/app/Services/TaskEditor.php
backend/app/Services/TaskScorer.php
backend/artisan
backend/bootstrap/app.php
backend/bootstrap/cache/.gitignore
backend/bootstrap/providers.php
backend/composer.json
backend/composer.lock
backend/config/ai.php
backend/config/app.php
backend/config/auth.php
backend/config/cache.php
backend/config/cors.php
backend/config/database.php
backend/config/demo.php
backend/config/filesystems.php
backend/config/logging.php
backend/config/mail.php
backend/config/queue.php
backend/config/services.php
backend/config/session.php
backend/database/.gitignore
backend/database/migrations/2026_09_23_000001_create_alemedu_tables.php
backend/database/seeders/DatabaseSeeder.php
backend/database/seeders/DemoSeeder.php
backend/database/seeders/data/briefs.json
backend/docs/AI.md
backend/docs/API.md
backend/docs/alemedu.http
backend/docs/examples/ai-questions.json
backend/docs/examples/decision.json
backend/docs/examples/offer-create.json
backend/docs/examples/publish.json
backend/docs/examples/task-create.json
backend/docs/examples/task-response.json
backend/docs/examples/task-update.json
backend/lang/ru/validation.php
backend/phpunit.xml
backend/public/.htaccess
backend/public/favicon.ico
backend/public/index.php
backend/public/robots.txt
backend/resources/prompts/task-questions.txt
backend/routes/api.php
backend/routes/web.php
backend/scripts/prepare.php
backend/scripts/smoke.php
backend/start.ps1
backend/storage/app/.gitignore
backend/storage/app/private/.gitignore
backend/storage/app/public/.gitignore
backend/storage/framework/.gitignore
backend/storage/framework/cache/.gitignore
backend/storage/framework/cache/data/.gitignore
backend/storage/framework/sessions/.gitignore
backend/storage/framework/testing/.gitignore
backend/storage/framework/views/.gitignore
backend/storage/logs/.gitignore
backend/tests/Feature/ApiTest.php
backend/tests/Feature/ConfigureAiTest.php
backend/tests/Feature/OpenAiTest.php
backend/tests/Feature/SingleServerTest.php
backend/tests/TestCase.php
backend/tests/Unit/TaskScorerTest.php
compose.yaml
deploy/apache.conf
deploy/container-prepare.php
deploy/entrypoint.sh
deploy/php.ini
deploy/ports.conf
docs/DEMO.md
docs/DEPLOY.md
docs/JURY.md
frontend/.env.example
frontend/.gitignore
frontend/.gitkeep
frontend/README.md
frontend/e2e/ai.spec.js
frontend/e2e/catalogue.spec.js
frontend/e2e/decisions.spec.js
frontend/e2e/flow.spec.js
frontend/e2e/onboarding.spec.js
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/playwright.config.js
frontend/public/favicon.svg
frontend/scripts/check-deployment.mjs
frontend/scripts/e2e-backend.mjs
frontend/src/App.vue
frontend/src/components/ApiError.vue
frontend/src/components/Icon.vue
frontend/src/components/ScorePanel.vue
frontend/src/components/TaskCard.vue
frontend/src/components/__tests__/ScorePanel.test.js
frontend/src/lib/__tests__/api.test.js
frontend/src/lib/api.js
frontend/src/lib/editorState.js
frontend/src/lib/fields.js
frontend/src/lib/session.js
frontend/src/main.js
frontend/src/router.js
frontend/src/style.css
frontend/src/views/CatalogView.vue
frontend/src/views/GuideView.vue
frontend/src/views/HomeView.vue
frontend/src/views/NotFoundView.vue
frontend/src/views/TaskDetailView.vue
frontend/src/views/TaskEditorView.vue
frontend/src/views/TaskOffersView.vue
frontend/src/views/WorkspaceView.vue
frontend/src/views/__tests__/TaskOffersView.test.js
frontend/vite.config.js
render.yaml
start.ps1
Ветки (3)

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.