AAYMA
RU
Войти

QCareer

Сервис Career Quest: сотрудник видит навыки, требования следующего грейда и дефициты, получает до трёх рекомендаций развития с объяснениями и…

Доведённый продукт
Команда «QForce» 11💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: QForce
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Доведённый продукт

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

Суть

Сервис Career Quest: сотрудник видит навыки, требования следующего грейда и дефициты, получает до трёх рекомендаций развития с объяснениями и отмечает участие. HR получает аналитику дефицитов, импорт JSON/CSV и очередь заявок.

Как устроено

Сервер импортирует каталог навыков, требования ролей и грейдов, профили, активности и историю участия в PostgreSQL через Prisma. Готовность считается по формуле 100×Σmin(текущий, требуемый)/Σтребуемых. Планировщик на правилах строит последовательности до трёх шагов с учётом входных требований, дат, потолков навыков и истории. Опционально LLM выбирает среди уже проверенных планов, при ошибке включается RULES_FALLBACK. После завершения активности прирост навыков начисляется и рекомендации пересчитываются.

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

  • rule-based sequential planner
  • readiness score formula
  • LLM selection among verified plans
  • rules fallback
  • modular monolith

Особенности

LLM не генерирует рекомендации, а только выбирает среди проверенных сервером планов, поэтому основной сценарий работает без AI-ключа. Повторное завершение участия не начисляет прирост дважды. Интерфейс на семи языках.

Стек

TypeScript · NestJS 11 · Nuxt 4 · Vue 3 · Tailwind CSS · Prisma · PostgreSQL 17.6 · Docker Compose · Jest · Playwright

Модели

OpenAI Responses API (gpt-4.1-mini по умолчанию) · Ollama


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

README

README.md

QCareer — Career Quest

Сервис развития сотрудников: от текущих навыков до конкретного следующего шага.

Текущие исправления повторного аудита ТЗ и результаты проверки: docs/weakness-verification.md. Предыдущие проверки сохранены как история: до слияния языков, после слияния.

Nuxt 4 + Vue 3 frontend и существующий NestJS + Prisma + PostgreSQL backend. Интерфейс получает данные через API; импорт, рекомендации, участие и прогресс сохраняются в PostgreSQL. Контракты экранов и ограничения описаны в docs/api-integration.md.

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

Проект связывает профили сотрудников, требования к ролям и грейдам, каталог развивающих активностей и историю участия. Рекомендации учитывают эти данные и сопровождаются объяснениями. В репозитории реализованы веб-интерфейс, серверное API и хранение данных в PostgreSQL.

Грейд — уровень должности; активность — курс, практикум или другое обучающее мероприятие; HR — кадровая служба. LLM — языковая AI-модель, которую можно дополнительно подключить для выбора рекомендаций.

Для первого запуска достаточно Docker: он запускает интерфейс, backend и базу данных вместе. Данные для демонстрации уже входят в репозиторий. Ключ AI не обязателен: без него доступны вход, профили, траектория, подбор по правилам, участие, HR-аналитика и импорт. Начните с запуска, затем пройдите сценарий для жюри.

Что реализовано

Для когоВозможности
СотрудникВход по логину и паролю; просмотр профиля, навыков, следующего грейда и дефицитов; получение до трёх рекомендаций с объяснениями и ожидаемым эффектом; оценка полезности рекомендаций.
СотрудникКаталог активностей с фильтром по формату и пагинацией; просмотр условий и дат; запись, изменение статуса участия и завершение; история и результат изменения навыков.
HRСводка по сотрудникам, дефицитам навыков, участию и рекомендациям; наблюдаемые сигналы, требующие внимания; список сотрудников с фильтрами, профиль и подбор рекомендаций выбранному сотруднику. В интерфейсе запись и оценка рекомендаций доступны только самому сотруднику.
HRИмпорт JSON/CSV: предварительная проверка, диагностика ошибок, применение пакета и повторный просмотр сохранённого отчёта.
HR и жюриИзолированные копии проверочных профилей и истории, включая сокращённый профиль из ТЗ; явные допущения, поиск по ID/имени, создание отдельного входа сотрудника.
Сотрудник и HRЗаявки при недостатке подходящего обучения: конкретные дефициты, очередь HR, ответ сотруднику. Заявка не изменяет навыки.

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

Как работает решение

  1. Загрузка данных. При первом запуске сервер импортирует каталог навыков и требований, профили сотрудников, активности и историю участия. HR может позже загрузить дополнительные данные через интерфейс.
  2. Расчёт траектории. После входа сотрудник видит текущие навыки и требования следующего грейда своей роли. Сервер рассчитывает готовность и показывает недостающие уровни.
  3. Планирование до трёх шагов. Сервер рассматривает весь каталог и последовательности с учётом аудитории, входных требований, дат, повторяемости, потолков навыков и истории. Подготовительный шаг может открыть следующий курс; прирост считается после каждого шага. Даты имеют точность до дня и минимальную длительность, а не обещают реальное расписание сотрудника.
  4. Необязательный этап AI. Если LLM подключена, она выбирает среди проверенных планов. Сервер проверяет последовательность целиком и показывает факторы, прогноз и сравнение с альтернативой. Ограничение первыми десятью событиями убрано; при ограниченном поиске это отражается в диагностике.
  5. Действие сотрудника. Сотрудник записывается на активность и отмечает её завершение. Сервер сохраняет участие, начисляет допустимый прирост навыков и пересчитывает готовность.
  6. Новый результат. Предыдущий подбор становится устаревшим; сотрудник обновляет рекомендации с учётом нового состояния. HR видит сохранённые данные в профиле и аналитике.

Готовность к следующему грейду — доля покрытых требований: 100 × Σ min(текущий уровень, требуемый уровень) / Σ требуемых уровней. Это расчётный показатель соответствия требованиям, а не вероятность повышения. При недостаточных данных интерфейс показывает отдельное состояние.

По умолчанию LLM отключена: приложение использует серверный подбор по правилам (RULES_FALLBACK, aiUsed=false). При ошибке, таймауте или невалидном ответе подключённой модели также используется этот режим. Основной сценарий доступен без внешнего AI-сервиса и API-ключа.

Технологии

КомпонентИспользуется в репозитории
ЯзыкиTypeScript на backend; JavaScript и Vue-компоненты на frontend; CSS и SQL-миграции.
FrontendNuxt 4, Vue 3, Vue Router, Tailwind CSS, Nitro. Приложение работает как SPA (ssr: false).
BackendNode.js, NestJS 11 с Express, REST API, Swagger / OpenAPI.
ДанныеPostgreSQL 17.6, Prisma 6.19, миграции и начальный импорт.
Валидация и доступZod, csv-parse, JWT (jsonwebtoken), Helmet; пароли хешируются через scrypt из Node.js.
Облачный AI, опциональноАдаптер OpenAI Responses API со структурированным JSON-ответом. Значение LLM_MODEL по умолчанию — gpt-4.1-mini; фактическое включение требует настройки провайдера.
Локальный AI, опциональноАдаптер нативного API Ollama: проверка модели и запрос /api/chat. Конкретная локальная модель в репозитории не закреплена.
ПроверкиJest, Supertest, тесты через Node.js, Playwright, TypeScript, ESLint на backend.
ОкружениеDocker и Docker Compose; Docker-образы Node.js 22.20.0 и PostgreSQL 17.6.

