- Connections dashboard with add/remove flow and background health checks - VK OAuth connection with profile info and health monitoring - Sync configuration page with master toggle and filter summary - Catalog browser with store/group/product tables, filter management, CSV export - Alembic migrations for all new tables - run/read_config.py for shell sync script DB integration - CHANGELOG.md updated for v1.8.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 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 manage all their connections: add new ones, view status, edit, and delete. The dashboard starts empty — users explicitly add each connection they need.
Supported connection types: Evotor, VK (one per type per user).
Data Design
Current state (separate models)
EvotorConnection and VkConnection remain as-is — they hold service-specific fields (store_id/store_name for Evotor, vk_user_id/first_name/last_name for VK). The connections dashboard reads from both tables.
No new unified "connection" table needed. The dashboard builds a virtual list by querying both tables. The "add" flow is just a gateway to the existing per-service OAuth pages.
Model additions (both EvotorConnection and VkConnection)
Already planned:
is_online(Boolean, default=False, server_default="0")last_checked_at(DateTime, nullable)
Plan
1. Model Changes — web/models.py
Add is_online and last_checked_at to both EvotorConnection and VkConnection.
2. Alembic Migration
Add health check fields to both connection tables.
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,GET https://api.evotor.ru/storeswith Bearer tokencheck_vk_connection(access_token) -> bool— async,GET https://api.vk.com/method/users.getwith tokenrun_health_checks()— queries all connection rows, checks each, updatesis_onlineandlast_checked_athealth_check_loop(interval)— infinite loop withasyncio.sleep
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 connections router
6. Connections Route — web/routes/connections.py (new)
GET /connections — Main dashboard. Requires auth.
Queries both EvotorConnection and VkConnection for the current user. Builds a list of available service types and their connection state:
SERVICE_TYPES = [
{"type": "evotor", "name": "Эвотор", "icon": "bi-shop", "connect_url": "/evotor", "disconnect_url": "/evotor/disconnect"},
{"type": "vk", "name": "ВКонтакте", "icon": "bi-chat-dots", "connect_url": "/vk", "disconnect_url": "/vk/disconnect"},
]
For each type, attach the connection record (or None). Template renders based on state.
GET /connections/add — "Add connection" page.
Shows only service types the user has NOT yet connected:
- Card per available type with service name, icon, short description
- "Подключить" button linking to the service's OAuth page (
/evotoror/vk) - If all types already connected — message "Все доступные сервисы подключены"
- Back link to
/connections
POST /connections/delete?type=evotor|vk — Delete a connection.
Same as existing disconnect endpoints but accessed from the dashboard. Deletes the connection record, redirects to /connections.
(The existing /evotor/disconnect and /vk/disconnect routes remain as aliases.)
7. Templates
web/templates/connections.html — Dashboard:
┌─────────────────────────────────────────────────┐
│ Подключения [+ Добавить] │
├─────────────────────────────────────────────────┤
│ │
│ ┌─ Card ─────────────────────────────────────┐ │
│ │ 🏪 Эвотор ● (green) │ │
│ │ Магазин "Чайная" │ │
│ │ Последняя проверка: 06.03.2026 14:30 │ │
│ │ │ │
│ │ [Настроить] [Отключить] │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌─ Card ─────────────────────────────────────┐ │
│ │ 💬 ВКонтакте ● (green) │ │
│ │ Иван Иванов │ │
│ │ Последняя проверка: 06.03.2026 14:30 │ │
│ │ │ │
│ │ [Настроить] [Отключить] │ │
│ └────────────────────────────────────────────┘ │
│ │
│ (Нет подключений — нажмите «Добавить») │
│ │
└─────────────────────────────────────────────────┘
Each connection card:
- Icon + service name + status indicator (green/red/grey)
- Details line (store name for Evotor, profile name for VK)
- Last checked timestamp in card footer
- "Настроить" button → links to service page (
/evotoror/vk) for reconnect/details - "Отключить" button → POST to
/connections/delete?type=...with confirmation
Empty state: message prompting user to add their first connection.
web/templates/connections_add.html — Add connection page:
┌─────────────────────────────────────────────────┐
│ Добавить подключение │
├─────────────────────────────────────────────────┤
│ │
│ ┌─ Card ─────────────────────────────────────┐ │
│ │ 🏪 Эвотор │ │
│ │ Подключите кассу Эвотор для синхронизации │ │
│ │ каталога товаров. │ │
│ │ [Подключить →] │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌─ Card ─────────────────────────────────────┐ │
│ │ 💬 ВКонтакте │ │
│ │ Подключите аккаунт ВКонтакте для │ │
│ │ публикации товаров в вашу группу. │ │
│ │ [Подключить →] │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ← Вернуться к подключениям │
│ │
└─────────────────────────────────────────────────┘
8. Navbar Update — web/templates/base.html
Replace "Эвотор" link with "Подключения" → /connections.
9. Evotor/VK Callback Updates
On successful OAuth callback in both /evotor/callback and /vk/callback:
- Set
is_online=Trueandlast_checked_at=now() - Redirect to
/connections(already done for Evotor)
10. Evotor/VK Template Back Links
Change back links on /evotor and /vk pages: "Вернуться к подключениям" → /connections.
11. Delete Confirmation
The "Отключить" button on the dashboard uses a simple JS confirm() dialog: "Вы уверены, что хотите отключить {service name}?" before submitting the POST form.
Files Summary
| File | Action |
|---|---|
web/models.py |
Modify — add is_online, last_checked_at to both connection models |
web/config.py |
Modify — add HEALTH_CHECK_INTERVAL_SECONDS |
web/main.py |
Modify — lifespan + register connections router |
web/routes/evotor.py |
Modify — set online on callback, redirect to /connections |
web/routes/vk.py |
Modify — set online on callback, redirect to /connections |
web/routes/connections.py |
Create — dashboard, add page, delete endpoint |
web/health_checker.py |
Create — background checks for both Evotor and VK |
web/templates/connections.html |
Create — dashboard with cards |
web/templates/connections_add.html |
Create — add connection page |
web/templates/base.html |
Modify — navbar link |
web/templates/evotor.html |
Modify — back link to /connections |
web/templates/vk.html |
Modify — back link to /connections |
| Alembic migration | Create |
Verification
- Run
alembic upgrade head - Start the app, verify background task logs appear
- Visit
/connections— empty state, "Добавить" button visible - Click "Добавить" → shows Evotor and VK as available services
- Add Evotor → goes through OAuth → returns to
/connectionswith green status card - Add VK → same flow → both connections visible
- Click "Добавить" again → shows "Все доступные сервисы подключены"
- Click "Отключить" on Evotor → confirmation dialog → connection removed → card disappears
- Click "Добавить" → Evotor is available again
- Wait for health check cycle → verify
is_onlineandlast_checked_atupdate on remaining connections