Files
ticket-system/ARCHITECTURE.md
2026-03-05 14:27:30 +00:00

29 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура и бизнес-правила (Ticket System)
## 1. Базовые принципы
- **Стек:** FastAPI, SQLAlchemy 2.0 (asyncpg), PostgreSQL, Redis, RabbitMQ.
- **Модели данных:** Описаны в `backend/database/models.py`.
- **Ключевые сущности:** User, Tournament, Seat, Ticket.
## 2. Жизненный цикл билета (State Machine)
Статус билета (`TicketStatus` в таблице `tickets`) строго ограничен:
1. `AVAILABLE` — место свободно для бронирования.
2. `LOCKED` — место временно захвачено пользователем (15 минут на оплату).
3. `PAID` — оплата прошла успешно.
4. `SCANNED` — билет погашен на входе.
5. `REFUNDED` — возврат.
## 3. Сценарий А: Конкурентное бронирование (Критический путь)
Захват места должен исключать "состояние гонки" (race condition).
1. При POST-запросе на захват места (`/api/seats/{seat_id}/lock`), FastAPI обращается к Redis.
2. Пытается установить ключ `lock:seat:{seat_id}` с помощью `SETNX` и TTL 15 минут.
3. **Успех:** Если Redis вернул 1, обновляем статус билета в БД на `LOCKED` и привязываем `user_id`. Возвращаем HTTP 200.
4. **Отказ:** Если ключ уже существует, немедленно возвращаем HTTP 409 Conflict. БД не трогаем.
## 4. Сценарий Б: Асинхронная выдача билета (Idempotency)
Защита от двойных списаний и зависаний интерфейса при долгой генерации PDF.
1. Платежный шлюз присылает Webhook об успешной оплате.
2. FastAPI проверяет поле `idempotency_key` в таблице `tickets`. Если ключ уже обработан — игнорируем запрос.
3. Обновляем статус билета на `PAID`.
4. Отправляем событие `ticket_paid` (содержит `ticket_id` и данные пользователя) в очередь RabbitMQ. Отвечаем шлюзу HTTP 200.
5. Фоновый воркер забирает задачу, генерирует PDF (reportlab), грузит в MinIO (boto3) и сохраняет ссылку в БД.