diff --git a/site/templates/architect.html b/site/templates/architect.html index a44680b..eb680ce 100644 --- a/site/templates/architect.html +++ b/site/templates/architect.html @@ -163,16 +163,70 @@
ADD без имени услуги → UNRESOLVED (не применяется, помечается для ручной проверки)UPDATE/DELETE с пустым идентификатором → UNRESOLVEDsum = price × qty — расхождение → флагcontent_hash — один и тот же файл дважды не обрабатывается01.03.2026 → 2026-03-01 (авто-нормализация)1 000,50 → 1000.50 (авто-нормализация)| Угроза | +Защита | +
|---|---|
| ZIP-бомба (архив 1 KB → 10 GB) | +Лимит 500 файлов, 500 MB, ratio сжатия ≤ 100× | +
Path traversal в ZIP (../../etc/passwd) |
+ Проверка имени файла ДО os.path.basename |
+
| Битые кодировки имён в ZIP | +cp437 → utf8 перекодировка | +
| Файлы не-Word/PDF (exe, картинки, etc.) | +Whitelist: только pdf/docx/doc/zip — остальные unknown_format |
+
| Дубликаты файлов (тот же контент, другое имя) | +sha256(original_bytes) → пропуск с пометкой duplicate |
+
| Дубликаты услуг (одна услуга в разных допниках) | +UPSERT по name_hash (имя + дата начала) — разные периоды = разные строки |
+
| ADD без названия услуги | +→ UNRESOLVED, не применяется |
+
| UPDATE/DELETE без идентификатора цели | +Пустой target_hash → UNRESOLVED |
+
| Неизвестный тип операции от LLM | +→ UNRESOLVED |
+
Кривые числа (1 000,50) |
+ Авто-нормализация: пробелы → удалить, запятая → точка | +
Кривые даты (01.03.2026) |
+ Авто-нормализация: DD.MM.YYYY → YYYY-MM-DD | +
| Арифметические ошибки | +Проверка price × qty = sum — расхождение → флаг |
+
| Мусорные документы (счета, акты, платёжки) | +Трёхэтапный фильтр: имя файла → заголовки (2000 симв.) → LLM | +
Тихие ошибки (try/except: pass) |
+ Везде logging.warning с контекстом |
+
📋 Заказчик: «кривых документов можно ожидать.
@@ -233,11 +287,139 @@ -Встроенный редактор с историей версий: сохранил новую версию → она сразу используется LLM. Старые версии остаются в истории — можно откатиться.
+Встроенный редактор промптов с полным CRUD и историей версий:
++
- Создание, редактирование, удаление промптов — через веб-интерфейс
+- Активация версии — один клик, и она сразу используется LLM
+- История версий — все предыдущие редакции сохраняются, можно откатиться
+- Без правки кода и без редеплоя — юрист может сам экспериментировать с промптами
+
-8. Стек технологий
+8. Хранение документов конфиденциальность
+ ++📋 Заказчик: «Загрузка из локали, НЕ S3 (конфиденциальность).» ++ +Исходные файлы (.docx/.pdf/.doc/zip) НЕ сохраняются в БД. После загрузки и парсинга они удаляются с сервера. В БД хранятся только:
++
+- Метаданные: имя файла, дата, хеш содержимого
+- Результат парсинга:
+elements_json(текст и таблицы)- Результат классификации: тип, номер, дата, контрагент
+- События спецификации: ADD/UPDATE/DELETE
+Сами бинарные файлы на диске не остаются.
+ +
+ +9. Инженерные практики качество кода
+ +Decoupling — разделение ответственности
+Пайплайн разбит на независимые слои с чёткими интерфейсами:
+ ++
+ ++ +Слой +Что делает +Можно заменить отдельно ++ +Контракты данных +5 frozen dataclass'ов: +ParseResult,ClassifyResult,GroupingResult,BatchGroupingResult,CompareOpФормат данных не привязан к хранилищу ++ +LLM-клиент +Протокол +LLMClient.complete(prompt) → strHttpxLLMClient ↔ FakeLLMClient ↔ другая модель ++ +Репозиторий +Протокол +Repository(17 методов)PgRepository ↔ MemRepository (тесты) ++ +Загрузка ++ parse_multipart()— чистая функцияПарсер не зависит от HTTP-фреймворка ++ +Классификация ++ classify_batch(batch_id, llm_client, repo)— Dependency InjectionЛюбой LLM + любое хранилище +Dependency Injection
+Все внешние зависимости (LLM, БД) пробрасываются через параметры, а не через глобальные
+import:+
+ +- +
call_llm(prompt, llm_client=None)— DI с обратной совместимостью- +
classify_batch(batch_id, llm_client=None, repo=None)— можно подставить любой backend- В продакшене: HttpxLLMClient + PgRepository
+- В тестах: FakeLLMClient (record/replay) + MemRepository (в памяти)
+
+ +10. Тестирование 26/26 PASS
+ ++
+ ++ +Модуль +Тестов +Что проверяют ++ +Контракты + загрузка +13 +Создание dataclass'ов, garbage-фильтр, multipart-парсинг, path-traversal ++ +LLM + Репозиторий +9 +FakeLLMClient, MemRepository CRUD, все 17 методов ++ +Классификация +4 +Garbage по имени файла, garbage по заголовкам, classify с FakeLLM, no pending +Все тесты проходят без доступа к БД и LLM — через
+ +FakeLLMClient(record/replay) иMemRepository. Запуск:pytest deploy/tests/ -v.
+ +11. Изоляция окружений
+ ++
+ ++ +Окружение +URL +БД +Назначение ++ +Продакшен ++ contracts.kube5s.ru+ contractsРабочая система ++ +Тестовый ++ check.kube5s.ru+ contracts_checkОтладка, эксперименты — не затрагивает продакшен +Тестовое окружение — полная копия пайплайна на отдельном порту (8777) с отдельной БД. Можно загружать, классифицировать, сравнивать — не боясь испортить рабочие данные.
+ +
+ +12. Стек технологий
@@ -274,7 +456,7 @@
-9. Конечная цель будущее
+13. Конечная цель будущее
📋 Заказчик: «Конечная цель: построчное сравнение CRM ↔ фискальная система.
@@ -286,7 +468,7 @@ PAYG (суффикс -m) — особый случай. Сверку с CRM то
-10. Что дальше требует участия Заказчика
+14. Что дальше требует участия Заказчика
📋 Заказчик: «Это всё пока опыты и набивание шишек.
diff --git a/site/templates/index.html b/site/templates/index.html index 18ad417..adf5500 100644 --- a/site/templates/index.html +++ b/site/templates/index.html @@ -73,7 +73,7 @@