# Анализ уязвимостей Event Sourcing — Gemini Web **Дата:** 2026-06-21 ## 🚨 Критические уязвимости ### 1. Race Condition в `seq` `apply_events.cfm` — `MAX(seq)` + `seq++` в цикле. При параллельных запросах — одинаковые seq. **Фикс:** `INSERT ... SELECT COALESCE(MAX(seq),0)+1` атомарно. ### 2. Опустошение контракта при full_replace `apply_events.cfm` — DELETE из spec_current ДО проверки что ops не пуст. LLM упала → спецификация стёрта. **Фикс:** валидация ops.length перед удалением. ### 3. Падение типизации price/qty `apply_events.cfm` — LLM может вернуть строку вместо числа. `cf_sql_float` падает. **Фикс:** `isNumeric()` перед float. ### 4. N+1 запросов в UPDATE `apply_events.cfm` — для каждого UPDATE отдельный SELECT. 200 позиций = 200 запросов. **Фикс:** один SELECT всех строк до цикла. ### 5. Построчный INSERT full_replace `apply_events.cfm` — цикл INSERT вместо массового. **Фикс:** `INSERT INTO ... SELECT`. ### 6. Хэш зависит от LLM-форматирования `apply_events.cfm` — `md5(lower(trim(name)) || date_start)`. LLM написала «Услуги» vs «Услуга» → разный хэш → ADD/DELETE вместо UPDATE. **Фикс:** LLM сама возвращает target_hash. ### 7. Несовместимость типов last_event_id `apply_events.cfm` — UUID пишется как `cf_sql_varchar`. **Фикс:** правильный UUID-тип. ## Файлы для анализа | Файл | Роль | |------|------| | `contractor/apply_events.cfm` | Транзакционное применение ops | | `contractor/db.cfc` | Схема таблиц spec_events, spec_current | | `contractor/deploy/llm_prompt.py` | Промпты LLM (ВМ) | | `contractor/deploy/convert_server.py` | SSE + вызов LLM + apply_events (ВМ) | | `contractor/index.cfm` | UI, EventSource, раздел сравнения |