Database Schema
Бекенд використовує реляційну базу даних із доступом через Entity Framework Core (EF Core). Схема спроєктована з урахуванням нормалізації та чіткого ізолювання доменних зон.
Основні домени даних
Section titled “Основні домени даних”База даних складається з кількох логічних блоків, які відповідають за різні аспекти бізнес-логіки:
- Користувачі (Auth):
Users,RefreshTokens. Відповідають за автентифікацію, ролі та управління довгостроковими сесіями. - Кінокаталог (Catalog):
Movies,Genres,MovieGenres. Каталог фільмів, який регулярно синхронізується та доповнюється даними з TMDB. - Топологія кінотеатру (Cinema):
Halls,Seats,SeatTypes,Technologies. Описують фізичну структуру залів та типи місць (Люкс, Стандарт тощо). - Сеанси та Ціни (Scheduling & Pricing):
Sessions,Pricings,PricingItems. Гнучка матриця цін, яка дозволяє налаштовувати вартість залежно від дня тижня та типу місця. - Продажі (Sales):
Orders,Tickets,SeatLocks. Транзакційні дані щодо купівель та тимчасових бронювань.
Конфігурація сутностей (Fluent API)
Section titled “Конфігурація сутностей (Fluent API)”Ми принципово не використовуємо Data Annotations (атрибути на кшталт [Table], [Required]) у класах домену. Це дозволяє зберегти ядро системи (Cinema.Domain) абсолютно чистим від залежностей бази даних.
Усі налаштування таблиць, зв’язків та індексів інкапсульовані в окремих класах конфігурацій (реалізаціях IEntityTypeConfiguration<T>) у шарі Infrastructure (наприклад, UserConfiguration, OrderConfiguration).
Ключові архітектурні рішення на рівні БД:
- Уніфікація часу: Усі дати та час зберігаються виключно в UTC. Для цього глобально застосовується кастомний
DateTimeUtcConverter. - Каскадність: Використовуються суворі зовнішні ключі (Foreign Keys) з каскадним видаленням там, де це диктує бізнес-логіка (наприклад, при видаленні залу видаляються всі його місця).
Механізм блокування місць (Seat Locking) Advanced
Section titled “Механізм блокування місць (Seat Locking) ”Для уникнення конфліктів “подвійного бронювання” (коли два користувачі одночасно намагаються купити один і той самий квиток) ми використовуємо гібридну дворівневу систему:
- Redis (Швидкі розподілені локи): Коли користувач обирає місце,
RedisSeatLockingServiceстворює тимчасовий ключ у пам’яті. Це миттєво блокує місце для інших і дозволяє надіслати подію про блокування всім клієнтам через SignalR. - База даних (Транзакційність): Під час оформлення замовлення створюються записи в таблиці
SeatLocks, а згодом - вOrders. EF Core транзакція гарантує, що на рівні реляційної цілісності місце дійсно вільне. Після успішної оплати замовлення блокування знімаються, а місця переходять у статус куплених (Tickets).