Files
site_aegisone/py_service/sql/v1.5.0_migration.sql
T
angel 72b6879f4b v1.7.0: refactor max_bot to flat structure, add VCF+UserModel+NLP history context, portal pages and proxy fixes
- Refactored max_bot from nested packages to flat module structure
- Q2: Extended BotUser model (patronymic, email, org, address, vcf_raw, contact_hash, phone_verified, email_verified, last_interaction, total_conversations, total_tickets)
- Q2: VCF parser (FN, N, TEL, EMAIL, ORG, ADR), upsert on re-contact, NLP history context (_get_user_history_context -> YandexGPT)
- Q1: Broadcast preview modal with 10s confirmation timer
- Q3: CSS var(--white)->var(--bg-card), var(--text)->var(--text-primary)
- Q4: bot_settings showNotification(), editable max_bot_id
- Q5: Webhook secret passthrough via X-Max-Bot-Api-Secret
- Masking sensitive keys, dialog_cleared handler, migrate via _add_column_if_not_exists()
- Rate limit (asyncio.sleep 0.5 per 10), dead code removed, conv.intent context in contact.py
- Portal pages: bot_consent, bot_kb (edit), bot_settings, bot_test, bot_tickets, portal_settings
- Tests: 21/21 passing, added test_yandex_gpt.py, test_email_sender.py
- Deploy: deploy_full.sh, schema.sql, seed_knowledge_base.sql
2026-05-29 02:30:30 +03:00

99 lines
6.1 KiB
SQL

