111 lines
8.3 KiB
Markdown
111 lines
8.3 KiB
Markdown
# Задание Opus — сервис обфускации документов «DrHider»
|
||
|
||
Файл: `/home/naeel/nubes/contracts/contracts-flask/History/opus-drhider-request-2026-06-29.md`
|
||
|
||
Дата: 29.06.2026
|
||
|
||
## Контекст
|
||
|
||
Есть работающий сервис сверки договоров (https://contracts.kube5s.ru/docs/pipeline):
|
||
- Загрузка .docx/.pdf/.doc/zip
|
||
- Парсинг → классификация → группировка → LLM-сравнение → результат
|
||
|
||
Пользователь (юрист) загружает реальные документы с чувствительными данными.
|
||
Даже в закрытом контуре он может не хотеть передавать реальные ФИО/телефоны/адреса/названия компаний.
|
||
|
||
## Задача
|
||
|
||
Сделать **DrHider** — сервис обфускации документов перед загрузкой в основной сервис.
|
||
|
||
**URL:** `https://contractor.pythonk8s.services.ngcloud.ru/DrHider`
|
||
|
||
**UI:** такая же страница загрузки, как в основном сервисе (выбор файлов, drag&drop, прогресс).
|
||
|
||
**На вход:** те же форматы — .docx, .pdf, .doc, .zip (с файлами внутри).
|
||
|
||
**На выходе:** ZIP-архив, содержащий:
|
||
1. Обфусцированные файлы (те же имена, то же форматирование)
|
||
2. `mapping.csv` — таблица соответствия: `тип_данных, оригинал, замена`
|
||
|
||
**Требования к обфускации:**
|
||
|
||
1. **Согласованность (главное):** одна и та же сущность во всех документах заменяется на одно и то же фиктивное значение. «Иванов И.И.» везде → «Смирнов А.Б.». «ООО Ромашка» везде → «ООО Василёк». Иначе группировка и сравнение сломаются.
|
||
|
||
2. **Что заменять:**
|
||
- ФИО физических лиц
|
||
- Названия компаний/контрагентов (ООО, ЗАО, ИП и т.д.)
|
||
- Телефоны (+7, 8-800, городские)
|
||
- Email-адреса
|
||
- Почтовые и юридические адреса
|
||
- ИНН, ОГРН, КПП, расчётные счета, БИК
|
||
- Паспортные данные (серия/номер)
|
||
- Номера договоров? (спорно — они нужны для группировки. Может, заменять с сохранением уникальности?)
|
||
|
||
3. **Что НЕ заменять:**
|
||
- Названия услуг (colocation, аренда стойки, etc.)
|
||
- Цены, количества, суммы (это предмет сверки)
|
||
- Даты (важны для порядка допников)
|
||
- Единицы измерения (шт., м², кВт·ч)
|
||
|
||
4. **Качество замены:**
|
||
- Имена → случайные русские ФИО (из словаря имён/фамилий)
|
||
- Компании → случайные названия ООО (из словаря или генерированные)
|
||
- Телефоны → валидные номера того же формата (+7 9XX ...)
|
||
- Email → валидные адреса на фиктивных доменах
|
||
- Адреса → правдоподобные (город из словаря + улица + дом)
|
||
- ИНН/ОГРН → валидные контрольные суммы
|
||
|
||
5. **Формат .docx:** сохранить стили, таблицы, форматирование. Замена — поиск-замена по тексту внутри XML (python-docx).
|
||
|
||
6. **Формат .pdf:** сложнее — pdfplumber только читает. Для записи нужно: либо (а) pymupdf/fitz для редактирования текста, либо (б) сгенерировать новый PDF из извлечённого текста с заменами. Какой подход для MVP?
|
||
|
||
7. **ZIP на выходе:** запаковать обфусцированные файлы + mapping.csv в один ZIP.
|
||
|
||
## Интеграция с основным сервисом
|
||
|
||
Обфусцированные файлы должны корректно проходить основной пайплайн:
|
||
- Парсинг — ОК (форматы те же)
|
||
- Классификация — ОК (обфусцированные названия компаний, но номера договоров узнаваемы)
|
||
- Группировка — ОК (parent_number сохраняется)
|
||
- LLM-сравнение — ОК (ADD/UPDATE/DELETE по услугам, просто имена компаний заменены)
|
||
|
||
## Архитектурные вопросы
|
||
|
||
**⛔ КРИТИЧЕСКОЕ ТРЕБОВАНИЕ: никаких следов реальных документов.**
|
||
|
||
- **Без БД.** Вся обработка — в оперативной памяти. Никакого хранения.
|
||
- **Без временных файлов с реальными данными.** Файлы читаются в память, обрабатываются, результат пишется. Промежуточные файлы на диске — только обфусцированные.
|
||
- **Без логирования реальных данных.** Логи — только «обработано N файлов», без содержимого.
|
||
- **Поток:** загрузка → двухпроходная обработка в памяти → ZIP на выходе → HTTP-ответ → очистка памяти.
|
||
- **mapping.csv** — единственное место где реальные данные «сохраняются», и то внутри ZIP, который уходит пользователю. На сервере не остаётся.
|
||
- **После завершения запроса:** вся память освобождается, временная директория (если была) — удаляется.
|
||
|
||
1. **Где исполняется?** Варианты:
|
||
- На VM (рядом с convert_server.py) — тот же стек, проще интеграция
|
||
- Отдельный managed-сервис — отдельный деплой, изоляция
|
||
|
||
2. **Обнаружение сущностей:** как находить что заменять?
|
||
- Regex-паттерны (телефоны, email, ИНН — однозначно)
|
||
- NER через LLM? (найти ФИО, компании, адреса в тексте)
|
||
- Гибрид: regex для формальных, LLM для имён/адресов?
|
||
|
||
3. **Согласованность замены:** как обеспечить сквозную замену?
|
||
- Глобальный словарь mapping в памяти на время обработки
|
||
- Сначала просканировать все файлы → собрать все сущности → сгенерировать замены → применить
|
||
|
||
4. **API или отдельная страница?**
|
||
- Отдельная HTML-страница с upload-формой (как index.html)
|
||
- Или API-endpoint `/api/drhider` на VM, вызываемый с Flask-фронтенда
|
||
|
||
5. **PDF-запись:** pymupdf (AGPL, лицензия!) или другой способ?
|
||
|
||
## Ожидаемый ответ
|
||
|
||
1. **Детальный план:** архитектура, компоненты, поток данных
|
||
2. **Способ обнаружения сущностей:** regex + NER? только regex на MVP?
|
||
3. **PDF-запись:** pymupdf или альтернатива?
|
||
4. **Согласованность:** алгоритм двухпроходного сканирования
|
||
5. **Интеграция:** где код, как связать с основным сервисом
|
||
6. **MVP — что в первой версии, что потом**
|
||
7. **Риски:** где может сломаться (например, PDF с текстом в кривых кодировках, docx с колонтитулами)
|