Career Quest
Веб-приложение для сотрудника и HR: профиль, карьерная траектория, skill gaps, 1–3 объяснимые развивающие активности и HR-панель с агрегатами.
О проекте
Команда: Code3
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Рабочий MVP
Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития
Суть
Веб-приложение для сотрудника и HR: профиль, карьерная траектория, skill gaps, 1–3 объяснимые развивающие активности и HR-панель с агрегатами.
Как устроено
FastAPI загружает employees.json, events.json, skills.json и activity_history.csv, считает effective skills с учётом завершённых активностей и max_level, определяет разрывы до целевого грейда. Недопустимые мероприятия отсекаются по роли, грейду, prerequisites и истории; rule-based scoring ранжирует оставшиеся по сокращению разрыва, критичным навыкам, цели, истории и выполнимости. OpenAI Responses API по желанию переранжирует детерминированный top-8 до 3, получая только ID и подтверждённые evidence; при ошибке используется детерминированный top-3.
Ключевые решения
- rule-based eligibility filtering
- hybrid recommendation scoring
- LLM reranking top-8→3
- strict response validation
- deterministic fallback
- HR-агрегации
Особенности
LLM только переранжирует готовый детерминированный шорт-лист и получает минимум данных (ID события, score, evidence IDs) без полного профиля сотрудника. HR-панель намеренно показывает агрегаты без персональных рейтингов. Фронтенд сначала собран в v0 (.v0-import), затем подключён к API.
Стек
Next.js 16 · React 19 · TypeScript · Tailwind CSS · shadcn/ui · Recharts · Python · FastAPI · Pydantic · httpx · OpenAI SDK · Docker · v0
Модели
gpt-4o-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-faed41f1-code3.
README
README.mdCareer Quest
AI-навигатор карьерного развития сотрудников для HackAlem AI / Halyk Bank.
Сотруднику сложно увидеть связь между обучением, текущими навыками и следующим карьерным шагом. Career Quest показывает профиль и карьерную траекторию, выявляет разрывы в навыках и предлагает 1–3 объяснимые развивающие активности. HR получает агрегированный обзор skill gaps и участия в активностях.
Что реализовано
- выбор сотрудника и просмотр его профиля;
- текущий и целевой грейд, навыки и требования карьерной траектории;
- история активностей;
- rule-based подбор 1–3 подходящих активностей с объяснениями;
- пересчёт in-memory прогресса после завершения активности;
- HR-панель: skill gaps, сотрудники без рекомендации и участие в мероприятиях;
- импорт дополнительных
employees.jsonиactivity_history.csvчерез API; - детерминированный fallback без внешнего LLM.
Основной сценарий
- Frontend загружает список сотрудников из FastAPI.
- Для выбранного сотрудника backend рассчитывает effective skills: учитывает завершённые после review активности и ограничение
max_level. - Система определяет требования цели/следующего грейда, skill gaps и critical skills.
- Недопустимые мероприятия исключаются по роли, грейду, prerequisites, истории completed и доступности.
- Rule-based scoring ранжирует кандидатов по gap reduction, critical skills, career goal, history fit и feasibility.
- Пользователь видит до трёх рекомендаций с подтверждёнными факторами и может завершить активность.
- HR-панель показывает агрегированные данные без персональных рейтингов.
AI и рекомендации
Основой является explainable hybrid recommendation engine: eligibility, score, evidence и тексты факторов рассчитываются локально в backend. Это позволяет приложению работать без внешних AI-сервисов.
Опционально настроенный OpenAI Responses API выполняет только reranking deterministic top-8 до трёх событий. Ему передаются event ID, название, deterministic score и подтверждённые evidence IDs/facts — без полного профиля, истории сотрудника или ключа. Ответ строго валидируется; при отсутствии OPENAI_API_KEY, timeout, API-ошибке или невалидном ответе backend возвращает deterministic top-3.
Модель задаётся переменной OPENAI_MODEL; шаблон указывает gpt-4o-mini.
Стек
- Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS, shadcn/ui, Recharts.
- Backend: Python 3.12+, FastAPI, Pydantic, httpx, OpenAI SDK.
- Данные: JSON и CSV.
- Контейнеризация backend: Docker.
Архитектура
Next.js frontend
|
v
FastAPI API (/api)
|
+--> data loader --> employees.json / events.json / skills.json / activity_history.csv
|
+--> deterministic recommendation engine
| |
| +--> optional OpenAI Responses reranker
|
+--> HR analytics
Frontend обращается только к FastAPI. Backend загружает и валидирует датасет при старте; изменения после Complete и импортированные данные хранятся в памяти процесса.
Структура
Career Quest/
├── frontend/ # Next.js интерфейс
├── backend/
│ ├── app/ # FastAPI, services и schemas
│ ├── data/raw/career_quest_dataset/# исходный датасет
│ ├── scripts/check_openai.py # ручная проверка OpenAI
│ ├── tests/ # backend tests
│ └── Dockerfile
├── docs/ # задача, архитектура и API-заметки
└── README.md
Данные
Используется синтетический датасет из backend/data/raw/career_quest_dataset/:
employees.json— профили сотрудников;events.json— каталог развивающих мероприятий;skills.json— навыки и требования ролей/грейдов;activity_history.csv— история участия в активностях.
Датасет загружается только backend. Frontend не читает JSON или CSV напрямую.
Требования
- Python 3.12 или новее;
- Node.js и Corepack/pnpm (проект фиксирует
[email protected]); - Docker — опционально, для контейнерного backend.
Переменные окружения
Frontend
Создайте frontend/.env.local:
NEXT_PUBLIC_API_URL=http://127.0.0.1:8000/api
Backend
backend/.env необязателен. Без него работает локальный deterministic ranking. Для OpenAI reranking создайте его по backend/.env.example:
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4o-mini
OPENAI_API_KEY хранится только в окружении или backend/.env и не должен попадать в Git. Значения переменных операционной системы имеют приоритет над .env.
Быстрый запуск
1. Клонирование
git clone <repository-url>
cd <repository-directory>
2. Backend
cd backend
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
Backend доступен по http://127.0.0.1:8000; интерактивная OpenAPI-документация FastAPI — http://127.0.0.1:8000/docs.
3. Frontend
В отдельном терминале из корня репозитория:
cd frontend
corepack enable
pnpm install
pnpm dev
Откройте http://localhost:3000.
Проверка для жюри
- Запустите backend и frontend.
- Откройте приложение и выберите сотрудника в верхнем списке.
- На странице «Профиль сотрудника» проверьте грейд, навыки и историю активностей.
- Перейдите в «Рекомендации»: отображаются от одной до трёх активностей и причины выбора.
- Завершите рекомендованную активность и убедитесь, что интерфейс обновляет прогресс.
- Откройте «HR-панель» для агрегированных skill gaps и статистики участия.
Основные API endpoints
| Метод | Путь | Назначение |
|---|---|---|
| GET | /health | Проверка доступности backend. |
| GET | /api/employees | Список сотрудников. |
| GET | /api/employees/{employee_id} | Профиль сотрудника. |
| GET | /api/employees/{employee_id}/trajectory | Карьерная траектория и gaps. |
| GET | /api/employees/{employee_id}/activities | История активностей. |
| GET | /api/employees/{employee_id}/recommendations | Рекомендации. |
| POST | /api/employees/{employee_id}/complete/{event_id} | Завершить активность в памяти. |
| GET | /api/hr/dashboard | HR-агрегации. |
| POST | /api/import | Импорт проверочных profiles/history. |
Также доступны совместимые маршруты /api/hr-dashboard и /api/recommendations/{recommendation_id}/complete.
Тесты и production build
cd backend
.\.venv\Scripts\python.exe -m pytest
cd frontend
pnpm build
Deployment
Backend можно собрать с имеющимся Dockerfile:
cd backend
docker build -t career-quest-backend .
docker run --rm -p 8000:8000 career-quest-backend
Для frontend нужен production API URL в NEXT_PUBLIC_API_URL; backend CORS разрешает http://localhost:3000 и http://127.0.0.1:3000. Конфигурация конкретного хостинга для frontend или backend в репозитории отсутствует.
Checklist перед деплоем
- Backend production dependencies установлены.
-
NEXT_PUBLIC_API_URLуказывает на доступный backend API. - CORS дополнен production origin при необходимости.
- При использовании OpenAI секрет задан только через environment variables.
- Проверены
pytestиpnpm build. - Пройден основной пользовательский сценарий.
Демо
Deployed-версия: [Добавить ссылку после деплоя]
Ограничения MVP
- Данные синтетические.
- Полноценная авторизация не реализована.
- Complete, импортированные данные и cache хранятся только в памяти процесса и сбрасываются после перезапуска backend.
- OpenAI reranking необязателен; без ключа используется deterministic ranking.
Авторы коммитов
История коммитов
- 2026-09-23 17:59Revert "fix"hnzwii
- 2026-09-23 17:57fixhnzwii
- 2026-09-23 17:50read mehnzwii
- 2026-09-23 17:47openaiMadina
- 2026-09-23 17:28fixMadina
- 2026-09-23 17:14Fix recomhnzwii
- 2026-09-23 16:54Полный HR-viewMadina
- 2026-09-23 16:41empty statesMadina
Все коммиты (18)
- 2026-09-23 16:33NVIDIA LLM-слой с безопасным fallbackMadina
- 2026-09-23 16:19Career trajectory на профилеMadina
- 2026-09-23 16:04импорт проверочных профилейMadina
- 2026-09-23 15:27Fixed routes and APIhnzwii
- 2026-09-23 14:47Backend fastAPI addedhnzwii
- 2026-09-23 14:32Added backend initial structurehnzwii
- 2026-09-23 14:14Added first prototype of frontendhnzwii
- 2026-09-23 13:54documentation updateMadina
- 2026-09-23 13:36Add career quest datasetkbAdiya
- 2026-09-23 13:24initial commithnzwii
Структура репозитория (156 файлов)
.env.example .gitignore .v0-import/.gitignore .v0-import/app/(app)/hr-dashboard/page.tsx .v0-import/app/(app)/layout.tsx .v0-import/app/(app)/profile/page.tsx .v0-import/app/(app)/recommendations/page.tsx .v0-import/app/api/mock/employees/[id]/activities/route.ts .v0-import/app/api/mock/employees/[id]/recommendations/route.ts .v0-import/app/api/mock/employees/[id]/route.ts .v0-import/app/api/mock/employees/route.ts .v0-import/app/api/mock/hr-dashboard/route.ts .v0-import/app/api/mock/recommendations/[id]/complete/route.ts .v0-import/app/globals.css .v0-import/app/layout.tsx .v0-import/app/page.tsx .v0-import/components.json .v0-import/components/app-shell/app-shell.tsx .v0-import/components/hr-dashboard/employees-without-recommendation-card.tsx .v0-import/components/hr-dashboard/participation-card.tsx .v0-import/components/hr-dashboard/skill-gaps-card.tsx .v0-import/components/hr-dashboard/status-stat-cards.tsx .v0-import/components/profile/activity-timeline-card.tsx .v0-import/components/profile/profile-header-card.tsx .v0-import/components/profile/skills-card.tsx .v0-import/components/recommendations/recommendation-card.tsx .v0-import/components/ui/alert.tsx .v0-import/components/ui/avatar.tsx .v0-import/components/ui/badge.tsx .v0-import/components/ui/button-group.tsx .v0-import/components/ui/button.tsx .v0-import/components/ui/card.tsx .v0-import/components/ui/chart.tsx .v0-import/components/ui/empty.tsx .v0-import/components/ui/field.tsx .v0-import/components/ui/label.tsx .v0-import/components/ui/progress.tsx .v0-import/components/ui/select.tsx .v0-import/components/ui/separator.tsx .v0-import/components/ui/skeleton.tsx .v0-import/components/ui/spinner.tsx .v0-import/components/ui/table.tsx .v0-import/components/ui/tabs.tsx .v0-import/components/ui/tooltip.tsx .v0-import/data/activity_history.csv .v0-import/data/employees.json .v0-import/lib/activities-catalog.ts .v0-import/lib/api.ts .v0-import/lib/employee-context.tsx .v0-import/lib/hr-aggregation.ts .v0-import/lib/server/data-store.ts .v0-import/lib/types.ts .v0-import/lib/utils.ts .v0-import/next.config.mjs .v0-import/package.json .v0-import/pnpm-lock.yaml .v0-import/pnpm-workspace.yaml .v0-import/postcss.config.mjs .v0-import/tsconfig.json LICENSES.md README.md backend/.env.example backend/.gitkeep backend/Dockerfile backend/README.md backend/app/__init__.py backend/app/api/__init__.py backend/app/api/routes.py backend/app/core/__init__.py backend/app/core/config.py backend/app/main.py backend/app/schemas/__init__.py backend/app/schemas/employee.py backend/app/schemas/hr.py backend/app/schemas/import_data.py backend/app/schemas/recommendation.py backend/app/services/__init__.py backend/app/services/ai_recommender.py backend/app/services/data_loader.py backend/app/services/hr_analytics.py backend/app/services/importer.py backend/app/services/recommender.py backend/app/services/trajectory.py backend/data/raw/career_quest_dataset/README.kz.md backend/data/raw/career_quest_dataset/README.md backend/data/raw/career_quest_dataset/README.ru.md backend/data/raw/career_quest_dataset/activity_history.csv backend/data/raw/career_quest_dataset/employees.json backend/data/raw/career_quest_dataset/events.json backend/data/raw/career_quest_dataset/skills.json backend/requirements.txt backend/scripts/check_openai.py backend/tests/test_ai_recommendations.py backend/tests/test_employees.py backend/tests/test_health.py backend/tests/test_hr_analytics.py backend/tests/test_import.py backend/tests/test_recommendations.py docs/api.md docs/architecture.md docs/demo-script.md docs/progress.md docs/task.md frontend.env.local frontend/.env.example frontend/.gitignore frontend/app/(app)/hr-dashboard/page.tsx frontend/app/(app)/import/page.tsx frontend/app/(app)/layout.tsx frontend/app/(app)/profile/page.tsx frontend/app/(app)/recommendations/page.tsx frontend/app/globals.css frontend/app/layout.tsx frontend/app/page.tsx frontend/components.json frontend/components/app-shell/app-shell.tsx frontend/components/hr-dashboard/employees-without-recommendation-card.tsx frontend/components/hr-dashboard/participation-card.tsx frontend/components/hr-dashboard/skill-gaps-card.tsx frontend/components/hr-dashboard/status-stat-cards.tsx frontend/components/profile/activity-timeline-card.tsx frontend/components/profile/career-trajectory-card.tsx frontend/components/profile/profile-header-card.tsx frontend/components/profile/skills-card.tsx frontend/components/recommendations/recommendation-card.tsx frontend/components/ui/alert.tsx frontend/components/ui/avatar.tsx frontend/components/ui/badge.tsx frontend/components/ui/button-group.tsx frontend/components/ui/button.tsx frontend/components/ui/card.tsx frontend/components/ui/chart.tsx frontend/components/ui/empty.tsx frontend/components/ui/field.tsx frontend/components/ui/label.tsx frontend/components/ui/progress.tsx frontend/components/ui/select.tsx frontend/components/ui/separator.tsx frontend/components/ui/skeleton.tsx frontend/components/ui/spinner.tsx frontend/components/ui/table.tsx frontend/components/ui/tabs.tsx frontend/components/ui/tooltip.tsx frontend/lib/api.ts frontend/lib/demo-access.ts frontend/lib/employee-context.tsx frontend/lib/types.ts frontend/lib/utils.ts frontend/next.config.mjs frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml frontend/postcss.config.mjs frontend/tsconfig.json frontend/type-tests/demo-access.type-test.ts frontend/type-tests/hr-dashboard.type-test.ts
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.