Skip to content

Repository files navigation

Event-Driven Marketplace Order Processing Platform

CI

Production-oriented Python backend project demonstrating event-driven architecture, Redis cache-aside, PostgreSQL persistence, MongoDB raw event storage, RedPanda/Kafka consumers, Docker Compose, GitHub Actions CI and basic Kubernetes deployment manifests.

Первая версия намеренно не содержит LLM/AI-функций. Фокус проекта: Python backend, event-driven architecture, базы данных, кеширование, контейнеризация, CI/CD и основы Kubernetes.

Архитектура

                 HTTP
              +--------+
              | client |
              +---+----+
                  |
                  v
          +---------------+
          |   order-api   |
          | FastAPI       |
          +---+-------+---+
              |       |
 source       |       | domain events
 of truth     v       v
       +------------+      +----------------+
       | PostgreSQL |      | RedPanda/Kafka |
       +------------+      | order.events   |
              ^            +---+--------+---+
              |                |        |
              |                v        v
       +------+-----+  +-------------+  +------------------+
       |   Redis    |  | order-worker|  | analytics-worker |
       | cache only |  +------+------+  +---------+--------+
       +------------+         |                   |
                              v                   v
                         +---------+         +---------+
                         | MongoDB |         | Redis   |
                         | events  |         | metrics |
                         +---------+         +---------+

PostgreSQL хранит текущее состояние заказов и является источником правды. Redis используется только для cache-aside чтений, короткоживущей аналитики и быстрого idempotency-фильтра. MongoDB хранит raw event payloads с гибкой структурой. RedPanda/Kafka развязывает синхронный API и фоновую обработку событий.

Стек

  • Python 3.12
  • FastAPI и Pydantic v2
  • SQLAlchemy 2 async и Alembic
  • PostgreSQL
  • Redis
  • MongoDB через Motor
  • RedPanda как Kafka-compatible broker
  • Docker Compose
  • Ruff, MyPy и Pytest
  • GitHub Actions CI
  • Базовые Kubernetes manifests для application-сервисов

HTTP API

  • POST /orders — создать заказ.
  • GET /orders/{order_id} — получить детали заказа через Redis cache-aside.
  • GET /orders/{order_id}/status — получить статус заказа через Redis cache-aside.
  • POST /orders/{order_id}/pay — отметить заказ как оплаченный.
  • POST /orders/{order_id}/cancel — отменить заказ.
  • GET /analytics/summary — получить eventually consistent аналитику за сегодня из Redis.
  • GET /health — базовая проверка здоровья сервиса.

Пример создания заказа:

curl -X POST http://localhost:8000/orders \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "user-1",
    "items": [
      {"sku": "SKU-1", "quantity": 2, "price": "19.99"}
    ]
  }'

Event Flow

  1. order-api принимает HTTP-команду.
  2. Service layer валидирует бизнес-переход.
  3. PostgreSQL обновляется и коммитится.
  4. Связанные Redis-ключи инвалидируются при write operations.
  5. Доменное событие публикуется в order.events.
  6. order-worker читает событие, валидирует его через Pydantic, проверяет idempotency и сохраняет raw event в MongoDB.
  7. analytics-worker читает тот же topic в отдельной consumer group и обновляет аналитику в Redis.
  8. Невалидные события или события, которые не удалось обработать после retry, публикуются в order.events.dlq.

Формат события:

{
  "event_id": "uuid",
  "event_type": "order.created",
  "occurred_at": "2026-05-15T12:00:00Z",
  "payload": {
    "order_id": "string",
    "user_id": "string",
    "total_amount": "99.90"
  }
}

Поддерживаемые типы событий:

  • order.created
  • order.paid
  • order.cancelled
  • order.delivered

Redis Cache-Aside Strategy

API использует cache-aside для статуса и деталей заказа.

Для чтения:

  1. Проверить Redis.
  2. Если cache hit — вернуть данные из кеша.
  3. Если cache miss — прочитать PostgreSQL.
  4. Положить ответ в Redis с TTL.
  5. Вернуть ответ клиенту.

Для записи:

  1. Обновить PostgreSQL.
  2. Инвалидировать связанные Redis-ключи.
  3. Опубликовать Kafka event.

Redis keys:

  • order:{order_id}:status, TTL 60 секунд
  • order:{order_id}:details, TTL 60 секунд
  • analytics:summary:today, TTL 120-300 секунд
  • idempotency:{event_id} как быстрый worker-side duplicate filter

Redis никогда не является источником правды для состояния заказов.

