Телеграм-бот для ресторана: гость выбирает дату, время и столик, администратор подтверждает в чате. Двойное бронирование исключено на уровне базы.
Бот, через который гость бронирует столик, а администратор подтверждает или отклоняет заявку прямо в чате.
Для гостя: пошаговая форма — дата, время, число человек, столик, контакты. Занятые и уже прошедшие слоты помечены и не выбираются. Показываются только те столики, куда помещается указанное число гостей. Свои брони видно списком, отмена в один клик. Телефон можно отправить кнопкой или ввести руками, номер проверяется.
Для администратора: уведомление о каждой новой брони с кнопками «Подтвердить» и «Отклонить», гость сразу получает результат. Отчёты за сегодня, завтра, произвольный день и за всё время.
Главное решение — защита от двойного бронирования. Проверять занятость запросом перед вставкой ненадёжно: между проверкой и записью успевает вклиниться второй гость. Поэтому запрет живёт в самой базе — частичный уникальный индекс по столику, дате и времени, из которого исключены отменённые брони. Две одновременные заявки на один слот физически не могут обе записаться.
Python 3.11, aiogram 3, SQLite. Асинхронный код, конечный автомат для многошаговой формы, зависимости прокидываются в обработчики через встроенный механизм aiogram.
Фрагмент из настоящего кода проекта — чтобы было видно, что внутри.
CREATE TABLE IF NOT EXISTS bookings ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, username TEXT, table_id INTEGER NOT NULL REFERENCES tables(id), book_date TEXT NOT NULL, book_time TEXT NOT NULL, guests INTEGER NOT NULL, status TEXT NOT NULL DEFAULT 'pending');-- Один столик нельзя занять дважды на один и тот же слот.-- Отменённые брони из проверки исключаются.---- Проверять занятость запросом перед вставкой ненадёжно: между-- проверкой и записью успевает вклиниться второй гость. Здесь-- запрет живёт в самой базе, и обойти его нельзя.CREATE UNIQUE INDEX IF NOT EXISTS idx_booking_slot ON bookings (table_id, book_date, book_time) WHERE status <> 'cancelled';CREATE INDEX IF NOT EXISTS idx_booking_user ON bookings (user_id);CREATE INDEX IF NOT EXISTS idx_booking_date ON bookings (book_date);Заявка на проект
Заполните форму — обсудим детали и сроки.
TechnoMarket — магазин техники
