System Overview
Бекенд побудований на .NET із використанням принципів Clean Architecture. Це забезпечує незалежність бізнес-логіки від зовнішніх сервісів та бази даних.
Структура шарів (Clean Architecture)
Section titled “Структура шарів (Clean Architecture)”Проєкт розділений на чотири основні проєкти (шари), залежність між якими йде виключно ззовні всередину.
Core / Domain (Cinema.Domain) No Dependencies
Section titled “Core / Domain (Cinema.Domain) ”Ядро системи. Не має жодних зовнішніх залежностей.
- Сутності (Entities):
Movie,Session,Order,Seat,Ticket. - Бізнес-логіка: Доменні сервіси (
SeatLayoutService,OrderingDomainService). - Моделі: Переліки (
Enums), абстракції помилок (Result,Error) та кастомні винятки (DomainException). - Інтерфейси: Визначення контрактів (
IMovieInfoProvider), реалізація яких лежить на зовнішніх шарах.
Application (Cinema.Application)
Section titled “Application (Cinema.Application)”Містить бізнес-правила (Use Cases) нашої системи. Знає про Domain, але нічого не знає про базу даних чи веб-сервер.
- CQRS: Поділ на папки
Commands(запис) таQueries(читання) для кожного модуля (Users, Movies, Orders тощо). - Валідація:
FluentValidationдля перевірки вхідних даних перед виконанням логіки (CreateOrderValidator). - Поведінка (Behaviors): Пайплайни MediatR (
ValidationBehavior,IdempotencyBehavior) для наскрізної обробки запитів. - DТО: Об’єкти передачі даних та налаштування мапінгу.
Infrastructure (Cinema.Infrastructure)
Section titled “Infrastructure (Cinema.Infrastructure)”Шар реалізації. Тут міститься код для взаємодії із зовнішнім світом. Залежить від Application.
- База даних: Реалізація
ApplicationDbContext(Entity Framework Core) та конфігурації сутностей. - Сервіси: Реалізації інтерфейсів з Application (
SmtpEmailService,RedisSeatLockingService). - Фонові задачі:
CancelExpiredOrdersJob(наприклад, через Quartz). - Повідомлення: Консьюмери подій (
TicketPurchasedConsumer).
Presentation / API (Cinema.Api)
Section titled “Presentation / API (Cinema.Api)”Точка входу в систему. Відповідає виключно за маршрутизацію HTTP-запитів та налаштування залежностей (Dependency Injection).
- Controllers: Тонкі контролери, які лише приймають HTTP-запит і відправляють його в MediatR (
_mediator.Send()). - SignalR Hubs:
TicketHubдля забезпечення зв’язку з фронтендом у реальному часі. - Middleware: Глобальна обробка винятків (
GlobalExceptionHandler) та логування.
Потік даних (Data Flow)
Section titled “Потік даних (Data Flow)”Стандартний життєвий цикл запиту в нашій системі виглядає так:
- API: Контролер отримує HTTP-запит, формує об’єкт Command або Query і передає його в
ISender(MediatR). - Application (Pipeline): Запит проходить через
ValidationBehavior. Якщо дані невалідні, негайно повертається помилка. - Application (Handler): Викликається відповідний обробник (наприклад,
CreateOrderCommandHandler). - Domain / Infrastructure: Обробник звертається до репозиторіїв або зовнішніх сервісів через абстракції (Інтерфейси). Якщо це Command — викликаються методи сутностей для зміни стану.
- API: Обробник повертає об’єкт
Result<T>, який контролер трансформує у відповідний HTTP-статус (200 OK, 400 Bad Request, 404 Not Found).
Патерн CQRS Core
Section titled “Патерн CQRS ”Ми використовуємо патерн Command Query Responsibility Segregation (CQRS) за допомогою бібліотеки MediatR. Це дозволяє оптимізувати операції читання та запису незалежно одна від одної.
Commands (Команди)
Section titled “Commands (Команди)”Відповідають за зміну стану системи (Create, Update, Delete, Lock).
- Мають жорстку інкапсуляцію логіки в
CommandHandler. - Використовують Domain Entities для зміни стану (наприклад, бронювання місця
Seat). - Можуть бути ідемпотентними (реалізують
IIdempotentCommand), щоб уникнути дублювання критичних операцій (наприклад, оплати).
Queries (Запити)
Section titled “Queries (Запити)”Відповідають за отримання даних. Не змінюють стан системи (Read-only).
- Оптимізовані для швидкості: часто використовують DTO та
AsNoTracking()в EF Core, або навіть прямі SQL-запити. - Підтримують пагінацію (
GetMoviesWithPaginationQuery).
Зовнішні інтеграції
Section titled “Зовнішні інтеграції”Система інтегрується з низкою зовнішніх провайдерів для забезпечення повного циклу роботи кінотеатру. Всі ці інтеграції інкапсульовані в шарі Infrastructure:
- TMDB API (
TmdbService): Відповідає за синхронізацію кінокаталогу. Дозволяє імпортувати фільми (ImportMovieCommand), завантажувати постери, жанри та метадані (тривалість, опис). - Gemini AI (
GeminiEmbeddingService): Використовує моделі ШІ для генерації векторних вбудовувань (embeddings). Це дозволяє реалізовувати розумні рекомендації фільмів або семантичний пошук на платформі. - SMTP (
SmtpEmailService): Класичний протокол надсилання транзакційних email-повідомлень (підтвердження реєстрації, надсилання придбаних квитків користувачам). - Redis (
RedisSeatLockingService): Забезпечує розподілене блокування місць у реальному часі. Коли користувач обирає місце, Redis гарантує, що ніхто інший не зможе забронювати його одночасно. - QuestPDF (
QuestPdfTicketGenerator): Відповідає за програмну генерацію персоналізованих квитків у форматі PDF із штрих-кодами після успішної оплати замовлення.