v1.7.1: fix all P1-P4, C1-C6, H1-H6, M1-M7, L1-L3 from error.md — async migrations, CSS variables, SQL validation, event loop, prompt injection, VCF parsing, race conditions, unused imports, gitignore

This commit is contained in:
2026-05-29 03:46:41 +03:00
parent 72b6879f4b
commit 54af5892d5
21 changed files with 406 additions and 156 deletions
+43 -47
View File
@@ -5,7 +5,6 @@ from app.database import async_session
from app.models import BotUser, BotConversation, BotMessage, BotTicket, BotTicketMessage, BotTicketStatus
from app.max_api import max_api
from app.settings_cache import settings_cache
from app.config_reader import config_reader
from app.email_sender import email_sender
logger = logging.getLogger(__name__)
@@ -22,66 +21,61 @@ async def handle_inquiry(user_id: int, conv_id: int, text: str) -> None:
user_result = await db.execute(select(BotUser).where(BotUser.id == user_id))
user = user_result.scalar_one_or_none()
if not user:
await max_api.send_message(
user_id,
"Произошла ошибка при обработке запроса. Пожалуйста, попробуйте ещё раз позже.",
)
return
conv.inquiry_text = text
conv.state = "escalated"
await _finalize_ticket_in_tx(db, user_id, conv, user, text)
await db.commit()
await _finalize_ticket(user_id, conv, user, text)
async def _finalize_ticket(
async def _finalize_ticket_in_tx(
db,
user_id: int,
conv: BotConversation,
user: BotUser,
inquiry_text: str,
) -> None:
async with async_session() as db:
user_name = user.first_name or user.last_name or ""
ticket_title = f"Обращение от {user_name or 'клиента'} ({user_id})"
if len(inquiry_text) > 100:
ticket_title = inquiry_text[:97] + "..."
user_name = user.first_name or user.last_name or ""
ticket_title = f"Обращение от {user_name or 'клиента'} ({user_id})"
if len(inquiry_text) > 100:
ticket_title = inquiry_text[:97] + "..."
ticket = BotTicket(
user_id=user_id,
title=ticket_title,
description=inquiry_text,
priority="normal",
status="Новая",
created_by="bot",
)
db.add(ticket)
await db.commit()
await db.refresh(ticket)
ticket = BotTicket(
user_id=user_id,
title=ticket_title,
description=inquiry_text,
priority="normal",
status="Новая",
created_by="bot",
)
db.add(ticket)
await db.flush()
msg = BotTicketMessage(
ticket_id=ticket.id,
direction="incoming",
text=inquiry_text,
)
db.add(msg)
msg = BotTicketMessage(
ticket_id=ticket.id,
direction="incoming",
text=inquiry_text,
)
db.add(msg)
status_log = BotTicketStatus(
ticket_id=ticket.id,
new_status="Новая",
changed_by="bot",
)
db.add(status_log)
status_log = BotTicketStatus(
ticket_id=ticket.id,
new_status="Новая",
changed_by="bot",
)
db.add(status_log)
conv_result = await db.execute(
select(BotConversation).where(BotConversation.id == conv.id)
)
conv_obj = conv_result.scalar_one_or_none()
if conv_obj:
conv_obj.state = "completed"
conv.state = "completed"
await db.commit()
async with async_session() as db2:
user_obj = await db2.get(BotUser, user_id)
if user_obj:
user_obj.total_tickets = (user_obj.total_tickets or 0) + 1
await db2.commit()
user.total_tickets = (user.total_tickets or 0) + 1
user_info = f"ID: {user_id}\nИмя: {user.first_name or 'не указано'} {user.last_name or ''}"
contact = user.phone or "не указан"
@@ -93,14 +87,16 @@ async def _finalize_ticket(
"Обращение через Виртуального помощника AegisOne Engineering",
)
email_sender.send_ticket_escalation(
import asyncio
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, lambda: email_sender.send_ticket_escalation(
to=support_email,
subject=email_subject,
user_info=user_info,
contact=contact,
inquiry=inquiry_text,
history=history,
)
))
await max_api.send_message(
user_id,