# ГК ОСКАР · Закрытый дашборд HR-аналитики

Приватное многостраничное веб-приложение для просмотра результатов корпоративного
тестирования сотрудников ГК ОСКАР. Превращает выгрузку из Яндекс.Форм (Excel) в
управленческую аналитику: компания, подразделения, сотрудники, блоки вопросов,
проблемные вопросы, риски, управленческие решения, дообучение и качество данных.

> Доступ только по логину. Данные сотрудников не покидают сервер и не отправляются
> во внешние облачные/AI-сервисы. Индексация поисковиками запрещена (`noindex` + `robots`).

## Стек

- **Next.js 15** (App Router, TypeScript) — страницы, защищённые маршруты, API.
- **PostgreSQL + Prisma** — собственная мини-база проекта (строка подключения из `DATABASE_URL`).
- **ExcelJS** — серверный парсинг выгрузки Яндекс.Форм.
- **Recharts** — диаграммы (donut, bar, heatmap).
- **Tailwind CSS** — светлая премиум-тема.
- **jose** — подпись сессионной cookie (один общий логин/пароль).

## Установка

```bash
npm install
cp .env.example .env   # DATABASE_URL уже выдан фабрикой; задайте SESSION_SECRET
npm run db:push        # создать таблицы в собственной базе проекта
npm run seed           # предзагрузить аналитику из data/initial.xlsx
```

## Запуск

```bash
npm run dev      # http://localhost:3000
# прод:
npm run build && npm run start
```

## Вход

| Поле   | Значение |
| ------ | -------- |
| Логин  | `hr`     |
| Пароль | `1234`   |

Учётные данные хранятся **только на сервере** (`HR_LOGIN` / `HR_PASSWORD` в `.env`),
в клиентский код не попадают. Каждая страница дашборда и каждый API-маршрут требуют
авторизации.

## Загрузка / замена Excel

Раздел **«Загрузка данных»** (после входа):

- загрузить новый Excel и пересчитать аналитику;
- очистить текущий датасет;
- отчёт об импорте, ошибки и предупреждения по недостающим/неизвестным полям.

Первый вход уже показывает реальную аналитику из приложенного файла — повторно
загружать его не нужно.

> **Боевая версия:** страница «Загрузка данных» и её API (`/admin`, `/api/admin/*`)
> по умолчанию **закрыты в production** (отдают 404, пункт меню скрыт). В dev-режиме
> раздел доступен для замены датасета. Чтобы временно открыть его и на проде, задайте
> в `.env` переменную `ADMIN_ENABLED=1` и пересоберите/передеплойте проект.

## Как считается результат

- **64 вопроса**, 6 блоков (этика, взаимодействие, ИБ, коммерческая тайна, велкомбук, отпуск).
- Ответ сверяется с ключом (`src/lib/test-config.ts`). Вопрос 41 — открытый, проверяется
  семантически (ключевые концепты: информация · объекты · коммерческая тайна · ценность);
  неполные ответы помечаются как «Сомнительно».
- Для каждой попытки: процент правильных, статус по шкале, результат по блокам, список
  ошибок и критичных ошибок, индекс качества, риск-статус.
- **Шкала статуса:** 0–49 % «Не прошел», 50–69 % «Удовлетворительно», 70–89 % «Хорошо»,
  90–100 % «Отлично».
- **Критичные вопросы:** 11, 12, 13, 25–39, 40–53.
- **Индекс качества:** `0.6·overall + 0.3·critical_block + 0.1·(100 − critical_penalty)`,
  где `critical_penalty = min(30, число_критичных_ошибок · 10)`.
- **Риск-статус:** «Без критичных рисков» / «Есть критичные ошибки» / «Требуется целевой
  инструктаж» (если критичные ошибки в ИБ/коммерческой тайне/конфиденциальной информации).

## Обработка дублей

В Excel могут быть несколько попыток одного сотрудника. **Сохраняются все попытки**, но в
итог засчитывается **последняя по «Времени создания»**. История всех попыток видна в карточке
сотрудника. Идентификация — по ФИО + подразделение + должность. При риске совпадения ФИО
показывается предупреждение качества данных.