Версии зависимостей и команды зафиксированы в backend/package.json, frontend/package.json и соответствующих package-lock.json.

Архитектура проекта

flowchart LR
    User[Сотрудник / HR] --> UI[Nuxt / Vue: интерфейс]
    UI -->|/api/v1| Proxy[Nitro: API proxy]
    Proxy --> API[NestJS: REST API]
    API --> Modules[Модули предметной области]
    Modules -->|Prisma| DB[(PostgreSQL)]
    Files[JSON / CSV] --> Import[Импорт и валидация]
    Import --> Modules
    Modules --> Rec[Подбор рекомендаций]
    Rec -. при включении .-> LLM[OpenAI / Ollama]

Backend построен как модульный монолит. Внутри модулей разделены бизнес-правила, пользовательские операции, инфраструктура и HTTP-контроллеры.

Модули backendОтветственность
identity-access, employeesАвторизация, роли доступа и профили сотрудников.
competency-catalog, learning-catalogНавыки, роли, грейды, требования и каталог активностей.
developmentТраектория, доступность активностей, участие и журнал изменения навыков.
recommendationsРанжирование, адаптеры LLM, проверка объяснений, хранение подборов и обратной связи.
hr-analyticsСводные показатели и представления для HR.
development-requestsСохраняемые обращения сотрудника, очередь и ответы HR при недостатке подходящего обучения.
dataset-import, healthИмпорт с диагностикой и проверка работоспособности приложения.
.
├── frontend/
│   ├── app/                  # Страницы, компоненты, работа с API
│   ├── server/routes/        # Proxy /api и проверка готовности
│   └── tests/                # Тесты клиента и браузерные сценарии
├── backend/
│   ├── src/modules/          # Бизнес-модули
│   ├── prisma/               # Схема БД и миграции
│   ├── data/fixtures/        # Синтетический набор для демонстрации
│   ├── scripts/              # Bootstrap, импорт, smoke и оценка рекомендаций
│   ├── test/                 # Unit, integration, E2E и архитектурные тесты
│   └── docs/                 # Контракты данных и описание алгоритмов
├── docs/                     # Интеграция frontend/backend, OpenAPI, отчёты
├── compose.yaml              # Общий запуск приложения
└── .env.example              # Пример настроек локального окружения

Браузер обращается к /api/v1 на том же адресе, что и frontend. Nitro пересылает запросы в NestJS: в Compose это http://api:3001. Бизнес-данные приходят из backend; токен сессии хранится в sessionStorage. PostgreSQL использует постоянный Docker volume.

Подробности: архитектура backend, связь экранов с API, алгоритм рекомендаций.

Установка и запуск

Быстрый запуск через Docker

Потребуются Docker Engine / Docker Desktop с Linux-контейнерами, Docker Compose 2.24+, свободные порты 3000 и 3001, доступ к реестрам Docker и npm при первой сборке. Локально устанавливать Node.js для этого способа не нужно.

  1. Откройте терминал в корне репозитория, где находится compose.yaml.

  2. Запустите приложение:

    docker compose up --build -d
    
  3. Проверьте состояние:

    docker compose ps -a
    

    Ожидается: postgres, api, frontend — Up (healthy); одноразовые migrate и bootstrap — Exited (0). При первой сборке дождитесь окончания установки зависимостей, миграций и импорта.

  4. Откройте http://localhost:3000.

На первом запуске скачиваются образы и зависимости, создаются таблицы БД через миграции и выполняется bootstrap — импорт данных и создание отсутствующих демо-аккаунтов. Корневой Compose загружает полный синтетический набор frontend/app/data: 200 сотрудников, 40 активностей, 60 навыков и 2743 записи истории за два года. Отдельный backend Compose использует fixtures — небольшой тестовый набор из шести профилей.

В свежем окружении .env не обязателен: корневой запуск выбирает полный набор (DATA_MODE=input, INPUT_DATA_DIR=../frontend/app/data), демонстрационные аккаунты и отключённую LLM. Данные сохраняются в PostgreSQL. Существующие backend/.env и корневой .env могут переопределять логины, пароли и настройки LLM; параметры полного набора задаются корневым Compose отдельно. Правила ниже объясняют, откуда берётся каждое значение.

Для демонстрации с AI в Windows PowerShell доступна одна команда ./start-demo.ps1. При отсутствии настройки она запрашивает ключ скрытым вводом, записывает его только в игнорируемый .env, запускает Compose и проверяет готовность API. ./start-demo.ps1 -CheckOnly проверяет настройки без запуска и платного вызова; ./start-demo.ps1 -Rules явно запускает режим без модели, сохраняя AI-настройки. Рабочий ключ не распространяется с репозиторием. Healthcheck подтверждает конфигурацию, а фактический вызов — результат AI_ASSISTED при генерации.

Адрес по умолчаниюНазначение
localhost:3000/loginВход в приложение.
localhost:3001/docsSwagger UI для проверки API.
localhost:3001/openapi.jsonOpenAPI-спецификация работающего backend.
http://localhost:3000/api/v1Базовый адрес API через frontend proxy.
http://localhost:3001/api/v1Базовый адрес API напрямую.
localhost:3001/health/readyГотовность backend и PostgreSQL.
localhost:3000/health/readyГотовность frontend и доступность backend.

Демонстрационные учётные записи для новой базы с настройками из примеров:

РольЛогинПароль
Сотрудник (E0001)employeechange-this-demo-employee-password
HRhrchange-this-demo-hr-password

Это опубликованные настройки локальной демонстрации. Перед публичным размещением нужны собственные секреты и настройка пользователей: production-конфигурация запрещает demo mode. Seed создаёт только отсутствующие аккаунты; изменение пароля в .env не меняет пароль уже созданного пользователя.

Настройки окружения

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

ФайлКогда используется
Корневой .env.exampleОпубликованный образец для всего проекта. Сам по себе не загружается как файл окружения; его редактирование не меняет настройки работающего приложения.
Корневой .envВаши настройки при запуске docker compose из корня. Сюда добавляют ключ AI для общего запуска.
backend/.env.exampleБазовые настройки backend Compose; в отличие от корневого примера, этот файл явно подключён через env_file.
backend/.envДополнительные настройки backend Compose; при запуске Node.js из backend/ его читает dotenv. Общий Compose тоже учитывает этот файл.

Чтобы изменить настройки всего проекта, отредактируйте существующий корневой .env. Только если его ещё нет, скопируйте .env.example: в PowerShell Copy-Item .env.example .env, в Bash cp .env.example .env. Не перезаписывайте настроенный файл. Настоящий ключ добавляйте в .env, исключённый из Git, а не в опубликованный .env.example.

Символ # в начале строки означает комментарий. Например, # LLM_API_KEY=... не задаёт ключ. Чтобы задать его, нужно удалить # в своём .env и заменить текст после = настоящим значением. Текст provide-only-if-the-selected-provider-requires-it или replace-with-your-real-provider-key — поясняющий плейсхолдер, а не рабочий ключ.

