Career Quest · KOMO
AI-навигатор развития: сотрудник выбирает цель, получает объяснимые рекомендации активностей, начинает/планирует их и видит рост навыков; HR видит…
О проекте
Команда: KOMO
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Доведённый продукт
Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития
Суть
AI-навигатор развития: сотрудник выбирает цель, получает объяснимые рекомендации активностей, начинает/планирует их и видит рост навыков; HR видит дефициты компетенций и импортирует профили.
Как устроено
Датасет career_quest (employees, skills, events, activity_history) сидится в PostgreSQL через Alembic-миграции. Сервер формирует допустимых кандидатов и агрегаты истории (последние 180 дней, формат, средние оценки), модель gpt-4.1-mini выбирает и объясняет рекомендации минимум тремя группами фактов; при ошибке/таймауте 8 с — «Подобрано по правилам · без AI». Кеш в Redis привязан к контексту сотрудника; выполнение активности начисляет навыки с запретом повторного начисления.
Ключевые решения
- LLM ранжирование допустимых кандидатов
- агрегаты истории участия
- проверка устойчивости к порядку кандидатов
- Redis-кеш
- импорт Excel/JSON шаблонов
- Playwright e2e
Особенности
Собственный QA-скрипт verify-ai на 10 синтетических профилях с ожиданиями: проверяет, что выбор модели меняется при противоположной истории участия и не зависит от порядка кандидатов (verify-history). Отдельный изолированный jury-стенд через --env-file и -p.
Стек
Python · FastAPI · SQLAlchemy · PostgreSQL · Redis · Alembic · Next.js · TypeScript · Docker Compose · Playwright
Модели
gpt-4.1-mini-2025-04-14
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-d98d69cd-komo.
README
README.mdCareer Quest · KOMO
AI-навигатор развития сотрудника для HackAlem AI / Halyk Bank. Сотрудник выбирает цель, получает объяснимые рекомендации, начинает или планирует активность и видит изменение навыков после подтверждения выполнения. HR видит дефициты компетенций, участие и сотрудников без актуального шага, импортирует новые профили и историю.
Стек: Python 3.12 / FastAPI / SQLAlchemy / PostgreSQL / Redis; Next.js / TypeScript. Модульный монолит, четыре сервиса Docker Compose. Данные синтетические.
Визуальное руководство по платформе
Открыть визуальную документацию со скриншотами — рассказ о том, как работает Career Quest, с пояснениями к экранам и действиям пользователей. Руководство поможет быстрее разобраться в интерфейсе и сориентироваться на платформе.
Инструкция по локальному запуску приведена ниже в этом README. О том, где открыть учебные ссылки и как учитывается выполнение, — в разделе «Материалы к активностям».
Локальный запуск для проверки жюри
Нужны запущенный Docker Desktop / Engine, Docker Compose 2.24+, интернет для первой сборки и AI, свободные порты 3000 и 8000. На этом Mac проверены Docker 28.5.1 и Compose 2.40.3. Python и Node на хосте для запуска приложения не нужны. Изолированный запуск из копии файлов и пустой БД проверяется отдельно от рабочего проекта; это не проверка на другой ОС.
Инструкция относится к этой версии файлов. Получите итоговый коммит или архив проекта; незапушенные локальные изменения отсутствуют в GitHub. Для клонирования репозитория организатора нужен доступ:
git clone https://github.com/BAITC-Hacks/hack-d98d69cd-komo.git
cd hack-d98d69cd-komo
docker info
docker compose version
Для первого запуска скопируйте .env.example в .env: cp .env.example .env в macOS/Linux или Copy-Item .env.example .env в PowerShell. Не перезаписывайте существующий .env. Откройте его редактором и заполните OPENAI_API_KEY демонстрационным ключом, переданным отдельно. Реальные ключи не входят в репозиторий. Затем одна команда:
docker compose up -d --build
Дождитесь успешного завершения команды, откройте http://localhost:3000. Миграции 0001 → 0002 → 0003, исходный датасет и аккаунты создаются автоматически. Проверка состояния:
docker compose ps
curl http://localhost:3000/api/v1/ready
В PowerShell можно открыть этот URL браузером или использовать curl.exe. Ответ {"status":"ready","database":"ok"} проверяет API и PostgreSQL; не подтверждает AI. Для проверки модели используйте раздел ниже.
| Роль | Логин | Пароль по умолчанию |
|---|---|---|
| Сотрудник E0028 | employee | employee-demo-2026 |
| HR | hr | hr-demo-2026 |
Это публичные демо-доступы к синтетическому локальному приложению. При изменении паролей в конфигурации действуют новые значения. Сотрудник видит только свой профиль; HR читает профили и импортирует данные, но не меняет чужие цели и участия.
Повторный запуск сохраняет цели, импорт, учетные записи сотрудников и завершения. Начальная загрузка не перезаписывает датасет в существующей БД. Команда остановки — docker compose down; данные остаются в volume. Не используйте down -v для рабочей БД. PostgreSQL и Redis не публикуют порты. Web и диагностический API привязаны к 127.0.0.1; этот комплект рассчитан на локальный запуск.
Конфигурация и реальный AI
| Переменная | Значение / назначение |
|---|---|
OPENAI_API_KEY | Ключ для OpenAI API; без него работает явно обозначенный fallback |
OPENAI_KEY | Альтернативное имя; OPENAI_API_KEY имеет приоритет |
OPENAI_MODEL | gpt-4.1-mini-2025-04-14; доступность зависит от выданного ключа |
EMPLOYEE_ID | E0028; должен существовать в загруженной БД |
EMPLOYEE_PASSWORD, HR_PASSWORD | Демо-пароли из таблицы; применяются при каждом запуске API |
SESSION_SECRET | Можно оставить пустым: подпись cookie генерируется один раз и сохраняется в БД |
WEB_PORT, API_PORT | 3000, 8000; при конфликте задайте свободные порты |
APP_ORIGIN | http://localhost:3000; должен совпадать с адресом в браузере |
APP_EXTRA_ORIGINS | По умолчанию http://localhost:3000,http://127.0.0.1:3000; дополнительные разрешенные адреса через запятую |
APP_ENV_FILE | Файл окружения API, по умолчанию .env; для демо экспертов .env.jury |
DATABASE_URL, REDIS_URL, DATASET_PATH заданы внутри Compose: адреса postgres, redis, путь /data. Для Docker не заменяйте их на localhost. API_INTERNAL_URL для Next.js — http://api:8000. При нестандартном web-порте измените также origin. Один лишь WEB_PORT не обновляет origin.
После изменения ключа, паролей или origin в .env примените настройки (при изменении портов пересоздайте также web):
docker compose up -d --force-recreate api
Проверка реального AI на новых полностью синтетических профилях, с заданными ожиданиями и без кеша:
docker compose exec -T api python -m app.qa_acceptance verify-ai --repeats 1
Скрипт добавляет десять QA-профилей, делает девять запросов модели и отдельно проверяет пустую цель без вызова модели. Успех — все quality_pass: true, непустые случаи source: ai, cached: false, время менее 10 секунд, код завершения 0. Fallback в непустом случае дает ошибку проверки. Для трех повторов каждого случая используйте --repeats 3 (27 платных API-запросов). Четыре случая сравнивают одинаковые цели и навыки при противоположной истории участия: выбор должен меняться, а старая история не должна перевешивать недавние пропуски. На обычном демо-сотруднике также доступен python -m app.smoke_ai --fresh; если его цель уже выполнена, используйте новые QA-профили.
Дополнительная проверка влияния истории без перестановки кандидатов серверным рейтингом:
docker compose exec -T api python -m app.qa_acceptance verify-history
Она делает восемь прямых вызовов той же модели на синтетических профилях: фиксированный и обратный порядок одинаковых кандидатов. Проверяет ожидаемый выбор и ссылки на факты истории; не изменяет БД. Это дополнение к проверке API и браузера, не их замена.
Таймаут модели — 8 секунд, автоматических повторов нет. Ошибка ключа, квоты, сети, таймаут или невалидный ответ дают явно обозначенный «Подобрано по правилам · без AI». В модель отправляются роль, грейд, стаж, цель, навыки, допущенные активности и агрегаты истории (участия в конкретном событии, последние 180 дней, формат, средние оценки с числом наблюдений); имя, ID сотрудника, руководитель и сырые записи истории исключены. Ключ используется только backend; .env* исключены из Docker-образов и Git, кроме безопасных примеров.
Отдельный запуск для экспертов
Скопируйте .env.jury.example в .env.jury, внесите отдельный демонстрационный ключ. Настройки примера используют порты 3002 / 8002, правильный origin и отдельный файл окружения API. Существующий .env.jury не перезаписывайте.
docker compose --env-file .env.jury -p career-quest-jury up -d --build
docker compose --env-file .env.jury -p career-quest-jury exec -T api python -m app.qa_acceptance verify-ai --repeats 1
Откройте http://localhost:3002. Для одновременной работы с проектами на 3000 и 3002 используйте отдельный профиль браузера или инкогнито: cookie localhost общие для портов. Это отдельная БД (career-quest-jury_postgres_data), не рабочий прогресс на 3000. Во всех командах этого запуска используйте оба параметра --env-file .env.jury -p career-quest-jury, включая logs, exec, restart, down. При обновлении ключа повторите up -d --force-recreate api с теми же параметрами.
Отдельный ключ проверен локально успешными свежими AI-вызовами. Его передача экспертам, срок действия и достаточный баланс до окончания проверки должны быть обеспечены отдельно через разрешенный организатором канал. Ключ не публикуется в README, Git или скриншотах. Локальная успешная проверка не подтверждает передачу доступа организатору.
Сквозной сценарий сотрудника
- Войти как сотрудник: открыть цель, соответствие требованиям, навыки и историю.
- Нажать «Изменить цель», выбрать роль и грейд, проверить требования и «Сохранить цель». Кнопка «Предложить цель по текущей роли» возвращает автоматическую цель. Текущий грейд и навыки не меняются; меняется цель сравнения.
- Нажать «Подобрать с AI» или «Обновить подбор». Открыть «Почему вам это подходит»: минимум три группы проверяемых фактов, ожидаемые навыки и прогресс. Если к активности добавлены материалы, нажать «Открыть материал» в блоке «Материалы по теме» или «Для подготовки к занятию». Ссылка откроется в новой вкладке; после возвращения участие и прогресс останутся прежними.
- В карточке AI нажать «Начать →» для рекомендованного самостоятельного курса, затем в диалоге «Начать активность». Другой путь: вкладка «Подходящие активности» → «Начать» → «Начать активность». Он появится в «Мои активности» со статусом «В процессе», без начисления навыков.
- После прохождения вне платформы открыть «Продолжить» → «Отметить выполненным». Показаны изменения до/после, обновлены история и подбор. В демо это собственное подтверждение сотрудника, без проверки учебной системой.
- Обновить страницу: результат сохранен. Изменение цели не скрывает начатые активности и не запрещает их завершение только из-за новой цели.
- Для мероприятия по расписанию: «Запланировать участие →» в рекомендации или «Запланировать» в списке активностей → дата из каталога → «Запланировать участие». Это локальная запись, не внешняя регистрация. До даты сессии завершение запрещено. Локальное незавершенное участие можно отменить.
На уже использованном E0028 курс «Подготовка к сертификации по облачным технологиям» может быть завершен. Это корректно: повторное начисление запрещено. Для повторения полного демо используйте новый профиль, описанный ниже, без очистки рабочей БД.
HR и импорт
В «Обзоре команды» доступны частота дефицитов, участие по всем статусам и сотрудники без актуального шага с причинами. Поиск ведет в профиль сотрудника; HR может запросить подбор и создать доступ к приложению, но не выполнять активность за сотрудника. Тестовые профили QA_… по умолчанию исключены из списка и всех агрегатов вместе со своей историей. Переключатель «Показать тестовые данные» включает их, не удаляя данные. Метка тестового профиля сохраняется в БД; обычные новые ID считаются рабочими.
На /hr/import выберите формат и нажмите «Скачать шаблон»: Excel (.xlsx) или JSON с синтетическим примером. Замените пример своими данными и загрузите в «Профили сотрудников». Один файл может включать и профили, и историю — тогда второй файл не нужен.
- Excel: лист
employees— полные профили,employee_skills— строкиemployee_id, skill_id, level,history— история. Листыroles,skills,eventsсодержат справочники;instructions— инструкцию. Названия листов и колонок сохраняйте, порядок колонок можно менять. Пустые строки пропускаются. Даты — ячейки Excel илиYYYY-MM-DD. Формулы перед загрузкой замените значениями. Старые.xlsпересохраните как.xlsx. - JSON: исходный
{meta, employees}, массив профилей или общий{meta, employees, history}. При отсутствииmetaприменяется Career Quest 1.0, срез 2026-10-01. Для отдельной истории — массив записей или{history: [...]}. - История отдельно: Excel с листом
history, JSON или CSV в UTF-8. CSV принимает запятую или точку с запятой, порядок исходных колонок свободный. Можно совместить JSON профилей и Excel/JSON/CSV истории. Один вид данных нельзя передавать сразу в двух файлах. - Для импорта только профилей удалите строки примера на
historyили сам лист. Для импорта только истории оставьтеhistoryи справочники. Пустойemployee_skillsозначает отсутствие оценок. Профили заменяются целиком — это не частичное обновление отдельных полей. - Лимиты: 4 МБ на файл, 2000 профилей / 20 000 участий за запрос; распакованный Excel до 32 МБ. Ошибки структуры Excel указывают лист, строку и поле, ошибки связей — ID профиля или участия. Новые ID поддерживаются.
API шаблона: GET /api/v1/hr/import/template?format=xlsx|json, только для HR. Шаблоны хранятся в backend/app/features/data_import/templates и входят в Docker-образ. OpenAPI и TypeScript-типы обновлены.
Проверяются значения, статусы, ссылки, роли/грейды, навыки и дата среза. Повторные ID внутри пакета отклоняются; идентичный повторный импорт не добавляет записи. Повторное завершение одного добровольного курса с другим ID также отклоняется — и внутри пакета, и относительно сохраненной истории. Для EV_036 и периодических обязательных обучений различаются даты участия; дубль одной даты запрещен. Ошибка содержит ID сотрудника, активности и конфликтующих записей. Обновления атомарны. Подтвержденные в приложении выполнения нельзя молча перезаписать импортом; несовместимый срез отклоняется.
После импорта откройте «Профиль ↗» сотрудника → «Доступ сотрудника». Введите или сохраните предложенный пароль (от 10 символов), нажмите «Создать доступ», передайте сотруднику показанный логин и пароль. Доступ работает для любого нового ID, не только QA. Пароль хранится в виде Argon2-хеша и не возвращается API; после ухода со страницы его нельзя просмотреть. Повторное создание дает конфликт, повторный импорт не сбрасывает доступ. Самостоятельная регистрация и восстановление пароля в MVP отсутствуют.
Три собственных синтетических примера в docs/fixtures/ проверяют критический разрыв против минимального навыка, prerequisites/потолки и смену роли без истории. Это не профили жюри.
Повторяемый E2E и новое демо
Тесты добавляют синтетические данные в выбранную БД; исходный E0028 и его прогресс не сбрасываются. Каждый запуск использует новые QA_R3_… ID. Для ручного демо без Python на хосте:
mkdir -p artifacts/round3
docker compose exec -T api python -m app.qa_acceptance prepare > artifacts/round3/demo.json
docker compose exec -T api python -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps(d["bundle"], ensure_ascii=False))' < artifacts/round3/demo.json > artifacts/round3/employees.json
docker compose exec -T api python -c 'import json,sys; print(json.load(sys.stdin)["history_csv"], end="")' < artifacts/round3/demo.json > artifacts/round3/history.csv
Команды перенаправления выше рассчитаны на macOS/Linux shell. В demo.json найдите employee_id, импортируйте полученные employees.json и history.csv через HR. В HR включите «Показать тестовые данные», найдите ID, откройте профиль и создайте доступ через «Доступ сотрудника». Для повторяемого демо можно задать qa-demo-r2 (10 символов). Выйдите из HR и войдите с показанным логином и выбранным паролем. Нажмите «Подобрать с AI», затем «Начать →» на первом рекомендованном курсе, подтвердите начало и выполнение. У этого синтетического профиля доступны два самостоятельных курса, поэтому после первого завершения есть следующий шаг. В HR включите показ тестовых данных и найдите этот ID.
Автоматические проверки
Backend использует настоящий PostgreSQL, а ответы модели в тестах подменены. Это проверка логики и ошибок, не доказательство реального AI:
docker compose exec -T api python -m pytest -q
Для браузерных тестов нужны Node.js 22, Docker CLI на хосте и запущенное приложение:
cd frontend
npm ci
npm run typecheck
npm run build
npx playwright install chromium
npm run test:e2e
Если установлен Google Chrome, вместо скачивания Chromium: PLAYWRIGHT_CHANNEL=chrome npm run test:e2e в macOS/Linux. Используется новый временный профиль браузера, личные сессии не нужны. PowerShell: $env:PLAYWRIGHT_CHANNEL="chrome"; npm run test:e2e.
По умолчанию тесты открывают http://localhost:3000 и вызывают CLI основного Compose-проекта из корня репозитория. При другом проекте задайте согласованные адрес и имя, например для экспертного демо:
TEST_BASE_URL=http://localhost:3002 COMPOSE_PROJECT_NAME=career-quest-jury PLAYWRIGHT_CHANNEL=chrome npm run test:e2e
При измененных демо-паролях передайте HR_PASSWORD и EMPLOYEE_PASSWORD в окружении тестов. Не запускайте с URL одного проекта и CLI другого. Для PowerShell задайте эти переменные через $env:ИМЯ="значение" перед npm run test:e2e.
E2E: загрузка шаблонов Excel/JSON → импорт и повтор → создание доступа в HR → вход нового сотрудника → сохранение цели → свежий реальный AI → начало и выполнение именно выбранной моделью активности → рост прогресса → reload → другой следующий шаг → HR-фильтр и профиль. Дополнительно — планирование, запрет досрочного завершения, отмена, мобильная ширина и ошибки импорта. Нет рабочего API-ключа — основной E2E должен упасть, fallback не засчитывается.
Скриншоты и JSON-результат — artifacts/round3/, импорт — artifacts/import-formats/; каталог можно переопределить через TEST_ARTIFACT_DIR; они игнорируются Git. В flow-result.json записываются выбранный event ID, следующий шаг, прогресс и браузерные ошибки. Тестовые записи сохраняются и не влияют на обычный HR-обзор.
Перезапуск и чистая установка
docker compose restart api web сохраняет данные. После правок кода нужен docker compose up -d --build, после правок .env — пересоздание API, а не просто restart.
Для независимого повторения установки используйте свежий clone/архив файлов и отдельный экспертный Compose-проект по инструкции выше. У него должен быть новый project name, чтобы Docker создал пустой volume. Измените порты и origin, если 3002/8002 заняты. Не удаляйте рабочий volume ради проверки чистого запуска.
Дополнительно: frontend в dev-режиме
Этот раздел нужен только разработчикам. Для проверки жюри достаточно Docker и http://localhost:3000 из первого раздела; dev-сервер и доступ по локальной сети не требуются.
Для frontend-разработки установите Node.js 22, оставьте API на 8000, остановите контейнер web (docker compose stop web) и из папки frontend выполните:
npm ci
API_INTERNAL_URL=http://127.0.0.1:8000 npm run dev -- --port 3000
Откройте http://localhost:3000. После разработки остановите dev-сервер и выполните docker compose up -d web, чтобы вернуться к Docker-версии.
Для командной разработки по LAN --hostname 0.0.0.0 уже задан в npm-скрипте. Текущий IP разработчика внесен в frontend/next.config.ts → allowedDevOrigins; при смене сети обновите его и перезапустите dev-сервер. IP указывается без протокола и порта. Для API полный адрес с портом дополнительно внесите в APP_EXTRA_ORIGINS, затем docker compose up -d --force-recreate api. Это отдельная настройка разработки, не часть запуска для жюри.
Диагностика
- Docker daemon недоступен: запустите Docker Desktop/Engine и проверьте
docker info. - Порт занят: поменяйте
WEB_PORT/API_PORT; для web одновременно обновитеAPP_ORIGINи разрешенные origin. - Вход дает
invalid_origin/403: адрес браузера должен входить вAPP_ORIGINилиAPP_EXTRA_ORIGINS; пересоздайте API после изменения. - AI показывает резервный подбор:
docker compose logs --tail=60 api.status=401— неверный ключ; 429 — квота/лимит; timeout — сеть или провайдер. Ключ не вставляйте в тикеты и логи. Повторитеverify-aiпосле исправления. - Пароль не подходит: проверьте настройки и перезапустите API; seed применяет выбранные демо-пароли.
- API не готов: проверьте
docker compose psиdocker compose logs --tail=80 api postgres. Все три миграции должны быть в checkout; не удаляйте данные и не подменяйте версию миграции вручную. - Цель выполнена или нет допустимых шагов: пустой результат с причиной корректен. Для полного сценария импортируйте свежий QA-профиль.
Архитектура и правила
Browser → Next.js /api/v1 proxy → FastAPI → PostgreSQL / Redis / OpenAI Responses API.
Фичи backend: identity, catalog, employees, development, recommendations, hr_analytics, data_import. Все предметные расчеты принадлежат development; frontend показывает данные API. PostgreSQL — источник истины, Redis — необязательный кеш на 5 минут.
- Названия и описания 40 активностей и названия навыков показаны по-русски. Исходные ID, файлы датасета и правила расчета сохранены. Технические названия вроде Python, TypeScript и React остаются без перевода.
- Исходный набор: 200 сотрудников, 40 событий, 60 навыков, 32 профиля ролей/грейдов, 2743 участия. Исходные файлы не изменяются.
- Расчетное сегодня фиксировано: 2026-10-01. Оно не двигается с системным временем; часы сервера нужны для TTL и служебных отметок.
- Базовые навыки — на
last_review_date. Последующие завершения учитываются по формулеmax(current, min(5, max_level, current + gain)). - Для импортированной self-paced истории дата строки — приближение даты учета. Завершение в день оценки считается включенным в базу; новое локальное подтверждение в тот же день начисляется после базы.
- Начало, планирование и отмена не дают навыков. Повторное завершение защищено транзакцией, блокировкой и квитанцией идемпотентности; повтор с другим содержимым дает конфликт.
- Обязательные события не рекомендуются. Исторический прирост EV_004 учитывается. Завершенные события не повторяются, кроме отдельных сессий EV_036.
- Допуски: текущая роль/грейд, требования к участию, расписание, история и полезный прирост. Вместе с прямыми шагами проверяется один подготовительный переход, включая совместимость дат сессий. Приоритет: прямой критический прирост → подготовка к критическому навыку → прочая польза с учетом истории и длительности. Это не планировщик произвольной многошаговой программы.
- Автоматическая цель — следующий грейд своей роли; для Lead — поддержание текущих требований. Ручная цель допускает другую роль и любой существующий грейд. Повышения грейда автоматически нет.
- Прогресс =
sum(min(current, required)) / sum(required) × 100; пустые требования дают 100%. Прогноз каждой активности независим от других карточек. - Backend создает проверяемые факты о цели, навыках, допусках и истории; модель выбирает 1–3 активности и факты минимум из трех групп. Проверяются ID, уникальность и принадлежность фактов. Числа и объяснения берутся из проверенных данных.
- Актуальность определяется
context_version: хеш данных сотрудника, его цели и истории, каталога, расчетной даты и версии логики. Действие другого сотрудника не сбрасывает подбор. Общая ревизия остается диагностической; HR не запускает массовые AI-запросы. - HR-завершенность = completed / все статусы, кроме planned и cancelled. В таблице показаны все группы, включая overdue; сумма групп равна числу участий.
Материалы к активностям
В рекомендациях и карточке активности есть блок «Материалы по теме», а для занятий по расписанию — «Для подготовки к занятию». Нажмите «Открыть материал»: источник откроется в новой вкладке, карточка останется доступна. Указаны название, источник, язык и упражнение или цель чтения.
Ссылки вручную сопоставлены с 30 из 40 активностей в backend/app/features/catalog/resources.py; это дополнительные материалы на английском, а не полные программы исходных курсов. Для остальных активностей интерфейс предлагает уточнить программу у HR. Исходный датасет не изменен. Адреса не генерируются моделью и не передаются в ее запрос: AI выбирает допустимую активность, backend добавляет связанные материалы. Источники перечислены в SOURCES.md.
Открытие ссылки не создает участия, не завершает курс и не начисляет навыки. «Начать активность» сохраняет участие; «Отметить выполненным» используйте после прохождения самой активности. В демо это подтверждение сотрудника, без проверки внешней платформой. Для занятий будущих дат прежний запрет досрочного завершения сохранен. Интернет нужен для внешних материалов; API-доступ OpenAI для их открытия не требуется.
После обновления проекта выполните docker compose up -d --build, обновите страницу браузера и нажмите «Подобрать с AI» или «Обновить подбор». Это загрузит рекомендации с материалами вместо старой версии без ссылок. Дополнительные переменные окружения и ручная миграция не нужны.
Что именно делает AI
Это AI-навигатор с подтверждением действий человеком: цель и состояние → проверка допустимых шагов → выбор модели → проверка результата → действие сотрудника → пересчет → новый выбор. Модель действительно выбирает между кандидатами, а не только пишет текст к фиксированному списку. Backend отвечает за допуски, числовые факты и сохранение результата. Это ограниченный рекомендательный агент; он не регистрирует человека во внешней LMS и не подтверждает реальное обучение.
Польза MVP — получить исполнимый следующий шаг и увидеть его вклад в карьерную цель; HR получает обзор дефицитов и участия. Рост навыков в демо основан на правилах датасета и собственном подтверждении сотрудника, а не на независимой оценке знаний.
API: http://localhost:3000/api/v1/docs. Swagger загружает UI с CDN; JSON /api/v1/openapi.json доступен локально. Снимок — docs/openapi.json; типы — frontend/src/shared/api/schema.d.ts.
Основные дополнительные маршруты: GET/POST /employees/{id}/access (только HR, создание локального доступа), GET /catalog/role-profiles, PATCH /employees/{id}/career-goal, POST /employees/{id}/activities/{event_id}/start, POST /employees/{id}/participations/{record_id}/cancel, refresh=true у POST рекомендаций. Все под /api/v1. Ключ идемпотентности обязателен для действий участия. После изменения контракта обновите OpenAPI и выполните npm run api:types в frontend.
Соответствие ТЗ и оценке
Источник: официальное ТЗ Career Quest, повторно прочитано 23.09.2026. Веса групп: работоспособность 25, техническая реализация 25, README/воспроизводимость 25, ценность 15, потенциал/оригинальность 10. Они не гарантируют баллы за наличие отдельных функций.
| Требование | Реализация | Проверка | Критерии |
|---|---|---|---|
| Профиль и траектория | Кабинет, навыки, цель, история, подходящие шаги | E2E сотрудника и HR, смена роли/автоцель | Работоспособность, ценность |
| 1–3 AI-шага | Responses API, проверенные кандидаты, проверка ответа | verify-ai, свежий вызов, новые профили | Работоспособность, техническая реализация |
| Минимум 3 фактора | Факты о профиле, навыках, истории и цели | Проверка fact IDs, принадлежности и групп | Техническая реализация, ценность |
| Прогресс после выполнения | Общий расчет, транзакция, идемпотентность | Start/complete, конкуренция, reload/restart | Работоспособность, техническая реализация |
| HR-view | Дефициты, отсутствие шага, участие по статусам | Сверка агрегатов и просмотр после E2E | Работоспособность, ценность |
| Проверочные профили | Атомарный импорт Excel/JSON/CSV с новыми ID | Импорт в браузере, повтор, ошибочный пакет | Работоспособность, воспроизводимость |
| Приватность и права | Собственный профиль, отдельная роль HR | 401/403, запрет чужих изменений | Техническая реализация |
| Скорость | AI-таймаут 8 с, кеш, локальные расчеты | Обычные ответы <2 с, AI <10 с | Работоспособность, техническая реализация |
| Запуск и документация | Compose, миграции, seed, инструкция | Чистая БД и новый project | README/воспроизводимость |
Смена цели и локальное участие — выбранные расширения, а не отдельные обязательные пункты ТЗ. Их ценность — сделать следующий шаг исполнимым в рамках демонстрационного учета. Добавлено дополнительное чтение для 30 активностей. Полные программы курсов, внешняя регистрация и проверка реального обучения не реализованы. Нет рейтингов, наград за обязательные процессы, реальных персональных данных, SSO, чата или автоматического повышения грейда.
Проверки четвертого прохода, до добавления материалов: 66 backend-тестов, по 3 браузерных сценария в рабочей и чистой установках; 27/27 реальных AI-ответов по заданным ожиданиям и 8/8 проверок независимости от порядка кандидатов. Чистая установка дополнительно прошла 9/9 AI-проверок с ключом жюри. Сборка слоев приложения проверена без кеша; новая БД заполнена автоматически. Это проверка на том же Mac, не испытание на другой ОС.
После добавления материалов отдельно прошли 66 backend-тестов, TypeScript, production-сборка и 3 браузерных сценария с реальным AI на основном localhost. E2E подтвердил: открытие Microsoft Learn не меняет навыки, прогресс и участия; после отдельного начала и подтверждения выполнения прогресс изменился с 92% до 94%, появился следующий шаг. Результат проверки материалов. Основной Docker Compose и локальный комплект жюри пересобраны; E2E этого дополнения выполнен на основном комплекте.
Результаты: docs/VERIFICATION.md. Статус: TASK.md. Компоненты, лицензии и источники: docs/SOURCES.md. Репозиторий организатора: BAITC-Hacks/hack-d98d69cd-komo.
Завершенные проверенные изменения коммитятся по разрешению пользователя. Последние изменения этого прохода зафиксированы локально; для передачи жюри нужен отдельный push итоговых коммитов. Предыдущая версия отправлялась после согласования истории. Официальная сдача через платформу не подтверждена. .env вне индекса; это не очищает прошлую историю. Наличие проекта на localhost не означает официальной сдачи.
Авторы коммитов
История коммитов
- 2026-09-23 17:46docs: explain learning materials flow and verification in READMEmi_llen_nial
- 2026-09-23 17:44feat(learning): add curated resources with verified employee flowmi_llen_nial
- 2026-09-23 17:30test(data): add ten synthetic employee profiles for manual importmi_llen_nial
- 2026-09-23 17:27docs: link visual platform guide with screenshotsmi_llen_nial
- 2026-09-23 17:25feat(copy): explain recommendations and employee actions in plain Russianmi_llen_nial
- 2026-09-23 17:11docs: record clean localhost acceptance and verified AI qualitymi_llen_nial
- 2026-09-23 17:07test: respect configured origins in independent localhost installationsmi_llen_nial
- 2026-09-23 17:02docs: focus jury instructions on localhost and complete employee onboardingmi_llen_nial
Все коммиты (28)
- 2026-09-23 17:02test(ai): verify history-sensitive choices independently of candidate ordermi_llen_nial
- 2026-09-23 17:01feat(ai): use recent participation history and verify competing recommendationsmi_llen_nial
- 2026-09-23 17:00feat(hr): provision employee access through the complete browser flowmi_llen_nial
- 2026-09-23 16:57fix(import): reject duplicate course completions atomicallymi_llen_nial
- 2026-09-23 16:42fix(dev): allow HMR from local network hostmi_llen_nial
- 2026-09-23 16:41docs: record successful synchronization with official repositorymi_llen_nial
- 2026-09-23 16:40fix(core): restore second-pass workflows and existing database migrationsmi_llen_nial
- 2026-09-23 16:40fix(recommendations): scope freshness and cache to employee contextmi_llen_nial
- 2026-09-23 16:40fix(hr): exclude synthetic profiles from default analyticsmi_llen_nial
- 2026-09-23 16:40fix(ai): consider feasible preparation alongside direct skill gainsmi_llen_nial
- 2026-09-23 16:40feat(demo): isolate expert credentials and local Compose environmentmi_llen_nial
- 2026-09-23 16:40test(e2e): validate difficult AI cases and complete the recommended activitymi_llen_nial
- 2026-09-23 16:40test(e2e): prove employee isolation and separate clean-run artifactsmi_llen_nial
- 2026-09-23 16:40test(e2e): exercise a real career target change before recommendationmi_llen_nial
- 2026-09-23 16:40docs: verify reproducible startup and record final task acceptancemi_llen_nial
- 2026-09-23 16:38feat(import): add Excel and JSON templates and validated uploadsmi_llen_nial
- 2026-09-23 16:19timeistsgehdu
- 2026-09-23 15:59timemi_llen_nial
- 2026-09-23 14:25base coremi_llen_nial
- 2026-09-23 13:40init commit with overall datami_llen_nial
Структура репозитория (145 файлов)
.dockerignore .env.example .env.jury.example .gitignore AGENTS.md ARCHITECTURE_PROMPT.md HACKATHON_RULES.md OVERVIEW.md README.md TASK.md backend/Dockerfile backend/alembic.ini backend/app/__init__.py backend/app/core/__init__.py backend/app/core/cache.py backend/app/core/config.py backend/app/core/db.py backend/app/core/errors.py backend/app/core/state.py backend/app/features/__init__.py backend/app/features/catalog/__init__.py backend/app/features/catalog/labels.py backend/app/features/catalog/models.py backend/app/features/catalog/resources.py backend/app/features/catalog/router.py backend/app/features/catalog/service.py backend/app/features/data_import/__init__.py backend/app/features/data_import/formats.py backend/app/features/data_import/router.py backend/app/features/data_import/schemas.py backend/app/features/data_import/service.py backend/app/features/data_import/templates/career-quest-template.json backend/app/features/data_import/templates/career-quest-template.xlsx backend/app/features/development/__init__.py backend/app/features/development/context.py backend/app/features/development/logic.py backend/app/features/development/models.py backend/app/features/development/schemas.py backend/app/features/development/service.py backend/app/features/employees/__init__.py backend/app/features/employees/access.py backend/app/features/employees/models.py backend/app/features/employees/router.py backend/app/features/employees/schemas.py backend/app/features/employees/service.py backend/app/features/hr_analytics/__init__.py backend/app/features/hr_analytics/router.py backend/app/features/hr_analytics/schemas.py backend/app/features/hr_analytics/service.py backend/app/features/identity/__init__.py backend/app/features/identity/models.py backend/app/features/identity/router.py backend/app/features/identity/schemas.py backend/app/features/identity/service.py backend/app/features/recommendations/__init__.py backend/app/features/recommendations/models.py backend/app/features/recommendations/router.py backend/app/features/recommendations/schemas.py backend/app/features/recommendations/service.py backend/app/main.py backend/app/qa_acceptance.py backend/app/qa_demo.py backend/app/seed.py backend/app/smoke_ai.py backend/migrations/env.py backend/migrations/versions/0001_initial.py backend/migrations/versions/0002_goals_participation.py backend/migrations/versions/0003_test_profiles.py backend/pytest.ini backend/requirements.lock backend/requirements.txt backend/tests/conftest.py backend/tests/test_ai.py backend/tests/test_ai_history.py backend/tests/test_context.py backend/tests/test_development.py backend/tests/test_hr_scope.py backend/tests/test_import_formats.py backend/tests/test_integration.py backend/tests/test_round2.py backend/tests/test_round4.py career_quest_dataset/README.kz.md career_quest_dataset/README.md career_quest_dataset/README.ru.md career_quest_dataset/activity_history.csv career_quest_dataset/employees.json career_quest_dataset/events.json career_quest_dataset/skills.json compose.yaml docs/IMPORT_VERIFICATION.md docs/SOURCES.md docs/VERIFICATION.md docs/fixtures/README.md docs/fixtures/activity_history.csv docs/fixtures/employees.json docs/fixtures/import-10-employees.json docs/openapi.json docs/verification/learning-resources.json docs/verification/round4-results.json frontend/Dockerfile frontend/next-env.d.ts frontend/next.config.ts frontend/package-lock.json frontend/package.json frontend/playwright.config.ts frontend/src/app/globals.css frontend/src/app/hr/employees/[id]/page.tsx frontend/src/app/hr/import/page.tsx frontend/src/app/hr/page.tsx frontend/src/app/layout.tsx frontend/src/app/login/page.tsx frontend/src/app/me/page.tsx frontend/src/app/not-found.tsx frontend/src/app/page.tsx frontend/src/features/activities/activity-dialog.module.css frontend/src/features/activities/activity-dialog.tsx frontend/src/features/activities/history.tsx frontend/src/features/activities/learning-resources.module.css frontend/src/features/activities/learning-resources.tsx frontend/src/features/auth/login.module.css frontend/src/features/auth/login.tsx frontend/src/features/auth/provider.tsx frontend/src/features/auth/shell.module.css frontend/src/features/auth/shell.tsx frontend/src/features/career-path/career-path.tsx frontend/src/features/career-path/goal-editor.module.css frontend/src/features/career-path/goal-editor.tsx frontend/src/features/data-import/import-screen.tsx frontend/src/features/data-import/import.module.css frontend/src/features/employee-profile/access-panel.module.css frontend/src/features/employee-profile/access-panel.tsx frontend/src/features/employee-profile/workspace.module.css frontend/src/features/employee-profile/workspace.tsx frontend/src/features/hr-analytics/dashboard.tsx frontend/src/features/hr-analytics/hr.module.css frontend/src/features/recommendations/recommendations.module.css frontend/src/features/recommendations/recommendations.tsx frontend/src/shared/api/client.ts frontend/src/shared/api/schema.d.ts frontend/src/shared/lib/random.ts frontend/src/shared/ui/index.tsx frontend/src/shared/ui/ui.module.css frontend/tests/import-formats.spec.ts frontend/tests/workflows.spec.ts frontend/tsconfig.json
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.