diff --git a/History/opus-dedup-2026-06-28.md b/History/opus-dedup-2026-06-28.md index 575d9f7..980c4ef 100644 --- a/History/opus-dedup-2026-06-28.md +++ b/History/opus-dedup-2026-06-28.md @@ -111,3 +111,56 @@ UPSERT по имени уже есть. Реальная проблема: **las 1. `documents.content_hash` + дедуп по нему на загрузке 2. Сортировка допников по `doc_date` 3. Опционально: `date_start` в `name_hash` + +--- + +## Ответ Opus — дополнительные засады (careless user) + +### 🔴 Критичное — «юзер грузит хуйню» + +**1. ZIP-бомба / нет лимитов.** unzip.py распаковывает всё без ограничений. Нужно: лимит ≤500 файлов, суммарный размер, проверка ratio. + +**2. Имена из ZIP без санитизации.** Path-traversal не отсекается для файлов из архива. Нужно: та же проверка `..`/`/` + cp437→utf8. + +**3. `try/except: pass` глушит ошибки удаления.** Минимум — логировать. + +**4. Ручной парс multipart по `PK\x03\x04`.** Хрупко. Лучше `cgi.FieldStorage`. + +### 🟠 Битый/мусорный контент + +**5. Supplement создаётся ДО парсинга.** Битый файл → висячий supplement. Нужно: не создавать при ошибке. + +**6. Пустой парсинг = тихо пропадает.** Скан/зашифрованный PDF → `elements_json` пуст → файл игнорируется без предупреждения. + +**7. Регистр/дубли имён.** `Договор.pdf` vs `договор.pdf` — разные документы. → закрыто `content_hash`. + +### 🟡 LLM возвращает мусор в ops + +**8. Пустой `target_hash` молча no-op.** → нужно `UNRESOLVED`. + +**9. ADD с пустым именем схлопывается.** → отбраковывать. + +**10. Неизвестный `action` молча игнорируется.** Опечатка LLM → без сигнала. + +**11. Арифметика только логируется.** `sum ≠ price*qty` — стоит флаг в UI. + +### 🟢 Числа, даты, нормализация + +**12. Локализованные числа теряются.** `"1 000,50"` → `None`. Нужна нормализация. + +**13. Даты без нормализации.** `01.01.2026` vs `2026-01-01`. Канонизировать перед хешем. + +### 🔵 Конкурентность + +**14. Гонка двух прогонов.** `reset()` без блокировки → каша. Нужен advisory-lock. + +**15. Нет идемпотентности батча.** → закрыто `content_hash`. + +### Приоритет + +1. Лимиты + санитизация ZIP (п.1,2,4) +2. `content_hash`-дедуп — ✅ уже сделано +3. Явный статус «не распознан» (п.5,6) +4. `UNRESOLVED` вместо тихих no-op (п.8,9,10) +5. Нормализация чисел/дат (п.12,13) +6. Advisory-lock (п.14) — при многопользовательности