AAYMA
RU
Войти

Career Quest

Карьерный навигатор для сотрудника и HR.

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

О проекте

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

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

Суть

Карьерный навигатор для сотрудника и HR. Сотрудник получает до трёх объяснимых рекомендаций по дефицитам навыков относительно целевой роли и строит личный маршрут; есть карьерный пропуск на 100 уровней, XP и награды, HR-панель с дефицитами и проверкой практик.

Как устроено

Демоданные (employees, events, skills, activity_history) загружаются в SQLite. Сервер на FastAPI считает пользу шага по требованиям цели с учётом времени, формата и предварительных требований. Самоотчёт обновляет расчётную модель навыков отдельно от аттестации. OpenAI Career Copilot через Responses API объясняет расчёты и собирает черновик маршрута из реальных мероприятий, сервер проверяет факты; без ключа работает локальный алгоритм. Клиент на Flutter Web для сотрудника и HR.

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

  • skill-gap рекомендации
  • симулятор «Что если»
  • геймификация (XP, сезоны, карьерный пропуск)
  • OpenAI Responses API structured output
  • локальный fallback

Особенности

Участие в программе и квалификация учитываются раздельно. XP за практику начисляются только после проверки HR, просмотр страницы опыта не даёт. CSV-экспорт защищён от формульных инъекций. Есть версионированная веб-админка наград с аудитом.

Стек

Flutter Web · Dart · Python · FastAPI · Pydantic · SQLite · httpx · pytest

Модели

OpenAI (Responses API)


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

README

README.md

Career Quest — твой путь. Больше чем работа.

Career Quest

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

Проект для кейса «Career Quest — платформа геймификации жизненного цикла сотрудника», владелец задачи — Halyk Bank. Сотрудник получает объяснимые рекомендации и видит результат своих шагов; HR отслеживает дефициты навыков, проверяет результаты и управляет программой мотивации.

Flutter Web · FastAPI · SQLite · OpenAI по ключу
Интерфейс на русском · Два сценария доступа · 100 уровней карьерного пропуска

Быстрый старт: из корня проекта выполните python run.py на Linux или py run.py в Windows. После сборки откройте http://127.0.0.1:8000. Нужны Python 3.11+ и Flutter с Dart 3.13.4+. Ключ OpenAI для первого запуска не требуется.

Тестовые данные уже в репозитории. При первом запуске сервер автоматически загрузит JSON/CSV из data/sample в новую SQLite, создаст демонстрационные аккаунты и сезон. Скачивать архив или вручную импортировать файлы не нужно. Быстрая загрузка тестового набора.

Инструкция для AI-оценки · Запуск · Android / APK · Архитектура · Демо для жюри · Проверка решения · Подключение AI

Содержание

  1. Проблема, цель и актуальность
  2. Решение и возможности
  3. Сценарий демонстрации
  4. Технологический стек
  5. Архитектура и схемы
  6. Алгоритмы: рекомендации, прогресс и награды
  7. Данные и хранение
  8. Как запустить
  9. Как подключить OpenAI
  10. Разработка и API
  11. Как проверить решение
  12. Структура репозитория
  13. Ограничения и развитие
  14. Документы проекта
  15. Администрирование Web

1. Проблема, цель и актуальность

Какую проблему решаем

Обучение, аттестации, мероприятия и карьерные возможности приходят сотруднику разрозненно. Список доступных курсов сам по себе не отвечает на вопросы: что выбрать сейчас, почему это полезно именно мне и как это связано с моей следующей ролью?

СитуацияЧто нужно человекуКак отвечает Career Quest
Много активностей, трудно выбратьПонятный следующий шагДо трёх рекомендаций с учётом цели, навыков и времени
Обучение воспринимается отдельно от карьерыСвязь действия с желаемой рольюТребования цели, дефициты и прогноз результата
Прогресс не виден между аттестациямиОбратная связь и повод продолжатьИстория действий, расчётный прогресс и карьерный пропуск
HR видит участие, но не всегда контекст развитияОбщая картина и проверяемые результатыСводка, дефициты, проверка практик и учёт наград

Цель продукта

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

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

Почему это актуально для кейса

Развитие требует регулярных действий, а карьерные решения и оценки происходят отдельными событиями. Между ними нужен понятный маршрут: цель → действие → результат → следующий шаг. Без этой связи сотрудник может участвовать в активностях, не понимая их пользы для своей цели.

Career Quest делает эту связь видимой и объяснимой. При этом участие в программе и профессиональная квалификация учитываются раздельно: активность сама по себе не доказывает готовность к повышению.

Ожидаемый эффект — более осознанный выбор активностей и регулярное развитие. Это гипотеза для будущего пилота, а не уже измеренный результат. В репозитории нет подтверждённых данных о росте удержания, производительности или окупаемости. Проверить пользу можно по времени выбора первого шага, способности сотрудника объяснить его связь с целью и доле завершённых шагов.

2. Решение и возможности

Один маршрут вместо разрозненных уведомлений

flowchart LR
    P["Профиль и последняя оценка"] --> G["Карьерная цель"]
    G --> R["До трёх объяснимых рекомендаций"]
    R --> A["Личный план и выполнение"]
    A --> F["История и расчётный прогресс"]
    F --> R
    A --> V["Проверка результата HR"]
    V --> X["Подтверждённые XP и награды"]
    classDef primary fill:#352747,stroke:#f392d5,color:#f5f3ff
    classDef secondary fill:#172343,stroke:#719bff,color:#f5f3ff
    class G,R,A primary
    class P,F,V,X secondary

Для сотрудника

ВозможностьПользовательский результат
Профиль и цельВидны роль, грейд, история и требования направления. Если цели нет, следующая ступень показывается как предложение
РекомендацииПодбор учитывает дефициты, время, формат, доступность, предварительные требования и уже выполненные действия
Личный маршрутДо трёх активных шагов: добавить, упорядочить, заменить, начать, завершить или отправить в архив
КаталогСамостоятельный выбор с поиском и фильтрами, если предложенный вариант не подходит
Симулятор «Что если»Можно посмотреть другую цель или набор действий до изменения своего плана
Прогресс и паспорт развитияРаздельное отображение оценённых и расчётных навыков; выгрузка паспорта в Markdown
OpenAI Career CopilotОбъясняет рекомендации и собирает проверяемый черновик маршрута из реальных мероприятий. Работает и без внешней модели
Карьерный пропускИгровая дорога из 100 уровней, текущая позиция, награды, переходы по десяткам и возврат к своему уровню
РегулярностьЕжедневные задания, серия активных дней, недельные миссии, достижения и рейтинг участия
НаградыКошелёк CQ, выбор подарков пропуска, магазин и история заявок

Для HR

  • Сводка по сотрудникам, карьерным целям, активностям и дефицитам навыков.
  • Фильтры по подразделению, роли, грейду и периоду; просмотр профиля, плана и истории сотрудника.
  • CSV-отчёт о дефицитах с защитой экспортируемых ячеек от интерпретации как формул.
  • Проверка результата практики: принять или отклонить, оставить комментарий.
  • Управление сезонами, участниками черновика, виртуальным бюджетом, товарами и вариантами подарков.
  • Работа с заявками: согласование, подготовка, выдача, отклонение и отмена по допустимым переходам.

Что отличает подход

  1. Рекомендации можно проверить. Сервер считает пользу шага по требованиям цели; объяснение опирается на эти расчёты.
  2. Прогноз отделён от оценки. Самоотчёт обновляет расчётную модель, сохраняя результат последней аттестации.
  3. Геймификация связана с подтверждёнными действиями. XP за практику появляются после проверки HR; просмотр страницы и нажатие на подарок не дают опыт.
  4. OpenAI помогает, но не управляет данными. Модель объясняет расчёты и предлагает маршрут, а сервер проверяет факты, лимиты и конфликты; без ключа остаётся локальный сценарий.

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

3. Сценарий демонстрации

Основной рассказ на 60–90 секунд

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

ВремяЧто показатьЧто это доказывает
0–15 сек.Профиль сотрудника, его цель и дефицит одного навыкаПроблема привязана к конкретному человеку и направлению
15–35 сек.Рекомендацию, объяснение пользы и добавление в маршрутВыбор опирается на цель, а не только на общий каталог
35–55 сек.Прогноз плана или заранее завершённую учебную практикуВидна связь действия с расчётным прогрессом; последняя оценка остаётся отдельной
55–75 сек.В витрине — подтверждённые XP, отметку «Ты здесь» и награду пропускаМеханика мотивации связана с учтёнными действиями
75–90 сек.Подготовленный результат в HR-сценарии или HR-сводкуУ продукта есть второй участник процесса и проверяемый результат

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

Демонстрация подтверждает работоспособность маршрута и прозрачность вычислений. Она не доказывает повышение квалификации человека или бизнес-эффект для банка: такие выводы требуют реальных оценок и пилота.

4. Технологический стек

УровеньТехнологияРоль в проекте
КлиентFlutter Web / DartАдаптивный интерфейс сотрудника и HR, единая визуальная система
HTTP-клиентDart httpАвторизация, запросы, обработка ошибок, сохранение параметров повторной операции
СерверPython / FastAPIAPI, права доступа, бизнес-операции и выдача веб-сборки
ВалидацияPydantic 2Схемы входных данных, ограничения и понятные ошибки
Запуск сервераUvicornЛокальный ASGI-процесс
ХранениеSQLite / Python sqlite3Исходные записи, аккаунты, сессии и транзакционное доменное состояние
AI с fallbackOpenAI Responses API через httpxСтруктурированные объяснения и черновики маршрутов; локальный алгоритм при сбое
Времяzoneinfo + tzdataСерверные даты и игровые дни в Asia/Almaty
Проверкиpytest, FastAPI TestClient, HTTP mocks, Flutter TestБизнес-инварианты, API, права, состояния и навигация
ВоспроизводимостьLock-файлы и run.pyЗакреплённые зависимости и общий запуск для Linux/Windows

Точные Python-зависимости: requirements.lock. Клиентские: frontend/pubspec.yaml и frontend/pubspec.lock.

Текущая локальная среда сборки: Python 3.14.7, Flutter 3.47.5, Dart 3.13.4. Заявленный минимум Python — 3.11; ограничение Dart в проекте — ^3.13.4. Выбирайте Flutter, который включает совместимую версию Dart.

Основная поставка — веб-приложение. Преимущество Flutter — возможность использовать общую базу интерфейса и API-клиента для Android: после подготовки платформы APK собирается командой Flutter. Порядок описан в разделе Android / APK. Android-сборка и настольный установщик пока не входят в проверенную поставку. Docker, Node.js, отдельный PostgreSQL и OpenAI SDK для обычного веб-запуска не нужны.

5. Архитектура и схемы

Общая архитектура

Приложение — модульный монолит: один Python-сервер обслуживает API и собранный Flutter Web. В стандартном запуске браузер обращается к тому же адресу, с которого загружен интерфейс.

flowchart TB
    U["Сотрудник / HR"] --> WEB["Flutter Web: экраны, маршрут, пропуск"]
    WEB --> CLIENT["CareerApi: токен, ревизия, Idempotency-Key"]
    CLIENT --> API["FastAPI: валидация, роль, владелец записи"]
    API --> ENGINE["Engine: транзакции и доменные операции"]
    ENGINE --> CAREER["career.py: цель, навыки, подбор, план"]
    ENGINE --> GAME["game.py + game_rules.py: сезон, XP, награды"]
    ENGINE --> HR["analytics.py: HR-сводки и экспорт"]
    ENGINE <--> DB[("SQLite: исходные таблицы + quest_state")]
    SEED["Встроенные синтетические данные"] -->|"Первичная инициализация"| DB
    TIMER["Серверный тик раз в минуту"] --> ENGINE
    API --> AI["assistant.py: контекст и проверка ответа"]
    AI -.->|"Ключ задан и AI_MODE=llm"| OPENAI["OpenAI Responses API"]
    AI --> FALLBACK["Локальный шаблон при отсутствии AI или ошибке"]
    classDef core fill:#172343,stroke:#719bff,color:#f5f3ff
    classDef accent fill:#352747,stroke:#f392d5,color:#f5f3ff
    class WEB,CLIENT,API,CAREER,GAME,HR,TIMER,SEED core
    class ENGINE,DB,AI,OPENAI,FALLBACK accent

Внешняя модель получает только подготовленный контекст объяснения. Она не имеет доступа к SQLite или инструментам изменения профиля, XP, наград и решений HR.

Границы ответственности

КомпонентЗа что отвечает
backend/main.pyИнициализация, вход/выход, зависимости доступа, формат ошибок, CORS и веб-сборка
backend/quest_api.pyHTTP-маршруты, входные схемы и вызовы доменных функций
backend/engine.pyВерсионированное состояние, ревизии, транзакции, идемпотентность и аудит
backend/career.pyЦель, оценки и прогноз, рекомендации, план, история и симуляция
backend/game.pyУчастники сезона, начисления, задания, права на награды, заявки и экономика
backend/game_rules.pyПравила уровней, наград, календаря и вариантов заданий
backend/analytics.pyСрезы HR и CSV-отчёт
backend/assistant.pyЛокальное объяснение, запрос OpenAI, верификация ответа и кеш
frontend/lib/core/api.dartHTTP-связь, сессия в памяти и безопасный повтор бизнес-запроса
frontend/lib/widgets/career_pass.dartВизуализация серверных XP, уровней и состояний наград

От выполненного шага до подтверждённых XP

sequenceDiagram
    actor E as Сотрудник
    participant UI as Flutter Web
    participant API as FastAPI + Engine
    participant DB as SQLite
    actor HR as HR
    E->>UI: Завершить практику и подтвердить самоотчёт
    UI->>API: Действие + expected_revision + Idempotency-Key
    API->>API: Проверить сессию, владельца, состояние и ключ
    API->>DB: Атомарно сохранить выполнение и новую ревизию
    DB-->>API: Запись сохранена
    API-->>UI: Расчётный прогресс обновлён, оценка прежняя
    E->>UI: Отправить результат на проверку
    UI->>API: Текст результата для HR
    HR->>API: Одобрить или отклонить
    alt Результат одобрен
        API->>DB: Начислить XP и положенные награды без дублей
        API-->>UI: Обновлённый прогресс при следующем запросе
    else Результат отклонён
        API->>DB: Сохранить решение и комментарий
        API-->>UI: Причина отказа, XP не начислены
    end

