AI Sana Challenge Hub
Веб-платформа, где бизнес превращает черновик задачи в структурированную карточку с помощью уточняющих вопросов от AI, видит прозрачный рейтинг…
О проекте
Команда: ORTA
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Рабочий MVP
Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд
Суть
Веб-платформа, где бизнес превращает черновик задачи в структурированную карточку с помощью уточняющих вопросов от AI, видит прозрачный рейтинг готовности 0–100, публикует её в каталоге и вручную выбирает студенческую команду среди откликов.
Как устроено
POST /api/clarify: OpenAI проверяет осмысленность черновика и генерирует не меньше трёх уточняющих вопросов по 7 категориям (при невалидном JSON возвращается явная ошибка). POST /api/card собирает структурированную карточку из черновика и ответов, недостающие поля остаются пустыми. Рейтинг считает детерминированная чистая функция calculateRating (7 взвешенных категорий, 4 уровня готовности) без AI и пересчитывает его при ручной правке. Каталог с фильтрами и подсветкой задач под профиль команды по ключевым словам, отклики и ручной выбор бизнесом, хранение в localStorage.
Ключевые решения
- LLM clarifying questions
- structured JSON card generation
- deterministic weighted rating
- keyword team matching
- request timeouts (AbortController)
Особенности
Рейтинг задачи полностью детерминирован и защищён от накрутки: набор символов без слов баллов не даёт, это покрыто 34 тестами. Репозиторий переиспользован после другого проекта (коммиты с 20.09 про «Староста-агента»), кейс начат отдельным коммитом.
Стек
Next.js 16 · React 19 · TypeScript · Tailwind CSS 4 · OpenAI SDK
Модели
gpt-5.4-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-422c070c-orta.
README
README.mdAI Sana Challenge Hub
Трек «Образование» · HackAlem AI · Кейс: «AI Sana Challenge Hub: от бизнес-задачи к решению»
Платформа, которая помогает представителю бизнеса превратить короткий черновик задачи в полноценную карточку с прозрачным рейтингом, опубликовать её в общем каталоге и вручную выбрать студенческую команду среди откликов.
1. Что сделано
Проверено по факту в коде (app/, lib/) — реализовано:
- Ввод черновика бизнес-задачи, включая 5 готовых примеров для быстрого теста (
SEED_DRAFTSвlib/seed.ts, кнопки вapp/page.tsx). - Вызов OpenAI API для анализа черновика и генерации ≥3 уточняющих вопросов по 7 категориям (
app/api/clarify/route.ts), с валидацией: если модель вернула меньше 3 вопросов или невалидный JSON — эндпоинт возвращает явную ошибку, а не тихий сбой. - Проверка осмысленности черновика: если вместо описания задачи введён бессвязный набор символов, ИИ не выдаёт формальные вопросы, а вежливо просит переформулировать (поле
understood: falseв ответе/api/clarify). - Время публикации у каждой задачи — в карточке видно, когда она попала в каталог (
createdAt). - Вызов OpenAI API для сборки структурированной карточки из черновика и ответов (
app/api/card/route.ts) — поля, для которых данных не хватило, остаются пустыми. - Ручное редактирование любого поля карточки с мгновенным пересчётом рейтинга (
updateCardFieldвapp/page.tsx). - Кнопки "Назад" на шагах 2 и 3 — можно вернуться к черновику или к вопросам и поправить их, не теряя введённые данные.
- Детерминированный расчёт рейтинга 0–100 по 7 взвешенным категориям (
lib/rating.ts) — чистая функция, без обращения к ИИ. - 4 уровня готовности (черновик / рабочая / готовая / приоритетная), вычисляемые по итоговому баллу.
- Публикация задачи в каталог с сортировкой по рейтингу (
publishTask). - Каталог с фильтрами по теме и уровню готовности (
filterTopic,filterReadinessвapp/page.tsx). - Подбор задач под команду: выбор своей команды в каталоге подсвечивает и поднимает наверх задачи, совпадающие по ключевым словам с профилем (интересы/навыки/технологии) — бейдж "Рекомендовано вашей команде" (
matchesTeamProfile). - Форма отклика команды: идея, план, срок и ссылка (
TeamResponseForm); число откликов не ограничено. Кнопка отправки неактивна, пока не заполнена идея решения. - Ручной выбор бизнеса по каждому отклику — кнопки "Выбрать команду" / "Отклонить" (
decideResponse); в коде нет ни одной функции автоматического назначения. - После выбора команды — блок "Дальнейшие шаги" со ссылкой на прототип и форматом связи (не полноценный чат — раздел 7 ТЗ прямо исключает real-time чат из объёма MVP).
- В карточке отклика бизнес видит не только идею, но и профиль команды (интересы, навыки, технологии), план и кликабельную ссылку на прототип — достаточно данных для осознанного выбора.
- Выбор роли при входе без логина ("Я представитель бизнеса" / "Я студенческая команда") — переключает видимую часть интерфейса, аккаунты и пароли отсутствуют.
- Визуальный индикатор "ИИ-помощник заполнил по вашим ответам" на экране карточки.
- Дашборд-layout в 3 колонки: слева блок "Мой аккаунт" (редактируемое имя, аналитика — опубликовано/откликов/принято у бизнеса, задач/тем у команды) и навигация (свои задачи у бизнеса / темы каталога у команды), в центре основной сценарий, справа лента последних откликов "Активность".
- У студенческой команды в каталоге — кнопка "Подробнее о задаче и откликнуться", открывающая крупное модальное окно (до 896px, на телефоне на весь экран) со всеми полями карточки и формой отклика. Плавное появление с размытием фона (
backdrop-blur+ анимация), закрытие по клику вне окна, крестику или клавише Esc. - Полный набор seed-данных: 5 черновиков, 5 готовых карточек с реальным рейтингом, 5 профилей команд, 5 откликов с разными статусами (
lib/seed.ts) — каталог заполнен сразу при открытии. - Визуальная схема сценария из 7 шагов на экране выбора роли (
StepsDiagram). - Защита от зависания: таймаут 20 сек на клиенте (
AbortControllerвapp/page.tsx) и 18 сек на сервере (OpenAI({ timeout })) для обоих AI-вызовов — при сбое сети или медленном ответе модели пользователь видит понятную ошибку максимум через ~20 сек, интерфейс не подвисает бесконечно.
Не реализовано (см. раздел 6 "Ограничения"): серверная база данных, авторизация, real-time чат.
2. Откуда / архитектура
Технологии (проверено по package.json):
| Пакет | Версия |
|---|---|
| next | 16.3.5 |
| react / react-dom | 19.2.8 |
| openai | ^7.23.0 |
| tailwindcss | ^4 |
| typescript | ^5 |
Структура проекта:
app/
├── page.tsx Весь клиентский интерфейс: выбор роли, сценарий бизнеса
│ (черновик → вопросы → карточка → публикация), каталог
│ и отклики команды. Компонент-стейтмашина на React useState.
├── layout.tsx Корневой layout и метаданные страницы
├── globals.css Цветовые токены темы и анимации модального окна
└── api/
├── clarify/route.ts POST: черновик → OpenAI (CLARIFY_PROMPT) → вопросы
└── card/route.ts POST: черновик + ответы → OpenAI (CARD_PROMPT) → карточка
lib/
├── types.ts Модели данных: Task, TaskCard, Team, TeamResponse
├── rating.ts calculateRating() — детерминированная формула рейтинга
├── prompts.ts CLARIFY_PROMPT и CARD_PROMPT — системные промпты
├── openai.ts Общий клиент OpenAI и единая обработка ошибок API
└── seed.ts Синтетические данные: черновики, карточки, команды, отклики
Ключевые модули:
| Модуль | Отвечает за | Использует ИИ |
|---|---|---|
app/api/clarify/route.ts | Проверка осмысленности черновика и генерация уточняющих вопросов | Да |
app/api/card/route.ts | Сборка структурированной карточки из черновика и ответов | Да |
lib/rating.ts | Баллы 0–100, уровни готовности, подсказки по недостающим полям | Нет — чистая функция |
app/page.tsx | Роли, шаги сценария, каталог, фильтры, отклики, выбор бизнеса | Нет |
lib/openai.ts | Ленивый клиент OpenAI, таймауты, перевод ошибок API в понятные сообщения | — |
Откуда данные:
- Единственный внешний сервис — OpenAI API (модель
gpt-5.4-mini), вызывается из двух серверных роутов. - Демонстрационные данные каталога и откликов — из
lib/seed.ts, подставляются в состояние при загрузке страницы. - Задачи и отклики, созданные пользователем, сохраняются в
localStorageи переживают перезагрузку страницы. Кнопка «Сбросить к демо-данным» в левой панели возвращает исходное состояние.
Переменные окружения (проверено по .env.example):
| Переменная | Назначение |
|---|---|
OPENAI_API_KEY | Ключ OpenAI API, обязателен для работы обеих AI-функций |
3. Что делает / как работает
Пошаговый сценарий, как он реально реализован в app/page.tsx:
-
Выбор роли. Пользователь видит экран с двумя кнопками — "Я представитель бизнеса" / "Я студенческая команда". Клик задаёт состояние
role, дальше рендерится соответствующая часть интерфейса. -
Черновик (роль "бизнес"). Пользователь вводит текст в
textareaили нажимает одну из кнопок "Пример 1–5" (автоподстановка изSEED_DRAFTS). По кнопке "Проанализировать черновик" вызываетсяhandleDraftSubmit, которая отправляетPOST /api/clarify. -
Уточняющие вопросы.
app/api/clarify/route.tsпередаёт черновик в OpenAI с системным промптомCLARIFY_PROMPT, получает JSON вида{ missing_categories, questions }и возвращает его на клиент. Интерфейс показывает список вопросов с полями ввода. -
Сборка карточки. После ответа на вопросы вызывается
handleAnswersSubmit→POST /api/card. Роут передаёт черновик и пары "вопрос-ответ" в OpenAI с промптомCARD_PROMPT, получает структурированный JSON (название, тема, контекст, потребность, пользователи, данные, ограничения, ожидаемый результат, критерии успеха, контакт, формат) и список незаполненных полей. -
Рейтинг. Сразу после получения карточки вызывается
calculateRating()изlib/rating.ts— локально, без обращения к ИИ. Функция проверяет длину каждого поля (порог 8 символов) и начисляет баллы по весам: контекст+потребность — 20, данные — 20, результат — 15, критерии успеха — 15, ограничения — 10, пользователи — 10, связь с бизнесом — 10. Итог показывается с расшифровкой по каждой категории и подсказкой, что заполнить, если баллов не хватает. -
Редактирование и публикация. Любое поле карточки можно изменить вручную — рейтинг пересчитывается на лету (
updateCardField). По кнопке "Подтвердить и опубликовать" задача добавляется в общий каталог (publishTask), отсортированный по убыванию рейтинга. -
Каталог (роль "команда"). Список задач с фильтрами по теме и уровню готовности. Каждая карточка показывает прогресс-бар рейтинга, цветной бейдж готовности, превью ожидаемого результата и аудитории.
-
Отклик. Под каждой задачей — форма
TeamResponseForm: выбор команды из списка, идея решения, план, ссылка на прототип. По отправке создаётся объектTeamResponseсо статусомpending. -
Выбор бизнеса. Переключившись обратно на роль "бизнес", пользователь видит раздел "Мои задачи и отклики" со всеми полученными откликами и может нажать "Выбрать команду" (статус →
accepted) или "Отклонить" (статус →declined) — функцияdecideResponse. Автоматического назначения в коде нет.
4. Установка и запуск
git clone https://github.com/BAITC-Hacks/hack-422c070c-orta.git
cd hack-422c070c-orta
npm install
cp .env.example .env.local
# вписать в .env.local: OPENAI_API_KEY=sk-...
npm run dev
Открыть http://localhost:3000. Проверено: npm run build проходит без ошибок TypeScript и без предупреждений сборки.
Автоматические тесты
npm test
34 проверки в двух наборах:
tests/rating.test.ts(19) — формула и веса (сумма максимумов = 100), четыре уровня готовности на граничных значениях, защита от накрутки (набор символов без слов баллов не даёт), соответствие seed-данных разделу 6 ТЗ: по 5 записей в каждой категории, корректные связи откликов с задачами и командами.tests/response-flow.test.ts(15) — полный путь отклика: отправка и привязка к нужной задаче, сохранение всех полей (идея, план, срок, ссылка), определение команды, переходы статусов «на рассмотрении → принят → отклонён → снова на рассмотрении», неизменность соседних откликов, порядок в ленте активности.
5. Как проверить решение
Воспроизводимый сценарий с реальными данными из проекта:
- Открыть главную страницу → выбрать "Я представитель бизнеса".
- Нажать "Пример 1" — подставится черновик "Нужно автоматизировать проверку заявок клиентов" → "Проанализировать черновик".
- Получить от 3 до 7 уточняющих вопросов (проверено живым вызовом: реальный ответ включал вопросы по всем 7 категориям для этого слабого черновика). Ответить хотя бы на 2–3 вопроса → "Собрать карточку".
- Убедиться, что карточка заполнилась только по данным ответов, а не заполненные поля остались пустыми (проверено: поля, на которые не отвечали, приходят в
missing_fieldsи остаются пустой строкой). - Посмотреть рейтинг с расшифровкой по 7 категориям → изменить любое поле карточки → убедиться, что баллы пересчитались мгновенно.
- Нажать "Подтвердить и опубликовать в каталог".
- Нажать "Сменить роль" → "Я студенческая команда".
- В каталоге (вместе с 5 демо-задачами) найти только что опубликованную, применить фильтры по теме/готовности, отправить отклик от имени любой из 5 команд.
- Снова сменить роль на бизнеса → в разделе "Мои задачи и отклики" увидеть новый отклик → принять или отклонить.
6. Ограничения
Сознательно не реализовано, и почему:
- Нет серверной базы данных. Задачи и отклики сохраняются в
localStorageбраузера: перезагрузка страницы их не теряет, но данные не общие между устройствами и пользователями. Раздел 7 Положения прямо исключает требование производственной инфраструктуры для пятичасового MVP, поэтому выбрано самое лёгкое хранилище, закрывающее сценарий демонстрации. - Нет авторизации и ролевой модели. Вместо этого — простой переключатель роли без логина, по тем же основаниям.
- Рекомендации задач студентам — реализованы без ИИ. Правилами (раздел 5 ТЗ) разрешено рекомендовать задачи по интересам и навыкам команды, но не обязательно и не указано, что через ИИ. Сделано как прозрачное совпадение ключевых слов профиля команды с темой/контекстом задачи (
matchesTeamProfileвapp/page.tsx) — предсказуемо, объяснимо и не добавляет риска ещё одного вызова внешнего API перед демонстрацией. - Тема задачи (
topic) не имеет отдельного справочника — определяется ИИ на этапе сборки карточки; фильтр в каталоге строится по темам, фактически встретившимся в данных. - Нет деплоя на Vercel на момент написания этого README — проект проверен и работает только локально (
npm run dev).
Соответствие критериям оценки (максимум 100 баллов)
| Критерий | Баллы | Статус |
|---|---|---|
| Сквозной сценарий | 20 | ✅ Проверен вручную end-to-end (раздел 5) |
| Качество карточки | 15 | ✅ Вопросы уместны, поля редактируются вручную |
| Геймификация бизнеса | 25 | ✅ lib/rating.ts — детерминированная формула, расшифровка, live-пересчёт |
| Каталог и отклики | 15 | ✅ Сортировка, фильтры, ручной accept/decline без автоназначения |
| AI-функция | 10 | ✅ Обе функции на реальном OpenAI API, не домысливают факты (проверено тестами) |
| Техническое качество | 10 | ✅ npm run build чисто, npm test — 34 проверки пройдено, обработка ошибок API (проверена на 6 некорректных запросах), таймауты против зависания, пройден код-ревью (5 багов исправлены), нет неиспользуемых зависимостей |
| Демонстрация | 5 | 🟡 Репетиция итогового прогона — следующий шаг |
Команда
- Oscar Altynbekov — капитан
Авторы коммитов
История коммитов
- 2026-09-23 17:06README: актуализация устаревших утвержденийOscar Altynbekov
- 2026-09-23 17:05Тесты пути отклика и фикс молчащей кнопки отправкиOscar Altynbekov
- 2026-09-23 17:02Автоматические тесты логики рейтинга и целостности данныхOscar Altynbekov
- 2026-09-23 16:56Надёжность сценария, честный рейтинг и доработки по итогам самооценкиOscar Altynbekov
- 2026-09-23 16:04Кнопки "Назад" на шагах 2 и 3 сценария бизнесаOscar Altynbekov
- 2026-09-23 15:59Модалка задачи: полноэкранная, с размытием и анимацией открытияOscar Altynbekov
- 2026-09-23 15:54Подбор задач под команду + модальное окно деталей задачиOscar Altynbekov
- 2026-09-23 15:44Код-ревью: 5 багов, критичных для живого демо, исправленыOscar Altynbekov
Все коммиты (31)
- 2026-09-23 15:37Профиль команды в откликах, блок "Мой аккаунт", подробности задачиOscar Altynbekov
- 2026-09-23 15:27Надёжность против зависания, светлее тема, схема из 7 шаговOscar Altynbekov
- 2026-09-23 15:18README v2: строго по фактам из кода + чистка мёртвого кодаOscar Altynbekov
- 2026-09-23 15:12README: полный профессиональный рерайт по структуре организаторовOscar Altynbekov
- 2026-09-23 15:09Строгая единая цветовая тема без исключенийOscar Altynbekov
- 2026-09-23 15:04Цветовая психология и растянутый layoutOscar Altynbekov
- 2026-09-23 14:54Дашборд-layout в 3 колонки по референсу дизайнаOscar Altynbekov
- 2026-09-23 14:50Seed-данные: 5 готовых карточек и 5 откликов (раздел 6 ТЗ)Oscar Altynbekov
- 2026-09-23 14:44Улучшенный дизайн карточек в каталоге студентовOscar Altynbekov
- 2026-09-23 14:42Полноэкранный layout, каталог сеткой в 2 колонкиOscar Altynbekov
- 2026-09-23 14:39Бейдж "ИИ-помощник" на экране карточкиOscar Altynbekov
- 2026-09-23 14:32Редизайн + переход на OpenAI API (gpt-5.4-mini)Oscar Altynbekov
- 2026-09-23 14:04Seed-данные и фильтры каталога по теме/готовностиOscar Altynbekov
- 2026-09-23 14:00Полный сквозной сценарий: карточка, рейтинг, каталог, отклики, выборOscar Altynbekov
- 2026-09-23 13:57Новый проект на HackAlem AI: AI Sana Challenge Hub (трек «Образование»)Oscar Altynbekov
- 2026-09-20 17:27Переключатель провайдера: Claude или OpenAI, общий цикл агента и инструменты; README как пошаговый отчётOscar Altynbekov
- 2026-09-20 16:53CLAUDE.md: рабочий способ деплояOscar Altynbekov
- 2026-09-20 16:46Исправления по отчёту тестера: обрыв цикла, откат записи, логирование, лимит фотоOscar Altynbekov
- 2026-09-20 16:33PITCH.md: питч на 3 минуты и ответы на вопросыOscar Altynbekov
- 2026-09-20 16:25Индикаторы подключений, офлайн-тесты инструментов, лимит фотоOscar Altynbekov
- 2026-09-20 16:22README: публичная ссылкаOscar Altynbekov
- 2026-09-20 16:21README: ссылка на деплой, правила Next.js для агентовOscar Altynbekov
- 2026-09-20 16:20Староста-агент: агентный цикл, 7 инструментов, SSE-лог, READMEOscar Altynbekov
Структура репозитория (22 файлов)
.env.example .gitignore AGENTS.md CLAUDE.md README.md app/api/card/route.ts app/api/clarify/route.ts app/globals.css app/layout.tsx app/page.tsx lib/openai.ts lib/prompts.ts lib/rating.ts lib/seed.ts lib/types.ts next.config.ts package-lock.json package.json postcss.config.mjs tests/rating.test.ts tests/response-flow.test.ts tsconfig.json
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.