|
|
|
|
@ -10,39 +10,24 @@
|
|
|
|
|
|
|
|
|
|
## Содержание |
|
|
|
|
|
|
|
|
|
- [Технологический стек](#технологический-стек) |
|
|
|
|
- [Функциональные возможности](#функциональные-возможности) |
|
|
|
|
- [Роли и права доступа](#роли-и-права-доступа) |
|
|
|
|
- [База данных](#база-данных) |
|
|
|
|
- [API Endpoints](#api-endpoints) |
|
|
|
|
- [Структура проекта](#структура-проекта) |
|
|
|
|
- [Установка и запуск](#установка-и-запуск) |
|
|
|
|
- [План разработки](#план-разработки) |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Технологический стек |
|
|
|
|
|
|
|
|
|
| Компонент | Выбор | |
|
|
|
|
|-----------|-------| |
|
|
|
|
| Backend | Node.js + Express | |
|
|
|
|
| Frontend | React (SPA) | |
|
|
|
|
| Database | PostgreSQL | |
|
|
|
|
| Authentication | JWT (токен в httpOnly cookie) | |
|
|
|
|
| Password | bcrypt | |
|
|
|
|
- [Нефункциональные требования](#нефункциональные-требования) |
|
|
|
|
- [Вне scope](#вне-scope-не-реализуется-в-данной-версии) |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Функциональные возможности |
|
|
|
|
|
|
|
|
|
### 4.1 Управление пользователями и подразделениями |
|
|
|
|
### Управление пользователями и подразделениями |
|
|
|
|
|
|
|
|
|
- Создание/редактирование/деактивация учётных записей сотрудников |
|
|
|
|
- Каждый сотрудник принадлежит одному подразделению |
|
|
|
|
- Создание/редактирование справочника подразделений |
|
|
|
|
- Назначение роли сотруднику: HR-менеджер / Руководитель подразделения / Сотрудник |
|
|
|
|
|
|
|
|
|
### 4.2 Создание и редактирование тестов |
|
|
|
|
### Создание и редактирование тестов |
|
|
|
|
|
|
|
|
|
**Тест содержит:** |
|
|
|
|
- Название теста |
|
|
|
|
@ -66,13 +51,13 @@
|
|
|
|
|
- Активная версия — та, которую видят сотрудники; автор может вручную переключить активную версию |
|
|
|
|
- Тест можно деактивировать (скрыть из списка, не удалять) |
|
|
|
|
|
|
|
|
|
### 4.3 Назначение теста |
|
|
|
|
### Назначение теста |
|
|
|
|
|
|
|
|
|
- Список получателей (отдел или конкретные сотрудники) |
|
|
|
|
- Срок сдачи — дата дедлайна |
|
|
|
|
- Допустимое количество попыток (1 или более) |
|
|
|
|
|
|
|
|
|
### 4.4 Прохождение теста |
|
|
|
|
### Прохождение теста |
|
|
|
|
|
|
|
|
|
- На главной странице сотрудник видит список назначенных тестов со статусами: |
|
|
|
|
- `Не начат` — ещё не открывал |
|
|
|
|
@ -83,21 +68,21 @@
|
|
|
|
|
- Порядок вопросов **случайный** при каждом прохождении |
|
|
|
|
- Возможность вернуться к предыдущему вопросу — определяется настройкой теста |
|
|
|
|
|
|
|
|
|
### 4.5 Результаты после завершения теста |
|
|
|
|
### Результаты после завершения теста |
|
|
|
|
|
|
|
|
|
- Итоговый балл и процент правильных ответов |
|
|
|
|
- Факт зачёта: **сдал / не сдал** |
|
|
|
|
- Разбор ошибок: по каждому вопросу — его ответ и правильный ответ |
|
|
|
|
|
|
|
|
|
### 4.6 Трекер попыток |
|
|
|
|
### Трекер попыток |
|
|
|
|
|
|
|
|
|
Единый интерфейс просмотра всех попыток прохождения тестов: |
|
|
|
|
- Фильтрация по подразделению, сотруднику, тесту, статусу, результату |
|
|
|
|
- Пагинация и сортировка |
|
|
|
|
|
|
|
|
|
### 4.7 AI-помощник (DeepSeek) |
|
|
|
|
### AI-помощник |
|
|
|
|
|
|
|
|
|
Интеграция с LLM DeepSeek для помощи при создании тестов: |
|
|
|
|
Интеграция с LLM для помощи при создании тестов: |
|
|
|
|
|
|
|
|
|
| Функция | Описание | |
|
|
|
|
|---------|----------| |
|
|
|
|
@ -118,319 +103,9 @@
|
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## База данных |
|
|
|
|
|
|
|
|
|
### Схема таблиц |
|
|
|
|
|
|
|
|
|
#### `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 ключами | |
|
|
|
|
Инструкции по установке и запуску приложения будут добавлены после выбора технологического стека. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
|