Files
evo-sync/docs/plans/connections-dashboard.md
mguschin 379f781e1e feat: add connections dashboard with background health checks
- Add /connections page showing all integrations with online/offline status
- Add background health checker that polls Evotor API every 10 minutes
- Add is_online and last_checked_at fields to evotor_connections table
- Replace Evotor navbar link with unified Connections link
- Redirect connect/disconnect flows to /connections
- Add Alembic migration for new columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 15:26:49 +03:00

3.7 KiB

Connections Dashboard with Background Health Checks

Context

Users currently access Evotor connection via a dedicated /evotor page linked from the navbar. As more integrations are planned, we need a unified Connections page where users can see all their connections at a glance, with real-time status indicators powered by background health checks.

Plan

1. Model Changes — web/models.py

Add to EvotorConnection:

  • is_online (Boolean, default=False, server_default="0")
  • last_checked_at (DateTime, nullable)

2. Alembic Migration

Generate migration for the two new columns on evotor_connections table.

3. Config Addition — web/config.py

Add HEALTH_CHECK_INTERVAL_SECONDS: int = 600 (10 minutes default).

4. Background Health Checker — web/health_checker.py (new)

  • check_evotor_connection(access_token) -> bool — async, calls GET https://api.evotor.ru/stores with Bearer token, returns True if 200
  • run_health_checks() — queries all EvotorConnection rows using its own SessionLocal(), checks each, updates is_online and last_checked_at
  • health_check_loop(interval) — infinite loop with asyncio.sleep, calls run_health_checks()

5. Wire Background Task — web/main.py

Add FastAPI lifespan context manager:

  • On startup: asyncio.create_task(health_check_loop(...))
  • On shutdown: cancel the task
  • Register new connections router

6. Connections Route — web/routes/connections.py (new)

GET /connections — requires auth, builds a list of connection descriptors:

connections = [{
    "name": "Эвотор",
    "icon": "bi-shop",
    "connected": bool,
    "is_online": bool,
    "last_checked_at": datetime | None,
    "details": store_name,
    "connect_url": "/evotor",
    "disconnect_url": "/evotor/disconnect",
}]

Future connections just append another dict — template stays generic.

7. Connections Template — web/templates/connections.html (new)

Card per connection showing:

  • Icon + name + optional details (store name)
  • Status: green bi-circle-fill (online), red bi-circle-fill (offline), grey bi-circle (not connected)
  • Action button: "Подключить" (link to connect_url) or "Отключить" (POST form to disconnect_url)
  • Card footer with last check timestamp

8. Navbar Update — web/templates/base.html

Replace "Эвотор" link with "Подключения" → /connections.

9. Evotor Callback Update — web/routes/evotor.py

On successful OAuth callback, set is_online=True and last_checked_at=func.now().

Change "Вернуться в личный кабинет" → "Вернуться к подключениям" linking to /connections.

Files Summary

File Action
web/models.py Modify — add 2 fields
web/config.py Modify — add interval setting
web/main.py Modify — lifespan + router
web/routes/evotor.py Modify — set online on callback
web/routes/connections.py Create
web/health_checker.py Create
web/templates/connections.html Create
web/templates/base.html Modify — navbar
web/templates/evotor.html Modify — back link
Alembic migration Create

Verification

  1. Run alembic upgrade head to apply migration
  2. Start the app, verify background task logs appear
  3. Visit /connections — should show Evotor as disconnected (grey)
  4. Connect Evotor via /evotor — should redirect back, connections page shows green status
  5. Disconnect — status returns to grey
  6. Wait for health check interval or trigger manually — verify is_online and last_checked_at update