Почему повторный запрос не должен удваивать награду

Бизнес-операции проверяют владельца, текущую ревизию и UUID Idempotency-Key. При повторе той же операции с тем же ключом и содержимым возвращается сохранённый ответ. Если ключ использован с другим содержимым, сервер отклоняет запрос. Устаревшая ревизия требует обновления данных.

Изменения выполняются внутри SQLite BEGIN IMMEDIATE; ошибка откатывает транзакцию. Для начислений действуют дополнительные бизнес-ключи. Клиент сохраняет исходные параметры операции после сетевого сбоя, чтобы повтор не превратился в новое списание или начисление.

Жизненный цикл сезона

stateDiagram-v2
    [*] --> draft
    draft --> scheduled: Публикация до даты старта
    draft --> active: Публикация к текущему старту
    scheduled --> active: Наступила дата старта
    active --> settling: Закончились 90 дней
    settling --> finalized: Закрылось окно проверки +7 дней
    finalized --> closed: Закрылось окно выбора подарков +14 дней
    closed --> [*]

Окна +7 и +14 отсчитываются от окончания активной части сезона. Переходы выполняются серверным таймером и при обращении к состоянию: перезапуск приложения не должен требовать ручного переключения сезона. Источник времени — сервер; игровые сутки считаются в Asia/Almaty.

6. Алгоритмы: рекомендации, прогресс и награды

Четыре независимых показателя

ПоказательЧто означаетКак меняется
Последняя оценка навыкаИсходная оценка квалификацииНе повышается от самоотчёта или игровых заданий
Расчётный уровеньОценка плюс модельный эффект завершённых после неё шаговПересчитывается по истории выполнений; ограничен 100
XPПодтверждённое участие в программе сезонаЗа принятые задания, одобренные практики и предусмотренные бонусы
CQ-монетыВнутренний баланс программы наградНачисления, покупки и возвраты учитываются отдельным журналом

100% соответствия расчётной модели не означает автоматическое повышение. Рейтинг XP также не является рейтингом профессиональной результативности сотрудников.

Соответствие карьерной цели

Для требований выбранной роли и грейда используется взвешенный показатель:

R = 100 × Σ [wᵢ × min(sᵢ, rᵢ) / rᵢ] / Σ wᵢ

sᵢ — оценённый или расчётный уровень навыка;
rᵢ — требуемый уровень навыка для цели;
wᵢ — вес требования: 3 для critical, 1 для остальных.

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

Как выбираются рекомендации

  1. Определить выбранную цель, требования и дефициты.
  2. Учесть действующий план: в нём может быть до трёх активных шагов.
  3. Исключить недоступные, выполненные, уже запланированные и скрытые сотрудником варианты; проверить предварительные требования и временные ограничения.
  4. Рассчитать пользу каждого кандидата для текущего прогнозируемого состояния.
  5. Проверить бюджет четырёх недель: недельное время × 4 минус время текущего плана.
  6. Выбрать лучший шаг, пересчитать будущие навыки и оставшийся бюджет, затем выбрать следующий.

Оценка кандидата в текущей реализации:

score = 100 × (0.75 × ΔR / (100 − R)
             + 0.15 × min(1, 60 / duration_minutes)
             + 0.10 × preferred_format)

ΔR — прирост соответствия цели после кандидата; preferred_format равен 1, если формат входит в предпочтения, иначе 0. При равенстве учитываются больший прирост, меньшая длительность и ID. Подбор детерминирован: одинаковое состояние даёт одинаковый результат.

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

Игровая экономика

ПравилоТекущее значение
Активная часть сезона90 дней
Уровниmin(100, floor(confirmed_xp / 200))
Ежедневные задания«Ежедневный шаг» — 100 XP; «Кейс дня» — 150 XP
ПопыткиДо трёх на задание
Недельная миссияПять подтверждённых активных дней — 250 XP
Защита серииДва пропущенных дня; защита сама не даёт XP
Практика после одобрения HRmin(300, max(100, 2 × duration_minutes)) XP
Подарки пропускаОсновные — каждые пять уровней; мини-награды и косметика — по сетке
CQ за полную сетку уровней4 800 CQ; другие источники баланса учитываются отдельно
Материальные лимиты полного пропуска670 000 ₸ основных подарков + 50 000 ₸ мини-наград

Материальные суммы — виртуальные лимиты учебной экономики, а не фактические выплаты. Подарки пропуска выбираются по заработанному праву, без списания CQ. Покупка в магазине использует CQ. Сервер отдельно учитывает остатки, резерв, выдачу и возврат.

Карьерный пропуск отображает эти данные как игровую дорогу. Заполнение линии берётся из подтверждённых XP; карточки различают закрытую награду, доступный выбор, резерв, получение и истечение срока.

7. Данные и хранение

Быстрая загрузка тестового набора

Файлы набора хранятся прямо в Git: data/sample и data/gamification/shop.json. Они приходят вместе с клонированием репозитория и используются сервером для автоматической инициализации.

Одна команда из корня проекта запускает приложение с тестовыми данными:

# Linux
python3 run.py
# Windows
py run.py

После запуска откройте http://127.0.0.1:8000. Пароли задаются через [скрыто]; если переменная пуста, при создании аккаунта сервер генерирует пароль и однократно выводит его в консоль. Готовность набора проверяется по dataset_ready: true в /api/health.

Если зависимости и веб-сборка уже готовы, используйте python run.py --skip-build (Windows: py run.py --skip-build): данные подключаются при старте сервера без повторной сборки Flutter. Первая установка зависимостей и сборка занимают дополнительное время; запуск всего проекта за одну секунду не гарантируется.

Существующая база сохраняется. Чтобы повторить проверку с исходными данными, укажите в .env новый путь CAREER_DB=data/local/check-01.sqlite3 и перезапустите сервер. Если такой файл уже существует, выберите следующее имя. Не удаляйте рабочую базу: повторный запуск не сбрасывает планы, историю и награды. Для демонстрации уже накопленного прогресса используйте отдельную витрину.

Исходные JSON/CSV остаются в репозитории; созданные SQLite, сессии и ключи в Git не попадают. Пользовательская загрузка ZIP/датасетов через интерфейс или API по-прежнему не требуется.

Что входит в репозиторий

Используется синтетический набор кейса, а не реальные персональные данные сотрудников банка.

ФайлСодержимое
data/sample/employees.json200 профилей сотрудников
data/sample/events.json40 исходных активностей
data/sample/skills.json60 навыков и 32 профиля требований «роль + грейд»
data/sample/activity_history.csv2 743 записи истории
data/gamification/shop.jsonИсходный каталог из 32 учебных SKU

Количество профилей в наборе не равно числу пользователей пилота. Первый локальный сезон создаётся для четырёх первых по ID сотрудников; аккаунты сотрудника и коллеги привязаны к двум разным профилям. HR управляет составом новых сезонов через черновик.

Как исходные данные адаптированы

  • Шкала навыков 0–5 → 0–100: оценки, требования и предварительные условия умножаются на 20.
  • Модельный прирост одной активности по навыку ограничен 20; исходные поля сохраняются.
  • В источнике нет точного расписания с часами и материалов LMS. Активности представлены как локальные самостоятельные практики с инструкциями и учебным результатом.
  • Исходная история сохраняется отдельно. Она не превращается задним числом в новые игровые начисления.
  • Загрузка ZIP и импорт пользовательских датасетов исключены из интерфейса и публичного API по решению команды. Служебные модули старой проверки исходников не означают доступную функцию импорта.

