"""Репозиторий администраторов веб-панели (Блок 4.2).""" from __future__ import annotations from typing import Any from common.db.pool import get_pool async def get_admin(telegram_id: int) -> dict[str, Any] | None: """Вернуть администратора по Telegram-ID (для проверки доступа).""" async with get_pool().connection() as conn: cur = await conn.execute( """ SELECT telegram_id, username, role, enabled, created_at, last_login_at FROM bot.admin_users WHERE telegram_id = %s """, (telegram_id,), ) return await cur.fetchone() async def ensure_admins(telegram_ids: list[int]) -> int: """Засеять администраторов из ADMIN_IDS (существующих не трогаем). Возвращает количество вставленных строк. """ if not telegram_ids: return 0 inserted = 0 async with get_pool().connection() as conn: for telegram_id in dict.fromkeys(telegram_ids): cur = await conn.execute( """ INSERT INTO bot.admin_users (telegram_id, role) VALUES (%s, 'admin') ON CONFLICT (telegram_id) DO NOTHING """, (telegram_id,), ) inserted += cur.rowcount or 0 return inserted async def touch_login(telegram_id: int) -> None: """Отметить успешный вход (не критично, ошибки не должны ломать логин).""" async with get_pool().connection() as conn: await conn.execute( "UPDATE bot.admin_users SET last_login_at = now() WHERE telegram_id = %s", (telegram_id,), ) async def list_admins() -> list[dict[str, Any]]: """Все администраторы веб-панели (для раздела «Админы»).""" async with get_pool().connection() as conn: cur = await conn.execute( """ SELECT telegram_id, username, role, enabled, created_at, last_login_at FROM bot.admin_users ORDER BY role, username NULLS LAST, telegram_id """ ) return await cur.fetchall() async def upsert_admin(telegram_id: int, username: str | None, role: str) -> None: """Добавить администратора или обновить имя/роль существующего.""" async with get_pool().connection() as conn: await conn.execute( """ INSERT INTO bot.admin_users (telegram_id, username, role, enabled) VALUES (%s, %s, %s, true) ON CONFLICT (telegram_id) DO UPDATE SET username = EXCLUDED.username, role = EXCLUDED.role, enabled = true """, (telegram_id, username, role), ) async def set_admin_role(telegram_id: int, role: str) -> bool: async with get_pool().connection() as conn: cur = await conn.execute( "UPDATE bot.admin_users SET role = %s WHERE telegram_id = %s", (role, telegram_id), ) return bool(cur.rowcount) async def set_admin_enabled(telegram_id: int, enabled: bool) -> bool: async with get_pool().connection() as conn: cur = await conn.execute( "UPDATE bot.admin_users SET enabled = %s WHERE telegram_id = %s", (enabled, telegram_id), ) return bool(cur.rowcount) async def delete_admin(telegram_id: int) -> bool: async with get_pool().connection() as conn: cur = await conn.execute("DELETE FROM bot.admin_users WHERE telegram_id = %s", (telegram_id,)) return bool(cur.rowcount)