7a06045bef158f8ec4a44d6b2f3afb58bd4863a5
Also add itsdangerous to requirements.txt (missing implicit dep of starlette SessionMiddleware) and a create_admin.py script for bootstrapping a system-role user with all permissions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EvoSync
Web service for syncing a product catalog from Evotor POS → VK Market. Users connect their Evotor account and a VK page; products from the cash register then appear automatically in the VK store.
Architecture
┌─────────────────────────────────────────┐
│ Docker Compose │
│ │
Browser / Evotor ─────► web :8000 (FastAPI + Uvicorn) │
:8080 │ │ │
│ ├── MariaDB :3306 (primary DB) │
│ ├── Redis :6379 (Celery broker) │
│ │ │
│ ├── worker (Celery worker) │
│ ├── beat (Celery beat scheduler) │
│ └── flower :5555 (queue monitor) │
└─────────────────────────────────────────┘
Services
| Service | Image / Dockerfile | Purpose | External port |
|---|---|---|---|
web |
Dockerfile.web |
FastAPI app, runs Alembic migrations on start | 8080 → 8000 |
worker |
Dockerfile.web |
Celery worker (sync, health, notifications…) | — |
beat |
Dockerfile.web |
Celery Beat — periodic task scheduler | — |
flower |
Dockerfile.web |
Celery queue monitoring UI | 5555 |
db |
mariadb:11.4 |
Primary relational database | — |
redis |
redis:7-alpine |
Celery broker and result backend | — |
Stack
- Python 3.12, FastAPI 0.115, Uvicorn
- SQLAlchemy 2 + Alembic, MariaDB (PyMySQL)
- Celery 5 + Redis
- Jinja2 — server-side HTML rendering (
web/templates/) - Pydantic Settings — configuration from env vars /
.env - bcrypt — password hashing
- python-json-logger — structured JSON logs to stdout
Database Schema
| Table | Purpose |
|---|---|
users |
User accounts (roles: system / admin / user; statuses: pending / active / suspended) |
evotor_connections |
User ↔ Evotor link (access_token, api_token returned to Evotor webhooks) |
vk_connections |
User ↔ VK OAuth link |
sync_configs |
Per-user sync settings |
sync_filters |
Product / group inclusion/exclusion filters |
cached_stores |
Cached list of Evotor stores |
cached_groups |
Cached Evotor product groups |
cached_products |
Cached Evotor product catalog |
roles |
RBAC roles |
permissions |
RBAC permissions |
role_permissions |
M2M: role ↔ permission |
user_roles |
M2M: user ↔ role |
Routes
Public / Authentication
| Method | Path | Description |
|---|---|---|
| GET | / |
Redirects to /profile or /login |
| GET | /health |
Health check (JSON) |
| GET/POST | /register |
User registration |
| GET | /confirm-email |
Email confirmation via token |
| GET | /resend-confirm |
Resend confirmation email |
| GET/POST | /login |
Login |
| GET | /logout |
Logout |
| GET/POST | /forgot-password |
Request password reset |
| GET/POST | /reset-password |
Reset password via token |
| GET/POST | /invite |
Complete registration via invite link |
Profile (requires session)
| Method | Path | Description |
|---|---|---|
| GET | /profile |
View profile |
| GET/POST | /profile/edit |
Edit profile |
| GET/POST | /profile/change-password |
Change password |
| GET/POST | /profile/delete |
Delete account |
Admin panel (/admin, roles: admin / system)
| Method | Path | Description |
|---|---|---|
| GET | /admin/users |
User list |
| GET | /admin/users/{id} |
User detail |
| POST | /admin/users/{id}/activate |
Activate user |
| POST | /admin/users/{id}/suspend |
Suspend user |
| POST | /admin/users/{id}/reset-password |
Reset user password |
| POST | /admin/users/{id}/send-invite |
Send invite email |
| POST | /admin/users/{id}/edit |
Edit user data |
| POST | /admin/users/{id}/delete |
Delete user |
| GET | /admin/roles |
Roles and permissions |
| POST | /admin/roles/{id}/permissions |
Update role permissions |
Evotor Webhooks (Bearer EVOTOR_WEBHOOK_SECRET)
| Method | Path | Description |
|---|---|---|
| POST | /user/create |
Evotor creates/links a user and receives an api_token |
| POST | /user/verify |
Evotor verifies user credentials and receives an api_token |
| POST | /user/token |
Evotor delivers its own access_token for a user |
API Docs
| Path | Description |
|---|---|
/docs |
Swagger UI |
/redoc |
ReDoc |
Configuration
All settings are read from environment variables or a .env file:
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
mysql+pymysql://…@db:3306/evosync |
MariaDB connection string |
REDIS_URL |
redis://redis:6379/0 |
Redis connection string |
SECRET_KEY |
change-me-in-production |
Session signing key |
BASE_URL |
http://localhost:8000 |
Public URL of the service |
EVOTOR_APP_ID |
— | Evotor application ID |
EVOTOR_WEBHOOK_SECRET |
— | Bearer secret for webhook endpoints |
JIVOSITE_WIDGET_ID |
— | JivoSite widget ID |
VK_DEFAULT_PHOTO_PATH |
/app/default_product.png |
Fallback image path for VK products |
VK_API_VERSION |
5.199 |
VK API version |
CATALOG_REFRESH_INTERVAL_SECONDS |
3600 |
Catalog cache refresh interval |
INVITE_EXPIRE_HOURS |
48 |
Invite link TTL in hours |
EMAIL_PROVIDER |
console |
Email provider (console / smtp / …) |
SMS_PROVIDER |
console |
SMS provider |
FLOWER_USER / FLOWER_PASSWORD |
admin / changeme |
Basic Auth credentials for Flower |
Running
cp .env.example .env # fill in your values
docker compose up -d --build
App is available at http://localhost:8080.
Flower (queue monitor) at http://localhost:5555.
Development
pip install -r requirements.txt
alembic upgrade head
uvicorn web.main:app --reload --port 8000
Tests
pytest --cov=web
Description
Releases
5
Release version 2.0.0
Latest
Languages
Python
58.4%
HTML
25.1%
Shell
12.5%
CSS
3.6%
Mako
0.2%
Other
0.2%