# Сводка сессии 2026-08-26 — contracts-flask (тесты + чистка + стресс) ## 1. Фикс логики сверки (v2.0.15 → v2.0.16) - **`full_replace` дублировал строки**: `reset()` чистил `spec_current` только на старте пайплайна, а `full_replace` (все ADD) применялся поверх старых строк → дубли. - Фикс: `db/spec_events.py::clear_current()` (чистит только `spec_current`, история `spec_events` сохраняется) + вызов в `process.py` при `mode == "full_replace"`. - Коммит `021c925`, запушено, прод передеплоен → `2.0.16`. - Детали: `History/2026-08-26-full-replace-fix.md`. ## 2. Документация - Архитектура: `DOC/architecture-contracts-flask.md` (актуальная, VM-буфер, клиентский ZIP). - Корневой `README.md` — подробный, со ссылкой на архитектуру. ## 3. Тесты ### Удалены старые (коммит `9a8ae0a`) - `deploy/tests/` (unit/pipeline/integration + `test_drhider.py`), `deploy/conftest.py`, `deploy/tests.js` — ссылались на старую `compare/`-архитектуру. ### Новые юнит/интеграционные (коммиты `8f8fabf`, `3b259cf`) - 13 файлов в `contracts-flask/tests/` + `conftest.py` (изоляция БД) + `README.md`. - Покрытие: metrics, grouping, llm_client, llm, classify, parse, connection, spec_events, spec_current, process_pipeline, routes. - **92 passed** (после чистки legacy; было 102). ### Нагрузочные (маркер `load`, коммиты `b7d60e1`, `08f7e3f`, `6fcbbdd`) - `tests/load/test_load_pipeline.py` — 100 контрактов × 20 допников × 10 услуг. - `tests/load/test_load_apply_ops.py` — 5000 ADD/UPDATE/DELETE. - `tests/load/test_load_concurrency.py` — конкурентная запись SQLite. - `tests/load/stress_http.py` — standalone HTTP-стресс. - Полный прогон: not-load 102 passed, load 3 passed (~3 мин). ### Находка №1: SQLite `database is locked` (коммит `08f7e3f`) - 16 конкурентных писателей → `database is locked`; 8 — нестабильно; **4 — стабильно** (= `MAX_WORKERS` приложения). Для текущего сценария (один пользователь) некритично. - `History/2026-08-26-load-sqlite-locked.md`. ## 4. Стресс-тест прода (коммит `08e8e3a`) - Прод: `contractor.pythonk8s.dev.nubes.ru`, под `pythonk8s` (cpu 1, mem 1Gi). - Прямой POST 100KB → **83% таймаутов** (шлюз рвёт >64KB) — подтверждён предел платформы, поэтому и существует VM-буфер. - Реальный файл 30KB → 200/200 ok (rps 10), под CPU 899m / MEM 520Mi, без OOM. - `History/2026-08-26-stress-100kb-gateway.md`. ## 5. Чистка мёртвого legacy-кода (коммит `aa58522`) - Удалены `POST /upload`, `POST /unzip-upload`, `_check_ext`, `_unzip`, `ALLOWED`, пустой blueprint, константы фронта `UPLOAD_URL`/`CONVERT_URL`/`UNZIP_URL`. - Загрузка теперь ТОЛЬКО через ВМ (`/api/upload_refs` → `contracts_upload_sink`). - `History/2026-08-26-cleanup-legacy-upload.md`. ## Хвосты / открытые вопросы 1. ~~`tests/load/stress_http.py` бьёт по удалённому `/upload`~~ — переписан на VM-путь (`PUT` ВМ → `/api/upload_refs`). 2. Прод-риск `database is locked` при конкурентных сверках — отложен (нет мультитенантности). 3. E2E с реальным LLM (`gpt-oss-120b`) на проде — не проверялся автоматически (тесты на Fake LLM).