## Структура Excel (подтверждено: `Sheet`, `A1:BX122`, 121 ответ, 76 колонок)

| Колонка | Поле |
| ------- | ---- |
| A | № п/п |
| B | ID ответа |
| C | Время создания (итоговая попытка — последняя) |
| D–G | ФИО · Должность · Подразделение · Руководитель |
| H | Дата заполнения |
| I…BT | Вопросы 1–64 (ответ вида «В. текст») |
| BU–BX | Имя · Фамилия · Логин · Эмейл (опционально) |

Нормализация при импорте: trim, схлопывание пробелов, `_x000D_` и переносов строк, разбор
буквы ответа (`А. …`, `Б …`, `В) …`), «Не указан/Не указано» для пустых руководителя/
подразделения, сведение разнобоя в названиях подразделений и руководителей.

## Страницы

1. Вход
2. Обзор по компании (KPI, статусы, средний по блокам, риски)
3. Подразделения (карточки, таблица, heatmap блок × подразделение)
4. Сотрудники (поиск, фильтры, карточки, модалка с разбором ошибок)
5. Блоки вопросов
6. Проблемные вопросы (все 64, индекс сложности)
7. Управленческие решения
8. Дообучение
9. Качество данных
10. Отчёты (выгрузка PDF/Excel)
11. Управление датасетом (загрузка/замена/очистка)

## Отчёты (PDF / Excel)

Страница **«Отчёты»** формирует готовые выгрузки по текущему загруженному датасету
(серверная генерация по запросу, доступна после входа). Четыре независимых файла:

| Файл | Для кого | Содержание |
| --- | --- | --- |
| `ГК-ОСКАР-Отчёт-по-компании.pdf` | Генеральное руководство | KPI, исполнительное резюме, статусы, блоки, рейтинг подразделений, топ проблемных вопросов, управленческие решения, дообучение |
| `ГК-ОСКАР-Отчёт-по-подразделениям.pdf` | Руководители направлений | Сводный рейтинг + отдельная страница на каждое подразделение (KPI, блоки, слабые вопросы, рекомендация, список сотрудников) |
| `ГК-ОСКАР-Карточки-сотрудников.pdf` | HR | Оглавление с номерами страниц + по одной странице на сотрудника (блоки, разбор всех неверных ответов, риск-статус, рекомендация, история попыток) |
| `ГК-ОСКАР-Карточки-сотрудников.xlsx` | HR | Вкладка «Оглавление» (ссылки) + «Все сотрудники» (фильтр/сортировка) + по одной вкладке на сотрудника (вкладка названа именем) |

- API: `/api/reports/company`, `/api/reports/departments`, `/api/reports/employees-pdf`,
  `/api/reports/employees-xlsx` — все под авторизацией (middleware).
- PDF — серверный `pdfkit` со встроенным шрифтом DejaVu Sans (`assets/fonts/`, кириллица).
  Excel — `exceljs`. Числа охвата (119/116) совпадают со страницей «Обзор компании».
- Самопроверка: `npx tsx scripts/gen-reports.ts` кладёт все 4 файла в `.factory/evidence/reports/`.

## Безопасность

- Авторизация на каждой странице и API-маршруте (middleware).
- Пароль не виден в клиентском коде; читается из переменных окружения.
- Данные сотрудников не отправляются во внешние API.
- `noindex` / `X-Robots-Tag` / `robots.txt`, `X-Frame-Options: DENY`.
- Технические трейсы пользователю не показываются.

## Развёртывание

Приложение разворачивается как самостоятельный сайт на отдельном домене/поддомене
(`hr-oskar-assessment` / `oskar-hr-dashboard`) и **не зависит** от среды кабинета AI Factory
и не раскрывает её внутренних маршрутов. Если отдельный домен в текущей среде недоступен —
используется максимально изолированный приватный предпросмотр, ограничение фиксируется в
финальном отчёте.

## Известные ограничения

- Один текущий опрос (история нескольких тестирований не хранится).
- Нет экспорта в PDF/Excel/CSV и ручного редактирования данных (по требованию).
- Нет сложной ролевой модели — один общий логин для HR/руководителей/менеджмента.
- Семантическая проверка вопроса 41 эвристическая; спорные ответы помечаются «Сомнительно».
