AAYMA
RU
Войти

QALDY AI — Career Quest

Веб-приложение карьерной траектории сотрудника: показывает разрывы навыков до целевого грейда, предлагает объяснимые активности развития и…

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

О проекте

Команда: QALDY AI
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Рабочий MVP

Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития

Суть

Веб-приложение карьерной траектории сотрудника: показывает разрывы навыков до целевого грейда, предлагает объяснимые активности развития и пересчитывает прогресс после их завершения; HR видит дефициты компетенций, участие и сотрудников без подходящего шага.

Как устроено

FastAPI-бэкенд с детерминированным движком рекомендаций проверяет аудиторию, prerequisites, историю, gain/max_level и разрывы до грейда на seed-датасете (200 профилей, 40 активностей, 60 навыков, 2743 записи истории). Необязательный LLM (OpenAI-совместимый Responses API) лишь переранжирует допустимых кандидатов в ограниченном диапазоне со структурированным ответом, объяснения строит сам движок; без ключа работает детерминированный fallback. HR может импортировать employees.json и activity_history.csv с dry-run, данные хранятся в SQLite; интерфейс на Next.js, доступ по demo Bearer-токенам с RBAC.

Ключевые решения

  • skill gap analysis
  • rule-based recommendation
  • LLM reranking
  • structured output
  • RBAC

Метрики

web-тесты 78/78 PASS, backend smoke 11/11; аудит 55 PASS / 3 FAIL / 42 BLOCKED; один AI-запрос ~7,02 с, 677 токенов

Особенности

LLM ограничен переранжированием уже допустимых кандидатов, а объяснения даёт проверяемый движок, что защищает от галлюцинаций. Честный аудит с долей непроверенных пунктов и явное разделение режимов ai/fallback в ответе API.

Стек

Python · FastAPI · SQLite · Next.js · React · TypeScript · Docker Compose · Playwright · Vitest · GitHub Actions

Модели

gpt-4o-mini


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-efa741b1-qaldy-ai.

README

README.md

QALDY AI — Career Quest

Что решает

Приложение для построения карьерной траектории сотрудника: показывает разрывы навыков, предлагает объяснимые следующие шаги и пересчитывает прогресс после завершения активности.

Сотрудник понимает, зачем проходить конкретное обучение и как оно приближает к следующему грейду. HR видит дефициты компетенций, участие и сотрудников без подходящего шага развития.

Технологии

  • Web: Next.js, React, TypeScript; Node.js 22.x.
  • API и расчёт рекомендаций: Python 3.12+, FastAPI; SQLite для импортов и завершений.
  • AI: OpenAI-compatible Responses API, структурированный ответ и проверка допустимых кандидатов; детерминированный fallback.
  • Проверки: pytest, Vitest/Testing Library, Playwright, ESLint, TypeScript; Docker Compose для совместного запуска.

JTBD

Сотрудник

Когда я готовлюсь к следующему грейду или новой роли, я хочу видеть разрывы между моими навыками и требованиями цели и получать достижимые активности с понятным объяснением, чтобы выбрать следующий шаг развития и отслеживать свой прогресс.

HR и команда развития

Когда я планирую развитие сотрудников, я хочу видеть общие дефициты навыков, участие в активностях и случаи, где нет подходящей рекомендации, чтобы определять приоритеты обучения и улучшать каталог развития.

Как запустить

Требуются Docker Desktop (или Docker Engine) и Docker Compose v2.

Из корня чистого checkout:

git clone https://github.com/BAITC-Hacks/hack-efa741b1-qaldy-ai.git
cd hack-efa741b1-qaldy-ai
docker compose up --build

На Windows без Docker установите Python 3.12+ и Node.js 22.x. Из корня checkout подготовьте зависимости и запустите приложение:

Push-Location .\apps\api
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
Pop-Location
Push-Location .\apps\web
npm ci
Pop-Location
powershell -ExecutionPolicy Bypass -File .\start-local.ps1

Скрипт запускает оба сервиса в фоне и открывает http://localhost:3000. Он требует уже подготовленных зависимостей и Node.js по стандартному пути C:\Program Files\nodejs\node.exe. При первом запуске создаётся demo HR-токен; для входа сотрудника настройте DEMO_EMPLOYEE_TOKENS по инструкции. Логи находятся в %TEMP%\qaldy-career-quest-local. Если порт 8000 занят несовместимым API, скрипт сообщает об этом и не останавливает чужой процесс.

Для чистого checkout Compose использует только локальные demo-токены: local-demo-employee-token-2026 для сотрудника E0001 и local-demo-hr-token-2026 для HR. Их можно заменить секретными значениями в .env через .\scripts\setup-demo-auth.ps1. Откройте главную страницу, введите нужный токен через меню профиля, затем используйте траекторию, HR-обзор, импорт или схему API. Без настройки LLM рекомендации рассчитываются детерминированно.

