Бронювання столика в ресторані — задача з нетривіальними технічними вузлами: часові слоти, місткість, депозити та правила скасування. Багато проєктів спотикаються на race condition при одночасних бронюваннях. Рішення — серверна валідація з блокуваннями PostgreSQL SELECT ... FOR UPDATE. Наш досвід — понад 10 реалізованих проєктів для ресторанів різного формату, від невеликих кафе до мережевих закладів із сотнями столиків. Середній час обороту столика — 90 хвилин, депозит часто встановлюється у розмірі вартості однієї страви. Щоб уникнути колізій, ми використовуємо транзакції та черги Laravel.
Чому серверна валідація критична?
Головна помилка при проєктуванні — зберігати бронювання просто як рядки в таблиці з datetime. Це працює до першого «столик на 4 зайнятий частково» або «гість хоче столик біля вікна чи біля бару». Перевірка доступності повинна виконуватися на сервері: при виборі дати та кількості гостей запит до бекенду повертає доступні часові слоти. Сервер перевіряє відсутність перетинів за часом (з урахуванням avg_turnover_time, наприклад 90 хвилин) та наявність столиків потрібної місткості. Використання SELECT ... FOR UPDATE гарантує, що паралельні запити не створять дві броні на один столик. Клієнтська валідація тут небезпечна — race condition неминучий.
Модель даних для резервування
Правильна модель: Table (номер, місткість, зона, особливості) → Reservation (table_id, datetime_start, datetime_end, guests_count, status, deposit_status) → Guest (профіль, історія візитів, вподобання). Таблиця Reservation містить статус: pending, confirmed, cancelled. Deposit_status — held, captured, refunded. Для перевірки доступності використовується запит, який шукає перетини за часом для конкретного столика.
Як влаштовані депозити?
Ресторан хоче застрахуватися від no-show (до 15% гостей не приходять). Депозит при бронюванні через ЮKassa — холдирування суми на картці (метод hold), списання при підтвердженні візиту або повернення при скасуванні. Холдирування — це не списання, а блокування коштів, як зазначено в документації ЮKassa. Політика скасування: безкоштовно за 24 години, 50% депозиту за 4 години, 100% при no-show. Логіка реалізована на бекенді за допомогою Laravel scheduled jobs — вони перевіряють бронювання за годину до дедлайнів і запускають холдирування або повернення.
Приклад розрахунку часу обороту столика
Якщо середній час перебування гостя — 1.5 години, то для 20 столиків при завантаженні 80% необхідно пропускну здатність 20×0.8×24/1.5 ≈ 256 гостей на день. На основі цих даних налаштовуються часові слоти.Сповіщення
Push через FCM: підтвердження броні одразу, нагадування за 24 години та за 2 години. Якщо ресторан приймає бронювання вручну — push «Ваш столик підтверджено» після схвалення менеджером. SMS через СМСЦентр як резервний канал — не всі користувачі дозволяють push.
Адміністративна панель
Менеджер ресторану бачить план залу на сьогодні з візуалізацією зайнятих/вільних столиків, може змінити бронювання, додати нотатки («алергія на горіхи», «день народження»), відмітити no-show. Веб-інтерфейс на React — зручніший для десктопа в залі.
Таблиця: порівняння підходів до перевірки доступності
| Критерій | Клієнтська валідація | Серверна валідація |
|---|---|---|
| Швидкість відповіді | Миттєва | Залежить від мережі |
| Race condition | Можливі колізії | Виключені блокуваннями |
| Складність реалізації | Низька | Середня |
| Рекомендація | Тільки для демо | Для продакшену |
Таблиця: приблизний розподіл часу на етапи
| Етап | Тривалість (тижні) |
|---|---|
| Аналітика та прототип | 2-3 |
| Дизайн UI/UX | 2-3 |
| Розробка клієнта | 8-10 |
| Розробка бекенду | 6-8 |
| Інтеграція та тестування | 3-4 |
| Деплой та документація | 1-2 |
Що входить в роботу
Ми надаємо повний цикл розробки:
- Дизайн UI/UX (Figma макети)
- Розробка клієнтського застосунку на Flutter 3.x
- Розробка бекенду на Laravel + PostgreSQL
- Адміністративна панель на React
- Інтеграція з ЮKassa, FCM, SMS-центром
- Тестування та налагодження
- Деплой в App Store та Google Play
- Технічна документація
- Підтримка 2 тижні після запуску
Застосунок включає бронювання з вибором столика за схемою залу, депозити, push- та SMS-сповіщення, адмін-панель для керування бронями та інтеграцію з CRM ресторану. Всі функції реалізуються з урахуванням серверної валідації та захисту від race condition.
Терміни та вартість
Застосунок із бронюванням, депозитами, сповіщеннями та адміністративною панеллю — від 12 до 16 тижнів. Вартість розраховується індивідуально після аналізу вимог. Зв'яжіться з нами для обговорення вашого проєкту — отримайте консультацію за сценарієм. Замовте демо-версію, щоб оцінити функціонал у дії.







