AAYMA
RU
Войти

AI Sana Challenge Hub

Веб-платформа, где бизнес превращает черновик задачи в структурированную карточку с помощью уточняющих вопросов от AI, видит прозрачный рейтинг…

Рабочий MVP
Команда «ORTA» 3💬 0 комментариевс 20 сентября 2026 г.

О проекте

Команда: 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.md

AI 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):

ПакетВерсия
next16.3.5
react / react-dom19.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:

  1. Выбор роли. Пользователь видит экран с двумя кнопками — "Я представитель бизнеса" / "Я студенческая команда". Клик задаёт состояние role, дальше рендерится соответствующая часть интерфейса.

  2. Черновик (роль "бизнес"). Пользователь вводит текст в textarea или нажимает одну из кнопок "Пример 1–5" (автоподстановка из SEED_DRAFTS). По кнопке "Проанализировать черновик" вызывается handleDraftSubmit, которая отправляет POST /api/clarify.

  3. Уточняющие вопросы. app/api/clarify/route.ts передаёт черновик в OpenAI с системным промптом CLARIFY_PROMPT, получает JSON вида { missing_categories, questions } и возвращает его на клиент. Интерфейс показывает список вопросов с полями ввода.

  4. Сборка карточки. После ответа на вопросы вызывается handleAnswersSubmit → POST /api/card. Роут передаёт черновик и пары "вопрос-ответ" в OpenAI с промптом CARD_PROMPT, получает структурированный JSON (название, тема, контекст, потребность, пользователи, данные, ограничения, ожидаемый результат, критерии успеха, контакт, формат) и список незаполненных полей.

  5. Рейтинг. Сразу после получения карточки вызывается calculateRating() из lib/rating.ts — локально, без обращения к ИИ. Функция проверяет длину каждого поля (порог 8 символов) и начисляет баллы по весам: контекст+потребность — 20, данные — 20, результат — 15, критерии успеха — 15, ограничения — 10, пользователи — 10, связь с бизнесом — 10. Итог показывается с расшифровкой по каждой категории и подсказкой, что заполнить, если баллов не хватает.

  6. Редактирование и публикация. Любое поле карточки можно изменить вручную — рейтинг пересчитывается на лету (updateCardField). По кнопке "Подтвердить и опубликовать" задача добавляется в общий каталог (publishTask), отсортированный по убыванию рейтинга.

  7. Каталог (роль "команда"). Список задач с фильтрами по теме и уровню готовности. Каждая карточка показывает прогресс-бар рейтинга, цветной бейдж готовности, превью ожидаемого результата и аудитории.

  8. Отклик. Под каждой задачей — форма TeamResponseForm: выбор команды из списка, идея решения, план, ссылка на прототип. По отправке создаётся объект TeamResponse со статусом pending.

  9. Выбор бизнеса. Переключившись обратно на роль "бизнес", пользователь видит раздел "Мои задачи и отклики" со всеми полученными откликами и может нажать "Выбрать команду" (статус → 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. Открыть главную страницу → выбрать "Я представитель бизнеса".
  2. Нажать "Пример 1" — подставится черновик "Нужно автоматизировать проверку заявок клиентов" → "Проанализировать черновик".
  3. Получить от 3 до 7 уточняющих вопросов (проверено живым вызовом: реальный ответ включал вопросы по всем 7 категориям для этого слабого черновика). Ответить хотя бы на 2–3 вопроса → "Собрать карточку".
  4. Убедиться, что карточка заполнилась только по данным ответов, а не заполненные поля остались пустыми (проверено: поля, на которые не отвечали, приходят в missing_fields и остаются пустой строкой).
  5. Посмотреть рейтинг с расшифровкой по 7 категориям → изменить любое поле карточки → убедиться, что баллы пересчитались мгновенно.
  6. Нажать "Подтвердить и опубликовать в каталог".
  7. Нажать "Сменить роль" → "Я студенческая команда".
  8. В каталоге (вместе с 5 демо-задачами) найти только что опубликованную, применить фильтры по теме/готовности, отправить отклик от имени любой из 5 команд.
  9. Снова сменить роль на бизнеса → в разделе "Мои задачи и отклики" увидеть новый отклик → принять или отклонить.

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 — капитан
Звёзды
⭐ 0
Форки
0
Язык
TypeScript
Последний push
в прошлом месяце
Коммиты
31
Авторы
2
Файлы
22
Ветки
1

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

Oscar Altynbekov 25Oscar Altynbekov 6

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

  • 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 комментариев

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

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