При общем запуске порядок файлов: backend/.env.example → backend/.env при наличии → корневой .env при наличии; более позднее заданное значение заменяет предыдущее. Отсутствующая или закомментированная строка не удаляет значение из более раннего файла. Поэтому отсутствие ключа в корневом примере не доказывает его отсутствие у backend. Чтобы гарантированно отключить вызовы модели, задайте LLM_PROVIDER=disabled в корневом .env.

Секция environment Compose имеет приоритет над этими файлами: она формирует DATABASE_URL, фиксирует внутренние порты и путь данных, а корневой overlay выбирает DATA_MODE и DEMO_EMPLOYEE_ID. При подстановке этих параметров Compose учитывает переменные терминала и файлы окружения проекта. Для общего запуска задавайте свои значения в корневом .env. Необязательные AS_OF_DATE и LLM_BASE_URL удаляйте или комментируйте, а не задавайте пустой строкой.

ПеременныеНазначение
FRONTEND_PORT, PORTПорты хоста 3000, 3001; внутренние порты фиксированы
POSTGRES_USER, POSTGRES_DBcareer_quest; PostgreSQL не публикует порт хоста
POSTGRES_PASSWORDПубличный локальный пароль из примера; замените для приватных данных
JWT_SECRET, JWT_TTL_SECONDSСекрет подписи ≥32 символов, TTL 3600 секунд
NODE_ENVBackend: development; frontend-контейнер всегда запускает production-сборку
DEMO_MODE, DEMO_*true, логины/пароли и ID импортированного сотрудника для demo seed
DATA_MODEКорневой запуск: input; backend отдельно: fixtures
INPUT_DATA_DIRКорневой запуск: ../frontend/app/data, относительно backend/, либо абсолютный путь
CORS_ORIGINShttp://localhost:3000,http://127.0.0.1:3000; браузер по умолчанию использует same-origin proxy
AS_OF_DATEНеобязательная бизнес-дата; иначе дата среза набора, не системные часы
DATABASE_URLВ Docker создаётся автоматически из POSTGRES_*. Для запуска backend через Node.js нужен адрес отдельно подготовленной PostgreSQL.
LLM_PROVIDERdisabled — правила; openai — облачный адаптер; local — Ollama. Один ключ не выбирает провайдера.
LLM_MODELПо умолчанию gpt-4.1-mini для OpenAI. Для Ollama задайте имя установленной локальной модели. При disabled не используется.
LLM_BASE_URLМожно не задавать: OpenAI использует https://api.openai.com/v1, Ollama — http://127.0.0.1:11434. Адрес должен соответствовать выбранному провайдеру.
LLM_API_KEYНужен для OpenAI; для Ollama — только если его сервер требует авторизацию. При disabled не используется.
LLM_TIMEOUT_MSТаймаут модели в миллисекундах: по умолчанию 5000, допустимо 100–6000.
ALLOW_EXTERNAL_LLMПо умолчанию false. Для OpenAI требуется true; для Ollama вне loopback/localhost тоже требуется true.

JWT_SECRET нужен для входа пользователей и не связан с AI. При обычном Docker-запуске он уже есть в примере. Если заменить его на строку короче 32 символов, конфигурация будет отклонена. Аналогично, при DEMO_MODE=true нужны оба демо-пароля длиной от 12 символов. Отключение DEMO_MODE не создаёт настоящих корпоративных пользователей и не удаляет уже существующие аккаунты.

Что будет с ключом AI и без него

Ниже описано поведение при новом подборе, если остальные настройки корректны, БД доступна и найдены подходящие активности. Ошибка настройки AI не равна ошибке запуска всего приложения.

НастройкиЧто происходит
LLM_PROVIDER=disabled, ключ отсутствуетПриложение работает, рекомендации рассчитываются по правилам. Вызовов AI нет.
LLM_PROVIDER=disabled, ключ добавленРовно тот же режим. Ключ сам по себе ничего не включает и не отправляется провайдеру.
LLM_PROVIDER=openai, ALLOW_EXTERNAL_LLM=falseВнешний запрос заблокирован, даже если ключ есть. Подбор по правилам; причина LLM_EXTERNAL_TRANSFER_DISABLED.
LLM_PROVIDER=openai, разрешение true, ключ отсутствует или пустойBackend запускается. При подборе запрос к OpenAI не выполняется; используются правила с причиной LLM_NOT_CONFIGURED.
LLM_PROVIDER=openai, разрешение true, настоящий ключ и доступная модельBackend обращается к OpenAI. Если ответ прошёл проверку, результат помечается AI_ASSISTED, aiUsed=true.
OpenAI отклонил ключ/модель, запрос не удался, истёк таймаут или ответ не прошёл проверкуСервер возвращает подбор по правилам (RULES_FALLBACK, aiUsed=false) с причиной в diagnostics.fallbackReason.
LLM_PROVIDER=local, ключ отсутствуетМожно работать с отдельно запущенным Ollama без авторизации. Нужны установленная модель, доступный адрес и прохождение проверок адаптера.
LLM_PROVIDER=local, ключ указанКлюч передаётся серверу Ollama как Authorization: Bearer …. Это не переключает запросы на OpenAI.

При отсутствии подходящих активностей модель не вызывается, даже если всё настроено. Подбор по правилам сохраняет профиль, требования, историю и расчёт ожидаемых изменений; пропускается только выбор и упорядочивание вариантов языковой моделью. Ошибка базы данных или невалидное значение окружения, например LLM_PROVIDER=unknown, всё же может остановить операцию или запуск: резервный алгоритм защищает именно от недоступности LLM.

Вариант 1 — запуск без AI. Оставьте ключ закомментированным и используйте в корневом .env:

LLM_PROVIDER=disabled
ALLOW_EXTERNAL_LLM=false

Вариант 2 — OpenAI. В корневом .env задайте:

LLM_PROVIDER=openai
LLM_MODEL=gpt-4.1-mini
LLM_API_KEY=replace-with-your-real-provider-key
ALLOW_EXTERNAL_LLM=true
LLM_TIMEOUT_MS=6000
LLM_BASE_URL=https://api.openai.com/v1

Замените плейсхолдер настоящим ключом. URL указан явно, чтобы не унаследовать адрес Ollama из другого файла настроек. Ключ используется только backend и не передаётся в браузер. Responses API получает ограниченный контекст выбора с store:false; детали запроса зафиксированы в адаптере OpenAI.

Вариант 3 — Ollama. Выберите LLM_PROVIDER=local, задайте LLM_MODEL с именем заранее установленной модели и LLM_BASE_URL запущенного Ollama. Общий Compose не устанавливает Ollama или веса модели. В Docker адрес 127.0.0.1 означает сам контейнер API; для Ollama на хосте Docker Desktop в примере приведён http://host.docker.internal:11434. Этот hostname требует ALLOW_EXTERNAL_LLM=true в текущем адаптере. При запуске backend обычным Node.js-процессом рядом с Ollama можно использовать http://127.0.0.1:11434 и ALLOW_EXTERNAL_LLM=false. Подробности — в документации рекомендаций.

После изменения .env из корня выполните:

docker compose up --build -d

