AI Sana — каталог практических бизнес-задач
Платформа, где бизнес описывает задачу, отвечает на уточняющие вопросы LLM и получает рейтинг проработанности 0–100; опубликованные задачи попадают…
О проекте
Команда: KTLVibes
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Рабочий MVP
Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд
Суть
Платформа, где бизнес описывает задачу, отвечает на уточняющие вопросы LLM и получает рейтинг проработанности 0–100; опубликованные задачи попадают в каталог, команды отправляют отклики, бизнес подтверждает прогресс и начисляет баллы.
Как устроено
Бизнес создаёт черновик из свободного описания, затем LLM (Chat Completions, response_format json_object, валидация схемой) по заполненной карточке подбирает следующий уточняющий вопрос; при ошибке — локальные шаблонные вопросы. Серверный рейтинг 0–100 считается по 11 полям с 4 уровнями, отдельный модуль проверяет содержательность ответов (отписки не повышают балл). Далее каталог с фильтрами, отклики команд, выбор бизнесом и +10 баллов за подтверждённый этап.
Ключевые решения
- LLM-генерация уточняющих вопросов
- JSON-mode + валидация схемы
- rule-based рейтинг по 11 полям
- проверка содержательности ответов
- fallback-вопросы
Особенности
Проверка «содержательности» ответов бизнеса: общие фразы и повторы не повышают рейтинг карточки — простая защита от накрутки геймификации.
Стек
Python · FastAPI · SQLModel · PostgreSQL 17 · React · TypeScript · Vite · Docker Compose · pytest · Playwright
Модели
OpenAI Chat Completions (по умолчанию gpt-6-luna, настраивается)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-4af4f6bc-ktlvibes.
README
README.mdAI Sana — каталог практических бизнес-задач
Краткое описание
Бизнесу сложно сформулировать свою задачу так, чтобы её могла взять в работу внешняя команда: описание получается общим, без данных, критериев успеха и способа проверки результата. Команды при этом не видят, какие задачи реально готовы к работе.
AI Sana решает обе стороны проблемы. Бизнес описывает задачу своими словами, сервис задаёт уточняющие вопросы и считает рейтинг проработанности карточки. Подтверждённые задачи попадают в общий каталог, где команды выбирают задачу и отправляют предложение. Бизнес вручную выбирает отклик и подтверждает фактический прогресс, за который команде начисляются баллы.
Для кого: малый и средний бизнес без технической экспертизы — с одной стороны; студенческие и профессиональные команды-исполнители — с другой.
Что реализовано
- Регистрация и вход по email и паролю, две роли:
businessиteam. Серверная сессия в HTTP-only cookie. - Личный кабинет — просмотр и редактирование профиля, смена пароля, удаление аккаунта.
- Конструктор задачи — черновик из свободного описания, затем уточняющие вопросы по одному, с сохранением и возможностью продолжить позже.
- AI-вопросы — следующий вопрос подбирает LLM по заполненной карточке; при отсутствии ключа или ошибке ответа работают локальные шаблонные вопросы.
- Рейтинг 0–100 — серверная оценка проработанности карточки по 11 полям, с четырьмя уровнями от «черновик» до «приоритетная».
- Проверка содержательности ответов — баллы начисляются только за конкретный ответ; отписки, общие фразы и повтор уже учтённого не повышают рейтинг.
- Каталог задач — все подтверждённые задачи, сортировка по рейтингу, фильтры по теме и уровню.
- Отклики команд — идея, план, срок, ссылка на прототип. Бизнес выбирает или отклоняет отклик.
- Подтверждение прогресса — бизнес описывает выполненный этап, команде начисляется 10 баллов.
- Разграничение доступа — бизнес управляет только своими задачами и их откликами; команда видит опубликованные задачи и свои отклики.
- Демо-данные — 5 бизнесов, 5 команд, 5 опубликованных задач, 5 черновиков, 5 откликов; создаются один раз при первом запуске.
- Тесты — pytest для API, рейтинга, AI-слоя, пользователей и миграции; Playwright-сценарий конструктора задачи.
Как работает решение
- Бизнес входит в аккаунт и в кабинете нажимает «Создать задачу».
- Вводит свободное описание проблемы и тему — создаётся черновик (
POST /api/tasks/drafts). - Сервис возвращает один уточняющий вопрос (
POST /api/tasks/{id}/questions). Бизнес отвечает, черновик сохраняется (PUT /api/tasks/{id}/draft), рейтинг пересчитывается, приходит следующий вопрос с учётом новых сведений. - Когда карточка заполнена, бизнес указывает название и подтверждает публикацию (
PUT /api/tasks/{id}/confirm). Задача со своим рейтингом появляется в каталоге. - Команда открывает каталог, выбирает задачу и отправляет предложение: идея, план, срок, ссылка на прототип (
POST /api/tasks/{id}/proposals). - Бизнес — владелец задачи — выбирает или отклоняет отклик (
PATCH /api/proposals/{id}/status). - Для выбранной команды бизнес описывает выполненный этап и подтверждает прогресс (
POST /api/tasks/{id}/progress) — команде начисляется 10 баллов.
Технологии
Backend
- Python, FastAPI, Uvicorn
- SQLModel (SQLAlchemy + Pydantic) — ORM и схемы
- PostgreSQL 17, драйвер psycopg 3
- httpx — HTTP-клиент для вызовов LLM
hashlib.scrypt— хеширование паролей (соль на пользователя,n=16384, r=8, p=1)- pytest — тесты
Frontend
- React, TypeScript, Vite
- react-router-dom — маршрутизация
- CSS без UI-фреймворка
Инфраструктура и тесты
- Docker, Docker Compose
- Playwright (Chromium) — сквозной тест
AI
- Любой провайдер, совместимый с OpenAI Chat Completions API. Адрес, ключ и модель задаются переменными
AI_API_URL,AI_API_KEY,AI_MODEL. По умолчанию в конфигурации —https://api.openai.com/v1/chat/completions, модельgpt-6-luna. - Ответ модели запрашивается в режиме
response_format: json_objectи валидируется схемой на сервере.
Архитектура проекта
hack-4af4f6bc-ktlvibes/
├── api/ FastAPI-приложение
│ ├── app/
│ │ ├── main.py сборка приложения, создание схемы и сидинг при старте
│ │ ├── models.py таблицы: User, UserSession, Task, Proposal,
│ │ │ ProgressConfirmation, SeedState
│ │ ├── auth.py сессии в cookie, зависимость current_user
│ │ ├── passwords.py scrypt-хеширование и проверка пароля
│ │ ├── rating.py расчёт рейтинга 0–100 и уровня
│ │ ├── checks.py проверка содержательности ответа
│ │ ├── ai.py запрос вопроса у LLM + локальный fallback
│ │ ├── user_migration.py перенос старых таблиц business/team в users
│ │ └── routes/ auth, users, tasks, proposals, progress, teams, actors
│ ├── seed.py, demo_data.py демо-данные
│ └── tests/ pytest
├── web/ React + Vite
│ └── src/features/ users (вход, регистрация, профиль),
│ business (кабинет, конструктор),
│ catalog (каталог),
│ proposals (карточка задачи, отклики)
├── db/init/ SQL инициализации PostgreSQL
├── e2e/ Playwright-сценарий
└── docker-compose.yaml db + api + web
Взаимодействие компонентов
Браузер → web (Vite, :5173) ──/api/*──▶ api (FastAPI, :8000) ──▶ db (PostgreSQL, :5432)
│
└──▶ LLM API (Chat Completions)
- Фронтенд обращается к API только по относительным путям
/api/...; Vite проксирует их наVITE_API_PROXY_TARGET(в Compose —http://api:8000). - Вход выдаёт HTTP-only cookie
aisana_session. Токен хранится в базе в виде SHA-256-хеша (таблицаusersession), срок жизни — 7 дней. - Роль и права определяются сессией на сервере, а не выбором в интерфейсе.
- Вызов LLM опционален: без
AI_API_KEY/AI_API_URLсервис работает на локальных вопросах.
Установка и запуск
Нужен Docker с Compose.
git clone https://github.com/BAITC-Hacks/hack-4af4f6bc-ktlvibes.git
cd hack-4af4f6bc-ktlvibes
cp .env.example .env # при необходимости впишите AI_API_KEY
docker compose up --build
Откройте http://localhost:5173.
| Сервис | Адрес |
|---|---|
| Веб-интерфейс | http://localhost:5173 |
| API | http://localhost:8000 |
| Проверка состояния | http://localhost:8000/api/health |
| PostgreSQL | localhost:5432 |
При первом запуске API создаёт таблицы и загружает демо-данные. Повторный запуск не дублирует их. База хранится в Docker volume postgres_data.
Переменные окружения
| Переменная | По умолчанию | Назначение |
|---|---|---|
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB | aisana | доступ к базе |
AI_API_KEY | пусто | ключ LLM; пусто — работают локальные вопросы |
AI_API_URL | https://api.openai.com/v1/chat/completions | адрес Chat Completions API |
AI_MODEL | gpt-6-luna | модель |
DEMO_USER_PASSWORD | demo12345 | пароль демо-аккаунтов при их создании |
COOKIE_SECURE | false | true для HTTPS |
Пароль демо-аккаунтов назначается при их создании или миграции. Позднее его можно изменить в «Мой профиль»; изменение переменной окружения не меняет уже сохранённые пароли.
Запуск фронтенда отдельно
Поднимите db и api через Compose, затем:
cd web
npm ci
npm run dev
Если API работает не на http://localhost:8000, задайте VITE_API_PROXY_TARGET до запуска Vite.
Тесты
# API
docker compose exec api pytest
# Сборка и типы фронтенда
cd web && npm run build
# Сквозной тест (API и web уже запущены)
cd e2e && npm install && npx playwright install chromium && npm test
Как проверить решение
Демо-аккаунты: пароль — значение DEMO_USER_PASSWORD (по умолчанию demo12345).
Бизнес — [email protected], команда — [email protected].
Полный сценарий (~5 минут)
- Войдите как бизнес. «Кабинет бизнеса» → «Создать задачу». Введите намеренно слабое описание (например, «хотим меньше звонков от клиентов») и тему — создастся черновик.
- Ответьте на первый вопрос, посмотрите, как изменился рейтинг. Нажмите «Сохранить и выйти», снова откройте черновик в кабинете и продолжите отвечать. Укажите название и тему, подтвердите публикацию.
- Откройте каталог и карточку задачи. Выйдите, войдите как команда (
[email protected]) и отправьте отклик: идея, план, срок и HTTP(S)-ссылка на прототип. - Выйдите, снова войдите как владелец задачи. В карточке выберите или отклоните отклик. Для выбранной команды опишите выполненный этап и подтвердите прогресс — начислится 10 баллов. Обновите страницу: решение сохранено.
Короткая проверка (~1 минута) — только путь «каталог → отклик → решение»: возьмите готовую задачу «Сократить ожидание ответа», принадлежащую «Демо бизнес».
Низкий рейтинг не блокирует отклик: это видно на задачах уровня «черновик» в каталоге.
Что проверять отдельно
- Без
AI_API_KEYконструктор всё равно задаёт вопросы — работает локальный fallback. - Ответ-отписка («не знаю», «разное») не повышает рейтинг.
- Команда не может открыть чужой кабинет и не видит чужие отклики; API вернёт
404, а без сессии —401.
Данные и интеграции
- PostgreSQL 17 — единственное хранилище. Таблицы:
users,usersession,task,proposal,progressconfirmation,seedstate. - Демо-данные (
api/demo_data.py,api/seed.py) — синтетические, созданы для хакатона. Внешние наборы данных не используются. - LLM через Chat Completions API — единственная внешняя интеграция, опциональная. Отправляются исходное описание задачи и заполненные поля карточки; принимается JSON с одним следующим вопросом, валидируемый схемой
QuestionList. Таймаут 8 с, при любой ошибке — локальный fallback. - Миграция старой схемы (
api/app/user_migration.py) — если база содержит таблицыbusinessиteamиз ранней версии, их записи и связи переносятся вusers; старые таблицы остаются в базе для восстановления данных.
Основные эндпоинты
| Метод и путь | Назначение |
|---|---|
POST /api/auth/login, GET /api/auth/me, POST /api/auth/logout | вход, текущий пользователь, выход |
POST /api/users, GET/PATCH/DELETE /api/users/{id} | регистрация и свой аккаунт |
POST /api/tasks/drafts, PUT /api/tasks/{id}/draft | черновик задачи |
POST /api/tasks/{id}/questions | следующий уточняющий вопрос |
POST /api/tasks/{id}/score-preview | предварительный рейтинг |
PUT /api/tasks/{id}/confirm | публикация карточки |
GET /api/tasks, GET /api/tasks/{id}, GET /api/tasks/mine | каталог, карточка, свои задачи |
POST /api/tasks/{id}/proposals, GET .../proposals, GET .../my-proposals | отклики |
PATCH /api/proposals/{id}/status | выбор или отклонение отклика |
POST /api/tasks/{id}/progress, GET /api/tasks/{id}/progress | подтверждение прогресса |
GET /api/health | проверка состояния |
Рейтинг и каталог
Рейтинг от 0 до 100 рассчитывает сервер по осмысленно заполненным полям подтверждённой карточки:
| Сведения | Баллы |
|---|---|
| Контекст и потребность | 10 + 10 |
| Данные и способ доступа | 10 + 10 |
| Ожидаемый результат | 15 |
| Метрика и целевое значение успеха | 10 + 5 |
| Ограничения | 10 |
| Пользователи | 10 |
| Контакт и формат взаимодействия | 5 + 5 |
Уровни: 0–39 — «черновик», 40–69 — «рабочая», 70–89 — «готовая», 90–100 — «приоритетная». Уровень «черновик» относится к рейтингу опубликованной задачи: она остаётся в каталоге, и команда может откликнуться. Неподтверждённый черновик задачи в каталоге не показывается.
Каталог сортирует задачи по убыванию рейтинга; при равном рейтинге выше стоит более поздняя публикация. В каталоге новая оценка появляется после ручного подтверждения карточки бизнесом.
Баллы за поле начисляются, когда ответ содержит конкретные сведения. Пустые отписки, общие фразы и повтор уже учтённого ответа рейтинг не повышают; для целевого значения нужно число или явное проверяемое условие. Проверка основана на правилах (api/app/checks.py), поэтому бизнес может уточнить ответ вручную.
Ограничения
- Нет деплоя. Публичной размещённой версии нет — проект запускается локально через Docker Compose.
- Нет миграций схемы. Таблицы создаются через
SQLModel.metadata.create_allпри старте; Alembic не подключён. Изменение моделей требует пересоздания базы. - AI используется только для вопросов. Модель не заполняет карточку, не оценивает рейтинг и не подбирает команды — ответы вводит и подтверждает бизнес. Оценка содержательности и рейтинг считаются правилами на сервере, без LLM.
- Подбор команд ручной. Автоматического матчинга задач и команд нет: бизнес сам просматривает отклики.
- Нет уведомлений. Ни email, ни push; о новом отклике или решении пользователь узнаёт, открыв страницу.
- Нет восстановления пароля и подтверждения email при регистрации.
- Прогресс упрощён. Одно подтверждение на пару «задача–команда», фиксированные 10 баллов, без этапов и частичных начислений.
- Нет загрузки файлов. Данные и прототип описываются текстом и ссылкой.
- Нет модерации опубликованных задач и откликов.
- Нет пагинации в каталоге — отдаётся весь список.
- Прототип не проверяется — ссылка валидируется только как HTTP(S)-URL.
- Интерфейс только на русском языке.
Deployed-версия
Отсутствует. Проект запускается локально командой docker compose up --build (см. раздел «Установка и запуск»).
Исходный код: https://github.com/BAITC-Hacks/hack-4af4f6bc-ktlvibes
Авторы коммитов
История коммитов
- 2026-09-23 17:57update: readmeolik04
- 2026-09-23 17:47Merge origin/main into mainolik04
- 2026-09-23 17:42Push #9darkkhan04
- 2026-09-23 17:41add: auth and userolik04
- 2026-09-23 17:29Push #8darkkhan04
- 2026-09-23 17:09Push #7darkkhan04
- 2026-09-23 16:42update: setup codeolik04
- 2026-09-23 16:42update: AI partolik04
Все коммиты (22)
- 2026-09-23 16:07Push #6darkkhan04
- 2026-09-23 15:50Push #5darkkhan04
- 2026-09-23 15:49dDidar
- 2026-09-23 15:40Add business task builder and e2e flowDidar
- 2026-09-23 15:37Push#4darkkhan04
- 2026-09-23 15:30Merge branch 'main' of https://github.com/BAITC-Hacks/hack-4af4f6bc-ktlvibesdarkkhan04
- 2026-09-23 15:28Push#3darkkhan04
- 2026-09-23 15:16add: initial backendolik04
- 2026-09-23 15:16update: gitignoreolik04
- 2026-09-23 15:13Add Front Skeletondarkkhan04
- 2026-09-23 14:29Front for 2 developersdarkkhan04
- 2026-09-23 14:16update: dev planDidar
- 2026-09-23 14:05add: dev planDidar
- 2026-09-23 13:58add: .gitignoreolik04
Структура репозитория (69 файлов)
.env.example .gitignore BACKEND_PLAN.md FRONTEND_PLAN.md MVP_PLAN.md README.md api/Dockerfile api/app/__init__.py api/app/ai.py api/app/auth.py api/app/checks.py api/app/db.py api/app/main.py api/app/models.py api/app/passwords.py api/app/rating.py api/app/routes/__init__.py api/app/routes/actors.py api/app/routes/auth.py api/app/routes/progress.py api/app/routes/proposals.py api/app/routes/tasks.py api/app/routes/teams.py api/app/routes/users.py api/app/schemas.py api/app/serializers.py api/app/user_migration.py api/demo_data.py api/requirements.txt api/seed.py api/tests/conftest.py api/tests/test_ai.py api/tests/test_api.py api/tests/test_rating.py api/tests/test_user_migration.py api/tests/test_users.py db/init/01-test-db.sql docker-compose.yaml e2e/README.md e2e/package.json e2e/playwright.config.ts e2e/tests/business.spec.ts web/.gitignore web/Dockerfile web/index.html web/package-lock.json web/package.json web/src/App.tsx web/src/features/business/BusinessWorkspace.tsx web/src/features/business/TaskEditor.tsx web/src/features/business/api.ts web/src/features/business/business.css web/src/features/business/index.ts web/src/features/catalog/CatalogPage.tsx web/src/features/catalog/api.ts web/src/features/proposals/BusinessProposals.tsx web/src/features/proposals/TaskPage.tsx web/src/features/proposals/TeamProposals.tsx web/src/features/proposals/api.ts web/src/features/users/AccountPage.tsx web/src/features/users/AuthPage.tsx web/src/features/users/authApi.ts web/src/features/users/users.css web/src/main.tsx web/src/shared/api.ts web/src/shared/types.ts web/src/styles.css web/tsconfig.json web/vite.config.ts
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.