Skip to content

Reliable billing: outbox, concurrency safety, Compose and integration tests - #1

Open
Stepanda1 wants to merge 2 commits into
mainfrom
feat/reliable-billing
Open

Stepanda1 wants to merge 2 commits into
mainfrom
feat/reliable-billing

Conversation

@Stepanda1

Copy link
Copy Markdown
Owner

Что изменено

  • Транзакционный EF outbox: платёж, подписка, идемпотентный ответ и событие сохраняются атомарно.
  • PostgreSQL advisory lock защищает одинаковые ключи между API-экземплярами; другой payload с тем же ключом возвращает 409.
  • Цена определяется сервером; клиентский amount удалён из контракта. POST возвращает 202 + Location, GET читает текущий статус.
  • Отдельные процессы API и worker, durable RabbitMQ queue, retry, inbox и идемпотентная активация.
  • Миграции, ограничения БД, индекс для cursor pagination, bounded concurrency и ProblemDetails.
  • Docker Compose с запуском одной командой, non-root runtime, health endpoints, JSON logs, GitHub Actions.
  • Короткий README со схемой Mermaid, отдельные архитектурные решения и результаты проверки.
  • Удалены WeatherForecast, дублирующий template-проект, устаревший дамп кода и пароль из appsettings.

Проверено локально

  • Сборка: 0 ошибок и предупреждений.
  • 17 тестов на настоящих PostgreSQL/RabbitMQ прошли, включая 20 параллельных повторов, rollback после записи платежа и 429 при перегрузке.
  • Полный Docker-стек: миграции, HTTP workflow, отключение RabbitMQ, перезапуск API, replay и outbox recovery.
  • Локальный прогон 2000 новых запросов при concurrency 40: все приняты и активированы; 413.27 accepted requests/s, p95 152.23 ms. Условия и ограничения записаны в docs/verification.md; это не production SLO.

Совместимость и границы

  • Контракт POST изменён: amount больше не принимается; ответ теперь 202.
  • Начальная миграция рассчитана на новую БД. Старую EnsureCreated-БД переносить отдельно с backup.
  • Оплата симулируется. Авторизация, платёжный провайдер, recurring billing и refunds не реализованы.
  • Удалённый пароль остаётся в Git history; если он использовался вне локального примера, его следует сменить.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ef6f1f76e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Subscription & Billing/Program.cs Outdated
}

if (app.Environment.IsDevelopment())
Predicate = check => check.Tags.Contains("ready") || check.Tags.Contains("masstransit")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the outbox API ready during broker outages

When /health/ready is used as the API readiness probe, including the MassTransit health check makes every API replica become unready when RabbitMQ is unavailable, so a load balancer stops routing the POST requests that the bus outbox is specifically designed to accept and persist during that outage. For ServiceRole=Api, readiness should depend on PostgreSQL but exclude broker health; keep the transport check for workers that cannot make progress without RabbitMQ.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant