Этап 1 миграции TestingWebApp на целевой стек (Python/Flask/Jinja),
БД остаётся clinic_tests.
E1.0 — База Flask-приложения: SQLAlchemy/psycopg2 пул, Flask sessions,
фабрика create_app, blueprint main с / и /health, base.html в стиле
кабинета HR (Tailwind CDN + Manrope + Material Symbols), 404/500.
E1.1 — Auth + /api/me: Flask sessions (signed cookie) вместо JWT,
bcrypt + Werkzeug, опц. HR_AUTH=1 с UPSERT в clinic_tests.users по
staff_id. UI /login, JSON /api/auth/{login,logout,me}, декораторы
@login_required / @require_role.
E1.2 — Тесты: список + редактор. 10 эндпоинтов, сервисы test_draft,
test_access, test_chain, ai_editor, llm_client, draft_validator,
editor_content. UI /tests (каталог + создание) и /tests/<id>/edit
(редактор с AI). Полный мобильный UX (аккордеоны/drag-n-drop) — в E1.7.
E1.3 — Импорт документов: pypdf + python-docx, эндпоинт
POST /api/tests/import/document, кнопка «Импорт документа» в
AI-панели редактора, лимит 16 МБ.
E1.8 — AI v2: страница /settings (статус ENV-ключа + ping),
ai/generate-by-title (без сетки), ai/check (рецензия), ai/improve
(массовое было→стало с чекбоксами). Унифицированный ответ AI-ошибок:
{ error, code, settingsUrl }.
Docker:
- docker-compose.dev.yml: добавлены DATABASE_URL, HR_AUTH/HR_DATABASE_URL,
DEEPSEEK_API_KEY/OPENAI_API_KEY/LLM_BASE_URL/LLM_MODEL и сеть postgres
для testing-flask.
Документация:
- docs/migration-final.md — двух-этапный план (Этап 1: унификация
стека внутри TestingWebApp; Этап 2: слияние с tgFlaskForm).
- docs/migration-final-inventory.md — карта 22 эндпоинтов Express.
Made-with: Cursor
8.6 KiB
Этап 2 (на будущее) — слияние TestingWebApp с HR_TG_Bot/tgFlaskForm
Не текущая фаза. Текущая работа — Этап 1: унификация стека внутри TestingWebApp (Express → Flask + React → Jinja). См. migration-final.md. Этот документ — план последующего слияния, когда заказчик решит объединять.
Простое объяснение тех же шагов: migration-to-tgflaskform-plain.md.
Связано: migration-final.md (главный трекер двух этапов), migration-final-inventory.md (карта Express + gap-analysis с уже существующим модулем tgFlaskForm), PROJECT_STATUS.md, README, код HR-кабинета: HR_TG_Bot/tgFlaskForm/webApp/interfaces/testing/, модели: HR_TG_Bot/tgFlaskForm/db/models.py.
0. Предусловие — Этап 1 закрыт
К моменту, когда этот документ берётся в работу, в TestingWebApp уже должно быть:
- Бэкенд переписан с Express на Flask внутри
flask_app/, все 22 эндпоинта работают. - Фронтенд переписан с React на Jinja-шаблоны в
flask_app/app/templates/. - БД — по-прежнему
clinic_tests, схема не менялась. - В репозитории остался один сервис приложения.
Если что-то из этого ещё не готово — Этап 2 не начинается.
1. Что меняется при слиянии
| Аспект | После Этапа 1 (отдельный сервис) | После Этапа 2 (часть HR-кабинета) |
|---|---|---|
| Репозиторий | TestingWebApp/flask_app/ |
HR_TG_Bot/tgFlaskForm/webApp/interfaces/testing/ |
| Деплой | Свой Docker-сервис, свой URL/порт | Часть основного tgFlaskForm, общий URL /cabinet/testing/... |
| БД | clinic_tests, UUID |
hr_bot_test, integer ID, схема testing_* |
| Авторизация | JWT/bcrypt + опциональный HR_AUTH |
Сессии общего HR-кабинета, привязка к staff_members |
| Модели | Свои (как в Express, но на Python) | Существующие TestingTest, TestingTestVersion, TestingQuestion, TestingAnswer, TestingAssignment, TestingAttempt, TestingAttemptAnswer, TestingSetting, TestingHeadPosition в db/models.py |
| UI | Jinja-шаблоны в flask_app/app/templates/ |
Jinja-шаблоны в tgFlaskForm/webApp/templates/cabinet/testing/ |
2. План Этапа 2 (по спринтам)
E2.0 — Сверка кода и моделей
- Сравнить структуру
flask_app/(после Этапа 1) с уже существующим модулемtgFlaskForm/webApp/interfaces/testing/. Где функции называются иначе — выбрать одно имя. - Сверить модели:
clinic_testsUUID-схема vshr_bot_testtesting_*integer-схема. Зафиксировать поле-в-поле соответствия (большая часть уже сделана в migration-final-inventory.md §10). - Критерий выхода: документ соответствий + решение по спорным точкам (например, кто прав —
is_activeна цепочке или на версии).
E2.1 — Перенос кода как blueprint
- Скопировать роуты, сервисы, шаблоны из
flask_app/вtgFlaskForm. Адаптировать:- Импорты — на
db/models.pyиdb/queries/testing_queries.pyHR-кабинета. - Авторизация — сменить с JWT/bcrypt на сессии и
werkzeug.security.check_password_hash. - URL-prefix с корневого на
/cabinet/testing/. - Шаблоны — наследование от
cabinet/base.html(хедер, нижний нав-бар).
- Импорты — на
- Критерий выхода: все экраны открываются через HR-кабинет, локальный smoke-тест зелёный.
E2.2 — Миграция данных (ETL)
Скрипт уже готов: HR_TG_Bot/tgFlaskForm/tools/migrate_clinic_tests_to_hr.py (437 строк, режимы --dry-run/--apply, идемпотентность через public._clinic_tests_migration_map).
Перед прогоном на актуальных данных дописать:
- Перенос
test_assignments1:1 — сейчас скрипт переносит только пары «тест-сотрудник» через попытки; нужны и «висящие» назначения без попыток. (Решение Этапа 2.) - Логирование пользователей без
staff_id: автор → WARN, попытка → WARN; никаких хардовых ошибок. (Решение Этапа 2.)
Порядок:
- Бэкап
clinic_testsиhr_bot_test. --dry-runна копии прод-БД, разбор лога.--applyна той же копии, ручная сверка через UI HR-кабинета.- После приёмки —
--dry-run+--applyна боевой БД.
E2.3 — Cutover
Если к этому моменту у TestingWebApp всё ещё «песочница для тестировщиков» (как сейчас) — простое переключение, без окна простоя и баннеров. Если появятся реальные пользователи — добавить пункт E2.3.1: коммуникация и redirect.
- Заморозка записи в
flask_app/старой инсталляции (read-only). - Прогон ETL на боевом.
- Маршрутизация: внешние ссылки
clinic-tests.example.com/*→hr-cabinet.example.com/cabinet/testing/*. - В корневом репозитории TestingWebApp — ветка
legacy/clinic-tests-flask, в README — ссылка на этот документ и дату EOL.
Критерий выхода: мониторинг ошибок (например Sentry, уже подключён в webApp/__init__.py), отсутствие P1 в первую неделю.
3. Что трогаем в HR-кабинете до Этапа 2
Ничего. Существующий модуль tgFlaskForm/webApp/interfaces/testing/ развивается своим темпом командой HR-кабинета и не должен подстраиваться под TestingWebApp до момента слияния. Если в нём появляются полезные правки — переносим в flask_app/ обратным потоком.
4. Риски Этапа 2 и как их снимать
| Риск | Мера |
|---|---|
Несовпадение users.staff_id ↔ staff_members.id |
Проверка перед --apply; пользователей без staff_id пропускаем по решению. |
| Расхождение моделей (UUID vs integer, поля «на цепочке» vs «на версии») | Закрыть в E2.0; подкрепить unit-тестами на конвертацию. |
| Назначения «отдел → N сотрудников» | Логировать развёртку с пометкой created_from_department=.... |
| Двойное развитие модуля HR-кабинета | До Этапа 2 — не править tgFlaskForm/cabinet/testing под нужды TestingWebApp. |
5. Производительность кабинета (общее)
Если после переноса страницы кабинета или мини-приложения работают медленно — пошаговый план измерений и правок: performance-flask-mini-app.md. Это вспомогательный документ, не часть этапов миграции.