Разработка мобильного приложения для бронирования услуг
Приложение для записи — это планировщик в обе стороны. Клиент видит свободные слоты и бронирует. Мастер видит свой день и управляет расписанием. Конфликты бронирования, двойные записи, отмены в последний момент — это не edge-cases, это ежедневная реальность. Архитектура должна с ними справляться.
Расписание: самое сложное место
Race condition при бронировании. Двое клиентов одновременно видят свободный слот в 14:00 у одного мастера и нажимают «Записаться». Кто получит слот? Без оптимистичной блокировки — оба. Правильное решение на сервере: оптимистичная блокировка с version поля или SELECT FOR UPDATE при создании записи. Мобильный клиент получает 409 Conflict — показываем «Извините, слот только что занят. Выберите другое время» и обновляем календарь.
Отображение расписания. Горизонтальный скролл дат + вертикальный список слотов — стандартный UI. На iOS — кастомный UICollectionViewCompositionalLayout, на Android — RecyclerView с nested RecyclerView (горизонтальный скролл дат). На Flutter — TableCalendar пакет или кастомное решение.
Слоты рассчитываются с учётом: рабочих часов мастера, длительности услуги, уже занятых слотов, перерывов между записями (например, 15 минут на подготовку после каждого клиента). Логика расчёта — на сервере, клиент получает готовый список доступных временных интервалов.
Мультимастер и мультиуслуга
Если запись идёт к конкретному мастеру — всё просто. Если клиент выбирает услугу, а система назначает первого доступного мастера — нужен алгоритм подбора: ищем мастеров с нужной специализацией, у которых есть свободное время. Round-robin или приоритизация по рейтингу.
Составные услуги (например, стрижка + окрашивание = 3 часа) — один слот на всю длительность, мастер занят непрерывно.
Push-напоминания
Напоминание за 24 часа и за 2 часа до записи. На сервере — scheduled job (cron, Sidekiq, Celery), который находит записи в нужном временном окне и отправляет push через FCM / APNs. Клиент не управляет этим — только принимает уведомление.
Отмена записи из уведомления — UNNotificationAction (iOS) / actionButton в FCM notification (Android). Пользователь отменяет прямо из pull-down уведомления, не открывая приложение.
Оплата при записи
Три варианта: без предоплаты, частичная предоплата, полная оплата онлайн. Частичная предоплата (например, 20%) — депозит против no-show. При отмене менее чем за X часов — депозит не возвращается. Логика возврата через API платёжного шлюза (refund / capture).
Холдирование суммы — продвинутый вариант: деньги замораживаются на карте в момент записи, списываются после визита. PaymentIntent с capture_method: manual в Stripe. Требует подтверждения со стороны бизнеса (confirmPaymentIntent).
Приложение мастера
Календарь на день/неделю с цветовой кодировкой по статусу записи. Карточка клиента: история визитов, предпочтения, заметки. Изменение статуса записи: подтверждена → клиент пришёл → завершена. Push мастеру на новую запись — высокоприоритетный (priority: high в FCM).
Блокировка времени вручную: мастер отмечает «недоступен 15:00–17:00» — слоты исчезают из выдачи для клиентов в реальном времени.
Отзывы
После завершённой записи — push с просьбой оценить услугу. Простая форма: звёзды + текст опционально. Отзыв привязан к конкретной записи — не к мастеру абстрактно. Рейтинг мастера = среднее по всем отзывам, показываем в карточке.
Стек
React Native или Flutter — оба подходят. Ключевой выбор не фреймворк, а правильный стейт-менеджмент для расписания: Riverpod (Flutter) или Zustand (React Native) с правильным invalidation при обновлении слотов. Websocket-соединение для real-time обновления занятости слотов — если мастер ведёт несколько каналов бронирования.
Ориентиры по срокам
MVP (запись к мастеру, базовое расписание, оплата, напоминания): 4–6 недель. Полноценная платформа с мультимастером, аналитикой занятости, мобильным приложением мастера и программой лояльности: 2–3 месяца. Стоимость — после анализа требований.







