🚀 MVP: FastAPI + React форма с SMS верификацией

 Инфраструктура: PostgreSQL, Redis, RabbitMQ, S3
 Backend: SMS сервис + API endpoints
 Frontend: React форма (3 шага) + SMS верификация
This commit is contained in:
AI Assistant
2025-10-24 16:19:58 +03:00
parent 8af23e90fa
commit 0f82eef08d
42 changed files with 2902 additions and 241 deletions

View File

@@ -0,0 +1,76 @@
"""
PostgreSQL Database Service
"""
import asyncpg
from typing import Optional, Dict, Any, List
from ..config import settings
import logging
logger = logging.getLogger(__name__)
class DatabaseService:
"""Сервис для работы с PostgreSQL"""
def __init__(self):
self.pool: Optional[asyncpg.Pool] = None
async def connect(self):
"""Создает пул подключений к PostgreSQL"""
try:
self.pool = await asyncpg.create_pool(
host=settings.postgres_host,
port=settings.postgres_port,
database=settings.postgres_db,
user=settings.postgres_user,
password=settings.postgres_password,
min_size=5,
max_size=20,
command_timeout=60
)
logger.info(f"✅ PostgreSQL connected: {settings.postgres_host}:{settings.postgres_port}/{settings.postgres_db}")
except Exception as e:
logger.error(f"❌ PostgreSQL connection error: {e}")
raise
async def disconnect(self):
"""Закрывает пул подключений"""
if self.pool:
await self.pool.close()
logger.info("PostgreSQL pool closed")
async def execute(self, query: str, *args) -> str:
"""Выполняет SQL запрос без возврата данных"""
async with self.pool.acquire() as conn:
return await conn.execute(query, *args)
async def fetch_one(self, query: str, *args) -> Optional[Dict[str, Any]]:
"""Возвращает одну запись"""
async with self.pool.acquire() as conn:
row = await conn.fetchrow(query, *args)
return dict(row) if row else None
async def fetch_all(self, query: str, *args) -> List[Dict[str, Any]]:
"""Возвращает все записи"""
async with self.pool.acquire() as conn:
rows = await conn.fetch(query, *args)
return [dict(row) for row in rows]
async def fetch_val(self, query: str, *args):
"""Возвращает одно значение"""
async with self.pool.acquire() as conn:
return await conn.fetchval(query, *args)
async def health_check(self) -> bool:
"""Проверка здоровья БД"""
try:
result = await self.fetch_val("SELECT 1")
return result == 1
except Exception as e:
logger.error(f"Database health check failed: {e}")
return False
# Глобальный экземпляр
db = DatabaseService()