196 lines
12 KiB
Markdown
196 lines
12 KiB
Markdown
# Система тестирования сотрудников клиники
|
||
|
||
Веб-приложение для проведения внутреннего тестирования сотрудников клиники.
|
||
Руководители подразделений и HR-менеджеры создают тесты и назначают их
|
||
сотрудникам. Все попытки и результаты сохраняются.
|
||
|
||
- **Прод:** **[https://edullm.pirogov.ai/](https://edullm.pirogov.ai/)**
|
||
- **Ветка разработки:** `dev`
|
||
- **ТЗ:** v1.2 от 2026-03-21 (статус — согласовано)
|
||
|
||
---
|
||
|
||
## Стек и состояние
|
||
|
||
**Целевой и единственный рабочий стек** — Python 3.11 + Flask 3 +
|
||
Jinja2 + Tailwind CDN + SQLAlchemy / psycopg2, код в
|
||
[`flask_app/`](flask_app/). На нём работает и прод, и dev (`:3108`).
|
||
|
||
Старые каталоги `backend/` (Node.js / Express) и `frontend/`
|
||
(React + Vite) — **архив**: не разворачиваются, в `docker-compose.dev.yml`
|
||
поднимается только сервис `testing-flask`, удаление папок запланировано
|
||
в спринте **E1.6**. Использовать их не надо, миграции и SQL-схема
|
||
сохранены в `backend/src/db/migrations/` исключительно как источник
|
||
структуры БД.
|
||
|
||
БД — **`clinic_tests`** (PostgreSQL, UUID-ключи). В Этапе 1 схема
|
||
не меняется.
|
||
|
||
**Этап 2** — слияние с общим HR-кабинетом `HR_TG_Bot/tgFlaskForm` —
|
||
запланирован на будущее, сейчас не делается. План:
|
||
[`docs/migration-to-tgflaskform.md`](docs/migration-to-tgflaskform.md)
|
||
([простыми словами](docs/migration-to-tgflaskform-plain.md)).
|
||
|
||
---
|
||
|
||
## Что уже работает на новом (Flask) контуре
|
||
|
||
E1.0–E1.3 и E1.8 закрыты. Чек-лист и журнал —
|
||
[`docs/migration-final.md`](docs/migration-final.md).
|
||
|
||
- **Авторизация** через куки-сессию Flask: bcrypt (локальные пользователи
|
||
`clinic_tests.users`) или Werkzeug-хеши при включённом `HR_AUTH=1`
|
||
(UPSERT в `clinic_tests.users` по `staff_id` из `hr_bot_test`).
|
||
UI: `/login`, JSON: `/api/auth/{login,logout,me}`.
|
||
- **Каталог тестов** `/tests` (видны активные + блок «Скрытые вами»),
|
||
создание теста через модалку.
|
||
- **Редактор** `/tests/<id>/edit`: правка названия/описания/проходного
|
||
балла, добавление/удаление/перемещение вопросов и вариантов,
|
||
переключатель «Цепочка активна», авто-форк новой версии при правке
|
||
после первой попытки.
|
||
- **AI-помощник** в редакторе:
|
||
- «По названию» — генерация всего теста по теме (количество вопросов
|
||
и вариантов задаёт автор);
|
||
- «По текущей сетке» — генерация по уже расставленным карточкам;
|
||
- «Проверить» — рецензия теста с вердиктом и разделами рекомендаций;
|
||
- «Улучшить» — массовое «было → стало» с чекбоксами;
|
||
- «AI: вопрос/переформулировать» — на отдельной карточке вопроса.
|
||
- **Импорт документа** в редакторе: PDF / DOCX / TXT / MD до 16 МБ,
|
||
через `pypdf` и `python-docx` → AI-черновик.
|
||
- **Настройки** `/settings` — статус общего LLM-ключа из ENV (DeepSeek
|
||
или OpenAI-совместимый), кнопка «Проверить подключение».
|
||
|
||
Подробная инструкция для тестировщика (только UI, без консоли) —
|
||
[`docs/QA-versioning-and-ai.md`](docs/QA-versioning-and-ai.md).
|
||
|
||
## Что ещё не реализовано
|
||
|
||
| Спринт | Что включает |
|
||
|---|---|
|
||
| **E1.4** — Назначение и прохождение | Назначить тест сотруднику, экран прохождения, экран результата с разбором ошибок. |
|
||
| **E1.5** — Трекер и настройки модуля | Единый список попыток с фильтрами, страница настроек цепочки. |
|
||
| **E1.6** — Cutover внутри репозитория | Удаление `backend/` и `frontend/`, чистка `docker-compose.dev.yml` от legacy-сервисов. |
|
||
| **E1.7** — UX-полировка редактора | 4 аккордеона (Шапка / AI / Вопросы / Действия) и drag-n-drop из [Спринта 3](docs/СПРИНТЫ_МОБИЛЬНЫЙ_ДИЗАЙН.md). |
|
||
|
||
---
|
||
|
||
## Установка и запуск
|
||
|
||
### Предпосылка: общий Postgres
|
||
|
||
Используется **тот же** PostgreSQL, что и в
|
||
[Postgres_TG_Bots](../Postgres_TG_Bots) (контейнер `hr_postgres_dev`,
|
||
сеть `hr_postgres_dev_net`, учётка `hr_bot_user`).
|
||
|
||
```bash
|
||
# (один раз) создать базу
|
||
psql "postgresql://hr_bot_user:hrbot123@localhost:5432/postgres" \
|
||
-c "CREATE DATABASE clinic_tests;"
|
||
|
||
# (один раз) внешняя сеть, если ещё не создана соседом
|
||
docker network create hr_postgres_dev_net || true
|
||
```
|
||
|
||
### Dev-стенд
|
||
|
||
Выбор интерфейса задаётся через env-переменную `COMPOSE_PROFILES`:
|
||
|
||
- `modern` — основной интерфейс на Flask/Jinja;
|
||
- `legacy` — legacy-раскладка интерфейса на том же Flask-стеке.
|
||
|
||
```bash
|
||
# Новый стек (рекомендуется)
|
||
COMPOSE_PROFILES=modern docker compose -f docker-compose.dev.yml up -d --build
|
||
|
||
# Legacy-раскладка (тот же Flask)
|
||
COMPOSE_PROFILES=legacy docker compose -f docker-compose.dev.yml up -d --build
|
||
```
|
||
|
||
| Что | URL |
|
||
|---|---|
|
||
| Приложение (Flask modern) | <http://localhost:3108> |
|
||
| Health-check | <http://localhost:3108/health> |
|
||
| Приложение (Flask legacy) | <http://localhost:3107> |
|
||
|
||
`docker-compose.dev.yml` пробрасывает в `testing-flask`:
|
||
- `DATABASE_URL` (по умолчанию на контейнерный Postgres `clinic_tests`);
|
||
- `HR_AUTH=1` / `HR_DATABASE_URL` по умолчанию — вход через HR-кабинет;
|
||
- `DEEPSEEK_API_KEY` / `OPENAI_API_KEY` / `LLM_BASE_URL` / `LLM_MODEL` —
|
||
для AI-функций. Достаточно положить ключ в корневой `.env` репозитория.
|
||
|
||
### Локально без Docker
|
||
|
||
См. [`flask_app/README.md`](flask_app/README.md) — `venv` +
|
||
`pip install -r requirements.txt` + `python run.py`.
|
||
|
||
---
|
||
|
||
## Данные и интеграция с HR
|
||
|
||
- **Две роли кластера Postgres.** В **`clinic_tests`** — только сущности
|
||
модуля тестирования (тесты, версии, назначения, попытки, локальные
|
||
технические учётки). В **`hr_bot_test`** (Postgres_TG_Bots /
|
||
hr_web_viewer) — штат, справочники, RBAC и веб-логины. Схемы не
|
||
смешиваем, второй кадровый учёт в `clinic_tests` не ведём.
|
||
- **Сотрудник** во всех бизнес-процессах — по
|
||
**`staff_members.id`** из `hr_bot_test`. В `clinic_tests` храним тот же
|
||
идентификатор; ФИО / отдел / роли подтягиваем из HR при отображении.
|
||
- **`telegram_id` сотрудника** в бизнес-логике модуля **не участвует**
|
||
(ни вход, ни проверка прав, ни выбор сотрудника, ни фильтрация).
|
||
- **Целевой RBAC** — единая система разрешений HR
|
||
(`staff_role_assignments`, `permissions`). Модуль тестирования
|
||
не дублирует матрицу; пока единый API не готов — в `clinic_tests`
|
||
допустимы временные флаги, явно помеченные как MVP.
|
||
- **`HR_AUTH=1`**: в Flask-контуре включает вход через `hr_bot_test.users`
|
||
(Werkzeug-хеши) с UPSERT в `clinic_tests.users`. См.
|
||
[`flask_app/.env.example`](flask_app/.env.example).
|
||
|
||
---
|
||
|
||
## Роли и права (по ТЗ)
|
||
|
||
| Роль | Кто | Создаёт тесты | Назначает | Видит результаты |
|
||
|---|---|:---:|:---:|:---:|
|
||
| **HR-менеджер** | Руководитель HR, директор | ✅ | Всем | Всех |
|
||
| **Руководитель подразделения** | Главврач, рук. отделения | ✅ | Только своему подразделению | Только своего подразделения |
|
||
| **Сотрудник** | Все остальные | ❌ | ❌ | Только свои |
|
||
|
||
> На текущем Flask-контуре (E1.0–E1.3, E1.8) проверяется только
|
||
> `@login_required`; разделение по ролям задействуется на E1.4–E1.5.
|
||
|
||
---
|
||
|
||
## Нефункциональные требования
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Количество пользователей | 50–200 человек |
|
||
| Платформа | Веб, браузер; mobile-friendly |
|
||
| Доступность | Внутренняя сеть клиники |
|
||
| Язык интерфейса | Русский |
|
||
| Время отклика | < 2 секунды |
|
||
|
||
## Вне scope (в текущей версии не делаем)
|
||
|
||
- Интеграция с AD / LDAP.
|
||
- Нативное мобильное приложение.
|
||
- Вопросы с вложениями (картинки, видео).
|
||
- Экспорт отчётов в Excel / PDF.
|
||
- Уведомления в MAX (отдельный спринт).
|
||
|
||
---
|
||
|
||
## Документация
|
||
|
||
| Файл | О чём |
|
||
|---|---|
|
||
| [`docs/PROJECT_STATUS.md`](docs/PROJECT_STATUS.md) | Что работает «прямо сейчас», что в работе, что в бэклоге. |
|
||
| [`docs/migration-final.md`](docs/migration-final.md) | Главный трекер миграции: спринты Этапа 1, журнал, критерии готовности. |
|
||
| [`docs/migration-final-inventory.md`](docs/migration-final-inventory.md) | Карта 22 эндпоинтов Express + gap-analysis с `tgFlaskForm`. |
|
||
| [`docs/migration-to-tgflaskform.md`](docs/migration-to-tgflaskform.md) | План Этапа 2 (слияние с HR-кабинетом). |
|
||
| [`docs/QA-versioning-and-ai.md`](docs/QA-versioning-and-ai.md) | Инструкция для тестировщика — только через сайт. |
|
||
| [`docs/СПРИНТЫ_МОБИЛЬНЫЙ_ДИЗАЙН.md`](docs/СПРИНТЫ_МОБИЛЬНЫЙ_ДИЗАЙН.md) | Целевой мобильный UX редактора (база для E1.7). |
|
||
| [`docs/РУКОВОДСТВО_КАБИНЕТ_ТЕСТОВ.md`](docs/РУКОВОДСТВО_КАБИНЕТ_ТЕСТОВ.md) | Кратко для врачей-кураторов. |
|
||
| [`flask_app/README.md`](flask_app/README.md) | Конкретные команды для нового контура. |
|
||
| [`docs/ТЗ.md`](docs/ТЗ.md) | Исходное ТЗ заказчика. |
|