Для этого чистого Compose-демо не требуется копировать .env.example: его DEMO_EMPLOYEE_TOKENS={} переопределит встроенный employee-доступ. Если используете собственный .env, настройте HR-токен через setup-demo-auth.ps1 и отдельно задайте соответствие ID → токен в DEMO_EMPLOYEE_TOKENS по SETUP.

Последовательность показа обязательного сценария и импорта профиля жюри приведена в JURY_DEMO.md.

Короткий показ: войдите employee-токеном → откройте /journey → покажите роль, грейд, навыки, историю и причины рекомендации → завершите доступную добровольную активность → проверьте изменение навыков и траектории → смените токен на HR → откройте /hr. HR может просматривать и импортировать данные, но не завершать активность от имени сотрудника.

Стартовый набор содержит 200 синтетических профилей, 40 активностей, 60 навыков и 2 743 записи истории. Схемы описаны в README датасета.

Чтобы остановить сервисы, выполните docker compose down. Именованный Docker volume career_quest_runtime хранит runtime-БД с завершениями активностей и импортированными профилями/историей.

Шаги проверки

  1. Проверьте доступность API и вход по токену: /health, затем /api/v1/auth/me.
  2. Пройдите ручной сценарий выше: профиль → объяснение → завершение → обновлённый прогресс → HR.
  3. При включённой модели проверьте recommendation_mode=ai способом из следующего раздела.
  4. Выполните автоматизированные команды ниже; сравнивайте результат с текущим commit.

Финальная локальная проверка 23 сентября 2026: web 78/78 PASS, ESLint и TypeScript PASS; backend smoke 11/11 PASS (health, профиль, рекомендации, четыре HR-маршрута и запреты доступа). Это конкретные запуски, а не заявление о прохождении всей матрицы из 100 пользовательских сценариев.

GitHub Actions запускает проверки при каждом push и pull_request:

  • API: установка Python-зависимостей разработки и pytest.
  • Web: npm ci, ESLint, проверка TypeScript, unit-тесты Vitest и Playwright E2E на production-сборке Next.js.

Для запуска проверок локально используйте Python 3.12+ и Node.js 22.x.

Backend (из корня репозитория):

cd apps/api
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m pytest

Frontend (из корня репозитория):

cd apps/web
npm ci
npm run lint
npm run typecheck
npm test
npm run build
npx playwright install chromium
npm run test:e2e

Playwright E2E запускает production-сервер Next.js и использует web fixtures; это проверка интерфейса, не сквозная проверка с запущенным FastAPI. В CI Chromium устанавливается автоматически.

AI и проверка его режима

Детерминированное ядро проверяет аудиторию, prerequisites, историю, реальные gain/max_level и разрывы до целевого грейда. Необязательный AI меняет порядок допустимых кандидатов в ограниченном диапазоне; фактические объяснения строит проверяемый движок.

Для AI-reranking задайте LLM_ENABLED=true, LLM_API_KEY, LLM_MODEL, LLM_BASE_URL и при необходимости LLM_TIMEOUT_SECONDS в локальном окружении API; перезапустите API с этой конфигурацией. Без ключа или при ошибке модели доступен явно обозначенный детерминированный режим. Секреты не добавляйте в Git.

23 сентября 2026 отдельно подтверждён реальный запрос на изолированных синтетических данных: HTTP 200, завершённый ответ, recommendation_mode=ai, модель gpt-4o-mini-2024-07-18, около 7,02 с, 677 токенов. Это один успешный замер, а не гарантия задержки для всех профилей. Браузерный стенд аудита на порту 3002 работал с отключённой LLM; его демонстрация не доказывает использование модели.

Для проверки своего API в PowerShell задайте EMPLOYEE_TOKEN в окружении текущей сессии, затем выполните:

$apiBase = 'http://localhost:8000'
$authHeaders = @{ Authorization = "Bearer $env:EMPLOYEE_TOKEN" }
$result = Invoke-RestMethod -Method Post -Uri "$apiBase/api/v1/employees/E0001/recommendations" -Headers $authHeaders
$result | Select-Object recommendation_mode, recommendation_notice, recommendations

Токен должен принадлежать E0001 или разрешённому HR; используйте ID из действующего набора данных. Проверяйте recommendation_mode и сообщение API, не называйте fallback ответом модели. Перед внешним вызовом соблюдайте правила хакатона по передаче синтетических данных.

Структура

apps/api/       FastAPI API, доменная логика и тесты
apps/web/       Next.js интерфейс сотрудника и HR
data/seed/      начальный набор JSON/CSV
docs/           настройка, архитектура, API и формат данных

Документация

