# DrHider — обфускация документов (Managed Flask) **URL:** https://drhider.pythonk8s.dev.nubes.ru/ **Репозиторий:** https://gitea.services.ngcloud.ru/Nail/drhider **Платформа:** Штурвал (Managed Flask на pythonk8s) **Дизайн фронтенда:** `/home/naeel/nubes/design/` --- ## Что делает Загружаешь документы (.docx, .pdf, .txt, .zip) — получаешь ZIP с обфусцированными копиями. Все персональные данные, реквизиты, телефоны, email заменяются на фиктивные. В архиве — mapping.csv с таблицей замен (оригинал → фиктивное). Обфускация двухпроходная: 1. **Проход 1 (сбор):** regex + LLM находят все сущности во всех файлах → глобальный словарь замен 2. **Проход 2 (замена):** применяем замены ко всем файлам → ZIP Согласованность: одна и та же сущность во всех файлах → одно и то же фиктивное значение. --- ## ⛔ ПРАВИЛА ДЛЯ АГЕНТОВ (читать перед ЛЮБЫМ действием) ### 1. НЕ смотреть локальные папки contracts/contracts-flask Весь старый код drhider — ТОЛЬКО на ВМ (`5.172.178.213`). НЕ локально. Единственное исключение: `/home/naeel/nubes/loadtest/` (образец структуры managed Flask). ### 2. Штурвал запускает Flask САМ - БЕЗ Dockerfile (удалён) - БЕЗ gunicorn (нет в requirements.txt) - Точка входа: `site/app.py` → `app = create_app()` - Деплой: `git push origin master` → авто-деплой в UI Штурвала ### 3. НЕ менять код без «делай» Даже если ошибка очевидна. Показать → описать → ЖДАТЬ. ### 4. После ЛЮБОЙ правки: ```bash python3 -c "import py_compile; py_compile.compile('файл.py', doraise=True)" git add -A && git commit -m "подробное описание" && git push ``` ### 5. Документировать ВСЁ в History/ Каждое изменение, план, ошибку — в отдельный .md файл. --- ## Структура проекта ### `drhider/` — пакет ядра обфускации | Файл | Назначение | Строк | |---|---|---| | `__init__.py` | re-export: `obfuscate_files`, `LLMClient`, `TwoPassObfuscator` | 10 | | `config.py` | Константы: regex-паттерны (ENTITY_PATTERNS, COMPANY_PATTERN, PERSON_PATTERN), словари имён/городов/улиц | 80 | | `checksum.py` | Контрольные суммы: ИНН10, ИНН12, ОГРН | 60 | | `random_utils.py` | Утилиты: `random_digits`, `random_letters` | 20 | | `llm_client.py` | LLMClient — HTTP-клиент к LLM API (aillm.ru) | 50 | | `extractor.py` | Извлечение текста из .docx/.pdf/.txt + `expand_zips` + `convert_pdfs_to_docx` | 180 | | `scanner.py` | Проход 1: `scan_regex` (regex) + `scan_llm_ner` (LLM NER) | 110 | | `replacer.py` | Проход 2: `apply_replacements`, `replace_in_docx`, `replace_in_text` | 100 | | `builder.py` | Сборка: `build_zip`, `build_mapping_csv` | 65 | | `obfuscator.py` | `TwoPassObfuscator` — оркестратор + `obfuscate_files()` | 100 | ### `drhider/generators/` — генераторы фиктивных значений Каждый файл — один генератор (10–40 строк). Интерфейс: `generate_xxx(original: str) -> str`. | Файл | Что генерирует | |---|---| | `phone.py` | +7 (XXX) XXX-XX-XX | | `email.py` | user@fake-domain | | `inn.py` | ИНН 10 и 12 знаков (с контрольной суммой) | | `ogrn.py` | ОГРН 13 знаков | | `kpp.py` | КПП 9 знаков | | `bik.py` | БИК 9 знаков (04XXXXXXX) | | `accounts.py` | Расчётный счёт (40702...) + корр. счёт (30101...) | | `passport.py` | Паспорт (XX XX XXXXXX) | | `company.py` | ООО/ЗАО/АО «СлучайноеНазвание» | | `person.py` | Фамилия И.О. | | `address.py` | Город, ул. Улица, д. N | `__init__.py` содержит `ENTITY_GENERATORS` — маппинг `entity_type → генератор`. ### `site/` — Flask-приложение | Файл | Назначение | |---|---| | `app.py` | `create_app()` — создание Flask, регистрация blueprint'ов, VERSION | | `routes/__init__.py` | `register_routes(app)` | | `routes/main_bp.py` | `GET /` — HTML-интерфейс | | `routes/health_bp.py` | `GET /health` — `{"ok": true, "version": "..."}` | | `routes/api_bp.py` | `POST /api/drhider` — multipart files → ZIP | | `templates/index.html` | UI (выбор файлов, прогресс, скачивание) | | `static/favicon.svg` | Иконка | ### Корневые файлы | Файл | Назначение | |---|---| | `requirements.txt` | `flask`, `python-docx`, `pdfplumber`, `httpx` | | `.gitignore` | `__pycache__/`, `*.pyc`, `.env` | | `.gitea/workflows/deploy.yaml` | CI: валидация Python | | `History/` | Документация всех изменений | | `README.md` | Этот файл | | `docs/ARCHITECTURE.md` | Архитектура | | `docs/DEPLOY.md` | Деплой, ВМ, переменные окружения | | `docs/DEVELOPMENT.md` | Порядок действий при изменении кода | --- ## API | Метод | Путь | Что делает | |---|---|---| | `GET` | `/` | HTML-интерфейс | | `GET` | `/health` | `{"ok": true, "version": "2.0.0"}` | | `POST` | `/api/drhider` | multipart/form-data (поле `files`) → `application/zip` | --- ## Переменные окружения (Штурвал) | Переменная | Значение | |---|---| | `LLM_API_KEY` | `sk-ucI5YvOticoOQ9Kuj5K9mQ` | | `LLM_URL` | `https://api.aillm.ru/v1/chat/completions` | | `LLM_MODEL` | `gpt-oss-120b` | --- ## Связь с ВМ contracts (legacy) На ВМ `5.172.178.213` (contracts.kube5s.ru) есть старая версия drhider: - `drhider_server.py` на порту 8767 — standalone HTTP-сервер - `drhider.py` — та же логика, что и в этом проекте (скопирована оттуда) Этот проект (`drhider.pythonk8s.dev.nubes.ru`) — **независимый managed Flask**, заменяет ВМ-версию. SSH к ВМ: `ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213`