Kafka Topics

  • order.events — доменные события, опубликованные order-api.
  • order.events.dlq — невалидные события или события, которые не удалось обработать после ограниченного числа retry.

Consumer groups:

  • order-worker-group
  • analytics-worker-group

Разные consumer groups нужны для того, чтобы order-worker и analytics-worker независимо получили один и тот же поток событий.

Роли Хранилищ

  • PostgreSQL: текущее состояние заказов, позиции заказов и надежное хранение processed event ids.
  • MongoDB: архив raw event payloads.
  • Redis: cache-aside чтения заказов, аналитика и короткоживущие idempotency-фильтры.
  • RedPanda/Kafka: асинхронная развязка сервисов через event stream.

Локальный Запуск

При необходимости создай локальный .env из примера:

cp .env.example .env

Запуск всего стека:

make docker-up

Полезные URL:

  • API: http://localhost:8000
  • OpenAPI: http://localhost:8000/docs
  • RedPanda Console: http://localhost:8080
  • внешний Kafka listener RedPanda: localhost:19092

Если host-порт уже занят, переопредели его в .env, например:

POSTGRES_HOST_PORT=15432

Остановка стека:

make docker-down

Локальная Разработка

Установка зависимостей:

python -m pip install --upgrade pip
python -m pip install ".[dev]"

Применить миграции:

make migrate

Запустить API локально:

make run

Запустить workers локально:

python -m order_platform.workers.order_worker
python -m order_platform.workers.analytics_worker

При локальном запуске без Docker инфраструктура должна быть доступна по значениям из .env или defaults из settings.py.

Тесты И Проверки Качества

make test
make lint
make typecheck

Тесты покрывают service layer для order workflows, cache invalidation и analytics idempotency. Также есть API integration test через FastAPI ASGI transport с SQLite и in-memory fakes.

CI/CD

GitHub Actions запускается на push в main и pull requests.

Pipeline:

  1. Install dependencies.
  2. ruff check .
  3. ruff format --check .
  4. mypy
  5. pytest
  6. docker build

Workflow: .github/workflows/ci.yml.

Kubernetes

Директория k8s/ содержит базовые manifests только для application-сервисов:

  • order-api Deployment
  • order-api Service
  • order-worker Deployment
  • analytics-worker Deployment
  • ConfigMap
  • Secret example

PostgreSQL, Redis, MongoDB и RedPanda намеренно не описаны как production StatefulSet в Kubernetes. Manifests рассчитаны на подключение к внешней инфраструктуре или локально доступным сервисам.

Применить manifests:

kubectl apply -k k8s/

Перед использованием нужно заменить image names и endpoints внешней инфраструктуры в k8s/configmap.yaml и k8s/secret.example.yaml.

Структура Проекта

src/order_platform/
  api/              FastAPI app, routes and dependencies
  core/             settings, enums and domain errors
  db/               SQLAlchemy session helpers
  infrastructure/   Redis, Kafka and MongoDB adapters
  models/           SQLAlchemy models
  repositories/     persistence access layer
  schemas/          Pydantic request/response/event schemas
  services/         business logic
  workers/          Kafka consumer entrypoints

Что Демонстрирует Проект

  • Слоистую FastAPI backend architecture.
  • PostgreSQL как authoritative state store.
  • Redis cache-aside pattern с явной invalidation.
  • Kafka-style event-driven processing через RedPanda.
  • Отдельные consumer groups для независимых async workflows.
  • MongoDB как raw event store.
  • Durable idempotency через PostgreSQL плюс быстрый Redis-фильтр.
  • DLQ handling после ограниченных retry.
  • Docker Compose окружение для локальной разработки.
  • CI quality gates через Ruff, MyPy, Pytest и Docker build.
  • Kubernetes basics для stateless application workloads.

Production Notes

Проект намеренно компактный, но основные production concerns видны в коде. Для более строгих гарантий доставки событий стоит добавить transactional outbox: API будет записывать событие в outbox table внутри той же PostgreSQL transaction, а отдельный dispatcher будет публиковать события в Kafka/RedPanda.

Kubernetes manifests также намеренно не разворачивают базы данных и broker как production-инфраструктуру. В реальном окружении PostgreSQL, Redis, MongoDB и Kafka/RedPanda обычно берутся из managed-сервисов или отдельного infrastructure layer.

About

Production-oriented FastAPI backend with PostgreSQL, Redis cache-aside, MongoDB event store, RedPanda/Kafka, Docker Compose, CI and Kubernetes manifests.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages