# ЭВОСИНК (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 ```