Что лежит в SQLite

data/local/career.sqlite3
├── dataset_context, employee_records, history_records
│   └── исходный набор и сохранённые исходные значения
├── personal_goals
│   └── совместимость с сохранёнными целями предыдущего этапа
├── accounts, sessions
│   └── локальные аккаунты и отзываемые сессии
└── quest_state
    └── одна версионированная JSON-запись:
        цели, предпочтения, план, выполнения, сезоны,
        XP, CQ-журнал, награды, заявки, проверки и аудит

Это описание фактического хранения. Логические сущности домена пока не разнесены по отдельным SQL-таблицам. Такой подход позволяет сохранить атомарность и быстро развивать локальный прототип; большой поток пользователей потребует другой организации хранения.

Первый запуск создаёт базу из встроенного набора. Повторный запуск использует существующую SQLite и не сбрасывает изменения пользователя. Правка JSON в data/sample не обновляет уже созданную базу. Файлы .env, SQLite, сессии, зависимости и сборки исключены из Git.

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

Требования

  • Python 3.11+, доступный как python, python3 или py.
  • Flutter в PATH, включающий Dart 3.13.4 или совместимый Dart 3.x новее.
  • Браузер для веб-приложения. Для flutter run -d chrome — установленный Chrome.
  • Интернет для первоначальной установки Python- и Dart-зависимостей. Режим помощника template не требует внешнего AI-сервиса.
  • Доступ к приватному репозиторию, если вы клонируете его самостоятельно.

Быстрый запуск на Linux

git clone https://github.com/BAITC-Hacks/hack-c6826b6b-peep.git
cd hack-c6826b6b-peep
python3 run.py

Если команда Python у вас называется python, используйте python run.py. Если проект уже скачан, начните с его корневой папки.

Быстрый запуск на Windows

В PowerShell:

git clone https://github.com/BAITC-Hacks/hack-c6826b6b-peep.git
cd hack-c6826b6b-peep
py run.py

Можно использовать python run.py, если Python установлен под этим именем. Активировать виртуальное окружение вручную не требуется.

Что делает run.py

  1. Проверяет, свободен ли выбранный локальный порт.
  2. Создаёт .venv, если окружение ещё не создано.
  3. Устанавливает зависимости из requirements.lock; повторяет установку при изменении lock-файла.
  4. Выполняет flutter pub get и собирает Flutter Web.
  5. Запускает Uvicorn на 127.0.0.1; сервер открывает существующую SQLite или создаёт новую.

После сообщения об успешном запуске:

АдресНазначение
http://127.0.0.1:8000Приложение
http://127.0.0.1:8000/docsSwagger UI
http://127.0.0.1:8000/api/healthСостояние сервиса

Терминал должен оставаться открытым. Остановка — Ctrl+C.

Повторный запуск без пересборки интерфейса:

python run.py --skip-build

Другой порт:

python run.py --port 8001

В Windows заменяйте python на py, если используете Python Launcher. --skip-build работает только при наличии ранее собранного frontend/build/web/index.html. После изменения Dart-кода запускайте без этого флага.

Демонстрационные аккаунты

РольЛогинИсточник пароля
Сотрудникemployee.demoИз DEMO_EMPLOYEE_PASSWORD или консоли сервера
Другой сотрудникcolleague.demoИз DEMO_COLLEAGUE_PASSWORD или консоли сервера
HRhr.demoИз DEMO_HR_PASSWORD или консоли сервера
Администраторadmin.demoИз DEMO_ADMIN_PASSWORD или консоли сервера
Суперадминистраторsuperadmin.demoИз DEMO_SUPERADMIN_PASSWORD или консоли сервера

На лендинге выбор профиля заполняет логин; пароль вводится вручную. Для админки откройте /admin. При пустой переменной окружения сервер создаёт случайный пароль и выводит его однократно в консоль при создании аккаунта. Это локальная демонстрационная авторизация на синтетических данных.

По умолчанию сессия действует восемь часов; срок настраивается администратором с соответствующим правом. При выходе сервер отзывает сессию. Токен хранится в памяти клиента: после обновления страницы нужно войти снова. Сотрудник не получает доступ к чужому личному профилю или HR-операциям через изменение адреса.

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

Создайте .env в корне, скопировав .env.example. Если .env уже существует, отредактируйте его, сохранив свои значения.

Linux:

cp .env.example .env

Windows PowerShell:

Copy-Item .env.example .env
ПеременнаяПо умолчаниюНазначение
AI_MODEtemplateЛокальное объяснение; llm включает попытку обращения к OpenAI
OPENAI_API_KEYПустоСерверный ключ OpenAI
OPENAI_MODELgpt-4o-miniМодель в адаптере; можно указать доступную модель с поддержкой нужной схемы ответа
CAREER_DBdata/local/career.sqlite3Путь к рабочей или отдельной витринной SQLite
CAREER_DATA_DIRdata/sampleИсточник первичной инициализации новой базы; не HTTP-импорт
ALLOWED_ORIGINShttp://localhost:8080,http://127.0.0.1:8080Разрешённые адреса отдельного dev-фронтенда
DEMO_EMPLOYEE_PASSWORDСлучайный, если пустоПароль сотрудника при создании нового аккаунта
DEMO_COLLEAGUE_PASSWORDСлучайный, если пустоПароль коллеги при создании нового аккаунта
DEMO_HR_PASSWORDСлучайный, если пустоПароль HR при создании нового аккаунта
DEMO_ADMIN_PASSWORDСлучайный, если пустоПароль администратора при создании нового аккаунта
DEMO_SUPERADMIN_PASSWORDСлучайный, если пустоПароль суперадминистратора при создании нового аккаунта

Сервер читает .env при запуске; заданные переменные процесса имеют приоритет. Изменение DEMO_*_PASSWORD не меняет пароль уже существующего аккаунта. Если вы задали свой пароль для новой базы, вводите его вручную в поле пароля выбранного профиля.

Отдельная витрина с накопленным прогрессом

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

После первого запуска, из корня проекта:

# Linux
.venv/bin/python -m backend.showcase --db data/local/showcase.sqlite3
# Windows PowerShell
.\.venv\Scripts\python.exe -m backend.showcase --db data/local/showcase.sqlite3

Команда откажется перезаписывать существующий файл или использовать настроенную рабочую базу. Для нового прогона укажите другое имя, например showcase-2.sqlite3.

После создания файла добавьте в .env:

CAREER_DB=data/local/showcase.sqlite3

Перезапустите сервер. Витрина содержит историю заданий, созданную через игровые правила, первый профиль на 100-м уровне, предыдущий завершённый сезон, два результата практик и две заявки на награды. Уровень и баланс получаются из начислений, а не ручной установки чисел. В интерфейсе есть пометка «Витринный сценарий».

Учётные записи создаются с настройками DEMO_*_PASSWORD, действовавшими в момент генерации. При пустых настройках пароли генерируются и однократно выводятся в консоль. Для возврата к основной базе удалите строку CAREER_DB из .env и перезапустите приложение.

Android: сборка приложения в APK

