О проекте
Команда: ITshechka
Кейс HackAlem.ai: Инновации — Самрук-Казына
Стадия: Рабочий MVP
Задача кейса: «Хаттама»: протокол и поручения по аудиозаписи совещания (каз./рус./смешанная речь)
Суть
Сервис протоколирования совещаний: загрузка аудио, транскрипт с диаризацией, саммари, поручения с ответственным и сроком, реестр поручений и экспорт протокола в DOCX/PDF.
Как устроено
Монорепо: Next.js-фронтенд, NestJS+Prisma+PostgreSQL бэкенд с AI-оркестратором и WebSocket для live-чанков, единые Zod-контракты. Локальный ML-пайплайн: STT (Whisper small проверен на двух MP3) → диаризация → детектор реплик-поручений (классификатор, обученный на синтетических данных) → извлечение исполнителя/срока. При недоступности AI worker используется демо-результат.
Ключевые решения
- Whisper small
- диаризация
- классификатор реплик-поручений
- извлечение дат/сроков
Особенности
Развёрнутый стенд и презентация в Canva; экспорт DOCX/PDF без внешнего конвертера; упор на on-premise и отсутствие облачных API. Однако публичный стенд работает на демо-результате без подключённого AI worker.
Стек
Next.js · NestJS · Prisma · PostgreSQL · TypeScript · Zod · Python · Docker Compose · nginx · pnpm
Модели
Whisper small
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-cc6c9023-itshechka.
README
README.mdHATTAMA AI
Совещание заканчивается — и поручения теряются, сроки забываются, непонятно кто отвечает, а протокол приходится составлять вручную. Важные решения остаются в разговоре вместо того, чтобы превращаться в действия.
HATTAMA AI превращает разговор в систему контроля: фиксирует главное, назначает ответственных и следит за исполнением поручений.
Монорепозиторий системы автоматического протоколирования совещаний с распознаванием русской, казахской и смешанной речи, выделением поручений и контролем сроков.
HATTAMA — латинизированное казахское слово «хаттама» (протокол). Название напрямую объясняет продукт и одинаково хорошо читается на русском, казахском и английском.
Что делает HATTAMA AI
- определяет говорящих (диаризация);
- автоматически выделяет поручения и решения из разговора;
- формирует краткое саммари встречи;
- распознаёт речь на русском, казахском и шала-казахском (смешанном) языке — один разговор, три языковых режима, AI понимает контекст даже когда языки смешиваются;
- назначает ответственного, задачу и срок по каждому поручению (например: «Алия, приготовь отчеты до пятницы» → ответственный: Алия, задача: подготовить отчёт, срок: до пятницы);
- экспортирует протокол в PDF/DOCX;
- контролирует исполнение поручений и присылает напоминания.
Ссылки для жюри
Демо-аккаунты для входа — в разделе «Доступ для демонстрации» ниже.
HATTAMA AI — прототип локально развёртываемого сервиса для протоколирования совещаний. Веб-приложение позволяет загрузить запись, просмотреть транскрипт, исправить поручения и скачать протокол в DOCX или PDF. Публичный стенд демонстрирует интерфейс и backend; при отсутствии подключённого AI worker обработка использует демо-результат. Локальное распознавание двух MP3 проверено отдельно.
Структура
.
├── apps/
│ ├── api/ # NestJS, Prisma и PostgreSQL
│ └── web/ # Next.js frontend
├── packages/
│ └── contracts/ # единые Zod-схемы и TypeScript-типы
└── ml/ # локальный STT, диаризация и анализ текста
apps/web и apps/api используют один pnpm workspace и один пакет @hackalem/contracts. Frontend взаимодействует с ML только через REST API backend.
Архитектура решения
Современный стек, готовность к on-premise.
Аудио/видео → Frontend → Backend API → PostgreSQL + AI pipeline.
AI pipeline: STT (RU/KZ/mixed) → диаризация → извлечение поручений → поручения с дедлайнами + саммари → протокол → экспорт в PDF/DOCX, dashboard поручений и напоминания.
- Frontend принимает аудио/видео и отображает протокол.
- Backend сохраняет запись и запускает локальный AI-пайплайн.
- ML распознаёт речь, разделяет спикеров, извлекает поручения и формирует саммари.
- Результат сохраняется в БД и доступен пользователю в виде транскрипта, action items, summary, export и dashboard поручений.
Безопасность и конфиденциальность
- локальная обработка данных;
- self-hosted AI;
- без передачи данных во внешние облачные API;
- готовность к on-premise;
- защита конфиденциальной информации.
Быстрый старт
corepack pnpm install
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env.local
docker compose up -d postgres
corepack pnpm prisma:generate
corepack pnpm --filter @hackalem/api exec prisma migrate deploy
corepack pnpm prisma:seed
corepack pnpm dev
- Frontend:
http://localhost:3000 - API:
http://localhost:4000/api/v1 - Swagger:
http://localhost:4000/api/docs - Health:
http://localhost:4000/api/v1/health
Запуск целиком в Docker
docker compose up -d --build
docker compose exec api pnpm prisma:seed
docker compose ps
Compose запускает PostgreSQL, API и web, применяет миграции при старте API и сохраняет базу и загруженные файлы в Docker volumes. Сайт доступен на http://localhost:3000, API — на http://localhost:4000/api/v1. Повторный seed обновляет демо-аккаунты и демо-встречу. Для остановки: docker compose down (данные в volumes сохраняются).
Демо на отдельном сервере
Публичный адрес текущего развёртывания: http://46.225.138.70:3001. На сервере проект лежит в /opt/hackalem; только gateway публикует порт 3001, API, web и PostgreSQL доступны внутри отдельной Docker-сети. Порты существующих сайтов 80/443/3000 не меняются.
Для повторного запуска на сервере:
cd /opt/hackalem
docker compose -f compose.yaml -f compose.remote.yaml up -d --no-build --pull never
docker compose -f compose.yaml -f compose.remote.yaml ps
Перед первым запуском deploy/setup-remote.sh создаёт закрытый .env со случайными секретами. Готовые образы передаются скриптом deploy/push-images.py; web-образ нужно собирать с NEXT_PUBLIC_API_URL=http://46.225.138.70:3001/api/v1. Для HTTPS нужен отдельный домен и маршрут в nginx.
Доступ для демонстрации
После миграции и corepack pnpm prisma:seed доступны два готовых аккаунта:
| Роль | Пароль | |
|---|---|---|
| Жюри | [email protected] | Jury2026! |
| Администратор | [email protected] | Admin2026! |
На странице входа аккаунт можно выбрать одним нажатием. В production эти пароли необходимо заменить.
Frontend по умолчанию подключён к реальному API. Для автономной демонстрации без backend установите NEXT_PUBLIC_USE_MOCKS=true в apps/web/.env.local и перезапустите Next.js.
Основные команды
corepack pnpm dev:web
corepack pnpm dev:api
corepack pnpm typecheck
corepack pnpm lint
corepack pnpm build
Реализовано
- multipart-загрузка аудио через
POST /api/v1/meetings/:id/audio-fileи backend WebSocket для live-чанков; - AI-оркестратор с локальным worker-адресом и demo-fallback при его недоступности;
- сквозной демо-сценарий frontend → загрузка аудио → backend → протокол;
- транскрипт, спикеры, темы, саммари и поручения;
- реестр поручений и обновление статусов;
- экспорт протокола в DOCX/PDF без внешнего конвертера;
- адаптивный frontend с RU/KZ/mixed интерфейсом;
- публичный продуктовый лендинг, регистрация и вход;
- серверные HttpOnly-сессии и защищённые API-маршруты;
- единые контракты между web и API.
Подробности frontend находятся в apps/web/README.md, границы ML-компонента — в ml/README.md. Проверка backend и ограничения реального MP3-пути описаны в backend smoke.
Локальная ML-часть
Исходники ML и воспроизводимые синтетические выборки находятся в ml/. Эталонные протоколы, транскрипты и два MP3 сохранены локально в ml/data/private/; эта папка исключена из Git. ml/SHA256SUMS.json содержит контрольные хеши комплекта, включая локальные приватные файлы. Обученный детектор реплик с поручениями хранится в ml/models/action_detector.json.
Для повторного обучения детектора используйте Python 3.11. Отдельное окружение и зафиксированные зависимости описаны в инструкции ML. Из каталога ml/:
python ml.py generate-data --seed 42
python ml.py train
python -m unittest discover -s tests -v
python ml.py rank --transcript data/demo/transcript.json --out outputs/demo_candidates.json
train обучает только вспомогательный классификатор на синтетическом тексте. MP3 не используются для его обучения; для запуска полного аудиопайплайна нужны отдельная аудиосреда и локальные веса моделей.
Оба исходных MP3 уже прошли локальное распознавание Whisper small и оценку текстовым детектором. Измерения и границы результата описаны в отчёте аудиопроверки. Полные ASR JSON сохраняются локально в ml/outputs/ и исключены из Git.
Известные ограничения
- Публичный стенд демонстрирует интерфейс и backend; при отсутствии подключённого AI worker обработка использует демо-результат.
- Локальное распознавание проверено на двух MP3-файлах отдельно от публичного стенда.
trainобучает только вспомогательный классификатор на синтетическом тексте; MP3 в его обучении не используются. Для запуска полного аудиопайплайна нужны отдельная аудиосреда и локальные веса моделей.- На публичном стенде возможны JS-ошибки в консоли браузера.
Авторы коммитов
История коммитов
- 2026-09-23 17:49Readme.mdLYNT1K1
- 2026-09-23 17:35Merge branch 'main' of https://github.com/BAITC-Hacks/hack-cc6c9023-itshechkaSoginasa
- 2026-09-23 17:34готово техничкаSoginasa
- 2026-09-23 17:29Add local RU-KZ speech pipeline and HATTAMA brandingSoginasa
- 2026-09-23 16:55DockerLYNT1K1
- 2026-09-23 16:55addmunikosh
- 2026-09-23 16:15smthLYNT1K1
- 2026-09-23 16:15Merge branch 'main' of https://github.com/BAITC-Hacks/hack-cc6c9023-itshechkaLYNT1K1
Все коммиты (23)
- 2026-09-23 16:07backend2LYNT1K1
- 2026-09-23 16:00designSoginasa
- 2026-09-23 15:32addmunikosh
- 2026-09-23 15:21front and back is connectedSoginasa
- 2026-09-23 14:43Addmunikosh
- 2026-09-23 14:42backend1LYNT1K1
- 2026-09-23 14:32feat(web): complete interactive frontend demoSoginasa
- 2026-09-23 14:07min fixesSoginasa
- 2026-09-23 14:00Merge branch 'main' of https://github.com/BAITC-Hacks/hack-cc6c9023-itshechkaSoginasa
- 2026-09-23 13:56connected 1/2Soginasa
- 2026-09-23 13:45Update README.mdLYNT1K1
- 2026-09-23 13:45Create README.mdLYNT1K1
- 2026-09-23 13:45BackendLYNT1K1
- 2026-09-23 13:44basics of frontendSoginasa
- 2026-09-23 13:44BackendLYNT1K1
Структура репозитория (150 файлов)
.dockerignore .gitignore .npmrc Dockerfile README.md apps/api/.env.example apps/api/package.json apps/api/prisma/migrations/20260923093220_init/migration.sql apps/api/prisma/migrations/20260923143000_add_task_priority/migration.sql apps/api/prisma/migrations/20260923183000_add_auth/migration.sql apps/api/prisma/migrations/migration_lock.toml apps/api/prisma/schema.prisma apps/api/prisma/seed.ts apps/api/scripts/smoke.ts apps/api/src/app.module.ts apps/api/src/common/api-error.ts apps/api/src/common/auth/auth.guard.ts apps/api/src/common/auth/public.decorator.ts apps/api/src/common/auth/session.ts apps/api/src/common/filters/api-exception.filter.ts apps/api/src/common/password.ts apps/api/src/common/pipes/zod-validation.pipe.ts apps/api/src/common/serialize.ts apps/api/src/config/env.schema.ts apps/api/src/main.ts apps/api/src/modules/ai/ai-orchestrator.service.ts apps/api/src/modules/ai/ai.controller.ts apps/api/src/modules/ai/ai.module.ts apps/api/src/modules/ai/demo-adapter.ts apps/api/src/modules/auth/auth.controller.ts apps/api/src/modules/auth/auth.module.ts apps/api/src/modules/auth/auth.service.ts apps/api/src/modules/exports/exports.controller.ts apps/api/src/modules/exports/exports.module.ts apps/api/src/modules/exports/exports.service.ts apps/api/src/modules/exports/protocol-docx.builder.ts apps/api/src/modules/exports/protocol-pdf.builder.ts apps/api/src/modules/health/health.controller.ts apps/api/src/modules/health/health.module.ts apps/api/src/modules/live/live.gateway.ts apps/api/src/modules/live/live.module.ts apps/api/src/modules/meetings/meetings.controller.ts apps/api/src/modules/meetings/meetings.module.ts apps/api/src/modules/meetings/meetings.service.ts apps/api/src/modules/tasks/tasks.controller.ts apps/api/src/modules/tasks/tasks.module.ts apps/api/src/modules/tasks/tasks.service.ts apps/api/src/modules/transcript/transcript.controller.ts apps/api/src/modules/transcript/transcript.module.ts apps/api/src/modules/transcript/transcript.service.ts apps/api/src/prisma/prisma.module.ts apps/api/src/prisma/prisma.service.ts apps/api/tsconfig.json apps/web/.env.example apps/web/README.md apps/web/eslint.config.mjs apps/web/next-env.d.ts apps/web/next.config.ts apps/web/package.json apps/web/postcss.config.mjs apps/web/src/app/dashboard/page.tsx apps/web/src/app/globals.css apps/web/src/app/layout.tsx apps/web/src/app/loading.tsx apps/web/src/app/login/page.tsx apps/web/src/app/meetings/[id]/page.tsx apps/web/src/app/meetings/page.tsx apps/web/src/app/new/page.tsx apps/web/src/app/page.tsx apps/web/src/app/register/page.tsx apps/web/src/app/tasks/page.tsx apps/web/src/components/app-shell.tsx apps/web/src/components/brand.tsx apps/web/src/components/ui/button.tsx apps/web/src/components/ui/card.tsx apps/web/src/components/ui/confirm-dialog.tsx apps/web/src/components/ui/sheet.tsx apps/web/src/components/ui/status-badge.tsx apps/web/src/features/auth/api.ts apps/web/src/features/auth/auth-provider.tsx apps/web/src/features/demo/demo-store.tsx apps/web/src/features/meetings/api.ts apps/web/src/features/meetings/audio-player.tsx apps/web/src/features/meetings/demo-utils.test.ts apps/web/src/features/meetings/demo-utils.ts apps/web/src/features/meetings/export-controls.tsx apps/web/src/features/meetings/hooks.ts apps/web/src/features/meetings/mock-data.ts apps/web/src/features/meetings/types.ts apps/web/src/lib/api.ts apps/web/src/lib/providers.tsx apps/web/src/lib/utils.ts apps/web/tsconfig.json compose.remote.yaml compose.yaml deploy/nginx.conf deploy/push-images.py deploy/set-public-origin.sh deploy/setup-remote.sh docs/backend-smoke.md docs/frontend-decisions.md docs/ml-audio-smoke.md ml/README.md ml/SHA256SUMS.json ml/data/demo/expected.json ml/data/demo/transcript.json ml/data/synthetic/manifest.json ml/data/synthetic/test.jsonl ml/data/synthetic/train.jsonl ml/data/synthetic/validation.jsonl ml/docs/BACKEND_CONTRACT.md ml/docs/DATA_COLLECTION.md ml/docs/HACKATHON_PLAN.md ml/docs/SOURCES.md ml/integration_example.py ml/meeting_ml/__init__.py ml/meeting_ml/audio.py ml/meeting_ml/backend_adapter.py ml/meeting_ml/bundle.py ml/meeting_ml/classifier.py ml/meeting_ml/cli.py ml/meeting_ml/common.py ml/meeting_ml/dates.py ml/meeting_ml/evaluate.py ml/meeting_ml/export.py ml/meeting_ml/extract.py ml/meeting_ml/prepare.py ml/meeting_ml/synthetic.py ml/ml.py ml/models/action_detector.json ml/models/download_manifest.json ml/quickstart.ps1 ml/quickstart.sh ml/reports/training_metrics.json ml/reports/verification.json ml/requirements-audio.txt ml/requirements.txt ml/tests/test_core.py package.json packages/contracts/package.json packages/contracts/src/ai-worker.ts packages/contracts/src/auth.ts packages/contracts/src/common.ts packages/contracts/src/exports.ts packages/contracts/src/index.ts packages/contracts/src/meetings.ts packages/contracts/src/tasks.ts packages/contracts/src/transcript.ts pnpm-lock.yaml pnpm-workspace.yaml
Ветки (2)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.