Обычный docker compose restart не применяет изменённые переменные окружения. После пересоздания контейнеров откройте рекомендации и нажмите «Подобрать заново»: простое открытие страницы читает сохранённый результат. Интерфейс показывает «Подбор с участием AI» или «Подбор по правилам сервера. AI не использован». В ответе API проверяйте data.source, data.aiUsed и data.diagnostics.fallbackReason. Положительный /health/ready подтверждает работу БД и backend, но не успешный вызов модели (liveVerified=false).

Если приложение уже запускали с другим набором

Старая база, прогресс и привязка демо-пользователя сохраняются. Изменение POSTGRES_DB не создаёт новую базу внутри уже инициализированного volume; изменение DEMO_EMPLOYEE_ID не перепривязывает существующий аккаунт. Для независимой демонстрации полного набора используйте новое имя Compose-проекта: у него будет собственный volume. Пример PowerShell из корня, при свободных портах 3100 и 3101:

$fullProject = 'career-quest-full-' + (Get-Date -Format 'yyyyMMddHHmmss')
$env:PORT = '3101'
$env:FRONTEND_PORT = '3100'
$env:POSTGRES_DB = 'career_quest_full'
$env:DATA_MODE = 'input'
$env:INPUT_DATA_DIR = '../frontend/app/data'
$env:DEMO_EMPLOYEE_ID = 'E0001'
docker compose -p $fullProject up --build -d --wait
Remove-Item Env:PORT, Env:FRONTEND_PORT, Env:POSTGRES_DB, Env:DATA_MODE, Env:INPUT_DATA_DIR, Env:DEMO_EMPLOYEE_ID

Откройте http://localhost:3100. Остальные настройки, включая demo mode, пароли и LLM, берутся из файлов окружения, как описано выше. В том же терминале остановите это окружение командой docker compose -p $fullProject stop. Предыдущий проект и его данные сохраняются. Такой же подход с отдельным именем проекта подходит для собственного набора данных; задайте его путь и ID сотрудника перед запуском.

Сборка и сеть

Frontend собирается по package-lock.json через npm ci в отдельной Docker-стадии. Runtime содержит только Nuxt .output, работает от пользователя node и запускает node .output/server/index.mjs. Это production Nitro server; он обслуживает SPA, прямые внутренние URL и API proxy.

Браузер обращается к относительному /api/v1. Nitro пересылает запрос на http://api:3001, сохраняя /api/v1, query-параметры, метод, тело, заголовок Authorization и статус ответа. Docker-имя api не попадает в публичный адрес клиента. Отдельный nginx для этой архитектуры не требуется.

