Skip to content

Общая архитектура

Стек

  • Python 3.13+, управление зависимостями — uv (pyproject.toml + uv.lock).
  • FastAPI — backend (вебхуки, API).
  • NiceGUI — GUI, встраиваемое в iframe МойСклад.
  • PostgreSQL — основная БД (asyncpg + SQLAlchemy ORM).
  • Redis — брокер Celery + кэш.
  • Celery — асинхронные задачи и периодический планировщик (beat).
  • Alembic — миграции БД.
  • Logfire — distributed tracing и мониторинг.
  • Docker Compose — весь стек поднимается одной командой.

Сервисы Docker Compose

Сервис Назначение Порт
traefik Reverse proxy, TLS (Let's Encrypt) 80, 443
gui NiceGUI/FastAPI — UI-страницы внутри МойСклад 8080
backend0 FastAPI — вебхуки от МойСклад 8081
backend1 FastAPI — вебхуки (резерв backend0, используется через INTERNAL_BACKEND_URL) 8082
worker0..2 Celery workers — выполнение фоновых задач —
beat Celery beat — периодические задачи —
flower Мониторинг Celery 5555
db PostgreSQL 5432
broker Redis (аутентификация по паролю) 6379

Два entry point

Один и тот же код монтируется в контейнеры gui и backend:

  • GUI: services/backend/src/gui.py — импортирует gui_routers и gui_class_endpoints из src/endpoints/routers.
  • Backend: services/backend/src/backend.py — импортирует backend_routers из src/endpoints/routers.

Таким образом GUI и backend — это два разных процесса, но общий код.

Модель приложения

Каждое приложение имеет две копии: dev (для тестирования) и production. Они различаются только UUID и именем, задаваемыми через переменные окружения .env / apps.env. Постоянные значения (production) — в src/constants.py, runtime-разрешение — в src/env.py.

Каждое приложение экспонирует: - GUI-страницы в src/endpoints/main/ — NiceGUI-страница настройки внутри МойСклад. - Виджеты в src/endpoints/widget/ — небольшие HTML-виджеты на карточках документов. - Кнопки в src/endpoints/button/ — кнопки-действия на карточках. - Popup в src/endpoints/popup/ — всплывающие окна. - Webhook handlers в src/endpoints/apps.py — приём и обработка событий от МойСклад.

Поток webhook

Все backend-приложения работают по единому двухэтапному шаблону:

  1. POST /<uid>/webhook-processor — быстрый endpoint, который ставит задачу в Celery (save_webhook). Некоторые приложения фильтруют события перед постановкой в очередь (например, set-prefix — только если изменено name или action == CREATE).
  2. POST /<uid>/internal-webhook — worker забирает задачу и выполняет бизнес-логику приложения.

Это гарантирует, что МойСклад получит HTTP 200 максимально быстро и не будет повторять webhook.

Структура директорий backend

services/backend/src/
  backend.py            # Entry point для backend (webhooks)
  gui.py                # Entry point для GUI (NiceGUI)
  bot.py                # aiogram бот (не используется в production)
  constants.py          # Production-константы (UUID, имена приложений)
  env.py                # Runtime-разрешение dev/prod
  enums.py              # Перечисления (типы документов, webhook actions)
  logger.py             # Настройка логирования

  endpoints/
    routers.py          # Агрегация всех роутеров
    apps.py             # Webhook-роутеры для каждого приложения
    vendor.py           # Vendor endpoints (установка/удаление приложений)
    main/               # NiceGUI страницы настроек
    widget/             # HTML-виджеты на карточках
    button/             # Кнопки на карточках
    popup/              # Popup-окна

  services/             # Бизнес-логика каждого приложения
  models/               # SQLAlchemy модели
  repositories/         # Базовые репозитории (только Account/App/Install)
  schemas/              # Pydantic-схемы
  database/             # Инициализация БД, Alembic
  moysklad/             # Клиент Moysklad API (sync + async)
  utils/                # Celery, Redis, mail, UoW, репозитории

Инфраструктурные компоненты

Подробности в отдельных файлах: - База данных и модели - Celery и периодические задачи - Клиент Moysklad API