NEXA
Marketplace бизнес-задач для студентов: бизнес описывает потребность, получает три AI-вопроса и структурированную Task Card с рейтингом готовности…
О проекте
Команда: Nexa
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Рабочий MVP
Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд
Суть
Marketplace бизнес-задач для студентов: бизнес описывает потребность, получает три AI-вопроса и структурированную Task Card с рейтингом готовности 0–100, публикует её; студенты отправляют предложения, бизнес принимает или отклоняет.
Как устроено
OpenAI Chat Completions (gpt-4o-mini) по свободному описанию генерирует ровно три уточняющих вопроса и затем Task Card только из данных пользователя, ответ валидируется JSON Schema и Zod. Отдельный детерминированный Rating Engine считает баллы по 7 критериям, показывает потерянные баллы и рекомендации. Задачи, команды и предложения хранятся в Cloudflare D1 через Drizzle; при недоступности OpenAI срабатывает детерминированный fallback.
Ключевые решения
- structured output с Zod/JSON Schema
- детерминированный rating engine
- explainable breakdown потерянных баллов
- rule-based fallback
Особенности
Чёткое разделение: AI только структурирует текст, баллы ставит детерминированный движок с объяснением каждого потерянного балла; full-stack на Cloudflare Workers + D1.
Стек
TypeScript · React · Vinext · Vite · Tailwind CSS · Cloudflare Workers · Cloudflare D1 · Drizzle ORM · Zod · Vitest
Модели
gpt-4o-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-a7700864-nexa.
README
README.mdNEXA
BUSINESS × TALENT
Хорошо поставленная задача находит свою команду.
NEXA помогает бизнесу превратить первоначальное, часто неполное описание потребности в структурированную бизнес-задачу, оценить её готовность и разместить в открытом каталоге. Студенческие команды самостоятельно изучают каталог, выбирают интересные задачи и отправляют предложения. Финальное решение о выборе команды принимает бизнес.
Ключевой сценарий:
слабое описание → 3 AI-вопроса → структурированная карточка
→ рейтинг 0–100 → объяснение потерянных баллов → улучшение
→ публикация → Marketplace → предложение команды → решение бизнеса
Краткое описание
Бизнес может понимать свою проблему, но сформулировать её слишком кратко:
Хотим автоматизировать техподдержку.
Такого описания недостаточно, чтобы команда быстро поняла контекст, пользователей, доступные данные, ограничения, ожидаемый результат и критерии успеха. NEXA сокращает разрыв между бизнес-потребностью и постановкой задачи, пригодной для оценки и начала работы.
NEXA — marketplace практических бизнес-задач, а не биржа вакансий:
| Участник | Путь |
|---|---|
| Бизнес | идея → структурированная задача → рейтинг → публикация → предложения |
| Студент | каталог → задача → предложение решения |
| NEXA | OpenAI + прозрачный Rating Engine + D1 + Marketplace |
Что реализовано
- Home Page с выбором сценария «Бизнес» или «Студент»;
- ввод задачи свободным текстом;
- server-side интеграция OpenAI;
- ровно три контекстных уточняющих вопроса;
- структурированная Task Card без добавления неизвестных фактов;
- редактирование карточки человеком;
- детерминированный рейтинг готовности 0–100;
- breakdown по критериям, потерянные баллы и недостающая информация;
- конкретные рекомендации и пересчёт рейтинга после редактирования;
- отдельное подтверждение и публикация задачи;
- Marketplace опубликованных задач с сортировкой по рейтингу;
- фильтры по категории и уровню готовности;
- предложение решения от студенческой команды;
- ручные решения бизнеса
ACCEPTEDиREJECTED; - хранение задач, команд и предложений в Cloudflare D1;
- детерминированный fallback при недоступности OpenAI;
- синтетические demo-данные для быстрого показа проекта.
Как работает решение
- Бизнес нажимает «Разместить задачу» и описывает потребность обычными словами.
- OpenAI анализирует описание и задаёт ровно три релевантных вопроса.
- Бизнес отвечает, после чего AI формирует структурированную Task Card только из предоставленной информации.
- Пользователь проверяет и редактирует карточку.
- Rating Engine рассчитывает score 0–100 и показывает, что уже засчитано, чего не хватает и сколько баллов потеряно.
- После дополнения карточки рейтинг пересчитывается.
- Бизнес подтверждает и публикует задачу.
- Опубликованная задача появляется в Marketplace; более высокий score поднимает её выше в каталоге.
- Студент выбирает задачу и отправляет предложение с идеей, планом и сроком.
- Бизнес вручную принимает или отклоняет предложение.
AI не назначает команду и не принимает финальное решение.
Как устроен рейтинг
AI отвечает за понимание естественного языка и структурирование ввода. Итоговый score рассчитывает отдельный детерминированный Rating Engine. Поэтому одинаковая карточка получает одинаковую оценку, а происхождение каждого балла можно объяснить.
| Критерий | Максимум |
|---|---|
| Контекст и потребность | 20 |
| Данные и материалы | 20 |
| Ожидаемый результат | 15 |
| Критерии успеха | 15 |
| Ограничения | 10 |
| Пользователи | 10 |
| Связь с бизнесом | 10 |
| Итого | 100 |
| Баллы | Уровень |
|---|---|
| 0–39 | Черновик |
| 40–69 | Рабочая |
| 70–89 | Готовая |
| 90–100 | Приоритетная |
Каждый критерий получает состояние EMPTY, PARTIAL или COMPLETE. Для неполного критерия интерфейс показывает:
- что уже засчитано;
- чего не хватает;
- сколько баллов потеряно;
- что можно дополнить.
Пример работы механики, закреплённый тестами:
85 / 100 — ГОТОВАЯ
Данные и материалы 10 / 20 −10
Ограничения 5 / 10 −5
После дополнения:
85 → 100
+15 баллов
Конкретный score зависит от содержания карточки. Низкий рейтинг не скрывает опубликованную задачу, но Marketplace сортирует опубликованные задачи по score по убыванию.
Технологии
Версии взяты из web/package.json.
| Технология | Для чего используется |
|---|---|
| TypeScript 5.9.3 | Типизация UI, API и сервисов |
| React 19.2.6 | Пользовательский интерфейс |
| Vinext 1.0.0-beta.5 | Full-stack React runtime и API routes |
| Vite 8.0.13 | Dev server и production build |
| Tailwind CSS 4.2.1 | Стили и desktop-first интерфейс |
| Cloudflare Workers / Wrangler 4.92.0 | Server-side runtime и bindings |
| Cloudflare D1 / SQLite | Хранение задач, команд и предложений |
| Drizzle ORM 0.45.2 / Drizzle Kit 0.31.10 | Схема, запросы и SQL-миграции |
OpenAI Chat Completions API, gpt-4o-mini | Три вопроса и Structured Task Card |
| Zod 3.25.76 | Проверка API-ввода и AI Structured Output |
| Vitest 5.0.1 | Automated tests |
Архитектура проекта
NEXA реализована как full-stack modular monolith:
React / Vinext Web UI
↓
Server-side API routes
├── AI Service ─────────────→ OpenAI API
├── Rating Service
├── Task Service
├── Marketplace Service
└── Proposal Service
↓
Drizzle ORM
↓
Cloudflare D1
Разделение ответственности:
- AI Service понимает свободное описание, формирует три вопроса и структурирует предоставленную информацию. Системная инструкция требует не добавлять неизвестные сроки, данные, технологии, контакты или ограничения.
- Rating Service детерминированно рассчитывает score, breakdown, недостающую информацию, рекомендации и уровень готовности. AI не выставляет баллы.
- Task Service создаёт, обновляет, подтверждает и публикует задачи; score пересчитывается server-side.
- Marketplace Service выбирает только опубликованные задачи и сортирует их по score.
- Proposal Service связывает задачу с командой и обрабатывает ручное решение бизнеса.
- D1 хранит состояние задач, команд и предложений.
При отсутствии API key, сетевой ошибке или временной недоступности OpenAI включается более простой детерминированный fallback. Он сохраняет основной demo flow, а Rating Engine продолжает работать независимо от AI.
Установка и запуск
Требования:
- Node.js
>=22.13.0; - Git;
- OpenAI API key — опционально, без него работает fallback.
Проверенная последовательность для чистого клона:
git clone https://github.com/BAITC-Hacks/hack-a7700864-nexa.git
Set-Location hack-a7700864-nexa/web
npm ci
Copy-Item .dev.vars.example .dev.vars
npm run db:migrate:local
npm run dev
Для macOS/Linux используйте:
git clone https://github.com/BAITC-Hacks/hack-a7700864-nexa.git
cd hack-a7700864-nexa/web
npm ci
cp .dev.vars.example .dev.vars
npm run db:migrate:local
npm run dev
npm run db:migrate:local применяет ожидающие SQL-миграции из web/drizzle/ к локальной D1 в web/.wrangler/state. При первом открытии приложения запрос /api/bootstrap автоматически добавляет demo-данные, если база пуста.
Настройка OpenAI
Tracked-шаблон web/.dev.vars.example содержит:
OPENAI_API_KEY=
После копирования укажите собственный ключ в локальном web/.dev.vars:
OPENAI_API_KEY=<your_key>
Не добавляйте кавычки, пробелы или префикс Bearer. Файл web/.dev.vars игнорируется Git и не хранится в репозитории. После изменения переменной полностью перезапустите dev server.
Откройте Local URL, который выведет npm run dev. Типичный адрес при свободном стандартном порте — http://localhost:5173, но фактический порт может отличаться.
Как проверить решение за 3–5 минут
- Запустите приложение и откройте Home.
- Нажмите «Разместить задачу».
- Введите: «Хотим автоматизировать первую линию технической поддержки.»
- Получите ровно три уточняющих вопроса и ответьте на них.
- Проверьте сформированную Task Card.
- Посмотрите рейтинг, breakdown и объяснение потерянных баллов.
- Дополните слабые поля и нажмите «Сохранить и пересчитать».
- Убедитесь, что рейтинг изменился в соответствии с введёнными данными.
- Подтвердите карточку и опубликуйте задачу.
- Нажмите логотип NEXA, чтобы вернуться на Home.
- Нажмите «Найти задачу» и откройте опубликованную задачу в Marketplace.
- Отправьте предложение от команды.
- Переключитесь на роль «Бизнес».
- Откройте предложения и нажмите «Выбрать» или «Отклонить».
- Проверьте итоговый статус
ACCEPTEDилиREJECTED.
Конкретное значение рейтинга зависит от ответов и последующего редактирования.
Данные и интеграции
Внешняя интеграция проекта — OpenAI Chat Completions API. Запрос выполняется только server-side, а ответ проходит JSON Schema и Zod validation.
Cloudflare D1 хранит три связанные сущности:
- Task — описание, структурированные поля, score и статусы подтверждения/публикации;
- Team — название, интересы, навыки и технологии;
- Proposal — связь Task и Team, идея решения, план, срок, прототип и статус.
При первом запуске пустая база получает отслеживаемый в репозитории синтетический набор: 5 задач, 5 команд и 5 предложений. Это demo-данные, а не реальные компании или пользователи.
Проверки качества и безопасность
На момент финальной проверки: 15/15 automated tests passed.
npm test
npm run typecheck
npm run lint
npm run build
Также подтверждено:
- OpenAI API key используется только server-side;
web/.dev.varsисключён из Git;- API key не возвращается API и не попадает в client bundle;
- пользовательский ввод проверяется через Zod и очищается перед сохранением;
- AI Structured Output валидируется;
- рейтинг, подтверждение и публикация контролируются server-side.
Ограничения текущей версии
В рамках 5-часового MVP сознательно ограничен scope:
- переключатель demo-ролей используется вместо полноценной authentication и RBAC;
- не реализованы realtime-чат, уведомления, загрузка файлов и полноценный project tracker;
- интерфейс оптимизирован прежде всего для ноутбука;
- fallback проще OpenAI и предназначен для сохранения демонстрационного сценария;
- команды выбирают задачи самостоятельно — автоматического подбора команд нет;
- vector database и RAG для рейтинговых рекомендаций не используются;
- production hardening, расширенная модерация и аудит доступа находятся за пределами MVP.
Deployed-версия
Публичная deployed-версия на момент сдачи отсутствует. Проект запускается локально по инструкции выше.
Авторы коммитов
История коммитов
- 2026-09-23 17:53Update README.mdyerzhankyzy99-max
- 2026-09-23 17:30Merge remote-tracking branch 'origin/main'Aidos Ziyabekov
- 2026-09-23 17:30fix: navigate to role-specific landing viewsAidos Ziyabekov
- 2026-09-23 17:15Update README.mdyerzhankyzy99-max
- 2026-09-23 16:54fix: correct quality score delta feedbackAidos Ziyabekov
- 2026-09-23 16:32docs: finalize README for HackAlem AIAidos Ziyabekov
- 2026-09-23 16:17feat: improve home and quality score feedbackAidos Ziyabekov
- 2026-09-23 15:24fix: include required vite plugin for clean cloneAidos Ziyabekov
Все коммиты (21)
- 2026-09-23 14:59fix: harden real OpenAI flowAidos Ziyabekov
- 2026-09-23 14:53feat: complete marketplace demo flowAidos Ziyabekov
- 2026-09-23 14:44feat: standardize OpenAI environment setupAidos Ziyabekov
- 2026-09-23 14:19chore: remove misplaced gitignore fileAidos Ziyabekov
- 2026-09-23 14:17Merge remote-tracking branch 'origin/main'Aidos Ziyabekov
- 2026-09-23 14:12docs: document hybrid architectureAidos Ziyabekov
- 2026-09-23 14:12refactor: enforce hybrid domain architectureAidos Ziyabekov
- 2026-09-23 14:04Add files via uploadaidos6666
- 2026-09-23 13:52chore: configure Sites deploymentAidos Ziyabekov
- 2026-09-23 13:50docs: add setup and demo guideAidos Ziyabekov
- 2026-09-23 13:50feat: implement Nexa marketplace MVPAidos Ziyabekov
- 2026-09-23 12:44chore: add safe gitignore defaultsAidos Ziyabekov
- 2026-09-23 12:36chore: add safe gitignore defaultsAidos Ziyabekov
Структура репозитория (135 файлов)
.gitignore README.md web/.dev.vars.example web/.gitignore web/.npmrc web/.openai/hosting.json web/README.md web/app/api/ai/analyze/route.ts web/app/api/ai/build-card/route.ts web/app/api/ai/diagnostic/route.ts web/app/api/analyze/route.ts web/app/api/bootstrap/route.ts web/app/api/proposals/[id]/status/route.ts web/app/api/proposals/route.ts web/app/api/tasks/[id]/confirm/route.ts web/app/api/tasks/[id]/proposals/route.ts web/app/api/tasks/[id]/publish/route.ts web/app/api/tasks/[id]/route.ts web/app/api/tasks/route.ts web/app/chatgpt-auth.ts web/app/globals.css web/app/layout.tsx web/app/nexa-app.tsx web/app/page.tsx web/cloudflare-env.d.ts web/components.json web/components/ui/accordion.tsx web/components/ui/alert-dialog.tsx web/components/ui/alert.tsx web/components/ui/aspect-ratio.tsx web/components/ui/attachment.tsx web/components/ui/avatar.tsx web/components/ui/badge.tsx web/components/ui/breadcrumb.tsx web/components/ui/bubble.tsx web/components/ui/button-group.tsx web/components/ui/button.tsx web/components/ui/calendar.tsx web/components/ui/card.tsx web/components/ui/carousel.tsx web/components/ui/chart.tsx web/components/ui/checkbox.tsx web/components/ui/collapsible.tsx web/components/ui/combobox.tsx web/components/ui/command.tsx web/components/ui/context-menu.tsx web/components/ui/dialog.tsx web/components/ui/direction.tsx web/components/ui/drawer.tsx web/components/ui/dropdown-menu.tsx web/components/ui/empty.tsx web/components/ui/field.tsx web/components/ui/form.tsx web/components/ui/hover-card.tsx web/components/ui/input-group.tsx web/components/ui/input-otp.tsx web/components/ui/input.tsx web/components/ui/item.tsx web/components/ui/kbd.tsx web/components/ui/label.tsx web/components/ui/marker.tsx web/components/ui/menubar.tsx web/components/ui/message-scroller.tsx web/components/ui/message.tsx web/components/ui/native-select.tsx web/components/ui/navigation-menu.tsx web/components/ui/pagination.tsx web/components/ui/popover.tsx web/components/ui/progress.tsx web/components/ui/radio-group.tsx web/components/ui/resizable.tsx web/components/ui/scroll-area.tsx web/components/ui/select.tsx web/components/ui/separator.tsx web/components/ui/sheet.tsx web/components/ui/sidebar.tsx web/components/ui/skeleton.tsx web/components/ui/slider.tsx web/components/ui/sonner.tsx web/components/ui/spinner.tsx web/components/ui/switch.tsx web/components/ui/table.tsx web/components/ui/tabs.tsx web/components/ui/textarea.tsx web/components/ui/toggle-group.tsx web/components/ui/toggle.tsx web/components/ui/tooltip.tsx web/db/index.ts web/db/schema.ts web/drizzle.config.ts web/drizzle/0000_black_silver_fox.sql web/drizzle/0001_vengeful_luckman.sql web/drizzle/0002_powerful_mandarin.sql web/drizzle/meta/0000_snapshot.json web/drizzle/meta/0001_snapshot.json web/drizzle/meta/0002_snapshot.json web/drizzle/meta/_journal.json web/eslint.config.mjs web/hooks/use-mobile.ts web/lib/ai-fallback.test.ts web/lib/ai-fallback.ts web/lib/domain.ts web/lib/home-navigation.test.ts web/lib/home-navigation.ts web/lib/score.test.ts web/lib/score.ts web/lib/seed.ts web/lib/utils.ts web/lib/validation/schemas.test.ts web/lib/validation/schemas.ts web/next.config.ts web/package-lock.json web/package.json web/postcss.config.mjs web/public/favicon.svg web/scripts/build-verified.sh web/scripts/execution-profile.mjs web/scripts/install-ci.mjs web/scripts/install-ci.sh web/scripts/install-pnpm.sh web/scripts/npm-install.mjs web/scripts/pnpm-install.mjs web/scripts/run-framework.mjs web/scripts/sites-env.mjs web/scripts/sites-env.sh web/services/ai/ai-service.ts web/services/marketplace/marketplace-service.ts web/services/proposals/proposal-service.ts web/services/rating/rating-service.test.ts web/services/rating/rating-service.ts web/services/tasks/task-service.ts web/tsconfig.json web/vite.config.ts web/vitest.config.ts web/wrangler.d1.jsonc
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.