NUXT_API_BASE — приватная runtime-настройка upstream (http://api:3001 в Compose, http://127.0.0.1:3001 при разработке). NUXT_PUBLIC_API_BASE — публичная runtime-настройка (/api/v1). Они читаются Nuxt при запуске, не подставляются секретами в клиентскую сборку. NITRO_PRESET=node-server применяется только при сборке образа. CORS backend не расширялся.

Порядок запуска: PostgreSQL healthy → миграции завершены → bootstrap завершён → API healthy → frontend. Для migrate и bootstrap нормальное состояние — Exited (0); для трёх постоянных сервисов — Up (healthy).

Остановка и диагностика

docker compose logs --tail=100 frontend api migrate bootstrap postgres
docker compose stop
docker compose start

docker compose down удаляет контейнеры, сохраняя данные в volume career-quest_postgres_data. Для обычной остановки не добавляйте -v: этот флаг удаляет volume с данными. После изменения кода или конфигурации повторите docker compose up --build -d.

Существующий volume сохраняет прогресс. Смена POSTGRES_PASSWORD в файле не изменяет пароль уже инициализированной базы. Корневой и backend Compose используют одно имя проекта; запускайте их согласованно.

Разработка без контейнера frontend

Нужны Node.js 22.16–24 и npm. Сначала запустите общий стек, затем из корня освободите порт frontend и запустите Nuxt:

docker compose stop frontend
cd frontend
npm ci
npm run dev

Dev server использует proxy на http://127.0.0.1:3001; другой адрес backend задаётся через NUXT_API_BASE. Публичная настройка NUXT_PUBLIC_API_BASE по умолчанию равна /api/v1. Если PowerShell блокирует npm.ps1, используйте npm.cmd.

Полный запуск backend как Node.js-процесса с отдельной PostgreSQL, команды миграций и сборки описаны в backend/README.md.

Как проверить решение

Сценарий для жюри

Обычная демонстрация полного набора после быстрого запуска, с новыми демо-аккаунтами:

  1. На странице входа войдите как employee с паролем из таблицы выше. Откроется профиль сотрудника E0001.
  2. Откройте профиль и «Траекторию»: сравните текущие навыки с требованиями следующего грейда.
  3. В рекомендациях нажмите «Подобрать заново»: проверьте предложенные шаги, объяснения и пометку об использовании AI или правил.
  4. Откройте карточку доступной активности, запишитесь и проверьте её в списке участия. Самостоятельную активность можно завершить; будущую запланированную сессию — только после наступления её даты по правилам набора. Обновите страницу, чтобы проверить сохранение результата.
  5. Выйдите, войдите как hr, откройте список сотрудников и профиль E0001. В исходном полном наборе 200 сотрудников; в профиле видны сохранённые изменения.
  6. Проверьте HR-сводку и подбор для выбранного сотрудника. Для дополнительных профилей используйте импорт: сначала «Проверить пакет» (dry-run, проверка без применения), затем «Применить импорт».

Готовность, состав рекомендаций и доступные активности зависят от сохранённого состояния. Для этого набора не нужно ожидать ровно 50% или искать fixture_person_a: это данные отдельного тестового примера ниже. Названия кнопок приведены для русского языка интерфейса.

Отдельное ручное демо с точными числами

Этот пример использует свежую отдельную БД с шестью профилями backend/data/fixtures. Он подходит для проверки изменения навыков без изменения основной базы. Из корня в отдельном PowerShell-терминале запустите только демонстрационное окружение, при свободных портах 3200 и 3201:

$demoProject = 'career-quest-demo-' + (Get-Date -Format 'yyyyMMddHHmmss')
$env:PORT = '3201'
$env:FRONTEND_PORT = '3200'
$env:POSTGRES_DB = 'career_quest_verify'
docker compose -p $demoProject -f compose.yaml -f docs/compose.verify.yaml up --build -d --wait
Remove-Item Env:PORT, Env:FRONTEND_PORT, Env:POSTGRES_DB

Откройте http://localhost:3200. Дополнительный Compose-файл (overlay) выбирает fixtures и отключает LLM. Используйте DEMO_MODE=true и демо-аккаунты из раздела запуска; если в .env заданы другие пароли, войдите с ними. Здесь employee связан с fixture_person_a. До ручной проверки не запускайте E2E-тесты на этом окружении: они меняют те же данные. Повторный запуск с тем же именем проекта тоже не сбрасывает прогресс.

ШагДействиеОжидаемый результат
1Войти на /login как employee. Открыть профиль и «Траекторию» (/path).Профиль Synthetic Demo A, роль Fixture Engineer, грейд Apprentice, следующий грейд Practitioner. System Design — 1, готовность — 50%.
2Открыть /recommendations, нажать «Подобрать заново».До трёх доступных шагов с объяснениями и ожидаемыми изменениями навыков. При стандартной конфигурации указан подбор по правилам.
3Открыть курс System Design и нажать «Записаться».Курс Synthetic System Design Course появляется в списке участия (/activities). Формат — самостоятельное обучение, без ожидания будущей сессии.
4В /activities завершить этот курс кнопкой «Завершить».Экран результата показывает System Design 1 → 2, готовность 50% → 60%. Грейд остаётся прежним.
5Перезагрузить страницу результата, затем открыть профиль и историю.Сохранённое завершение и новые значения повторно загружаются из backend.
6Ещё раз обновить рекомендации.Подбор учитывает новые навыки; завершённый неповторяемый курс исключён.
7Выйти и войти как hr. Открыть /hr-dashboard, /hr-people и профиль сотрудника.Доступны HR-сводки, список из шести исходных профилей, актуальные навыки и история сотрудника.
8В /import выбрать skills.json, employees.json, events.json, activity_history.csv, dataset-rules.json из backend/data/fixtures. Нажать «1. Проверить пакет», затем «2. Применить импорт».Появляются отчёты VALIDATED и APPLIED. Повторный импорт неизменённого набора сохраняет накопленный прогресс.

Числа в шаге 4 следуют из правил демонстрационного каталога: курс даёт +1 к System Design, а сумма требований следующего грейда равна 10. Это иллюстрация расчёта на синтетических данных, а не измерение реального профессионального роста.

Когда ручная проверка закончена, в том же терминале остановите только это демо:

docker compose -p $demoProject -f compose.yaml -f docs/compose.verify.yaml stop

Для проверки API без интерфейса используйте Swagger (основной стек: 3001, изолированное демо: 3201) и сценарии с HTTP-запросами, подставляя порт нужного окружения. API возвращает JWT при входе; защищённые запросы используют Authorization: Bearer <token>.

Автоматические проверки

Backend, команды из корня репозитория:

cd backend
npm ci
npm run prisma:generate
npm run lint
npm run typecheck
npm run build
npm test
npm run test:architecture

Для integration/E2E с настоящей изолированной PostgreSQL, находясь в backend/:

node scripts/test-postgres.mjs

Скрипт создаёт отдельную тестовую базу, применяет миграции и останавливает PostgreSQL после проверок. Вариант с Docker и TEST_DATABASE_URL описан в инструкции backend.

Frontend, в отдельном терминале из корня:

cd frontend
npm ci
npm run typecheck
npm run build
npm test
npx playwright install chromium

Браузерные E2E требуют свежую отдельную БД с fixtures, потому что создают участия и изменяют прогресс. Обычный корневой запуск с 200 профилями для них не подходит. Пример PowerShell из корня, с новым именем проекта для каждого полного прогона:

$testProject = 'career-quest-e2e-' + (Get-Date -Format 'yyyyMMddHHmmss')
$env:PORT = '3201'
$env:FRONTEND_PORT = '3200'
$env:POSTGRES_DB = 'career_quest_verify'
docker compose -p $testProject -f compose.yaml -f docs/compose.verify.yaml up --build -d --wait
$env:E2E_BASE_URL = 'http://127.0.0.1:3200'
Push-Location frontend
npm run test:e2e
Pop-Location
docker compose -p $testProject -f compose.yaml -f docs/compose.verify.yaml stop
Remove-Item Env:PORT, Env:FRONTEND_PORT, Env:POSTGRES_DB, Env:E2E_BASE_URL

Overlay отключает внешнюю LLM. Пример использует локальные demo credentials из таблицы выше; при их изменении задайте соответствующие E2E_EMPLOYEE_USERNAME, E2E_EMPLOYEE_PASSWORD, E2E_HR_USERNAME, E2E_HR_PASSWORD для тестов. Остановка сохраняет тестовый volume. CI создаёт собственное окружение и удаляет только его после проверки.

Проверки backend и отдельной тестовой БД описаны в backend/README.md. Chromium устанавливается один раз перед E2E; стек должен быть запущен. Текущая проверка: docs/weakness-verification.md. Исторические результаты после слияния языков: docs/merge-verification.md; до слияния, включая живой OpenAI: docs/fixes-verification.md; контракт: docs/api-integration.md. Наличие отчёта не заменяет проверки в новом окружении. npm test проверяет актуальный frontend; npm run test:legacy отдельно проверяет сохранённый старый движок, который рабочий UI не использует.

Данные и интеграции

Основной источник данных — импортируемые файлы. Стандартный корневой запуск использует 200 синтетических профилей, 60 навыков, 40 активностей и 2743 записи истории из frontend/app/data. Backend-only Compose и изолированные тесты используют 6 профилей, 4 навыка, 8 активностей и 7 записей истории из backend/data/fixtures, с датой среза 2026-10-01. Это наборы для разработки и проверки, не реальные данные сотрудников и не данные жюри.

ФайлСодержимое
skills.jsonНавыки, шкала 0–5, профили ролей, грейды и требования.
employees.jsonПрофили, исходные уровни навыков, дата оценки и сохранённая карьерная цель.
events.jsonАктивности, аудитории, форматы, даты, начальные требования и правила прироста навыков.
activity_history.csvИстория участия со статусами, датами и результатами.
dataset-rules.jsonНеобязательные правила: дата среза, трактовка отсутствующих навыков, базовая оценка, порядок грейдов и повторяемость.

Для собственного набора создайте backend/data/input, поместите туда четыре обязательных файла и при необходимости dataset-rules.json. В существующем корневом .env задайте DATA_MODE=input, INPUT_DATA_DIR=./data/input (путь относительно backend/) и, при включённом demo mode, DEMO_EMPLOYEE_ID существующего профиля. Затем выполните docker compose up --build -d. Входной каталог монтируется read-only. При отсутствии или невалидности обязательных файлов bootstrap останавливается с ошибкой; входные данные автоматически не заменяются демонстрационными. Существующая база и прогресс сохраняются, поэтому для независимого набора нужна отдельная база.

HR-импорт допускает полный или частичный пакет: до 5 файлов по 8 МиБ, с указанными именами. Сначала выполняется проверка без изменения профилей и истории, затем применение. Ссылки между сущностями проверяются; отклонённый пакет не вносит частичных бизнес-изменений. Структура и правила описаны в контракте данных.

Внешние интеграции, реализованные в коде, — необязательные OpenAI и Ollama для выбора рекомендаций. В модель передаются отобранные варианты и ограниченный контекст навыков, требований и истории, без имён сотрудников и полного массива профилей. При LLM_PROVIDER=disabled обращения к модели отсутствуют.

Каталог обучения загружается из файлов; подключений к внешним LMS, HR-системам, календарям и корпоративному SSO в текущем API нет. Файлы в frontend/app/data служат входом backend при общем запуске. Рабочий интерфейс получает данные через API; прежний локальный движок не используется для подмены серверных результатов.

Ограничения текущей версии

  • Нет самостоятельной регистрации, восстановления или смены пароля, обновления JWT и production-подключения SSO. После истечения токена нужен повторный вход.
  • HR может создать отдельный вход для импортированного сотрудника. Случайный пароль отображается один раз, хранится хеш; это не одноразовый пароль и не замена корпоративному SSO. Существующий аккаунт не перезаписывается.
  • Нет отдельной формы или endpoint для редактирования профиля и карьерной цели; HR может обновить эти сведения через импорт. Пересмотр исходной оценки навыков не реализован: изменение уже импортированной базовой оценки отклоняется как конфликт.
  • Траектория рассчитывается к следующему грейду текущей роли; сохранённая карьерная цель отображается отдельно. Автоматическое повышение грейда не выполняется.
  • Отметка о завершении поступает от пользователя. Прохождение курса не подтверждается внешней образовательной системой; изменение навыков рассчитывается по правилам каталога.
  • Результат зависит от качества импортированных оценок и требований. Если данных недостаточно, следующего грейда нет или подходящих активностей не осталось, система возвращает соответствующее состояние без рекомендаций.
  • При исчерпанном каталоге показаны начатые активности и дефициты; сотрудник может создать внутреннюю заявку HR. Новые учебные программы и их эффекты должен добавить HR: система не выдумывает курсы и не начисляет прогресс за обращение.
  • Подбор по правилам — инженерная эвристика. Репозиторий не подтверждает рост вовлечённости или качество рекомендаций на реальных данных жюри. Наличие адаптеров LLM не означает, что внешний AI включён или проверен в конкретном окружении.
  • Интерфейс поддерживает семь языков: русский, казахский, английский, немецкий, испанский, португальский и упрощённый китайский. Backend принимает только ru, kk, en: русский, казахский и английский передаются напрямую, остальные языки UI используют en в запросах API. Интерфейс переводит серверные факты без пересчёта результатов; неизвестные тексты каталога сохраняются в исходном виде, имена людей и идентификаторы не переводятся.
  • Нет полнотекстового поиска по каталогу. Сотрудников можно искать по ID и имени; фильтры HR по подразделению, роли и грейду используют точные значения.
  • У импортированной истории может не быть подробного результата изменения навыков. CSV не содержит точного времени завершения самостоятельного обучения; восстановление истории использует доступную дату по описанным правилам.
  • Доступность сессий и стандартное окно HR-аналитики привязаны к дате среза набора, а не автоматически к текущей дате компьютера. Сигналы HR отражают наблюдаемые данные; прогнозирования увольнений или мотивации нет.
  • Docker-конфигурация предназначена для локального запуска: HTTP-порты привязаны к 127.0.0.1, PostgreSQL не публикует порт на хост. Публичное размещение требует отдельной настройки окружения и доступа.

Развёрнутая версия

Подтверждённая ссылка на публично развёрнутое приложение в репозитории не указана. После локального запуска приложение доступно по адресу http://localhost:3000.

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

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

yuutsu 8AsekePC 6Ex-bex 3

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

  • 2026-09-23 17:53Merge latest launch documentation while preserving verified audit fixesAsekePC
  • 2026-09-23 17:51Fix sequential career plans, jury onboarding and HR recovery flowsAsekePC
  • 2026-09-23 17:30fix docsyuutsu
  • 2026-09-23 17:10Merge seven-language frontend with verified Career Quest fixesAsekePC
  • 2026-09-23 16:58Fix Career Quest audit findings and verify live AI integrationAsekePC
  • 2026-09-23 16:45Frontend: languages finished.Ex-bex
  • 2026-09-23 16:18update readme.mdyuutsu
  • 2026-09-23 15:48finish(backend->frontend)AsekePC
Все коммиты (17)
  • 2026-09-23 15:16finish(frontend)Ex-bex
  • 2026-09-23 15:13Update readme and add github workflowyuutsu
  • 2026-09-23 15:12finish(backend)yuutsu
  • 2026-09-23 15:07Add Career Quest PostgreSQL schema and migrationsyuutsu
  • 2026-09-23 14:42fix(frontend): fix test vueAsekePC
  • 2026-09-23 14:30feat(frontend): add default main.htmlEx-bex
  • 2026-09-23 13:52chore(frontend): install tailwindyuutsu
  • 2026-09-23 13:49feat(frontend): add basic routeyuutsu
  • 2026-09-23 13:42feat(backend):init\nfeat(frontend):inityuutsu
Структура репозитория (364 файлов)
.env.example
.github/workflows/backend-ci.yml
.gitignore
README.md
backend/.dockerignore
backend/.env.example
backend/.gitignore
backend/.prettierrc
backend/Dockerfile
backend/README.md
backend/compose.test.yaml
backend/compose.yaml
backend/data/dataset-rules.json
backend/data/fixtures/README.md
backend/data/fixtures/activity_history.csv
backend/data/fixtures/dataset-rules.json
backend/data/fixtures/employees.json
backend/data/fixtures/events.json
backend/data/fixtures/skills.json
backend/docs/adr/001-modular-monolith.md
backend/docs/adr/002-prisma-boundary.md
backend/docs/adr/003-hybrid-ai.md
backend/docs/architecture.md
backend/docs/data-contract.md
backend/docs/demo.md
backend/docs/evaluation-report.json
backend/docs/recommendation-engine.md
backend/docs/verification.md
backend/eslint.config.mjs
backend/jest.config.cjs
backend/nest-cli.json
backend/package-lock.json
backend/package.json
backend/prisma/migrations/20260923000100_development_requests/migration.sql
backend/prisma/migrations/202609230001_initial/migration.sql
backend/prisma/migrations/202609230002_domain_checks/migration.sql
backend/prisma/migrations/migration_lock.toml
backend/prisma/schema.prisma
backend/prisma/seed.ts
backend/scripts/bootstrap.ts
backend/scripts/evaluate-plans.ts
backend/scripts/evaluate-recommendations.ts
backend/scripts/import-dataset.ts
backend/scripts/plan-oracle.ts
backend/scripts/smoke.ts
backend/scripts/test-postgres.mjs
backend/scripts/verify-dataset.ts
backend/src/app.module.ts
backend/src/bootstrap.ts
backend/src/config/configuration.ts
backend/src/config/env.schema.ts
backend/src/main.ts
backend/src/modules/competency-catalog/application/catalog.service.ts
backend/src/modules/competency-catalog/competency-catalog.module.ts
backend/src/modules/competency-catalog/domain/catalog.ts
backend/src/modules/competency-catalog/infrastructure/prisma-catalog.ts
backend/src/modules/competency-catalog/presentation/catalog.controller.ts
backend/src/modules/competency-catalog/presentation/catalog.dto.ts
backend/src/modules/competency-catalog/public-infrastructure.ts
backend/src/modules/competency-catalog/public.ts
backend/src/modules/dataset-import/application/import.service.ts
backend/src/modules/dataset-import/application/validate-import.ts
backend/src/modules/dataset-import/dataset-import.module.ts
backend/src/modules/dataset-import/infrastructure/parsers/dataset.parser.ts
backend/src/modules/dataset-import/infrastructure/parsers/jury-normalizer.ts
backend/src/modules/dataset-import/infrastructure/prisma-import.store.ts
backend/src/modules/dataset-import/infrastructure/schemas/dataset.schemas.ts
backend/src/modules/dataset-import/presentation/http/import.controller.ts
backend/src/modules/dataset-import/presentation/http/import.dto.ts
backend/src/modules/dataset-import/public.ts
backend/src/modules/development-requests/application/development-requests.service.ts
backend/src/modules/development-requests/development-requests.module.ts
backend/src/modules/development-requests/infrastructure/prisma-development-request.store.ts
backend/src/modules/development-requests/presentation/development-requests.controller.ts
backend/src/modules/development/application/development.service.ts
backend/src/modules/development/development.module.ts
backend/src/modules/development/domain/events/participation-completed.ts
backend/src/modules/development/domain/policies.ts
backend/src/modules/development/infrastructure/development.repository.ts
backend/src/modules/development/infrastructure/import-writer.ts
backend/src/modules/development/presentation/development.controller.ts
backend/src/modules/development/presentation/development.dto.ts
backend/src/modules/development/public-infrastructure.ts
backend/src/modules/development/public.ts
backend/src/modules/employees/application/employee.service.ts
backend/src/modules/employees/domain/employee.ts
backend/src/modules/employees/employees.module.ts
backend/src/modules/employees/infrastructure/prisma-employees.ts
backend/src/modules/employees/presentation/employees.controller.ts
backend/src/modules/employees/presentation/employees.dto.ts
backend/src/modules/employees/public-infrastructure.ts
backend/src/modules/employees/public.ts
backend/src/modules/health/health.controller.ts
backend/src/modules/health/health.module.ts
backend/src/modules/hr-analytics/application/hr-analytics.port.ts
backend/src/modules/hr-analytics/application/hr-analytics.service.ts
backend/src/modules/hr-analytics/hr-analytics.module.ts
backend/src/modules/hr-analytics/infrastructure/prisma-hr.projection.ts
backend/src/modules/hr-analytics/presentation/hr-analytics.controller.ts
backend/src/modules/hr-analytics/presentation/hr-analytics.dto.ts
backend/src/modules/hr-analytics/public.ts
backend/src/modules/identity-access/application/auth.service.ts
backend/src/modules/identity-access/application/employee-account.service.ts
backend/src/modules/identity-access/domain/actor.ts
backend/src/modules/identity-access/identity-access.module.ts
backend/src/modules/identity-access/infrastructure/credentials.ts
backend/src/modules/identity-access/infrastructure/employee-accounts.ts
backend/src/modules/identity-access/infrastructure/prisma-users.ts
backend/src/modules/identity-access/presentation/auth.controller.ts
backend/src/modules/identity-access/presentation/auth.guard.ts
backend/src/modules/identity-access/presentation/decorators.ts
backend/src/modules/identity-access/presentation/employee-accounts.controller.ts
backend/src/modules/identity-access/public-http.ts
backend/src/modules/identity-access/public.ts
backend/src/modules/learning-catalog/application/catalog.service.ts
backend/src/modules/learning-catalog/domain/activity.ts
backend/src/modules/learning-catalog/infrastructure/prisma-catalog.ts
backend/src/modules/learning-catalog/learning-catalog.module.ts
backend/src/modules/learning-catalog/presentation/catalog.controller.ts
backend/src/modules/learning-catalog/presentation/catalog.dto.ts
backend/src/modules/learning-catalog/public-infrastructure.ts
backend/src/modules/learning-catalog/public.ts
backend/src/modules/recommendations/application/ports/recommendation.ports.ts
backend/src/modules/recommendations/application/use-cases/recommendations.service.ts
backend/src/modules/recommendations/domain/entities/recommendation-set.ts
backend/src/modules/recommendations/domain/policies/evidence.policy.ts
backend/src/modules/recommendations/domain/policies/planner.policy.ts
backend/src/modules/recommendations/domain/policies/ranking.policy.ts
backend/src/modules/recommendations/infrastructure/development-policies.adapter.ts
backend/src/modules/recommendations/infrastructure/llm/http-json.ts
backend/src/modules/recommendations/infrastructure/llm/local-llm.adapter.ts
backend/src/modules/recommendations/infrastructure/llm/openai.adapter.ts
backend/src/modules/recommendations/infrastructure/llm/prompts/selection.prompt.ts
backend/src/modules/recommendations/infrastructure/llm/response.schema.ts
backend/src/modules/recommendations/infrastructure/persistence/prisma-recommendation.repository.ts
backend/src/modules/recommendations/presentation/http/recommendations.controller.ts
backend/src/modules/recommendations/presentation/http/recommendations.dto.ts
backend/src/modules/recommendations/public.ts
backend/src/modules/recommendations/recommendations.module.ts
backend/src/shared/application/clock.port.ts
backend/src/shared/application/dataset-contracts.ts
backend/src/shared/application/pagination.ts
backend/src/shared/application/unit-of-work.port.ts
backend/src/shared/domain/canonical-json.ts
backend/src/shared/domain/context.ts
backend/src/shared/domain/domain-error.ts
backend/src/shared/domain/domain-event.ts
backend/src/shared/infrastructure/database/prisma-unit-of-work.ts
backend/src/shared/infrastructure/database/prisma.module.ts
backend/src/shared/infrastructure/database/prisma.service.ts
backend/src/shared/infrastructure/http/exception.filter.ts
backend/src/shared/infrastructure/http/rate-limit.ts
backend/src/shared/infrastructure/http/request-id.interceptor.ts
backend/src/shared/infrastructure/http/swagger.ts
backend/src/shared/infrastructure/http/validation.pipe.ts
backend/test/architecture/dependencies.spec.ts
backend/test/e2e/career-flow.spec.ts
backend/test/e2e/development-requests.spec.ts
backend/test/e2e/jury-flow.spec.ts
backend/test/evaluations/llm-live.spec.ts
backend/test/evaluations/recommendation-fixtures.ts
backend/test/integration/import-and-database.spec.ts
backend/test/support/database.ts
backend/test/unit/dataset-import.spec.ts
backend/test/unit/development-requests.spec.ts
backend/test/unit/development-service.spec.ts
backend/test/unit/development.spec.ts
backend/test/unit/employee-account.spec.ts
backend/test/unit/hr-analytics.spec.ts
backend/test/unit/jury-import.spec.ts
backend/test/unit/llm-adapters.spec.ts
backend/test/unit/plan-evaluation.spec.ts
backend/test/unit/recommendation-planner.spec.ts
backend/test/unit/recommendations.spec.ts
backend/tsconfig.build.json
backend/tsconfig.json
compose.backend.yaml
compose.rules.yaml
compose.yaml
docs/api-contract-verification.json
docs/api-integration.md
docs/audit-artifacts/frontend/browser-audit.json
docs/audit-artifacts/frontend/cold-cache-ui.json
docs/audit-artifacts/frontend/fixes-main-ui.json
docs/audit-artifacts/frontend/fixes-main-ui/employee-desktop.png
docs/audit-artifacts/frontend/fixes-main-ui/employee-profile-kk-mobile.png
docs/audit-artifacts/frontend/fixes-main-ui/employee-profile-mobile.png
docs/audit-artifacts/frontend/fixes-main-ui/employee-recommendations-desktop.png
docs/audit-artifacts/frontend/fixes-main-ui/hr-E0090-kk-mobile.png
docs/audit-artifacts/frontend/fixes-main-ui/hr-E0090-recommendations-desktop.png
docs/audit-artifacts/frontend/fixes-main-ui/hr-E0090-recommendations-mobile.png
docs/audit-artifacts/frontend/fixes-main-ui/hr-dashboard-desktop.png
docs/audit-artifacts/frontend/fixes-main-ui/hr-event-readonly-desktop.png
docs/audit-artifacts/frontend/fixes-main-ui/result.json
docs/audit-artifacts/frontend/full-data-employee-recommendations.png
docs/audit-artifacts/frontend/full-data-hr-E0090-no-recommendations.png
docs/audit-artifacts/frontend/full-dataset-dry-run.png
docs/audit-artifacts/frontend/full-dataset-ui.json
docs/audit-artifacts/frontend/hr-employee-no-recommendations.png
docs/audit-artifacts/frontend/merge-ui/hr-E0090-de-desktop.png
docs/audit-artifacts/frontend/merge-ui/hr-E0090-kk-mobile.png
docs/audit-artifacts/frontend/merge-ui/hr-E0090-zh-mobile.png
docs/audit-artifacts/frontend/merge-ui/result.json
docs/audit-artifacts/frontend/profile-hidden-on-recommendation-error.png
docs/audit-artifacts/frontend/weakness-main-ui.json
docs/audit-artifacts/frontend/weakness-main-ui/employee-dashboard-desktop.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-E0090-desktop.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-dashboard-desktop.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-de-mobile.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-en-mobile.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-es-mobile.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-kk-mobile.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-pt-mobile.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-ru-mobile.png
docs/audit-artifacts/frontend/weakness-main-ui/hr-requests-zh-mobile.png
docs/audit-data-security-fixes.md
docs/audit-data-security.md
docs/audit-frontend.md
docs/audit-full-data-results.json
docs/audit-full-data.mjs
docs/audit-full.override.yaml
docs/audit-recommendations-evaluation.json
docs/audit-recommendations-results.json
docs/audit-recommendations.cjs
docs/audit-recommendations.md
docs/audit-runtime-results.json
docs/audit-runtime.mjs
docs/audit/data-security-fix-results.json
docs/audit/data-security-probe-results.json
docs/audit/data-security-probes.cjs
docs/career-quest-audit.md
docs/compose.verify.yaml
docs/fixes-browser-results.json
docs/fixes-dataset-verification.json
docs/fixes-final-health.json
docs/fixes-live-boundaries.json
docs/fixes-live-evaluation.json
docs/fixes-live-http-results.json
docs/fixes-live-http.mjs
docs/fixes-runtime-results.json
docs/fixes-secret-check.json
docs/fixes-verification.md
docs/merge-browser-results.json
docs/merge-security-check.json
docs/merge-verification.md
docs/openapi.json
docs/verification.md
docs/weakness-after-deploy.json
docs/weakness-before-deploy.json
docs/weakness-browser-results.json
docs/weakness-dataset-verification.json
docs/weakness-live-evaluation.json
docs/weakness-live-http-results.json
docs/weakness-live-planid-evaluation.json
docs/weakness-rules-evaluation.json
docs/weakness-verification.md
frontend/.dockerignore
frontend/.gitignore
frontend/Dockerfile
frontend/README.md
frontend/app/app.vue
frontend/app/assets/css/app.css
frontend/app/assets/css/design.css
frontend/app/components/CqAsync.vue
frontend/app/components/CqBrand.vue
frontend/app/components/CqDataWarnings.vue
frontend/app/components/CqDepartment.vue
frontend/app/components/CqEmployeeAccount.vue
frontend/app/components/CqEvidence.vue
frontend/app/components/CqHeading.vue
frontend/app/components/CqIcon.vue
frontend/app/components/CqLanguage.vue
frontend/app/components/CqLanguageSwitcher.vue
frontend/app/components/CqMetric.vue
frontend/app/components/CqNotice.vue
frontend/app/components/CqProfile.vue
frontend/app/components/CqProgress.vue
frontend/app/components/CqRecent.vue
frontend/app/components/CqRecommendation.vue
frontend/app/components/CqRecommendations.vue
frontend/app/components/CqRecovery.vue
frontend/app/components/CqSkill.vue
frontend/app/components/CqState.vue
frontend/app/components/CqTag.vue
frontend/app/composables/useApi.js
frontend/app/composables/useCareer.js
frontend/app/composables/useLocale.js
frontend/app/data/activity_history.csv
frontend/app/data/employees.json
frontend/app/data/events.json
frontend/app/data/skills.json
frontend/app/layouts/auth.vue
frontend/app/layouts/default.vue
frontend/app/locales/messages.json
frontend/app/middleware/auth.global.js
frontend/app/pages/[...slug].vue
frontend/app/pages/activities.vue
frontend/app/pages/catalog.vue
frontend/app/pages/completion.vue
frontend/app/pages/error.vue
frontend/app/pages/event.vue
frontend/app/pages/forbidden.vue
frontend/app/pages/hr-dashboard.vue
frontend/app/pages/hr-employee.vue
frontend/app/pages/hr-events.vue
frontend/app/pages/hr-people.vue
frontend/app/pages/hr-requests.vue
frontend/app/pages/import.vue
frontend/app/pages/index.vue
frontend/app/pages/loading.vue
frontend/app/pages/login.vue
frontend/app/pages/no-recommendations.vue
frontend/app/pages/path.vue
frontend/app/pages/profile.vue
frontend/app/pages/recommendations.vue
frontend/app/pages/register.vue
frontend/app/pages/screens.vue
frontend/app/pages/settings.vue
frontend/app/pages/ui-kit.vue
frontend/app/utils/api-client.js
frontend/app/utils/engine.js
frontend/app/utils/explanation.js
frontend/app/utils/hr-analytics.js
frontend/app/utils/i18n.js
frontend/app/utils/icons.js
frontend/app/utils/labels.js
frontend/app/utils/pages.js
frontend/app/utils/session.js
frontend/design-reference/main.html
frontend/design-reference/test.vue
frontend/docs/AI_CONTRACT.md
frontend/docs/API_AND_DATA.md
frontend/docs/DEMO_SCRIPT.md
frontend/docs/PAGES.md
frontend/nuxt.config.ts
frontend/package-lock.json
frontend/package.json
frontend/playwright.config.js
frontend/public/favicon.ico
frontend/public/favicon.svg
frontend/public/robots.txt
frontend/server/routes/api/[...path].ts
frontend/server/routes/health/ready.get.ts
frontend/tailwind.config.js
frontend/tests/api-client.test.js
frontend/tests/audit/cold-cache-ui.mjs
frontend/tests/audit/final-main-ui.mjs
frontend/tests/audit/frontend-audit.mjs
frontend/tests/audit/full-dataset-ui.mjs
frontend/tests/audit/weakness-main-ui.mjs
frontend/tests/career.test.js
frontend/tests/e2e/audit-regressions.spec.js
frontend/tests/e2e/employee.spec.js
frontend/tests/e2e/hr.spec.js
frontend/tests/e2e/languages.spec.js
frontend/tests/e2e/weakness-flows.spec.js
frontend/tests/engine.test.js
frontend/tests/fixtures/employees-invalid.json
frontend/tests/fixtures/employees-valid.json
frontend/tests/fixtures/history-valid.csv
frontend/tests/hr-workflows.test.js
frontend/tests/i18n.test.js
frontend/tsconfig.json
start-demo.ps1

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

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

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