Статус и ограничения

  • Основной путь сотрудника и HR-аналитика реализован на seed-данных.
  • Employee- и HR-доступ определяются серверными demo Bearer-токенами. Это не production identity provider; публичное окружение по умолчанию закрывает demo-auth.
  • HR может загрузить employees.json и необязательный activity_history.csv, проверить их через dry-run и применить. Импортированные записи доступны в профилях, рекомендациях и HR-агрегатах; они сохраняются в SQLite.
  • Завершения активности и результаты импорта хранятся в SQLite по DATABASE_URL и переживают перезапуск API.
  • Веб-страницы дополнительных разделов продукта могут использовать локальные демонстрационные данные; наличие страницы не означает наличие live API.
  • Проведён аудит с ручным путём сотрудника, API-проверками и регрессионными тестами. Сводка: 55 PASS / 3 FAIL / 42 BLOCKED — 55% пунктов подтверждено, 45% остаются незакрытыми. Три FAIL относятся к историческим воспроизведениям, не все повторены после изменений; это не перечень трёх доказанных текущих дефектов и не утверждение о готовности на 100%.
  • Чистый запуск Docker имеет статус BLOCKED: Docker недоступен в среде аудита. Полный импорт неизвестного профиля через браузер, повторная полная репетиция и все измерения задержки интерфейса остаются неподтверждёнными. Один успешный AI-вызов не закрывает эти проверки. Актуальные границы и порядок сдачи перечислены в HANDOFF.md.

Перед использованием для реальных сотрудников замените demo-авторизацию, перенесите SQLite на production-grade хранилище с резервным копированием и согласуйте обработку персональных данных.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
22
Авторы
1
Файлы
145
Ветки
8

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

timqaldy 22

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

  • 2026-09-23 17:53fix: render HR participation and document project handofftimqaldy
  • 2026-09-23 17:37fix: complete employee profile detailstimqaldy
  • 2026-09-23 17:24fix: finalize required career quest flowtimqaldy
  • 2026-09-23 17:07fix: align journey policy with source datasettimqaldy
  • 2026-09-23 16:57fix: complete journey bridge activitiestimqaldy
  • 2026-09-23 16:52feat: harden backend data and deploymenttimqaldy
  • 2026-09-23 16:49fix: add persistent local app launchertimqaldy
  • 2026-09-23 16:43feat: complete career quest platform improvementstimqaldy
Все коммиты (22)
  • 2026-09-23 16:40fix(web): align Halyk branding and visual QAtimqaldy
  • 2026-09-23 16:34docs: сверить документацию с текущим кодомtimqaldy
  • 2026-09-23 16:15docs: align setup and CI with completed MVPtimqaldy
  • 2026-09-23 16:07fix: stabilize production E2E on mobiletimqaldy
  • 2026-09-23 16:04feat: add localized HR and import experiencestimqaldy
  • 2026-09-23 15:52feat: add SQLite persistence and validated importstimqaldy
  • 2026-09-23 15:45test: cover recommendation edge casestimqaldy
  • 2026-09-23 15:39feat: add HR analytics and backend RBACtimqaldy
  • 2026-09-23 15:38docs: обновить README проекта и добавить JTBDtimqaldy
  • 2026-09-23 15:33chore: persist runtime data in composetimqaldy
  • 2026-09-23 15:19feat: add OpenAI recommendation adaptertimqaldy
  • 2026-09-23 14:57feat: implement core user flowtimqaldy
  • 2026-09-23 14:18feat: create MVP structuretimqaldy
  • 2026-09-23 13:49docs: add project plan and setup instructionstimqaldy