Flutter упрощает переход от веб-прототипа к мобильному приложению. Основную часть интерфейса на Dart, визуальные компоненты и клиент запросов можно использовать повторно. Android-клиент обращается к тому же FastAPI, поэтому правила рекомендаций, прогресса и наград остаются общими для обеих платформ.

Текущий статус: в репозитории пока нет каталога frontend/android/; APK не собран и не проверен на устройстве. Ниже — инструкция для следующего этапа. После однократной подготовки выпуск APK сводится к команде сборки и проверке результата.

1. Подготовить инструменты

На Linux или Windows установите Android Studio и Android SDK с необходимыми инструментами по официальной инструкции Flutter. Затем проверьте окружение и примите необходимые лицензии SDK:

flutter doctor --android-licenses
flutter doctor

Перед сборкой устраните ошибки в разделе Android toolchain. Для проверки приложения понадобится эмулятор или Android-телефон с включённой USB-отладкой.

2. Добавить Android-платформу

Из корня репозитория:

cd frontend
flutter create --platforms=android --project-name=career_quest .
flutter pub get

Команда создаст недостающие файлы Android-проекта. После неё проверьте изменения в Git; существующий код приложения находится в lib/.

В созданном android/app/src/main/AndroidManifest.xml добавьте разрешение доступа к сети внутрь <manifest>, вне <application>:

<uses-permission android:name="android.permission.INTERNET" />

Это разрешение нужно клиенту для обращения к FastAPI; оно описано в документации по сети Flutter.

3. Указать сервер и собрать APK

Клиент уже принимает адрес через API_BASE_URL. В примере замените https://api.example.com на адрес работающего FastAPI, доступного телефону, без завершающего /. Это пример адреса, а не опубликованный сервер проекта.

Из каталога frontend:

flutter build apk --debug --dart-define=API_BASE_URL=https://api.example.com

Ожидаемый файл после успешной сборки: frontend/build/app/outputs/flutter-apk/app-debug.apk относительно корня репозитория. Это отладочная сборка для проверки на устройстве.

Для release-варианта настройте идентификатор приложения и собственную подпись по инструкции Flutter по выпуску Android-приложений, затем выполните:

flutter build apk --release --dart-define=API_BASE_URL=https://api.example.com

Ожидаемый файл: frontend/build/app/outputs/flutter-apk/app-release.apk. Для публикации через Google Play используется формат AAB: flutter build appbundle --release с тем же --dart-define и настроенной подписью.

Сервер запускается отдельно. FastAPI, SQLite и ключ OpenAI не включаются в APK; приложение требует соединения с сервером. Параметр API_BASE_URL содержит только его адрес.

Для локального Android Emulator сервер на компьютере доступен через http://10.0.2.2:8000; адрес 127.0.0.1 внутри устройства указывает на само устройство. Такое отображение адресов описано в документации Android Emulator. При локальной проверке по HTTP настройте разрешение незашифрованного трафика только для отладочного варианта по инструкции Flutter; для распространяемой сборки используйте HTTPS.

4. Проверить мобильный сценарий

Установите APK на устройство и пройдите вход, профиль, маршрут, карьерный пропуск и выход. Отдельно проверьте системную кнопку «Назад», экранную клавиатуру, прокрутку на небольшом экране, сохранение паспорта/отчётов и поведение при потере сети. Эти проверки нужны перед заявлением о готовности Android-версии.

9. Как подключить OpenAI

Приложение содержит серверный OpenAI Career Copilot: он объясняет расчёты и собирает черновик плана из доступных мероприятий. Для включения внешней модели достаточно ключа и настройки режима — менять Flutter-код не нужно.

В корневом .env:

AI_MODE=llm
OPENAI_API_KEY=ваш_ключ
OPENAI_MODEL=gpt-4o-mini

Перезапустите сервер, войдите сотрудником и откройте OpenAI-помощника. Можно задать один из контекстных вопросов или собрать маршрут в режиме «Сбалансированный», «Быстрый старт» или «Максимум эффекта». В результате явно показано, использован OpenAI или проверенный локальный алгоритм.

flowchart LR
    Q["Вопрос или режим маршрута"] --> C["Анонимный контекст из готовых расчётов и каталога"]
    C --> M{"Режим llm и ключ?"}
    M -->|"Нет"| T["Локальное объяснение"]
    M -->|"Да"| O["OpenAI Responses API"]
    O --> V{"Ответ прошёл проверку?"}
    V -->|"Да"| A["Объяснение или черновик маршрута"]
    V -->|"Нет / ошибка / таймаут"| T
    A --> UI["Ответ с обозначением режима"]
    T --> UI

Что передаётся и как проверяется ответ

  • В контекст входят цель, названия и уровни навыков, рассчитанные показатели, время и только допустимые активности каталога.
  • ФИО, ID сотрудника, подразделение, зарплата, свободные заметки и данные других сотрудников в этот контекст не включаются.
  • Адаптер вызывает Responses API со Structured Outputs: text.format.type=json_schema, строгая схема, store=false и ограничение ответа. Формат соответствует официальной документации OpenAI.
  • Общий таймаут — шестнадцать секунд. Автоматических повторных запросов к провайдеру нет.
  • Сервер проверяет структуру, допустимые ID активностей и числовые утверждения; цифры и ссылки в свободном тексте ответа отклоняются. Эти проверки ограничивают ответ, но не являются доказательством безошибочности любого текста модели.
  • Объяснения и черновики кешируются на 30 минут с учётом пользователя, ревизии состояния, вопроса или режима и модели.
  • Модель не записывает план: пользователь добавляет каждый предложенный шаг отдельно, после повторной серверной проверки.
  • При недоступном ключе, сетевой ошибке, таймауте или неприемлемом ответе сохраняется рабочий локальный сценарий.

Ключ должен оставаться только на сервере. Не добавляйте его в Git, Dart-код или --dart-define: веб-сборка доступна браузеру. Параметр store=false относится к запросу API и не является обещанием отсутствия любых журналов у внешнего провайдера.

ai_enabled=true в /api/health показывает наличие конфигурации, а не успешность платного запроса. Фактическую работу проверяйте по ответу помощника. Тесты адаптера используют HTTP mock; реальный вызов требует вашего ключа, доступа к модели и доступной квоты. Для полностью локальных объяснений верните AI_MODE=template.

10. Разработка и API

Раздельный запуск сервера и Flutter

Используйте два терминала после установки зависимостей через run.py. Если полный локальный сервер уже запущен, сначала остановите его, чтобы освободить порт.

Терминал 1 — сервер, из корня проекта:

# Linux
.venv/bin/python -m uvicorn backend.main:app --reload --host 127.0.0.1 --port 8000
# Windows PowerShell
.\.venv\Scripts\python.exe -m uvicorn backend.main:app --reload --host 127.0.0.1 --port 8000

Терминал 2 — интерфейс:

cd frontend
flutter run -d chrome --web-port 8080

В debug-режиме клиент использует http://127.0.0.1:8000. В обычной веб-сборке — адрес, с которого загружено приложение. Для другого API-адреса есть публичная клиентская настройка:

flutter run -d chrome --web-port 8080 --dart-define=API_BASE_URL=http://127.0.0.1:8001

API_BASE_URL — адрес сервера, а не секрет. При смене порта или хоста dev-фронтенда добавьте его origin в ALLOWED_ORIGINS и перезапустите сервер.

