feat: add VK OAuth connection with health checks

- Add VkConnection model with is_online/last_checked_at fields
- Add /vk OAuth flow (connect/callback/disconnect/page)
- Add VK entry to connections dashboard
- Extend background health checker to check VK tokens via users.get
- Add Alembic migration for vk_connections table
- Add VK_CLIENT_ID/SECRET/SCOPES/API_VERSION config settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mguschin
2026-03-06 15:29:42 +03:00
parent 379f781e1e
commit cfc7229daf
8 changed files with 358 additions and 9 deletions

View File

@@ -5,11 +5,13 @@ from datetime import datetime
import httpx
from web.database import SessionLocal
from web.models import EvotorConnection
from web.models import EvotorConnection, VkConnection
logger = logging.getLogger("uvicorn.error")
EVOTOR_STORES_URL = "https://api.evotor.ru/stores"
VK_USERS_GET_URL = "https://api.vk.com/method/users.get"
VK_API_VERSION = "5.131"
async def check_evotor_connection(access_token: str) -> bool:
@@ -25,16 +27,41 @@ async def check_evotor_connection(access_token: str) -> bool:
return False
async def check_vk_connection(access_token: str) -> bool:
try:
async with httpx.AsyncClient() as client:
resp = await client.get(
VK_USERS_GET_URL,
params={"access_token": access_token, "v": VK_API_VERSION},
timeout=10,
)
if resp.status_code != 200:
return False
data = resp.json()
return "error" not in data
except Exception:
return False
async def run_health_checks() -> None:
db = SessionLocal()
try:
connections = db.query(EvotorConnection).all()
for conn in connections:
is_online = await check_evotor_connection(conn.access_token)
conn.is_online = is_online
evotor_connections = db.query(EvotorConnection).all()
for conn in evotor_connections:
conn.is_online = await check_evotor_connection(conn.access_token)
conn.last_checked_at = datetime.utcnow()
vk_connections = db.query(VkConnection).all()
for conn in vk_connections:
conn.is_online = await check_vk_connection(conn.access_token)
conn.last_checked_at = datetime.utcnow()
db.commit()
logger.info("Health checks completed for %d connection(s)", len(connections))
logger.info(
"Health checks completed: %d Evotor, %d VK",
len(evotor_connections),
len(vk_connections),
)
except Exception:
logger.exception("Error during health checks")
db.rollback()