Files
remnawave-bedolaga-telegram…/app/database/crud/faq.py
Fringg eb18994b7d fix: complete datetime.utcnow() → datetime.now(UTC) migration
- Migrate 660+ datetime.utcnow() across 153 files to datetime.now(UTC)
- Migrate 30+ datetime.now() without UTC to datetime.now(UTC)
- Convert all 170 DateTime columns to DateTime(timezone=True)
- Add migrate_datetime_to_timestamptz() in universal_migration with SET LOCAL timezone='UTC' safety
- Remove 70+ .replace(tzinfo=None) workarounds
- Fix utcfromtimestamp → fromtimestamp(..., tz=UTC)
- Fix fromtimestamp() without tz= (system_logs, backup_service, referral_diagnostics)
- Fix fromisoformat/isoparse to ensure aware output (platega, yookassa, wata, miniapp, nalogo)
- Fix strptime() to add .replace(tzinfo=UTC) (backup_service, referral_diagnostics)
- Fix datetime.combine() to include tzinfo=UTC (remnawave_sync, traffic_monitoring)
- Fix datetime.max/datetime.min sentinels with .replace(tzinfo=UTC)
- Rename panel_datetime_to_naive_utc → panel_datetime_to_utc
- Remove DTZ003 from ruff ignore list
2026-02-17 04:45:40 +03:00

145 lines
3.8 KiB
Python

from collections.abc import Iterable
from datetime import UTC, datetime
import structlog
from sqlalchemy import delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from app.database.models import FaqPage, FaqSetting
logger = structlog.get_logger(__name__)
async def get_faq_setting(db: AsyncSession, language: str) -> FaqSetting | None:
result = await db.execute(select(FaqSetting).where(FaqSetting.language == language))
return result.scalar_one_or_none()
async def set_faq_enabled(db: AsyncSession, language: str, enabled: bool) -> FaqSetting:
setting = await get_faq_setting(db, language)
if setting:
setting.is_enabled = bool(enabled)
setting.updated_at = datetime.now(UTC)
else:
setting = FaqSetting(
language=language,
is_enabled=bool(enabled),
)
db.add(setting)
await db.commit()
await db.refresh(setting)
logger.info(
'✅ Статус FAQ для языка %s обновлен: %s',
language,
'enabled' if setting.is_enabled else 'disabled',
)
return setting
async def upsert_faq_setting(db: AsyncSession, language: str, enabled: bool) -> FaqSetting:
return await set_faq_enabled(db, language, enabled)
async def get_faq_pages(
db: AsyncSession,
language: str,
*,
include_inactive: bool = False,
) -> list[FaqPage]:
query = select(FaqPage).where(FaqPage.language == language)
if not include_inactive:
query = query.where(FaqPage.is_active.is_(True))
query = query.order_by(FaqPage.display_order.asc(), FaqPage.id.asc())
result = await db.execute(query)
pages = list(result.scalars().all())
return pages
async def get_faq_page_by_id(db: AsyncSession, page_id: int) -> FaqPage | None:
result = await db.execute(select(FaqPage).where(FaqPage.id == page_id))
return result.scalar_one_or_none()
async def create_faq_page(
db: AsyncSession,
*,
language: str,
title: str,
content: str,
display_order: int | None = None,
is_active: bool = True,
) -> FaqPage:
if display_order is None:
result = await db.execute(select(func.max(FaqPage.display_order)).where(FaqPage.language == language))
max_order = result.scalar() or 0
display_order = max_order + 1
page = FaqPage(
language=language,
title=title,
content=content,
display_order=display_order,
is_active=is_active,
)
db.add(page)
await db.commit()
await db.refresh(page)
logger.info('✅ Создана страница FAQ для языка', page_id=page.id, language=language)
return page
async def update_faq_page(
db: AsyncSession,
page: FaqPage,
*,
title: str | None = None,
content: str | None = None,
display_order: int | None = None,
is_active: bool | None = None,
) -> FaqPage:
if title is not None:
page.title = title
if content is not None:
page.content = content
if display_order is not None:
page.display_order = display_order
if is_active is not None:
page.is_active = bool(is_active)
page.updated_at = datetime.now(UTC)
await db.commit()
await db.refresh(page)
logger.info('✅ Страница FAQ обновлена', page_id=page.id)
return page
async def delete_faq_page(db: AsyncSession, page_id: int) -> None:
await db.execute(delete(FaqPage).where(FaqPage.id == page_id))
await db.commit()
logger.info('🗑️ Страница FAQ удалена', page_id=page_id)
async def bulk_update_order(
db: AsyncSession,
pages: Iterable[tuple[int, int]],
) -> None:
for page_id, order in pages:
await db.execute(
update(FaqPage).where(FaqPage.id == page_id).values(display_order=order, updated_at=datetime.now(UTC))
)
await db.commit()