ccec6ef950bef230175e590ccf6d2a996240cd3c
Система тестирования сотрудников клиники
Веб-приложение для проведения внутреннего тестирования сотрудников клиники. Руководители подразделений и HR-менеджеры создают тесты и назначают их сотрудникам. Система фиксирует все попытки и результаты.
Версия ТЗ: 1.2
Дата: 2026-03-21
Статус: Согласовано
Содержание
- Технологический стек
- Функциональные возможности
- Роли и права доступа
- База данных
- API Endpoints
- Структура проекта
- Установка и запуск
- План разработки
Технологический стек
| Компонент | Выбор |
|---|---|
| Backend | Node.js + Express |
| Frontend | React (SPA) |
| Database | PostgreSQL |
| Authentication | JWT (токен в httpOnly cookie) |
| Password | bcrypt |
Функциональные возможности
4.1 Управление пользователями и подразделениями
- Создание/редактирование/деактивация учётных записей сотрудников
- Каждый сотрудник принадлежит одному подразделению
- Создание/редактирование справочника подразделений
- Назначение роли сотруднику: HR-менеджер / Руководитель подразделения / Сотрудник
4.2 Создание и редактирование тестов
Тест содержит:
- Название теста
- Описание (опционально)
- Список вопросов (минимум 7)
- Порог зачёта — минимальный % правильных ответов
- Таймер прохождения — лимит в минутах (опционально)
Вопрос содержит:
- Текст вопроса
- Минимум 3 варианта ответа
- Один или несколько правильных ответов
Настройки теста:
- Разрешить возврат к предыдущему вопросу: да / нет
Версионирование:
- Автор может редактировать тест пока никто его не проходил
- Если тест уже проходили — создаётся новая версия (
version + 1), старая сохраняется - Все версии теста хранятся; результаты привязаны к конкретной версии
- Активная версия — та, которую видят сотрудники; автор может вручную переключить активную версию
- Тест можно деактивировать (скрыть из списка, не удалять)
4.3 Назначение теста
- Список получателей (отдел или конкретные сотрудники)
- Срок сдачи — дата дедлайна
- Допустимое количество попыток (1 или более)
4.4 Прохождение теста
- На главной странице сотрудник видит список назначенных тестов со статусами:
Не начат— ещё не открывалВ процессе— начал, не завершилЗавершён— сдал/не сдалПросрочен— дедлайн прошёл, не сдан
- Если задан таймер — отображается обратный отсчёт, по истечении тест завершается автоматически
- Порядок вопросов случайный при каждом прохождении
- Возможность вернуться к предыдущему вопросу — определяется настройкой теста
4.5 Результаты после завершения теста
- Итоговый балл и процент правильных ответов
- Факт зачёта: сдал / не сдал
- Разбор ошибок: по каждому вопросу — его ответ и правильный ответ
4.6 Трекер попыток
Единый интерфейс просмотра всех попыток прохождения тестов:
- Фильтрация по подразделению, сотруднику, тесту, статусу, результату
- Пагинация и сортировка
4.7 AI-помощник (DeepSeek)
Интеграция с LLM DeepSeek для помощи при создании тестов:
| Функция | Описание |
|---|---|
| Генерация теста | AI генерирует готовый набор вопросов с вариантами ответов по теме |
| Улучшение формулировки | AI переформулирует выбранный вопрос более чётко |
| Добавление дистракторов | AI генерирует правдоподобные неправильные варианты ответов |
| Проверка качества | AI анализирует весь тест и выдаёт рекомендации |
Роли и права доступа
| Роль | Кто | Создаёт тесты | Назначает тесты | Видит результаты |
|---|---|---|---|---|
| HR-менеджер | Руководитель службы HR, Директор клиники | ✅ | Всем сотрудникам клиники | Всех сотрудников |
| Руководитель подразделения | Главный врач, рук. службы администраторов | ✅ | Только своему подразделению | Только своего подразделения |
| Сотрудник | Все остальные работники | ❌ | ❌ | Только свои |
База данных
Схема таблиц
departments — Подразделения
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| name | VARCHAR(255) | Название подразделения |
| created_at | TIMESTAMP | Дата создания |
| updated_at | TIMESTAMP | Дата обновления |
users — Пользователи
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| login | VARCHAR(100) | Уникальный логин |
| password_hash | VARCHAR(255) | Хеш пароля |
| full_name | VARCHAR(255) | ФИО |
| role | ENUM | 'hr', 'manager', 'employee' |
| department_id | UUID | FK -> departments |
| is_active | BOOLEAN | Активна ли учётная запись |
| created_at | TIMESTAMP | Дата создания |
| updated_at | TIMESTAMP | Дата обновления |
tests — Тесты
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| title | VARCHAR(255) | Название теста |
| description | TEXT | Описание (опционально) |
| passing_threshold | INTEGER | Порог зачёта (%) |
| time_limit | INTEGER | Таймер в минутах (nullable) |
| allow_back | BOOLEAN | Возврат к предыдущему |
| is_active | BOOLEAN | Активен |
| is_versioned | BOOLEAN | Есть версии |
| created_by | UUID | FK -> users |
| created_at | TIMESTAMP | Дата создания |
| updated_at | TIMESTAMP | Дата обновления |
test_versions — Версии тестов
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| test_id | UUID | FK -> tests |
| version | INTEGER | Номер версии |
| is_active | BOOLEAN | Активная версия |
| created_at | TIMESTAMP | Дата создания |
questions — Вопросы
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| test_version_id | UUID | FK -> test_versions |
| text | TEXT | Текст вопроса |
| question_order | INTEGER | Порядок вопроса |
| has_multiple_answers | BOOLEAN | Несколько правильных |
answer_options — Варианты ответов
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| question_id | UUID | FK -> questions |
| text | TEXT | Текст варианта |
| is_correct | BOOLEAN | Правильный ответ |
| option_order | INTEGER | Порядок варианта |
test_assignments — Назначения тестов
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| test_version_id | UUID | FK -> test_versions |
| assigned_by | UUID | FK -> users |
| deadline | DATE | Срок сдачи |
| max_attempts | INTEGER | Допустимое число попыток |
| created_at | TIMESTAMP | Дата назначения |
test_assignment_targets — Получатели назначений
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| assignment_id | UUID | FK -> test_assignments |
| target_type | ENUM | 'department', 'user' |
| target_id | UUID | FK (department или user) |
test_attempts — Попытки прохождения
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| test_version_id | UUID | FK -> test_versions |
| user_id | UUID | FK -> users |
| attempt_number | INTEGER | Номер попытки |
| status | ENUM | 'in_progress', 'completed', 'expired' |
| started_at | TIMESTAMP | Начало |
| completed_at | TIMESTAMP | Завершение |
| correct_count | INTEGER | Правильных ответов |
| total_questions | INTEGER | Всего вопросов |
| passed | BOOLEAN | Зачёт |
user_answers — Ответы пользователя
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | PK |
| attempt_id | UUID | FK -> test_attempts |
| question_id | UUID | FK -> questions |
| selected_options | UUID[] | Выбранные варианты |
settings — Настройки
| Поле | Тип | Описание |
|---|---|---|
| key | VARCHAR(100) | PK |
| value | TEXT | Значение |
API Endpoints
Аутентификация
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /api/auth/login |
Вход в систему |
| POST | /api/auth/logout |
Выход из системы |
Подразделения
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/departments |
Список подразделений |
| POST | /api/departments |
Создать подразделение |
| PUT | /api/departments/:id |
Редактировать |
| DELETE | /api/departments/:id |
Деактивировать |
Пользователи
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/users |
Список сотрудников |
| POST | /api/users |
Создать сотрудника |
| GET | /api/users/:id |
Карточка сотрудника |
| PUT | /api/users/:id |
Редактировать |
| DELETE | /api/users/:id |
Деактивировать |
Тесты
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/tests |
Список тестов |
| POST | /api/tests |
Создать тест |
| GET | /api/tests/:id |
Тест с вопросами |
| PUT | /api/tests/:id |
Редактировать |
| DELETE | /api/tests/:id |
Деактивировать |
Назначения тестов
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/assignments |
Список назначений |
| POST | /api/assignments |
Назначить тест |
| GET | /api/assignments/:id |
Детали назначения |
| PUT | /api/assignments/:id |
Редактировать |
| DELETE | /api/assignments/:id |
Удалить |
| GET | /api/my-assignments |
Назначенные тесты (для сотрудника) |
Прохождение теста
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /api/attempts/start |
Начать попытку |
| GET | /api/attempts/:id |
Получить вопросы |
| POST | /api/attempts/:id/answers |
Отправить ответ |
| GET | /api/attempts/:id/answers |
Получить текущий прогресс |
| POST | /api/attempts/:id/complete |
Завершить тест |
Результаты
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/attempts/:id/result |
Получить результат |
| GET | /api/attempts/:id/review |
Получить разбор |
Трекер попыток
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/tracker |
Список всех попыток |
AI-помощник
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /api/ai/generate-test |
Сгенерировать тест |
| POST | /api/ai/improve-question |
Улучшить вопрос |
| POST | /api/ai/add-distractors |
Добавить неправильные варианты |
| POST | /api/ai/check-quality |
Проверить качество теста |
Настройки
| Метод | Эндпоинт | Описание |
|---|---|---|
| GET | /api/settings |
Получить настройки |
| PUT | /api/settings |
Обновить настройки |
| POST | /api/settings/test-connection |
Проверить подключение к DeepSeek |
Структура проекта
TestingWebApp/
├── docs/ # Документация
│ ├── ТЗ.md # Техническое задание
│ └── шаги/ # План разработки (11 шагов)
├── backend/ # Node.js + Express
│ ├── src/
│ │ ├── index.js # Точка входа
│ │ ├── db/ # Работа с БД
│ │ │ ├── db.js # Подключение к PostgreSQL
│ │ │ ├── migrate.js # Миграции
│ │ │ └── migrations/
│ │ │ └── 001_initial.sql
│ │ ├── routes/ # API роуты
│ │ │ └── auth.js
│ │ ├── middleware/ # Промежуточное ПО
│ │ │ └── auth.js
│ │ └── utils/ # Утилиты
│ │ └── auth.js
│ └── package.json
├── frontend/ # React SPA
│ ├── src/
│ │ ├── main.jsx # Точка входа
│ │ └── App.jsx # Главный компонент
│ ├── index.html
│ ├── vite.config.js
│ └── package.json
├── docker-compose.yml # PostgreSQL
└── README.md # Этот файл
Установка и запуск
Требования
- Node.js 18+
- PostgreSQL 14+
- Docker (для PostgreSQL)
Шаги
-
Клонировать репозиторий
-
Настроить окружение
Создать файл
backend/.env:DATABASE_URL=postgresql://user:password@localhost:5432/clinic_tests JWT_SECRET=your-secret-key PORT=3000 -
Запустить PostgreSQL
docker-compose up -d -
Установить зависимости и запустить backend
cd backend npm install npm run dev -
Запустить frontend
cd frontend npm install npm run dev -
Открыть приложение
- Frontend: http://localhost:5173
- Backend API: http://localhost:3000
План разработки
| Шаг | Название | Описание |
|---|---|---|
| 1 | Проект и инфраструктура | Структура проекта, Docker, настройка окружения |
| 2 | Проектирование БД | Создание всех таблиц и миграций |
| 3 | Аутентификация и авторизация | JWT, login/logout, RBAC |
| 4 | Управление пользователями | CRUD сотрудников и подразделений |
| 5 | Управление тестами | Создание, редактирование, версионирование |
| 6 | Назначение тестов | Выбор получателей, дедлайн, лимит попыток |
| 7 | Интерфейс прохождения | Прохождение с таймером, случайный порядок вопросов |
| 8 | Результаты и разбор | Итоговый балл, разбор ошибок |
| 9 | Трекер попыток | Единый интерфейс просмотра попыток |
| 10 | AI-помощник | Интеграция с DeepSeek |
| 11 | Страница настроек | Управление API ключами |
Нефункциональные требования
| Параметр | Значение |
|---|---|
| Количество пользователей | 50–200 человек |
| Платформа | Веб-приложение, браузер (desktop-first) |
| Доступность | Внутренняя сеть клиники |
| Язык интерфейса | Русский |
| Время отклика | < 2 секунды |
Вне scope (не реализуется в данной версии)
- Интеграция с AD/LDAP
- Мобильное приложение
- Вопросы с вложениями (изображения, видео)
- Экспорт отчётов в Excel / PDF
- Уведомления в MAX (отдельный спринт)
Description