Основные группы API

Полный актуальный контракт с телами запросов находится в Swagger UI. Старые документы этапов могут отличаться от текущих маршрутов.

СценарийПримеры маршрутов
Состояние и доступGET /api/health, POST /api/auth/login, POST /api/auth/logout
Профиль и цельGET /api/me/profile, GET /api/me/goal, PUT /api/me/goal
Прогресс и подборGET /api/me/progress, GET /api/me/recommendations, GET /api/activities
ПланGET /api/me/plan, POST /api/me/plan/items, POST /api/me/plan/items/{id}/complete
Симуляция и OpenAI-помощникPOST /api/me/simulations, GET /api/me/assistant/status, POST /api/me/assistant/explain, POST /api/me/assistant/plan
СезонGET /api/me/season, GET /api/me/season/pass, GET /api/me/season/tasks
НаградыGET /api/me/wallet, GET /api/me/rewards, POST /api/me/rewards/{id}/claim
HRGET /api/hr/overview, GET /api/hr/employees, GET /api/hr/reward-reviews

Пример оболочки доменного ответа — значения условные:

{
  "data": {"items": []},
  "meta": {
    "state_revision": 12,
    "server_time": "2026-09-23T10:00:00Z"
  }
}

Вход и health имеют собственные простые ответы. Защищённые маршруты принимают Authorization: Bearer <token>. Для бизнес-изменений нужны текущая expected_revision и UUID-заголовок Idempotency-Key; для DELETE ревизия передаётся в query. Вход, объяснение AI и предварительная симуляция не используют этот контракт мутации.

Ошибки возвращают код, понятное сообщение, детали и request_id. Например: UNAUTHORIZED — нет действующей сессии, FORBIDDEN — неподходящая роль, STALE_STATE — данные изменились с момента чтения. При STALE_STATE обновите данные и повторно подтвердите актуальное действие.

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

Быстрая приёмка через интерфейс

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

№Шаги проверкиОжидаемый результат
1Запустить приложение; открыть /api/healthstatus: ok, dataset_ready: true; лендинг доступен
2Войти как employee.demo; открыть профиль и цельВидны собственные данные, оценка и выбранное/предложенное направление
3Открыть рекомендацию и её объяснениеВидны активность, время, польза и условия доступности
4Добавить подходящий шаг в «Мой маршрут»Шаг появился в плане; обновился прогноз. Если подбор пуст, показана причина и доступен каталог
5Начать и завершить локальную практикуПоявилось выполнение; расчётный прогресс пересчитан, последняя оценка не переписана
6В истории нажать «Отправить результат на проверку» и описать работу в 80–2000 символахРезультат ожидает HR; самоотчёт не даёт подтверждённые XP за практику
7Войти HR; одобрить подготовленный учебный результатЗаписано решение; соответствующие XP начислены один раз
8Вернуться сотрудником в «Карьерный пропуск»Показаны актуальные XP, уровень и состояния наград; работают стрелки, десятки и «К моему уровню»
9В витрине выбрать доступный подарок или оформить покупку за CQСоздана тестовая заявка; для подарка пропуска CQ не списаны, для покупки баланс и резерв обновлены
10Войти HR и провести заявку по допустимым этапам выдачиСостояния заявки, остатки и виртуальный бюджет согласованы
11Перезапустить сервер, войти сноваПлан, история, решения и баланс сохранились
12Открыть узкий экран; повторить переходы и пролистывание пропускаЭлементы доступны, горизонтально прокручивается дорога, а не вся страница

При нехватке CQ или отсутствии открытого подарка используйте отдельную витрину. Не требуется менять XP и баланс вручную.

Проверка прав через Swagger

  1. Откройте /docs, выполните POST /api/auth/login с демонстрационным логином и паролем.
  2. Скопируйте значение token в окно Authorize для HTTP Bearer.
  3. У сотрудника GET /api/me/profile должен работать, а GET /api/hr/employees — вернуть 403.
  4. Для проверки чужого профиля возьмите другой существующий ID из синтетического набора и вызовите GET /api/employees/{id} под сотрудником. Ожидается 404.
  5. После POST /api/auth/logout повторный запрос с тем же токеном должен вернуть 401.

Автоматизированные проверки

Из корня проекта на Linux:

.venv/bin/python -m pytest -q

В Windows PowerShell:

.\.venv\Scripts\python.exe -m pytest -q

Проверки фронтенда — на обеих ОС:

cd frontend
flutter analyze
flutter test
flutter build web --release

Ожидается успешное завершение команд. Серверные тесты работают на временных синтетических SQLite и управляемых часах; тесты AI подменяют HTTP-вызов и не требуют платного ключа.

ОбластьЧто проверяетсяГде смотреть
ДоступСессии, выход, разграничение ролей и собственных записейtests/test_access_profiles.py
Карьерная модельФормулы, пропущенные оценки, план, симуляция, ограничения и атомарностьtests/test_career.py
Игровая модель90 дней, уровни, повторные операции, серия, награды, stock, возвраты, бюджет и итогиtests/test_gamification.py
AI-адаптерСостав контекста, схема запроса, проверка ответа, кеш и fallbacktests/test_assistant.py
Исходные данныеПроверка схем и сохранность исходного набора; исключение публичного импортаtests/test_foundation.py, tests/test_imports.py
ИнтерфейсВход, навигация, роли и завершение сессииfrontend/test/widget_test.dart
Повтор HTTP-операцииСохранение ключа, тела и ревизии после сетевого сбояfrontend/test/api_test.dart
ПропускПереходы, состояния наград, границы XP и увеличенный текст на 320 pxfrontend/test/career_pass_test.dart

Контрольные значения из тестовых фикстур:

  • Соответствие цели: 73.6111% → 79.8611% → 85.4167%; исходная оценка остаётся 73.6111%.
  • Полная сетка пропуска: 4 800 CQ, 670 000 ₸ + 50 000 ₸ лимитов подарков.
  • Обе ежедневные задачи без пропусков в контрольном сезоне: 27 790 XP за 90 дней; 100-й уровень достигается на 67-й день с учётом предусмотренных бонусов.

Эти значения проверяют реализацию правил. Они не описывают эффективность обучения реального сотрудника и не обязаны совпадать с процентами конкретного демонстрационного профиля.

Частые вопросы при запуске

СимптомЧто проверить
Flutter is not on PATHДоступна ли команда flutter --version; после настройки PATH откройте новый терминал
Ошибка ограничения Dart SDKВерсию Dart внутри Flutter: проект требует ^3.13.4
Python не может создать .venvУстановлены ли компоненты venv и pip для выбранного Python
Порт 8000 занятОстановите свой предыдущий сервер или укажите --port 8001
Нет веб-сборки / корневая страница не открываетсяВыполните python run.py без --skip-build; при ручном Uvicorn сборка должна существовать до его старта
Изменения интерфейса не видныПересоберите Flutter Web и обновите страницу; при необходимости выполните жёсткое обновление браузера
Dev-фронтенд не получает APIСервер запущен, API_BASE_URL верен, origin фронтенда включён в ALLOWED_ORIGINS
Стандартный пароль не подходитДля существующего аккаунта мог быть установлен свой DEMO_*_PASSWORD; изменение .env его не сбрасывает
После обновления страницы требуется входТак задумано: токен хранится в памяти, не в постоянном браузерном хранилище
Помощник показывает «Шаблон»Проверьте режим, ключ, доступность модели и перезапуск сервера; fallback также включается при ошибке или отклонённом ответе
В профиле нет рекомендацийПроверьте наличие цели, полноту оценок, бюджет времени, действующий план и причину пустого подбора
В новом пропуске нет открытых наградПодтверждённые XP начинаются с нуля; для подготовленного показа существует отдельная витрина

