Files
evo-sync/docs/plans/connections-dashboard.md
mguschin 9aeef73b10 feat: release v1.8.0 — connections dashboard, VK OAuth, sync config, catalog browser
- 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>
2026-03-06 16:08:19 +03:00

193 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/stores` with Bearer token
- `check_vk_connection(access_token) -> bool` — async, `GET https://api.vk.com/method/users.get` with token
- `run_health_checks()` — queries all connection rows, checks each, updates `is_online` and `last_checked_at`
- `health_check_loop(interval)` — infinite loop with `asyncio.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:
```python
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 (`/evotor` or `/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 (`/evotor` or `/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=True` and `last_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
1. Run `alembic upgrade head`
2. Start the app, verify background task logs appear
3. Visit `/connections` — empty state, "Добавить" button visible
4. Click "Добавить" → shows Evotor and VK as available services
5. Add Evotor → goes through OAuth → returns to `/connections` with green status card
6. Add VK → same flow → both connections visible
7. Click "Добавить" again → shows "Все доступные сервисы подключены"
8. Click "Отключить" on Evotor → confirmation dialog → connection removed → card disappears
9. Click "Добавить" → Evotor is available again
10. Wait for health check cycle → verify `is_online` and `last_checked_at` update on remaining connections