docs: Opus — дополнительные засады (careless user, 15 пунктов)
This commit is contained in:
@@ -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) — при многопользовательности
|
||||
|
||||
Reference in New Issue
Block a user