AI Sana Challenge Hub
MVP, в котором бизнес превращает описание проблемы в карточку задачи для студентов: AI задаёт уточняющие вопросы, дальше идут оценка готовности…
О проекте
Команда: zhansaya-dev
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Рабочий MVP
Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд
Суть
MVP, в котором бизнес превращает описание проблемы в карточку задачи для студентов: AI задаёт уточняющие вопросы, дальше идут оценка готовности, каталог, заявки команд, выбор команды бизнесом и этапы с баллами.
Как устроено
Единственный серверный endpoint POST /api/clarify отправляет сохранённое описание в OpenAI Responses API (gpt-4o-mini) со строгой JSON-схемой и получает 3–7 уточняющих вопросов. Ответы пользователь вручную раскладывает по 10 полям карточки. Детерминированная оценка готовности 0–100 считается по заполненности полей (веса, отсев заглушек), уровни Draft/Working/Ready/Priority. Публикация, заявки, решения бизнеса и этапы (10 баллов) хранятся в localStorage с Web Locks; AI не ранжирует команды и не проверяет результаты.
Ключевые решения
- LLM clarifying questions
- strict JSON schema output
- deterministic readiness scoring
- immutable publish snapshots
- Web Locks
Особенности
Весь цикл из 8 шагов (от черновика до подтверждённых этапов с баллами), причём все решения принимает человек, а AI ограничен уточняющими вопросами. Прозрачная формула готовности с таблицей весов. Есть ссылка на Vercel, хотя в тексте README сказано, что деплой не подтверждён.
Стек
Next.js 16 · React 19 · TypeScript · Tailwind CSS 4 · localStorage
Модели
gpt-4o-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-eac32eea-zhansaya-dev.
README
README.mdРаботающий MVP: AI Sana Challenge Hub — открывается без авторизации.
hack-eac32eea-zhansaya-dev
Hackathon team repository for zhansaya-dev
AI Sana Challenge Hub
MVP для хакатона: бизнес превращает краткое описание проблемы в понятную студентам задачу. Реализованы шаги 1–8: черновик, уточняющие вопросы AI, редактируемая карточка, прозрачная оценка готовности, локальный каталог, заявки команд, ручной выбор бизнеса и подтверждённые этапы проекта с баллами.
Интерфейс приложения — на английском. AI помогает только задавать вопросы; решения о публикации, выборе команды и завершении этапа принимает человек.
Локальный запуск
Нужны Node.js 20.9+ и npm. После клонирования репозитория команды выполняются из его корня:
npm ci
cp .env.example .env.local
Для настоящих уточняющих вопросов впишите свой ключ в .env.local:
OPENAI_API_KEY=
Не публикуйте значение ключа. Не используйте префикс NEXT_PUBLIC_. Ключ читается только серверным маршрутом; после изменения перезапустите приложение. Доступ к OpenAI API и достаточная квота необходимы отдельно. Без ключа черновики работают, а Improve with AI показывает явное сообщение настройки. В обычном приложении нет подставных вопросов или автоматического обхода ошибки.
Режим разработки:
npm run dev -- --hostname 127.0.0.1 --port 3000
Проверенный запуск production-сборки:
npm run build -- --webpack
npm start -- --hostname 127.0.0.1 --port 3000
Адрес: http://127.0.0.1:3000. Используйте один и тот же адрес и порт на протяжении демо: localhost и 127.0.0.1 имеют разное браузерное хранилище. Параметр --webpack явно выбирает проверенный сборщик; скрипт build сам по себе вызывает next build.
Публичное развёртывание не подтверждено; проверенного deployed URL нет.
Работающие возможности
- Черновик. Обязательное описание, необязательные организация и контакт. Сохраняются точный текст, UUID и даты. Список черновиков позволяет вернуться к работе.
- Уточнение. Сервер передаёт в OpenAI только сохранённое описание, запрашивает 3–7 конкретных вопросов и проверяет структурированный JSON. Вопросы и ответы редактируются и сохраняются по мере ввода. Есть загрузка, понятные ошибки и повторная попытка. Перегенерация вопросов с ответами требует подтверждения.
- Карточка. После хотя бы одного ответа пользователь выбирает, в какие поля его скопировать через Use answer … in. Дополнительного AI-вызова нет: описание попадает в Need/problem, контакт — в Business contact, выбранные ответы копируются дословно. Остальные поля пусты. Все десять полей редактируются: title, context, need/problem, users, available data/materials, constraints, expected result, success criteria, business contact, communication format. Исходные данные и история хранятся отдельно. Нужно сохранить правки и вручную нажать Confirm Card. Правки карточки или исходных ответов снимают подтверждение.
- Готовность. Детерминированная оценка полноты 0–100, расшифровка и подсказки. При редактировании показан явно обозначенный несохранённый предварительный результат; сохранение фиксирует поля. AI не назначает оценку.
- Каталог. Publish Challenge доступен для подтверждённой карточки при любом балле. Публикация создаёт неизменяемый снимок с прежним ID и датой. Повторный клик не создаёт копию. Есть сортировка по баллам, фильтр уровня, текстовый поиск, страницы деталей. Пустой заголовок отображается как «Title not provided». Поздние правки рабочей карточки не меняют опубликованный снимок; обновление публикации не реализовано.
- Заявки. В опубликованной задаче команда вводит название, идею, план, срок и необязательную HTTP(S)-ссылку на прототип. Проверяются обязательные поля и формат URL, но не доступность сайта. Заявка получает UUID, дату и статус pending и привязывается к опубликованной версии. На For Students видны все локальные заявки, а не личный кабинет отдельной команды.
- Решение бизнеса. For Business показывает задачи и заявки в хронологическом порядке. Accept/Reject требуют отдельного подтверждения. Решение окончательное, с датой. Принять можно только одну заявку на задачу; остальные остаются pending, пока бизнес явно не отклонит их. AI не ранжирует и не выбирает команды.
- Этапы и баллы. Только принятой заявке бизнес может записать завершённый результат длиной 1–1000 символов. Review milestone → Confirm milestone and award points сохраняет бизнес-подтверждение и ровно 10 баллов. Принятие заявки само по себе даёт 0. На обеих страницах показаны история и сумма по этой заявке/проекту. Повторный клик с тем же ID не даёт повторных баллов. AI не проверяет выполнение. Подтверждённые этапы не редактируются и не отменяются.
Правила оценки готовности
Поле получает все указанные баллы, если после нормализации оно непустое и не является известной заглушкой. Длина текста не увеличивает баллы. Пробелы, пунктуация и значения вроде Needs information, TBD, unknown, not provided, none, N/A не засчитываются. Полный список заглушек — в src/lib/readiness.ts; семантической проверки произвольного текста нет.
| Критерий | Баллы |
|---|---|
| Context + Need/problem | 10 + 10 |
| Available data/materials | 20 |
| Expected result | 15 |
| Success criteria | 15 |
| Constraints | 10 |
| Users | 10 |
| Business contact + Communication format | 5 + 5 |
Title и ручное подтверждение не дают баллов. Уровни: 0–39 Draft, 40–69 Working, 70–89 Ready, 90–100 Priority. Это оценка заполненности, не проверка правдивости, качества или реализуемости. Она не связана с баллами за завершённые этапы.
Архитектура и данные
Стек: Next.js 16.3.6 App Router, React 19, TypeScript, Tailwind CSS 4. Базы данных и авторизации нет. Единственный серверный endpoint — POST /api/clarify: OpenAI Responses API, модель gpt-4o-mini, строгая JSON-схема, серверная проверка, таймаут 30 секунд и store: false в запросе. Ошибки провайдера не пересылаются в браузер дословно. Ключ не записывается в localStorage и не выводится кодом в логи.
| Путь | Назначение |
|---|---|
src/app/challenges/new/ | Черновик, вопросы, карточка и оценка |
src/app/challenges/ и [id]/ | Каталог, опубликованная карточка, форма заявки |
src/app/business/ | Ручной разбор заявок; /business/proposals перенаправляет сюда |
src/app/students/ | Локальные заявки, решения и этапы |
src/app/api/clarify/route.ts | Серверный вызов OpenAI |
src/lib/draft-storage.ts | Черновики, история, подтверждение, снимки публикаций |
src/lib/task-card.ts, readiness.ts, catalog.ts | Копирование ответов, единая формула, фильтры |
src/lib/proposals.ts, milestones.ts | Заявки, решения и этапы с проверками |
src/components/proposal-milestones.tsx | Общая история этапов; форма только для бизнеса |
src/types/ | Типы Challenge, TeamProposal, ProjectMilestone |
tests/ | Проверки логики, ошибок API и браузерного хранения через имитацию |
В localStorage используются три ключа:
ai-sana.challenge-drafts.v1: черновики, вопросы/ответы, история, рабочая карточка, подтверждение и фиксированный опубликованный снимок.ai-sana.team-proposals.v1: заявки, ссылка на опубликованную версию, окончательное решение бизнеса и его дата.ai-sana.project-milestones.v1: ID этапа, задачи и принятой заявки, описание, 10 баллов, дата и отметка подтверждения бизнесом.
Данные читаются после загрузки клиентской страницы. Ошибки записи не должны стирать сохранённую работу. Некорректные записи блокируют соответствующие действия и показывают ошибку без автоматического сброса данных. Отсутствующее хранилище этапов означает пустую историю, но повреждённая история не заменяется нулём.
Ограничения MVP
- Данные доступны только в одном профиле браузера и origin (протокол, хост, порт). Разные браузеры, устройства и адреса не обмениваются задачами, заявками и баллами. Очистка данных сайта удаляет записи.
- Нет аккаунтов, разграничения доступа, проверки принадлежности бизнеса/команды и защиты localStorage от ручного изменения. Любой пользователь этого профиля может действовать как бизнес.
- Подтверждения решений и этапов используют Web Locks; нужен совместимый браузер и localhost либо HTTPS. Это не полноценная транзакционная база: одновременное редактирование черновиков и отправка заявок в разных вкладках не координируются целиком.
- Несохранённые поля черновика, карточки, заявки и нового этапа теряются при уходе/перезагрузке. Ответы уточнения сохраняются при вводе.
- Нет удаления/экспорта, редактирования заявок, отмены решений/этапов или обновления опубликованного снимка.
- Сознательно новая заявка или новый этап получает новый ID. Защита от двойного клика не распознаёт смысловые дубликаты.
- Нет платежей, рейтинга команд, чата, уведомлений, хранения файлов и внешних интеграций, кроме OpenAI для вопросов.
Демо за 5 минут
Подготовьте ключ и проверьте квоту заранее. Используйте один браузер и один адрес. Если ключа нет, честно объявите, что показанные вопросы — заранее подготовленная тестовая фикстура, и не выдавайте её за ответ AI. Обычная сборка без ключа не создаёт вопросы, поэтому для оставшейся части демонстрации нужен ранее сохранённый пример с ответами.
- 0:00–0:40. Home → Create a Challenge. Введите «We want to reduce queues in our university cafeteria.» и Save Draft. Покажите, что исходный текст сохранён.
- 0:40–1:30. Improve with AI. Объясните роль вопросов. Ответьте, кто пользуется столовой, какие данные есть и какой результат нужен. Не придумывайте реальные факты; демонстрационные ответы обозначьте как примеры.
- 1:30–2:30. Выберите назначения ответов, Create Task Card. Покажите пустые поля и независимое редактирование. Заполнение Expected result даёт +15, Success criteria — ещё +15. Save Card Edits → Confirm Card → Publish Challenge.
- 2:30–3:20. Откройте каталог и опубликованные детали. Покажите балл/фильтр и фиксированную версию. Submit Proposal: название команды, идея, план, срок. Сохраните; статус pending не означает выбор.
- 3:20–4:10. For Business → Accept → Confirm acceptance. Объясните: решение принимает бизнес, оно окончательное, остальные заявки сами не отклоняются. Баллы пока 0.
- 4:10–5:00. Запишите демонстрационный завершённый этап → Review milestone → Confirm milestone and award points. Покажите 10 баллов. For Students → обновить страницу: заявка, решение и этап сохранились. Завершите ограничением «пока только один браузер».
Проверки релиза
node --test tests/*.test.mjs
npm run lint
npm run typecheck
npm run build -- --webpack
На 23 сентября 2026: 22/22 теста, ESLint, TypeScript и production-сборка прошли. Тесты проверяют обработку ответов/ошибок OpenAI через фикстуры, сохранение исходных данных, ручные подтверждения, диапазоны оценки, неизменяемую публикацию, валидацию заявок, единственный выбор команды, идемпотентность решений/этапов и ошибки хранения. Это не проверка живого сервиса OpenAI.
В окружении релизной проверки OPENAI_API_KEY не настроен. Живой ответ OpenAI остаётся непроверенным. Обычный production-сервер запущен на http://127.0.0.1:3000; отсутствие ключа даёт явное сообщение настройки и не удаляет черновик. Полный браузерный сценарий повторно пройден отдельно с явно подписанными фикстурами: новый черновик → пять вопросов и ответы → карточка → рост оценки 10→40 → подтверждение → публикация → заявка → принятие с 0 баллов → этап с 10 баллами. Двойной клик не продублировал этап; обновление обеих страниц сохранило состояние. Подмена не входит в обычный запуск приложения.
Git, секреты и сдача
.gitignore исключает .env*, кроме пустого .env.example, а также secrets/, credentials.json, *.pem, *.key, *.p12, *.pfx, зависимости и результаты сборки. Правила проверены командой git check-ignore в временном репозитории. Поиск распространённых сигнатур ключей в исходниках/конфигурации совпадений не выявил; это не гарантия обнаружения любого секрета. .env.local сейчас отсутствует.
Исходная папка сборки не была Git-репозиторием. Для загрузки использован клон https://github.com/zhansaya-dev/AI-Sana-Challenge-Hub с сохранением существующей истории и файла AI SANA .pdf. До загрузки в репозитории были только PDF и краткий README с упоминанием Step 4; исходников приложения не было. Этот адрес указан владельцем проекта; назначение репозитория организаторами отдельно не проверялось. Наличие кода в GitHub не означает сдачу заявки на платформе хакатона. Публичное развёртывание не подтверждено.
Перед сдачей:
- Настроить реальный ключ локально и пройти сценарий с живыми уточняющими вопросами.
- Проверить, что этот GitHub-репозиторий соответствует назначению команды, и выполнить необходимые действия сдачи на платформе хакатона. При дальнейших изменениях проверять staged-файлы на секреты: ignore не защищает уже отслеживаемые файлы.
- Если правила хакатона требуют deployed URL, развернуть приложение с серверным ключом, проверить HTTPS/Web Locks и фактический URL. При этом данные всё равно останутся локальными для каждого браузера.
При этой релизной проверке изменены только README и правила исключения секретов; новые продуктовые функции не добавлялись.
При подготовке GitHub-версии перенесены исходники Steps 1–8, тесты, конфигурация и пустой .env.example. Локальные зависимости, сборка, секреты и внешние серверные фикстуры не входят в загрузку.
Небольшой пример: demo data
На странице Create a Challenge нажмите Open cafeteria demo data. Пример создаётся только по нажатию, не подменяет существующие черновики и помечен demo data в списке и редакторе. Единственное содержимое — явно разрешённый пользователем текст: «We want to reduce queues in our university cafeteria.» Организация, контакт, карточка, вопросы и ответы не заполнены. Никакие данные не скопированы из браузера. Даты создания — технические метаданные момента нажатия. Повторное открытие сохраняет ваши правки; несохранённые правки другого черновика нужно сначала сохранить или отменить. Для настоящих AI-вопросов по-прежнему нужен настроенный серверный ключ и явное нажатие Improve with AI. Пример сам не подтверждается и не публикуется.
Репозиторий хакатона
Актуальная версия с cafeteria demo data перенесена из zhansaya-dev/AI-Sana-Challenge-Hub (коммит 73df618dc5d5a3713181eae521752ce99d5e1ea5) в назначенный приватный репозиторий BAITC-Hacks/hack-eac32eea-zhansaya-dev. Истории обоих репозиториев объединены; исходный README организаторов сохранён в начале этого файла. Для дальнейшей сдачи используйте этот репозиторий. Ранее настроенное развёртывание Vercel относится к исходному репозиторию; автоматическая связь Vercel с репозиторием хакатона не заявляется.
Авторы коммитов
История коммитов
- 2026-09-23 17:46Add public MVP link at top of hackathon READMESaya [твоё имя]
- 2026-09-23 17:25Merge complete AI Sana Challenge Hub with cafeteria demo into hackathon repositorySaya [твоё имя]
- 2026-09-23 17:16Add opt-in cafeteria demo draft using approved descriptionSaya [твоё имя]
- 2026-09-23 16:23Add complete Challenge Hub MVP through Step 8Saya [твоё имя]
- 2026-09-23 15:42Add files via uploadzhansaya bagdar
- 2026-09-23 15:33Initial commitzhansaya bagdar
Структура репозитория (45 файлов)
.env.example .gitignore AI SANA .pdf README.md eslint.config.mjs next-env.d.ts next.config.ts package-lock.json package.json postcss.config.mjs src/app/api/clarify/route.ts src/app/business/page.tsx src/app/business/proposal-review.tsx src/app/business/proposals/page.tsx src/app/challenges/[id]/challenge-details.tsx src/app/challenges/[id]/page.tsx src/app/challenges/[id]/proposal-form.tsx src/app/challenges/new/clarification-panel.tsx src/app/challenges/new/draft-workspace.tsx src/app/challenges/new/page.tsx src/app/challenges/new/readiness-panel.tsx src/app/challenges/new/task-card-panel.tsx src/app/challenges/page.tsx src/app/challenges/use-catalog.ts src/app/globals.css src/app/layout.tsx src/app/page.tsx src/app/students/page.tsx src/components/header.tsx src/components/placeholder-page.tsx src/components/proposal-milestones.tsx src/lib/catalog.ts src/lib/clarification.ts src/lib/demo-draft.ts src/lib/draft-storage.ts src/lib/milestones.ts src/lib/proposals.ts src/lib/readiness.ts src/lib/task-card.ts src/types/challenge.ts src/types/milestone.ts src/types/team-proposal.ts tests/clarification.test.mjs tests/readiness.test.mjs tsconfig.json
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.