From ccec6ef950bef230175e590ccf6d2a996240cd3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=82=D0=B8?= =?UTF-8?q?=D0=BD=20=D0=9B=D0=B5=D0=B1=D0=B5=D0=B4=D0=B8=D0=BD=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9?= Date: Sat, 21 Mar 2026 16:52:11 +0500 Subject: [PATCH] added README --- README.md | 455 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 455 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8bd6ccb --- /dev/null +++ b/README.md @@ -0,0 +1,455 @@ +# Система тестирования сотрудников клиники + +Веб-приложение для проведения внутреннего тестирования сотрудников клиники. Руководители подразделений и 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 (отдельный спринт)