12. Структура репозитория

career-quest/
├── README.md                    # Обзор, архитектура, запуск и проверка
├── run.py                       # Общий локальный запуск Linux / Windows
├── .env.example                 # Шаблон серверных настроек
├── requirements.lock            # Закреплённые Python-зависимости
├── backend/
│   ├── main.py                  # Приложение, доступ и статическая веб-сборка
│   ├── quest_api.py             # Карьерный и игровой API
│   ├── database.py              # SQLite, исходные записи и сессии
│   ├── engine.py                # Версия состояния, транзакции и аудит
│   ├── career.py                # Цель, рекомендации, план и прогресс
│   ├── game.py                  # Сезоны, XP, заявки и экономика
│   ├── game_rules.py            # Детерминированные правила игры
│   ├── analytics.py             # HR-аналитика и экспорт
│   ├── assistant.py             # OpenAI и локальное объяснение
│   └── showcase.py              # Генератор отдельной витрины
├── frontend/
│   ├── lib/core/api.dart        # HTTP и управление клиентской сессией
│   ├── lib/pages/               # Экраны сотрудника и HR
│   ├── lib/widgets/             # Дизайн-система, лендинг и пропуск
│   ├── assets/                  # Иллюстрации и шрифты
│   ├── test/                    # Проверки клиента
│   └── pubspec.yaml             # Flutter / Dart-зависимости
├── data/
│   ├── sample/                  # Синтетический набор кейса
│   ├── gamification/shop.json   # Каталог учебных наград
│   └── local/                   # Локальные базы; не включаются в Git
├── tests/                       # Серверные тесты и фикстуры
└── docs/                        # Спецификация, дизайн и решения реализации

13. Ограничения и развитие

Границы текущей версии

  • Это локальный хакатонный прототип на синтетических данных, а не развёрнутая банковская HR-система.
  • Нет интеграции с корпоративной авторизацией, кадровой системой или LMS. Кнопки не записывают человека на реальные мероприятия банка.
  • Награды, заявки и бюджет — виртуальные. Приложение не выполняет оплату, закупку, бронирование или доставку.
  • Расчётный прирост навыков — модель для объяснения маршрута. Для подтверждения квалификации нужна отдельная оценка.
  • Домен хранится в одной JSON-записи SQLite и подходит для локального сценария. Здесь не заявлена проверенная промышленная нагрузка.
  • Внешний AI необязателен; его доступность зависит от сети и настройки аккаунта провайдера. Успешные HTTP mocks не заменяют проверку реального ключа.
  • Загрузка архивов и пользовательских датасетов исключена из текущей поставки. Для Android описан путь сборки APK, но сама мобильная версия ещё не собрана и не проверена; desktop-сборка также не поставляется.

Как расширять применение

Следующий пользователь / заказчикЧто потребуетсяОсновное препятствие
Пилот одного подразделенияТребования ролей, согласованные правила оценки, ответственный HR и программа активностейКачество исходных оценок и время проверяющих
Несколько подразделений банкаКорпоративный SSO, область доступа руководителей, интеграции с HRIS/LMS, согласование бюджетаРазличающиеся модели компетенций и процессы согласования
Более крупная организацияНормализованная БД, отдельные фоновые задачи, наблюдаемость, резервное копирование и нагрузочные проверкиОбщая запись состояния и сериализация операций прототипа
Другие компании и отраслиНастраиваемые матрицы ролей, каталог, правила подтверждения и разделение данных организацийПереносимость модели навыков и изоляция данных

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

14. Документы проекта

ДокументКогда читать
Полная спецификацияПродуктовые правила, сценарии и приёмка
Решения реализацииАдаптация данных, выполненные блоки и технические ограничения
Визуальная системаПалитра, компоненты и стиль новых экранов
АдминистрированиеПрава, публикации, корректировки и ограничения админки
Матрица проверокРезультаты тестов и сборок, границы ручной проверки
Игровая дорога пропускаНавигация, состояния наград и правила отображения XP
Описание исходного набораПоля и устройство синтетических данных
Правила командыКонтекст хакатона, границы задачи и принципы работы

Документы этапов 1–2 в docs/ сохранены как история проектирования. Текущий объём определяется полной спецификацией, решениями реализации и исключением загрузки ZIP/датасетов. Этот README описывает фактическое устройство проекта; живой контракт HTTP — в Swagger запущенного сервера.

15. Администрирование Web

Админка управляет теми же данными, которые видят сотрудник и HR: карьерными справочниками, активностями, сезонами, наградами и оформлением. Изменения сохраняются в SQLite и переживают перезапуск. Основной процесс изменения конфигурации — форма → черновик → предпросмотр → публикация.

Как войти

  1. Запустите приложение по инструкции выше и откройте http://127.0.0.1:8000/admin.
  2. Войдите как admin.demo или superadmin.demo. Для новых аккаунтов пароли задаются в .env переменными DEMO_ADMIN_PASSWORD и DEMO_SUPERADMIN_PASSWORD. Если они пусты, пароль генерируется и однократно выводится в консоль сервера.
  3. Для полного демонстрационного сценария используйте superadmin.demo: публикация экономики и корректировки требуют расширенных прав. HR открывает доступные ему разделы кнопкой «Администрирование» в своём кабинете.

Изменение .env не сбрасывает пароль существующего аккаунта. Созданный через админку пользователь должен сменить временный пароль при первом входе. Рабочую базу для включения админки удалять не нужно.

Роли и доступ

РольДоступ по умолчанию
СотрудникСобственный кабинет; административные операции недоступны
HRПросмотр сотрудников, проверка выполненных работ и обработка заявок на награды
АдминистраторСправочники, сотрудники, активности, сезоны, пропуск, магазин, бюджеты, оформление, AI и аудит; чувствительные операции требуют дополнительных разрешений
СуперадминистраторВсе разрешения, включая управление ролями и сессиями, публикацию экономики, корректировки, системные настройки и резервные копии

Сервер проверяет разрешения независимо от видимости меню. Блокировка аккаунта, смена роли или сброс пароля отзывают его сессии. Нельзя изменить собственный доступ или отключить последнего активного суперадминистратора.

Что можно настроить

РазделВозможности
Люди и доступАккаунты, сотрудники, подразделения, оценки навыков, карьерные цели и просмотр профиля сотрудника без входа от его имени
Карьера и обучениеНавыки, роли, грейды, матрица требований, каталог активностей, правила рекомендаций и лимиты плана
Сезоны и пропускДаты, участники, от 1 до 200 уровней, возрастающие пороги XP, монеты, подарки, небольшие призы и косметические награды
ГеймификацияПравила XP, задания, достижения, серии активности, рейтинги и номинации
Магазин и выдачаТовары, пулы подарков, остатки, бюджеты и обработка тестовых заявок на награды
Тексты и оформлениеЗаголовки рабочих экранов, уведомления, название, логотип, баннер, основной цвет и фон без пересборки клиента
AI-помощникРежим, модель, лимит ответа и таймаут для объяснений и составителя маршрута; ключ OpenAI остаётся в окружении сервера
Контроль и обслуживаниеИстория публикаций, аудит, корректировки с основанием, экспорт конфигурации и резервная копия SQLite

