From c45274227193b4fb431f51f5a9c04c0c3810a66e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 29 Jun 2026 14:17:08 +0400 Subject: [PATCH] docs: Opus prompt for DrHider obfuscation service --- History/opus-drhider-request-2026-06-29.md | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 History/opus-drhider-request-2026-06-29.md diff --git a/History/opus-drhider-request-2026-06-29.md b/History/opus-drhider-request-2026-06-29.md new file mode 100644 index 0000000..2f29348 --- /dev/null +++ b/History/opus-drhider-request-2026-06-29.md @@ -0,0 +1,108 @@ +# Задание Opus — сервис обфускации документов «DrHider» + +Дата: 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 с колонтитулами)