161 lines
8.5 KiB
Markdown
161 lines
8.5 KiB
Markdown
# ЭВОСИНК (EvoSync)
|
||
|
||
Сервис автоматической синхронизации товарного каталога из [Эвотор](https://evotor.ru) в [ВКонтакте](https://vk.com).
|
||
|
||
## Возможности
|
||
|
||
- Подключение аккаунта Эвотор через OAuth
|
||
- Подключение сообщества ВКонтакте через токен
|
||
- Фильтрация по магазинам, группам и товарам (включить/исключить)
|
||
- Автоматическая фоновая синхронизация по расписанию
|
||
- Создание, обновление и удаление товаров в ВК-магазине
|
||
- Личный кабинет с веб-интерфейсом
|
||
- Просмотр закешированного каталога товаров
|
||
|
||
## Стек технологий
|
||
|
||
- **Backend**: FastAPI, SQLAlchemy ORM, Alembic
|
||
- **База данных**: MariaDB (драйвер pymysql)
|
||
- **Шаблоны**: Jinja2 (интерфейс на русском языке)
|
||
- **Аутентификация**: Cookie-сессии, bcrypt
|
||
- **Деплой**: Docker Compose
|
||
|
||
## Быстрый старт
|
||
|
||
### Требования
|
||
|
||
- Docker и Docker Compose
|
||
- MariaDB/MySQL (можно использовать хост-машину или отдельный контейнер)
|
||
|
||
### Настройка
|
||
|
||
1. Скопируйте файл переменных окружения:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
2. Отредактируйте `.env`:
|
||
|
||
```env
|
||
# База данных
|
||
DATABASE_URL=mysql+pymysql://evosync:evosync@db:3306/evosync
|
||
|
||
# Безопасность (обязательно измените в production)
|
||
SECRET_KEY=your-random-secret-key-here
|
||
|
||
# URL приложения (используется в OAuth-редиректах)
|
||
BASE_URL=https://your-domain.ru
|
||
|
||
# Эвотор
|
||
EVOTOR_APP_ID=your-evotor-app-id
|
||
EVOTOR_WEBHOOK_SECRET=your-webhook-secret
|
||
|
||
# Для отдельного MySQL-контейнера (опционально)
|
||
DB_ROOT_PASSWORD=rootpass
|
||
DB_NAME=evosync
|
||
DB_USER=evosync
|
||
DB_PASSWORD=evosync
|
||
```
|
||
|
||
3. Запустите сервис:
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
Приложение будет доступно по адресу `http://localhost:8080`.
|
||
|
||
При старте контейнер автоматически применяет миграции базы данных (`alembic upgrade head`).
|
||
|
||
## Переменные окружения
|
||
|
||
| Переменная | Обязательно | По умолчанию | Описание |
|
||
|---|---|---|---|
|
||
| `DATABASE_URL` | Да | — | MySQL connection string (pymysql) |
|
||
| `SECRET_KEY` | Да | `change-me-in-production` | Ключ для подписи сессий |
|
||
| `BASE_URL` | Да | `http://localhost:8080` | Публичный URL (для OAuth-callback) |
|
||
| `EVOTOR_APP_ID` | Да | — | ID приложения Эвотор |
|
||
| `EVOTOR_WEBHOOK_SECRET` | Да | — | Секрет для верификации вебхуков Эвотор |
|
||
| `VK_API_VERSION` | Нет | `5.131` | Версия VK API |
|
||
| `VK_DEFAULT_PHOTO_PATH` | Нет | `/app/default_product.png` | Путь к изображению товара по умолчанию |
|
||
| `JIVOSITE_WIDGET_ID` | Нет | — | ID виджета Jivosite (онлайн-чат) |
|
||
| `SYNC_INTERVAL_SECONDS` | Нет | `3600` | Интервал синхронизации (сек) |
|
||
| `CATALOG_REFRESH_INTERVAL_SECONDS` | Нет | `3600` | Интервал обновления каталога (сек) |
|
||
| `HEALTH_CHECK_INTERVAL_SECONDS` | Нет | `600` | Интервал проверки соединений (сек) |
|
||
|
||
## Структура проекта
|
||
|
||
```
|
||
evo-sync/
|
||
├── web/
|
||
│ ├── main.py # FastAPI-приложение, регистрация роутеров, фоновые задачи
|
||
│ ├── config.py # Настройки из переменных окружения (pydantic-settings)
|
||
│ ├── models.py # SQLAlchemy-модели (User, EvotorConnection, VkConnection, ...)
|
||
│ ├── database.py # Движок и сессия SQLAlchemy
|
||
│ ├── auth.py # Хеширование паролей, работа с сессиями
|
||
│ ├── schemas.py # Pydantic-схемы для форм
|
||
│ ├── sync_engine.py # Фоновый движок синхронизации (Эвотор → ВК)
|
||
│ ├── routes/
|
||
│ │ ├── auth.py # Регистрация, вход, выход, подтверждение email
|
||
│ │ ├── profile.py # Профиль пользователя
|
||
│ │ ├── reset.py # Сброс пароля
|
||
│ │ ├── evotor.py # OAuth-подключение Эвотор
|
||
│ │ ├── vk.py # Подключение ВКонтакте (ввод токена)
|
||
│ │ ├── connections.py # Обзор всех подключений
|
||
│ │ ├── sync.py # Настройка и управление синхронизацией
|
||
│ │ └── catalog.py # Просмотр закешированного каталога
|
||
│ ├── templates/ # Jinja2-шаблоны (русский интерфейс)
|
||
│ └── migrations/ # Alembic-миграции
|
||
├── Dockerfile.web # Docker-образ веб-приложения (Python 3.12-slim)
|
||
├── docker-compose.yml # Оркестрация сервисов
|
||
├── docker-entrypoint.sh # Скрипт запуска контейнера
|
||
├── alembic.ini # Конфигурация миграций
|
||
├── requirements.txt # Python-зависимости
|
||
└── .env.example # Шаблон переменных окружения
|
||
```
|
||
|
||
## Модели базы данных
|
||
|
||
| Модель | Таблица | Назначение |
|
||
|---|---|---|
|
||
| `User` | `users` | Аккаунт пользователя |
|
||
| `EvotorConnection` | `evotor_connections` | OAuth-токен Эвотор |
|
||
| `VkConnection` | `vk_connections` | Токен сообщества ВКонтакте |
|
||
| `SyncConfig` | `sync_configs` | Настройки синхронизации пользователя |
|
||
| `SyncFilter` | `sync_filters` | Фильтры по магазинам/группам/товарам |
|
||
| `CachedStore` | `cached_stores` | Кеш магазинов Эвотор |
|
||
| `CachedGroup` | `cached_groups` | Кеш групп товаров Эвотор |
|
||
| `CachedProduct` | `cached_products` | Кеш товаров Эвотор + статус синхронизации |
|
||
|
||
## Как работает синхронизация
|
||
|
||
1. По расписанию (каждые `SYNC_INTERVAL_SECONDS` секунд) запускается `sync_engine.run_sync()`
|
||
2. Для каждого пользователя с активным `SyncConfig` и подключёнными Эвотор и ВК:
|
||
- Загружаются товары и группы из Эвотор API
|
||
- Применяются фильтры (включить/исключить магазины, группы, товары)
|
||
- Загружаются текущие товары и альбомы из ВК
|
||
- Создаются/обновляются/удаляются альбомы и товары в ВК-магазине
|
||
- В БД обновляется поле `synced_at` у синхронизированных товаров
|
||
|
||
**Особенности:**
|
||
- Товары на развес (единицы измерения в граммах) получают скорректированную цену (×10)
|
||
- Совпадение товаров ВК и Эвотор происходит по нормализованному названию
|
||
- Товары с `allow_to_sell=false` не синхронизируются в ВК
|
||
|
||
## Разработка
|
||
|
||
Для локальной разработки с горячей перезагрузкой кода папка `./web` монтируется в контейнер как volume. После изменения Python-файлов uvicorn перезапустится автоматически.
|
||
|
||
Создание новой миграции:
|
||
|
||
```bash
|
||
docker compose exec web alembic revision --autogenerate -m "описание изменений"
|
||
```
|
||
|
||
Применение миграций вручную:
|
||
|
||
```bash
|
||
docker compose exec web alembic upgrade head
|
||
```
|