# Changelog — AegisOne MAX Bot ## 1.7.1 (29.05.2026) ### Исправления - **P1 (CRITICAL):** _add_column_if_not_exists — async def + await, миграции выполняются - **P2 (CSS):** bot_consent, bot_tickets, bot_kb, bot_settings — var(--light-bg) → var(--bg-card), хардкод цвета → CSS-переменные - **P3 (Event loop):** email_sender.send_ticket_escalation — обёрнут в run_in_executor - **P4 (SQL injection):** _add_column_if_not_exists — валидация _validate_sql_name/type - **C1 (CRITICAL):** BotConversation импортирован в main.py - **C2 (VCF N-field):** regex исправлен, захватывает полную строку N: - **C3 (Email typo):** contact.py — user.email вместо user.phone - **C4 (None user):** inquiry.py — проверка user is None - **C5 (Висячий тикет):** inquiry.py — flush + единый commit - **C6 (Secrets):** docker-compose.yml — переменные через .env - **H1 (Prompt injection):** yandex_gpt.py — instruction boundary, _sanitize_input - **H2 (Дубль BotMessage):** contact.py — удалён дублирующий save - **H3 (VCF phone regex):** расширен захват полного номера - **H4 (Race condition):** greeting.py — try/except + rollback при IntegrityError - **H5 (Silent error):** email_sender.py — logger.error добавлен - **M1 (TOCTOU):** main.py — audit-log только при изменении статуса - **M2 (Двухсессионный дизайн):** inquiry.py — единая транзакция - **M3 (Stale state):** greeting.py — conv из текущей сессии - **M4 (Double-load race):** settings_cache.py — asyncio.Lock - **M5 (ORG regex):** захват полного ORG без обрезки по ; - **M7 (bot_test.html):** тема наследуется через CSS-переменные + скрипт инициализации - **L1 (Dead code):** _extract_name_from_vcf удалена - **L2 (Импорты):** неиспользуемые Optional, json, config_reader удалены - **L3 (.gitignore):** .opencode/, .env.example добавлены ## 1.7.0 (29.05.2026) ### Новые функции - **Рефакторинг архитектуры:** плоская структура модулей (models.py, yandex_gpt.py, keyboards.py, email_sender.py, config_reader.py) вместо вложенных пакетов - **VCF + User Model (Q2):** - BotUser расширен: patronymic, email, organization, address, vcf_raw, contact_hash, phone_verified, email_verified - VCF-парсер: FN, N, TEL, EMAIL, ORG, ADR — все поля сохраняются - Upsert пользователя при повторном контакте (greeting.py) - total_conversations инкремент, last_interaction обновление - handle_contact_share сохраняет все VCF-поля (handoff.py) - total_tickets инкремент в _finalize_ticket (inquiry.py) - **NLP history context:** _get_user_history_context() — последние 10 сообщений + открытые заявки → YandexGPT - **Broadcast с превью и таймером (Q1):** модалка подтверждения с таймером 10 секунд - **CSS-переменные (Q3):** var(--white)→var(--bg-card), var(--text)→var(--text-primary) - **bot_settings (Q4):** showNotification(), max_bot_id редактируемый - **Webhook secret (Q5):** проброс X-Max-Bot-Api-Secret через прокси - Маскировка sensitive API-ключей в /api/bot/settings - dialog_cleared handler — сброс состояния диалога - Миграции через _add_column_if_not_exists() — новые колонки BotUser - Rate limit в broadcast: asyncio.sleep(0.5) после каждых 10 - Уточнение сообщения (contact.py) с учётом conv.intent - Тесты: test_yandex_gpt.py, test_email_sender.py