Структура репозитория (145 файлов)
.env.example
.github/dependabot.yml
.github/workflows/ci.yml
.gitignore
.python-version
.vercelignore
HANDOFF.md
JURY_DEMO.md
Makefile
README.md
apps/api/.dockerignore
apps/api/Dockerfile
apps/api/README.md
apps/api/app/__init__.py
apps/api/app/api/__init__.py
apps/api/app/api/auth.py
apps/api/app/api/dependencies.py
apps/api/app/api/hr_schemas.py
apps/api/app/api/import_schemas.py
apps/api/app/api/router.py
apps/api/app/api/routes/__init__.py
apps/api/app/api/routes/employees.py
apps/api/app/api/routes/health.py
apps/api/app/api/routes/hr.py
apps/api/app/api/routes/imports.py
apps/api/app/api/schemas.py
apps/api/app/application/__init__.py
apps/api/app/application/hr_service.py
apps/api/app/application/import_service.py
apps/api/app/application/journey_service.py
apps/api/app/domain/__init__.py
apps/api/app/domain/errors.py
apps/api/app/domain/models.py
apps/api/app/infrastructure/__init__.py
apps/api/app/infrastructure/dataset_loader.py
apps/api/app/infrastructure/llm_adapter.py
apps/api/app/infrastructure/sqlite_repository.py
apps/api/app/main.py
apps/api/pyproject.toml
apps/api/requirements.lock
apps/api/tests/test_bridge_and_continuation_completion.py
apps/api/tests/test_core_user_flow.py
apps/api/tests/test_dataset_loader.py
apps/api/tests/test_health.py
apps/api/tests/test_hr_rbac.py
apps/api/tests/test_import_and_persistence.py
apps/api/tests/test_jury_import_flow.py
apps/api/tests/test_llm_adapter.py
apps/api/tests/test_master_domain_scenarios.py
apps/api/tests/test_qa_master_acceptance.py
apps/api/tests/test_status_completion_ranges.py
apps/web/.dockerignore
apps/web/AGENTS.md
apps/web/CLAUDE.md
apps/web/Dockerfile
apps/web/README.md
apps/web/eslint.config.mjs
apps/web/next-env.d.ts
apps/web/next.config.ts
apps/web/package-lock.json
apps/web/package.json
apps/web/playwright.config.ts
apps/web/public/.gitkeep
apps/web/public/halyk-mark-official.png
apps/web/src/app/ai-navigator/page.tsx
apps/web/src/app/career-map/page.tsx
apps/web/src/app/globals.css
apps/web/src/app/hr/page.tsx
apps/web/src/app/hr/participation.test.tsx
apps/web/src/app/import/page.tsx
apps/web/src/app/journey/page.tsx
apps/web/src/app/layout.tsx
apps/web/src/app/learning/page.tsx
apps/web/src/app/library/page.tsx
apps/web/src/app/opportunities/page.tsx
apps/web/src/app/page.tsx
apps/web/src/app/profile/page.tsx
apps/web/src/app/quests/page.tsx
apps/web/src/app/skills/page.tsx
apps/web/src/app/team/page.tsx
apps/web/src/components/app-shell.test.tsx
apps/web/src/components/app-shell.tsx
apps/web/src/features/journey/api.test.ts
apps/web/src/features/journey/api.ts
apps/web/src/features/journey/employee-journey-screen.tsx
apps/web/src/features/journey/profile-details.test.tsx
apps/web/src/features/journey/types.ts
apps/web/src/features/prototype/core-pages.tsx
apps/web/src/features/secondary/secondary-pages.module.css
apps/web/src/features/secondary/secondary-pages.tsx
apps/web/src/lib/auth.ts
apps/web/src/lib/demo/fixtures.ts
apps/web/src/lib/demo/index.ts
apps/web/src/lib/demo/persistence.test.ts
apps/web/src/lib/demo/persistence.ts
apps/web/src/lib/demo/reducer.test.ts
apps/web/src/lib/demo/reducer.ts
apps/web/src/lib/demo/selectors.test.ts
apps/web/src/lib/demo/selectors.ts
apps/web/src/lib/demo/state.test.ts
apps/web/src/lib/demo/store.ts
apps/web/src/lib/demo/types.ts
apps/web/src/lib/i18n.tsx
apps/web/src/test/fixtures.ts
apps/web/src/test/handlers.ts
apps/web/src/test/server.ts
apps/web/src/test/setup.ts
apps/web/tests/core-flow.e2e.spec.ts
apps/web/tests/routes.a11y.spec.ts
apps/web/tests/routes.e2e.spec.ts
apps/web/tests/routes.visual.spec.ts
apps/web/tests/support/app-test.ts
apps/web/tests/support/routes.ts
apps/web/tests/visual/__snapshots__/ai-navigator.png
apps/web/tests/visual/__snapshots__/career-map.png
apps/web/tests/visual/__snapshots__/home.png
apps/web/tests/visual/__snapshots__/learning.png
apps/web/tests/visual/__snapshots__/library.png
apps/web/tests/visual/__snapshots__/opportunities.png
apps/web/tests/visual/__snapshots__/profile.png
apps/web/tests/visual/__snapshots__/quests.png
apps/web/tests/visual/__snapshots__/skills.png
apps/web/tests/visual/__snapshots__/team.png
apps/web/tsconfig.json
apps/web/vitest.config.ts
data/seed/README.md
data/seed/career_quest_dataset/README.ru.md
data/seed/career_quest_dataset/activity_history.csv
data/seed/career_quest_dataset/employees.json
data/seed/career_quest_dataset/events.json
data/seed/career_quest_dataset/skills.json
docker-compose.yml
docs/API.md
docs/ARCHITECTURE.md
docs/DATASET.md
docs/HR_METRICS.md
docs/PROJECT_PLAN.md
docs/RECOMMENDATION_ENGINE.md
docs/SETUP.md
docs/VERCEL_DEPLOYMENT.md
index.py
requirements.txt
scripts/setup-demo-auth.ps1
start-local.ps1
tests/README.md
Ветки (8)

Обсуждение 0 комментариев

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

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