-- Migration for v1.5.0: Yandex Disk integration + SLA Tickets + MAX notifications
-- File sync queue
CREATE TABLE IF NOT EXISTS file_sync_queue (
id SERIAL PRIMARY KEY,
local_path VARCHAR(500) NOT NULL,
remote_path VARCHAR(500) DEFAULT '',
entity_type VARCHAR(50) NOT NULL,
entity_id INTEGER NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','uploading','synced','error')),
error TEXT DEFAULT '',
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_file_sync_status ON file_sync_queue(status);
CREATE INDEX IF NOT EXISTS idx_file_sync_entity ON file_sync_queue(entity_type, entity_id);
-- Bot tickets
CREATE TABLE IF NOT EXISTS bot_tickets (
id SERIAL PRIMARY KEY,
ticket_number VARCHAR(20) UNIQUE NOT NULL,
user_id INTEGER REFERENCES bot_users(id) ON DELETE SET NULL,
object_id INTEGER REFERENCES objects(id) ON DELETE SET NULL,
customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
title VARCHAR(500) NOT NULL,
description TEXT DEFAULT '',
priority VARCHAR(20) DEFAULT 'normal' CHECK (priority IN ('low','normal','high','urgent')),
status VARCHAR(20) NOT NULL DEFAULT 'open' CHECK (status IN ('open','in_progress','resolved','closed')),
created_by VARCHAR(20) DEFAULT 'bot',
assigned_to INTEGER REFERENCES users(id) ON DELETE SET NULL,
sla_contract_id INTEGER REFERENCES sla_contracts(id) ON DELETE SET NULL,
has_attachment BOOLEAN DEFAULT FALSE,
attachment_type VARCHAR(50) DEFAULT '',
attachment_path VARCHAR(500) DEFAULT '',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
resolved_at TIMESTAMP NULL,
closed_at TIMESTAMP NULL
);
CREATE INDEX IF NOT EXISTS idx_bot_ticket_status ON bot_tickets(status);
CREATE INDEX IF NOT EXISTS idx_bot_ticket_user ON bot_tickets(user_id);
CREATE INDEX IF NOT EXISTS idx_bot_ticket_object ON bot_tickets(object_id);
CREATE INDEX IF NOT EXISTS idx_bot_ticket_number ON bot_tickets(ticket_number);
-- Bot ticket messages
CREATE TABLE IF NOT EXISTS bot_ticket_messages (
id SERIAL PRIMARY KEY,
ticket_id INTEGER REFERENCES bot_tickets(id) ON DELETE CASCADE,
direction VARCHAR(3) NOT NULL CHECK (direction IN ('in','out')),
text TEXT DEFAULT '',
has_attachment BOOLEAN DEFAULT FALSE,
attachment_path VARCHAR(500) DEFAULT '',
sender VARCHAR(20) DEFAULT 'client',
timestamp TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_bot_ticket_msg_ticket ON bot_ticket_messages(ticket_id);
-- Bot ticket status log
CREATE TABLE IF NOT EXISTS bot_ticket_statuses (
id SERIAL PRIMARY KEY,
ticket_id INTEGER REFERENCES bot_tickets(id) ON DELETE CASCADE,
old_status VARCHAR(20) DEFAULT '',
new_status VARCHAR(20) NOT NULL,
changed_by VARCHAR(20) DEFAULT 'system',
timestamp TIMESTAMP NOT NULL DEFAULT NOW(),
comment TEXT DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_bot_ticket_status_log ON bot_ticket_statuses(ticket_id);
-- Add max_user_id to users table
ALTER TABLE users ADD COLUMN IF NOT EXISTS max_user_id BIGINT NULL;
-- Add Yandex Disk settings
INSERT INTO bot_settings (key, value, description) VALUES
('yandex_disk_token', 'y0__wgBEMHM9zsYiuxBIMi6sswXML_twIQIyCDWBrrNPjQcoQZR6J2x57oBLcg', 'OAuth токен Яндекс Диска'),
('yandex_disk_root', '/AegisOne_Service', 'Корневая папка на Яндекс Диске'),
('yandex_disk_client_id', '00fd594faf604161b773a53737bb5462', 'Client ID приложения Яндекс'),
('yandex_disk_client_secret', '32a46b6dfd3c499e8cced25fed64b426', 'Client Secret приложения Яндекс'),
('storage_backend', 'yandex', 'Режим хранения: local/yandex/both'),
('max_file_size_mb', '100', 'Максимальный размер файла (MB)'),
('public_link_expiry_days', '30', 'Срок публичных ссылок по умолчанию (дни)'),
('auto_archive_enabled', 'true', 'Авто-архивация закрытых обращений'),
('auto_archive_after_days', '30', 'Через сколько дней архивировать'),
('max_group_chat_id', '', 'ID группового чата MAX для уведомлений')
ON CONFLICT (key) DO NOTHING;
-- Add SLA Ticket feature
INSERT INTO bot_features (feature_key, name, description, enabled, sort_order) VALUES
('sla_ticket', 'Заявка по SLA', 'Подать заявку о неисправности для клиентов с активным SLA', true, 0)
ON CONFLICT (feature_key) DO NOTHING;
-- Add ticket-related response templates
INSERT INTO bot_response_templates (template_key, template_text, description, variables) VALUES
('sla_ticket_check', 'Проверяю ваш SLA контракт...', 'Проверка SLA перед созданием заявки', '[]'),
('sla_ticket_found', 'SLA найден: {object_name}, уровень: {service_level}. Опишите неисправность. Вы можете прикрепить фото или документ.', 'SLA найден, запрос описания', '["object_name","service_level"]'),
('sla_ticket_not_found', 'SLA контракт не найден или не активен. Свяжитесь с нами:\n\n📞 {phone_1}\n📞 {phone_2}\n✉️ {support_email}', 'SLA не найден', '["phone_1","phone_2","support_email"]'),
('sla_ticket_created', 'Заявка #{ticket_number} создана.\n\nПриоритет: {priority}\nОжидаемое время реакции: {response_time}\n\nИнженер будет назначен в ближайшее время.', 'Подтверждение создания заявки', '["ticket_number","priority","response_time"]'),
('ticket_status_update', 'Ваша заявка #{ticket_number} — {status}.\nИнженер: {engineer}', 'Уведомление о смене статуса заявки', '["ticket_number","status","engineer"]'),
('ticket_resolved', 'Заявка #{ticket_number} выполнена. Оцените качество:\n\n⭐ 1 — Плохо\n⭐⭐ 2\n⭐⭐⭐ 3\n⭐⭐⭐⭐ 4\n⭐⭐⭐⭐⭐ 5 — Отлично', 'Запрос оценки после выполнения', '["ticket_number"]')
ON CONFLICT (template_key) DO NOTHING;