Add ProfileSyncMiddleware to keep user profile data updated in the database

- Integrated ProfileSyncMiddleware to ensure that user profile information (username, first_name, last_name) remains current in the database.
- Updated get_enhanced_user_statistics to use timezone-aware datetime for accurate SQL queries, preventing naive/aware comparison issues.
- Clarified comments in the user statistics function for better understanding of active user metrics and subscription handling.
This commit is contained in:
machka-pasla
2025-08-15 23:40:23 +03:00
parent 13a9e58e27
commit a75a1f483c
9 changed files with 227 additions and 7 deletions
+47
View File
@@ -0,0 +1,47 @@
import logging
from typing import Callable, Dict, Any, Awaitable, Optional
from aiogram import BaseMiddleware
from aiogram.types import Update, User as TgUser
from sqlalchemy.ext.asyncio import AsyncSession
from db.dal import user_dal
class ProfileSyncMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[Update, Dict[str, Any]], Awaitable[Any]],
event: Update,
data: Dict[str, Any],
) -> Any:
session: AsyncSession = data.get("session")
tg_user: Optional[TgUser] = data.get("event_from_user")
if session and tg_user:
try:
db_user = await user_dal.get_user_by_id(session, tg_user.id)
if db_user:
update_payload: Dict[str, Any] = {}
if db_user.username != tg_user.username:
update_payload["username"] = tg_user.username
if db_user.first_name != tg_user.first_name:
update_payload["first_name"] = tg_user.first_name
if db_user.last_name != tg_user.last_name:
update_payload["last_name"] = tg_user.last_name
if update_payload:
await user_dal.update_user(session, tg_user.id, update_payload)
logging.info(
f"ProfileSyncMiddleware: Updated user {tg_user.id} profile fields: {list(update_payload.keys())}"
)
except Exception as e:
logging.error(
f"ProfileSyncMiddleware: Failed to sync profile for user {getattr(tg_user, 'id', 'N/A')}: {e}",
exc_info=True,
)
return await handler(event, data)