Files
TestingWebApp/README.md
T
Константин Лебединский ccec6ef950 added README
2026-03-21 16:52:11 +05:00

456 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Система тестирования сотрудников клиники
Веб-приложение для проведения внутреннего тестирования сотрудников клиники. Руководители подразделений и HR-менеджеры создают тесты и назначают их сотрудникам. Система фиксирует все попытки и результаты.
**Версия ТЗ:** 1.2
**Дата:** 2026-03-21
**Статус:** Согласовано
---
## Содержание
- [Технологический стек](#технологический-стек)
- [Функциональные возможности](#функциональные-возможности)
- [Роли и права доступа](#роли-и-права-доступа)
- [База данных](#база-данных)
- [API Endpoints](#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)
### Шаги
1. **Клонировать репозиторий**
2. **Настроить окружение**
Создать файл `backend/.env`:
```env
DATABASE_URL=postgresql://user:password@localhost:5432/clinic_tests
JWT_SECRET=your-secret-key
PORT=3000
```
3. **Запустить PostgreSQL**
```bash
docker-compose up -d
```
4. **Установить зависимости и запустить backend**
```bash
cd backend
npm install
npm run dev
```
5. **Запустить frontend**
```bash
cd frontend
npm install
npm run dev
```
6. **Открыть приложение**
- 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 (отдельный спринт)