Как опубликовать изменение

  1. Заполните форму, укажите основание и сохраните черновик.
  2. Откройте предпросмотр: проверьте влияние на прогресс, XP, CQ и необходимый резерв бюджета. Блокирующие ошибки нужно исправить до публикации.
  3. Опубликуйте изменение. Если данные успели измениться, выполните предпросмотр заново.
  4. Обновите кабинет сотрудника и проверьте результат. Тексты и оформление также обновляются при входе и возврате в окно.

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

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

Короткий сценарий проверки

В отдельной витринной базе войдите как superadmin.demo, добавьте достаточный резерв бюджета и увеличьте монетную награду первого уровня. Сохраните черновик, проверьте рассчитанную разницу и опубликуйте. У сотрудника, уже прошедшего этот уровень, появится только доплата; повторное обновление не создаст второе начисление.

Админка реализована для Web, без импорта данных и конфигурации. Выдача наград и бюджетные операции — тестовые. Редактор текстов охватывает рабочие заголовки и уведомления; лендинг и FAQ остаются компонентами приложения. Резервная копия создаётся на сервере, восстановления произвольного файла через интерфейс нет.

Подробные правила и ограничения: руководство администратора. Результаты проверок: матрица сборок и тестов.


Career Quest
Видеть цель. Понимать следующий шаг. Замечать свой прогресс.

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

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

Vsevolod Smolskiy 9Sergey 8

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

  • 2026-09-23 17:16docs: describe Web administration access and publication workflowSergey
  • 2026-09-23 17:14Merge Web administration with updated career workspace and AI plannerSergey
  • 2026-09-23 17:04feat: add versioned Web administration and audited reward controlsSergey
  • 2026-09-23 17:01feat: complete career workspace, AI planner and project documentationVsevolod Smolskiy
  • 2026-09-23 16:51Merge origin/main with demo checklistSergey
  • 2026-09-23 16:50docs: add pre-demo verification checklistSergey
  • 2026-09-23 16:04feat: turn career pass into interactive reward roadVsevolod Smolskiy
  • 2026-09-23 15:45Merge concurrent repository updateVsevolod Smolskiy
Все коммиты (17)
  • 2026-09-23 15:43fix: verify release flows and preserve idempotent retriesVsevolod Smolskiy
  • 2026-09-23 15:37Merge origin/main into mainSergey
  • 2026-09-23 15:34initialSergey
  • 2026-09-23 15:33feat: implement full Career Quest experienceVsevolod Smolskiy
  • 2026-09-23 14:24chore: include hackathon starter dataset for team setupVsevolod Smolskiy
  • 2026-09-23 14:24Merge remote-tracking branch 'origin/main'Vsevolod Smolskiy
  • 2026-09-23 14:22chore: save current hackathon progressVsevolod Smolskiy
  • 2026-09-23 14:19chore: update hackathon projectVsevolod Smolskiy
  • 2026-09-23 14:18initialSergey
Структура репозитория (124 файлов)
.env.example
.gitignore
AGENTS.md
EVALUATION.md
README.md
backend/__init__.py
backend/admin_api.py
backend/admin_schemas.py
backend/admin_service.py
backend/analytics.py
backend/assistant.py
backend/career.py
backend/config.py
backend/data.py
backend/database.py
backend/engine.py
backend/game.py
backend/game_rules.py
backend/imports.py
backend/main.py
backend/migrations/003_admin_control.sql
backend/models.py
backend/permissions.py
backend/policies.py
backend/profiles.py
backend/quest_api.py
backend/showcase.py
data/gamification/shop.json
data/sample/README.kz.md
data/sample/README.md
data/sample/README.ru.md
data/sample/activity_history.csv
data/sample/employees.json
data/sample/events.json
data/sample/skills.json
docs/01-case.md
docs/02-options.md
docs/03-execution.md
docs/04-technical-preparation.md
docs/05-roadmap.md
docs/06-api-contract.md
docs/07-stage2-verification.md
docs/08-design-system.md
docs/09-full-spec.md
docs/10-implementation.md
docs/11-admin.md
docs/11-career-pass-ui.md
docs/build_matrix.md
docs/design/career-city-reference-prompt.txt
docs/design/readme-cover.svg
docs/design/style-reference.png
frontend/.gitignore
frontend/.metadata
frontend/README.md
frontend/analysis_options.yaml
frontend/assets/fonts/Inter.ttf
frontend/assets/fonts/OFL.txt
frontend/assets/images/career_city_reference.png
frontend/assets/images/career_landscape.png
frontend/lib/core/api.dart
frontend/lib/features/admin/admin_forms.dart
frontend/lib/features/admin/admin_shell.dart
frontend/lib/main.dart
frontend/lib/pages/career_views.dart
frontend/lib/pages/directory.dart
frontend/lib/pages/game_views.dart
frontend/lib/pages/hr_views.dart
frontend/lib/pages/login.dart
frontend/lib/pages/profile.dart
frontend/lib/pages/workspace.dart
frontend/lib/widgets/career_pass.dart
frontend/lib/widgets/landing_sections.dart
frontend/lib/widgets/ui.dart
frontend/linux/.gitignore
frontend/linux/CMakeLists.txt
frontend/linux/flutter/CMakeLists.txt
frontend/linux/runner/CMakeLists.txt
frontend/linux/runner/main.cc
frontend/linux/runner/my_application.cc
frontend/linux/runner/my_application.h
frontend/pubspec.lock
frontend/pubspec.yaml
frontend/test/admin_test.dart
frontend/test/api_test.dart
frontend/test/career_pass_test.dart
frontend/test/fixtures/api.json
frontend/test/widget_test.dart
frontend/web/favicon.png
frontend/web/icons/Icon-192.png
frontend/web/icons/Icon-512.png
frontend/web/icons/Icon-maskable-192.png
frontend/web/icons/Icon-maskable-512.png
frontend/web/icons/career-quest.svg
frontend/web/index.html
frontend/web/manifest.json
frontend/windows/.gitignore
frontend/windows/CMakeLists.txt
frontend/windows/flutter/CMakeLists.txt
frontend/windows/runner/CMakeLists.txt
frontend/windows/runner/Runner.rc
frontend/windows/runner/flutter_window.cpp
frontend/windows/runner/flutter_window.h
frontend/windows/runner/main.cpp
frontend/windows/runner/resource.h
frontend/windows/runner/resources/app_icon.ico
frontend/windows/runner/runner.exe.manifest
frontend/windows/runner/utils.cpp
frontend/windows/runner/utils.h
frontend/windows/runner/win32_window.cpp
frontend/windows/runner/win32_window.h
pytest.ini
requirements.lock
requirements.txt
run.py
scripts/evaluation_smoke.py
scripts/prepare_data.py
tests/conftest.py
tests/test_access_profiles.py
tests/test_admin.py
tests/test_assistant.py
tests/test_career.py
tests/test_foundation.py
tests/test_gamification.py
tests/test_imports.py

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

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

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