# DrHider — Полный аудит и план рефакторинга **Дата:** 2026-07-12 **Платформа:** Штурвал (Managed Flask) — запускает Flask сам, без Dockerfile/gunicorn **URL:** https://drhider.pythonk8s.dev.nubes.ru/ **Репозиторий:** https://gitea.services.ngcloud.ru/Nail/drhider --- ## Текущее состояние (аудит каждого файла) | Файл | Статус | Решение | |---|---|---| | `Dockerfile` | ❌ НЕ НУЖЕН | Штурвал сам запускает Flask. Удалить. | | `drhider_server.py` | ❌ НЕ НУЖЕН | Standalone-сервер с ВМ (:8767). Flask app.py уже обрабатывает /api/drhider. Удалить. | | `requirements.txt` | ⚠️ Нужны правки | Убрать `gunicorn` и `gevent`. Оставить `flask`, `python-docx`, `pdfplumber`, `httpx`. | | `.gitignore` | ✅ OK | Без изменений. | | `.gitea/workflows/deploy.yaml` | ✅ OK | CI для Штурвала. | | `site/app.py` | ⚠️ Нужны правки | Удалить блок `if __name__ == "__main__"` (gunicorn). При рефакторинге — вынести LLMClient. | | `site/templates/index.html` | ✅ OK | UI. | | `site/static/favicon.svg` | ✅ OK | Иконка (из loadtest). | | `drhider.py` | ⚠️ МОНОЛИТ | 560 строк. Разбить на ~20 модулей. | | `History/` | ✅ OK | Документация. | --- ## План рефакторинга (Фаза 1: удаление лишнего) ### Шаг 1.1 — Удалить `Dockerfile` ### Шаг 1.2 — Удалить `drhider_server.py` ### Шаг 1.3 — Исправить `requirements.txt` (убрать gunicorn, gevent) ### Шаг 1.4 — Исправить `site/app.py` (убрать блок `if __name__ == "__main__"`) ### Шаг 1.5 — Проверить синтаксис → commit → push --- ## План рефакторинга (Фаза 2: модульная структура) ### Новая структура `drhider/` пакета (вместо `drhider.py` 560 строк): ``` drhider/ # Пакет ядра обфускации ├── __init__.py # re-export: obfuscate_files() ├── config.py # Константы: ENTITY_PATTERNS, COMPANY_PATTERN, PERSON_PATTERN, │ # RU_SURNAMES, RU_NAMES, RU_PATRONYMICS, │ # RU_CITIES, RU_STREETS, FAKE_DOMAINS ├── checksum.py # _checksum_inn10, _checksum_inn12, _checksum_ogrn ├── random_utils.py # _random_digits, _random_letters ├── generators/ # Генераторы фиктивных значений │ ├── __init__.py # ENTITY_GENERATORS маппинг │ ├── phone.py # generate_phone │ ├── email.py # generate_email │ ├── inn.py # generate_inn10, generate_inn12 │ ├── ogrn.py # generate_ogrn │ ├── kpp.py # generate_kpp │ ├── bik.py # generate_bik │ ├── accounts.py # generate_rs, generate_ks │ ├── passport.py # generate_passport │ ├── company.py # generate_company │ ├── person.py # generate_person │ └── address.py # generate_address ├── extractor.py # _extract_text, _expand_zips, _convert_pdfs_to_docx ├── scanner.py # Проход 1: _scan_regex, _scan_llm_ner ├── replacer.py # Проход 2: _replace_in_docx, _replace_in_text, _apply_replacements ├── builder.py # Сборка: _build_zip, _build_mapping_csv ├── obfuscator.py # TwoPassObfuscator — оркестратор └── llm_client.py # LLMClient (из app.py → сюда) site/ # Flask-приложение ├── __init__.py ├── app.py # Только create_app() + регистрация blueprint'ов ├── routes/ │ ├── __init__.py # Регистрация всех blueprint'ов │ ├── main_bp.py # GET / │ ├── health_bp.py # GET /health │ └── api_bp.py # POST /api/drhider ├── templates/index.html └── static/favicon.svg ``` ### Принципы: - Каждый файл ≤ 50 строк (где возможно) - Каждый файл — одна ответственность - Максимум docstring и инлайн-комментариев - Все импорты явные, никаких `import *` --- ## Результат рефакторинга (2026-07-12) ### Итоговая структура ``` drhider/ # Пакет ядра обфускации ├── __init__.py # re-export: obfuscate_files, LLMClient, TwoPassObfuscator ├── config.py # Константы: ENTITY_PATTERNS, словари имён/городов/улиц ├── checksum.py # Контрольные суммы: ИНН10, ИНН12, ОГРН ├── random_utils.py # Утилиты: random_digits, random_letters ├── llm_client.py # LLMClient — HTTP-клиент к LLM API ├── extractor.py # Извлечение текста + expand_zips + convert_pdfs_to_docx ├── scanner.py # Проход 1: scan_regex, scan_llm_ner ├── replacer.py # Проход 2: apply_replacements, replace_in_docx, replace_in_text ├── builder.py # Сборка: build_zip, build_mapping_csv ├── obfuscator.py # TwoPassObfuscator — оркестратор └── generators/ # Генераторы фиктивных значений ├── __init__.py # ENTITY_GENERATORS маппинг ├── phone.py, email.py # Телефон, email ├── inn.py, ogrn.py, kpp.py # ИНН, ОГРН, КПП ├── bik.py, accounts.py # БИК, счета (р/с, к/с) ├── passport.py # Паспорт ├── company.py, person.py # Компания, ФИО └── address.py # Адрес site/ # Flask-приложение ├── app.py # create_app() + VERSION (20 строк) ├── routes/ │ ├── __init__.py # register_routes() │ ├── main_bp.py # GET / │ ├── health_bp.py # GET /health │ └── api_bp.py # POST /api/drhider ├── templates/index.html └── static/favicon.svg ``` ### Что изменилось | Было | Стало | |---|---| | `drhider.py` — 560 строк монолит | Пакет `drhider/` — 22 модуля по 20–100 строк | | `site/app.py` — 100 строк (всё в одном файле) | `app.py` 33 строки + 3 blueprint'а по 20–50 строк | | `Dockerfile` | Удалён (Штурвал сам) | | `drhider_server.py` | Удалён (Flask заменяет) | ### Коммиты - `a2f754a` — Фаза 1: удалён Dockerfile, drhider_server.py, gunicorn - `37581eb` — Фаза 2: config.py, checksum.py, random_utils.py, generators/ - `2cf4e08` — Фаза 2: llm_client.py, extractor.py, scanner.py, replacer.py, builder.py, obfuscator.py - `51bc1a7` — Фаза 2: site/app.py → blueprint'ы, старый drhider.py удалён | Переменная | Значение | |---|---| | `LLM_API_KEY` | `sk-ucI5YvOticoOQ9Kuj5K9mQ` | | `LLM_URL` | `https://api.aillm.ru/v1/chat/completions` | | `LLM_MODEL` | `gpt-oss-120b` |