From b42a3c3d55ead19611f5054f298c9d588b0d097d 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:06:24 +0500 Subject: [PATCH] docs folder with steps --- .DS_Store | Bin 0 -> 6148 bytes docs/.DS_Store | Bin 0 -> 6148 bytes docs/ТЗ.md | 163 ++++++++++++++++++++++++++ docs/шаги/01-project-setup.md | 44 +++++++ docs/шаги/02-database-design.md | 139 ++++++++++++++++++++++ docs/шаги/03-auth.md | 56 +++++++++ docs/шаги/04-users-departments.md | 49 ++++++++ docs/шаги/05-test-management.md | 54 +++++++++ docs/шаги/06-test-assignment.md | 50 ++++++++ docs/шаги/07-test-taking.md | 72 ++++++++++++ docs/шаги/08-results-review.md | 78 ++++++++++++ docs/шаги/09-attempt-tracking.md | 53 +++++++++ docs/шаги/10-ai-assistant.md | 89 ++++++++++++++ docs/шаги/11-settings.md | 63 ++++++++++ 14 files changed, 910 insertions(+) create mode 100644 .DS_Store create mode 100644 docs/.DS_Store create mode 100644 docs/ТЗ.md create mode 100644 docs/шаги/01-project-setup.md create mode 100644 docs/шаги/02-database-design.md create mode 100644 docs/шаги/03-auth.md create mode 100644 docs/шаги/04-users-departments.md create mode 100644 docs/шаги/05-test-management.md create mode 100644 docs/шаги/06-test-assignment.md create mode 100644 docs/шаги/07-test-taking.md create mode 100644 docs/шаги/08-results-review.md create mode 100644 docs/шаги/09-attempt-tracking.md create mode 100644 docs/шаги/10-ai-assistant.md create mode 100644 docs/шаги/11-settings.md diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3a1fbfc98f2bbccc488490c6d11ed3078c38e591 GIT binary patch literal 6148 zcmeHK%}*0S6rTrGwji>Uf{4*H>BR%ehlF4}SQm^zNgx!k2v~R9p{^`5b$8o>grsM^ z_y_n0c=zJbi~oQJPbPZv>eZ9J`Pd?$i6>)pUo!K1Gw);f{WdeRLkIz@Rvsh7B!n2) z1SUGM`-up>@W05eHn1PsqzncNEb`zvbI4P0f$ojR=cKMqW zSwzdvX#`ch&R;uK&ke%S(f82So;Y!`!!V34V|Gs4 zePVKAe?MvTXGg9r7Pq`@#-A$M0rw>--5Mi!hDxg*w^Y~lz=x=wk7jRFQL?k^RQKr~ zvp3b3PW7h-2GRp(2G0(i8#-S!`y9KpRq@5UPIHg@mRF+%x5QcAeL@Q%-3f(KG*d_X z7HRqZ!PL@j6@AhN6EfE=pHj9~@!j(L=4L>{!VmiDJ$q-VmAxk@`P}msc;JREXRGT0 zGCmv9?OC?T@!@r3d%h}6!3y;Q#G-j5rm*4J4)x}l#lw(quiCzEvkJ9#g{R1dH7)p5 zWRkCuui7P-RkGK=C`z-rg-E%m6q96?g2zWX(lkQ$jr~dL$tA`aO=fdqumTmR!egjILuF`-zWD{6Q3Etl zX?^p0-e(?X6`YIwwcmdOx^AQEzo|GbG-e=X;CC4i`$Gnsz?{aWLb-KdC$9jA;x|GH z>hjkgF(W1ra~hipaRvocD544leZ>HMa{v{N_MG-_DpcVF5_y5B|@hD~>X5gP<01`9#84F9&XX~-z#95oc_5hm@ q;n!3sL$K4wu~fuSJcvyS+A=~x%xP>Y#2J+MM?lgLcQFHhl!5PA9N7T? literal 0 HcmV?d00001 diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7a91f8b9d2d268d6cd3ed78ad772cfe65f204871 GIT binary patch literal 6148 zcmeHK%}T>S5dJpyQ0b*NJt*uG2vYEzq)`a?2kFI=QhTiQ10wfDdy<)Fj~Fz^JsR9m7dY=lyW=l1 zAbWSD`z5>9-M=fny5&yJQR9L-N5PmHH@L 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 | Значение | + +--- + +## Результат + +- Созданы все таблицы с связями +- Накатанные миграции +- Схема БД готова diff --git a/docs/шаги/03-auth.md b/docs/шаги/03-auth.md new file mode 100644 index 0000000..11b0116 --- /dev/null +++ b/docs/шаги/03-auth.md @@ -0,0 +1,56 @@ +# Шаг 3: Аутентификация и авторизация + +## Цель + +Реализовать систему входа в систему и разграничения прав доступа. + +--- + +## Задачи + +### 3.1. Аутентификация + +- **Эндпоинт:** `POST /api/auth/login` +- Принимает: `{ login, password }` +- Возвращает: JWT токен в httpOnly cookie +- Проверка пароля через bcrypt + +### 3.2. Выход + +- **Эндпоинт:** `POST /api/auth/logout` +- Очищает cookie с токеном + +### 3.3. Защита роутов (Middleware) + +- Проверка валидности JWT +- Извлечение user_id и роли из токена + +### 3.4. Права доступа (RBAC) + +| Роль | Доступ | +|------|--------| +| HR | Все операции | +| Manager | Своё подразделение | +| Employee | Только свои данные | + +### 3.5. Middleware авторизации + +```javascript +// Проверка роли +function requireRole(roles: string[]) { + // Проверяет, что user.role входит в массив roles +} + +// Проверка подразделения (для manager) +function requireDepartment(departmentId: string) { + // Проверяет, что user.department_id === departmentId +} +``` + +--- + +## Результат + +- Работающий вход по логину/паролю +- Защищённые API роуты +- Разграничение прав по ролям diff --git a/docs/шаги/04-users-departments.md b/docs/шаги/04-users-departments.md new file mode 100644 index 0000000..3fb5621 --- /dev/null +++ b/docs/шаги/04-users-departments.md @@ -0,0 +1,49 @@ +# Шаг 4: Управление пользователями и подразделениями + +## Цель + +Реализовать CRUD операции для сотрудников и справочника подразделений. + +--- + +## Задачи + +### 4.1. Управление подразделениями + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/departments` | GET | Список подразделений | +| `/api/departments` | POST | Создать подразделение | +| `/api/departments/:id` | PUT | Редактировать | +| `/api/departments/:id` | DELETE | Деактивировать | + +### 4.2. Управление пользователями + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/users` | GET | Список сотрудников | +| `/api/users` | POST | Создать сотрудника | +| `/api/users/:id` | GET | Карточка сотрудника | +| `/api/users/:id` | PUT | Редактировать | +| `/api/users/:id` | DELETE | Деактивировать | + +### 4.3. Фильтрация + +- GET `/api/users` поддерживает фильтры: + - `department_id` — по подразделению + - `role` — по роли + - `is_active` — по статусу + +### 4.4. Права доступа + +- **HR:** полный доступ ко всем пользователям +- **Manager:** только своё подразделение +- Создание пользователей — только администратор (ручной ввод) + +--- + +## Результат + +- Админка для управления сотрудниками +- Справочник подразделений +- Назначение ролей сотрудникам diff --git a/docs/шаги/05-test-management.md b/docs/шаги/05-test-management.md new file mode 100644 index 0000000..4bb5e99 --- /dev/null +++ b/docs/шаги/05-test-management.md @@ -0,0 +1,54 @@ +# Шаг 5: Управление тестами (админка) + +## Цель + +Реализовать создание и редактирование тестов с вопросами и версионированием. + +--- + +## Задачи + +### 5.1. CRUD тестов + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/tests` | GET | Список тестов | +| `/api/tests` | POST | Создать тест | +| `/api/tests/:id` | GET | Тест с вопросами | +| `/api/tests/:id` | PUT | Редактировать | +| `/api/tests/:id` | DELETE | Деактивировать | + +### 5.2. Управление вопросами + +- Добавление/редактирование вопросов к версии теста +- Минимум 3 варианта ответа на вопрос +- Указание одного или нескольких правильных ответов +- Перетаскивание для изменения порядка (drag & drop) + +### 5.3. Версионирование + +- При создании теста — версия 1, помечается как активная +- При редактировании: + - Если никто не проходил — изменяется текущая версия + - Если уже были попытки — создаётся новая версия (version + 1) +- Переключение активной версии вручную +- Просмотр истории версий + +### 5.4. Настройки теста + +- `passing_threshold` — порог зачёта (%) +- `time_limit` — таймер в минутах (опционально) +- `allow_back` — разрешить возврат к предыдущему вопросу + +### 5.5. Права доступа + +- **HR, Manager:** могут создавать и редактировать тесты +- **Employee:** только прохождение + +--- + +## Результат + +- Полноценный конструктор тестов +- Версионирование с сохранением истории +- Управление вопросами и ответами diff --git a/docs/шаги/06-test-assignment.md b/docs/шаги/06-test-assignment.md new file mode 100644 index 0000000..f3a0390 --- /dev/null +++ b/docs/шаги/06-test-assignment.md @@ -0,0 +1,50 @@ +# Шаг 6: Назначение тестов + +## Цель + +Реализовать функционал назначения тестов сотрудникам и подразделениям. + +--- + +## Задачи + +### 6.1. Назначение теста + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/assignments` | GET | Список назначений | +| `/api/assignments` | POST | Назначить тест | +| `/api/assignments/:id` | GET | Детали назначения | +| `/api/assignments/:id` | PUT | Редактировать | +| `/api/assignments/:id` | DELETE | Удалить | + +### 6.2. Параметры назначения + +- `test_version_id` — активная версия теста +- `deadline` — срок сдачи (дата) +- `max_attempts` — допустимое количество попыток +- `targets` — получатели: + - Тип: `department` или `user` + - Список ID подразделений/сотрудников + +### 6.3. Ограничения + +- **HR:** может назначить любому сотруднику любого подразделения +- **Manager:** может назначить только сотрудникам своего подразделения + +### 6.4. API для сотрудника + +- **GET** `/api/my-assignments` — список назначенных тестов для текущего пользователя +- Статусы: + - `not_started` — не начат + - `in_progress` — в процессе + - `completed` — завершён + - `expired` — просрочен + +--- + +## Результат + +- Назначение тестов подразделениям или сотрудникам +- Ограничение по дедлайну и попыткам +- Список назначений для сотрудника diff --git a/docs/шаги/07-test-taking.md b/docs/шаги/07-test-taking.md new file mode 100644 index 0000000..9e6d839 --- /dev/null +++ b/docs/шаги/07-test-taking.md @@ -0,0 +1,72 @@ +# Шаг 7: Интерфейс прохождения теста + +## Цель + +Реализовать интерфейс для сотрудника, позволяющий проходить назначенные тесты. + +--- + +## Задачи + +### 7.1. Начало прохождения + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/attempts/start` | POST | Начать попытку | +| `/api/attempts/:id` | GET | Получить вопросы | + +**Логика:** +- Проверить лимит попыток +- Создать запись попытки со статусом `in_progress` +- Перемешать вопросы в случайном порядке +- Запустить таймер (если задан) + +### 7.2. Ответ на вопрос + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/attempts/:id/answers` | POST | Отправить ответ | +| `/api/attempts/:id/answers` | GET | Получить текущий прогресс | + +**Параметры:** +- `question_id` — ID вопроса +- `selected_options` — массив ID выбранных вариантов + +### 7.3. Навигация + +- Переход к следующему вопросу +- Возврат к предыдущему (если `allow_back = true`) +- Переход к конкретному вопросу по номеру + +### 7.4. Завершение теста + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/attempts/:id/complete` | POST | Завершить тест | + +**Логика:** +- Проверить ответы на все вопросы +- Подсчитать правильные ответы +- Вычислить процент +- Сравнить с порогом зачёта +- Обновить статус попытки на `completed` + +### 7.5. Таймер + +- Обратный отсчёт на фронтенде +- При истечении — автоматическое завершение +- Проверка на бэкенде при отправке ответа + +### 7.6. Обработка просрочки + +- При запросе списка назначений проверить дедлайн +- Если дедлайн прошёл и попытка не завершена — пометить как `expired` + +--- + +## Результат + +- Прохождение теста со случайным порядком вопросов +- Таймер с автозавершением +- Сохранение прогресса +- Навигация по вопросам diff --git a/docs/шаги/08-results-review.md b/docs/шаги/08-results-review.md new file mode 100644 index 0000000..d732cd0 --- /dev/null +++ b/docs/шаги/08-results-review.md @@ -0,0 +1,78 @@ +# Шаг 8: Результаты и разбор ошибок + +## Цель + +Реализовать отображение результатов теста и разбора ответов сотруднику. + +--- + +## Задачи + +### 8.1. Просмотр результатов + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/attempts/:id/result` | GET | Получить результат | + +**Ответ:** +```json +{ + "test_title": "Название теста", + "version": 1, + "correct_count": 8, + "total_questions": 10, + "percentage": 80, + "passed": true, + "passing_threshold": 75, + "completed_at": "2026-03-21T10:30:00Z" +} +``` + +### 8.2. Разбор ошибок + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/attempts/:id/review` | GET | Получить разбор | + +**Ответ:** +```json +{ + "questions": [ + { + "id": "uuid", + "text": "Текст вопроса", + "user_selected": ["option_id_1", "option_id_2"], + "correct_options": ["option_id_1", "option_id_3"], + "is_correct": false, + "options": [ + { "id": "option_id_1", "text": "Вариант А", "is_correct": true }, + { "id": "option_id_2", "text": "Вариант Б", "is_correct": false }, + { "id": "option_id_3", "text": "Вариант В", "is_correct": true } + ] + } + ] +} +``` + +### 8.3. Логика отображения + +- Сразу после завершения — перенаправление на страницу результатов +- Показывать балл, процент, зачёт/не зачёт +- Для каждого вопроса: + - Выбранные ответы сотрудника + - Правильные ответы + - Индикатор правильно/неправильно + - Все варианты ответов с подсветкой + +### 8.4. Доступ + +- Сотрудник видит только свои результаты +- Результаты доступны после завершения попытки + +--- + +## Результат + +- Итоговый балл и процент +- Статус зачёта +- Полный разбор по каждому вопросу diff --git a/docs/шаги/09-attempt-tracking.md b/docs/шаги/09-attempt-tracking.md new file mode 100644 index 0000000..37323a8 --- /dev/null +++ b/docs/шаги/09-attempt-tracking.md @@ -0,0 +1,53 @@ +# Шаг 9: Трекер попыток + +## Цель + +Реализовать единый интерфейс просмотра всех попыток прохождения тестов. + +--- + +## Задачи + +### 9.1. API трекера + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/tracker` | GET | Список всех попыток | + +**Параметры фильтрации:** +- `department_id` — по подразделению +- `user_id` — по сотруднику +- `test_id` — по тесту +- `status` — по статусу (in_progress, completed, expired) +- `passed` — по результату (true, false) + +### 9.2. Поля в трекере + +| Поле | Источник | +|------|----------| +| Сотрудник | users.full_name, departments.name | +| Тест | tests.title | +| Попытка № | test_attempts.attempt_number | +| Начало | test_attempts.started_at | +| Завершение | test_attempts.completed_at | +| Результат | correct_count / total_questions, % | +| Зачёт | passed (true/false) | + +### 9.3. Права доступа + +- **HR:** видит все попытки по всей клинике +- **Manager:** видит попытки только своего подразделения +- **Employee:** видит только свои попытки + +### 9.4. Пагинация и сортировка + +- Пагинация по 20/50/100 записей +- Сортировка по дате начала (убывание) + +--- + +## Результат + +- Таблица попыток с фильтрами +- Ограничение данных по роли +- Полная история прохождений diff --git a/docs/шаги/10-ai-assistant.md b/docs/шаги/10-ai-assistant.md new file mode 100644 index 0000000..ca4d0f1 --- /dev/null +++ b/docs/шаги/10-ai-assistant.md @@ -0,0 +1,89 @@ +# Шаг 10: AI-помощник (DeepSeek) + +## Цель + +Интегрировать LLM DeepSeek для помощи при создании тестов. + +--- + +## Задачи + +### 10.1. Настройка API + +- Сохранить API ключ DeepSeek в таблице `settings` +- Ключ хранится только на бэкенде, не передаётся на фронтенд + +### 10.2. Функции AI-помощника + +#### Генерация теста + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/ai/generate-test` | POST | Сгенерировать тест | + +**Запрос:** +```json +{ + "topic": "Оказание первой помощи", + "question_count": 10 +} +``` + +**Ответ:** готовый тест с вопросами и вариантами ответов + +#### Улучшение формулировки + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/ai/improve-question` | POST | Улучшить вопрос | + +**Запрос:** +```json +{ + "question": "Что делать при переломе?" +} +``` + +#### Добавление дистракторов + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/ai/add-distractors` | POST | Добавить неправильные варианты | + +**Запрос:** +```json +{ + "question": "Признаки инфаркта:", + "correct_answer": "Боль в груди", + "count": 3 +} +``` + +#### Проверка качества + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/ai/check-quality` | POST | Проверить качество теста | + +**Запрос:** +```json +{ + "test": { ... } +} +``` + +**Ответ:** рекомендации по улучшению + +### 10.3. Обработка ошибок + +- Timeout при длительном ответе API +- Логирование ошибок +- Fallback при недоступности DeepSeek + +--- + +## Результат + +- AI-генерация вопросов +- Улучшение формулировок +- Рекомендации по качеству diff --git a/docs/шаги/11-settings.md b/docs/шаги/11-settings.md new file mode 100644 index 0000000..871cdfc --- /dev/null +++ b/docs/шаги/11-settings.md @@ -0,0 +1,63 @@ +# Шаг 11: Страница настроек + +## Цель + +Реализовать страницу настроек для управления API ключами и системными параметрами. + +--- + +## Задачи + +### 11.1. Страница настроек + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/settings` | GET | Получить настройки | +| `/api/settings` | PUT | Обновить настройки | + +### 11.2. Поля настроек + +| Поле | Описание | +|------|----------| +| deepseek_api_key | API ключ DeepSeek (скрыт на фронтенде) | + +### 11.3. Проверка подключения + +| Эндпоинт | Метод | Описание | +|----------|-------|----------| +| `/api/settings/test-connection` | POST | Проверить подключение к DeepSeek | + +**Ответ:** +```json +{ + "success": true, + "message": "Подключение успешно" +} +``` + +или + +```json +{ + "success": false, + "message": "Ошибка: неверный API ключ" +} +``` + +### 11.4. Безопасность + +- API ключ никогда не передаётся в ответах GET `/api/settings` +- При GET возвращается `***hidden***` вместо ключа +- PUT принимает новый ключ и сохраняет в БД + +### 11.5. Права доступа + +- Только HR может изменять настройки + +--- + +## Результат + +- Страница `/settings` +- Ввод и сохранение API ключа +- Проверка подключения к DeepSeek