Синие арки и янтарный шар на отдельных светлых плитках.

К вопросам по статье

Два менеджера открыли календарь и увидели свободную площадку. Каждый оформил бронь, пока другой ещё заполнял карточку. Оба действовали правильно, но бизнес получил два обязательства на один ресурс.

Проверять занятость в момент записи

В календаре площадок занятость нужно перепроверять при сохранении. Показ свободного времени — подсказка для человека, а подтверждённая бронь требует согласованного решения по актуальным данным.

Если проверка и запись разделены без защиты от одновременных действий, обе операции способны пройти. Поэтому важно не только вычислить пересечение, но и обеспечить согласованное сохранение.

С чего начинается модель занятости

Прежде чем выбирать календарный компонент, нужно решить, какое обещание бизнес даёт клиенту. «Зал доступен на экране» означает только результат последнего чтения. «Бронь подтверждена» означает обязательство предоставить конкретный ресурс в конкретное время. Между этими фразами находится операция, которая должна учитывать действия других сотрудников. Именно её проектируют первой.

Для одного зала удобно рассматривать два интервала: время услуги и время, в течение которого ресурс недоступен другим заказам. Клиент арендует зал с 16:00 до 18:00, а подготовка начинается в 15:30 и уборка заканчивается в 18:20. Внутренний запрет пересечения относится к 15:30–18:20. В подтверждении клиенту при этом остаётся согласованная аренда, а не служебный интервал.

Такое разделение помогает избежать скрытой наценки временем. Если менеджер вручную увеличивает окончание каждой брони ради уборки, клиентская длительность и техническое ограничение начинают смешиваться. При переносе сотрудник забудет прибавить буфер, а отчёт по занятости посчитает подготовку продажей услуги. Отдельные поля делают происхождение блокировки объяснимым.

Таблица граничных условий

Допустим, уже подтверждена аренда 10:00–12:00. Если используется полуоткрытая модель интервала, начало входит в него, а окончание служит границей следующего. Это математическое соглашение нужно зафиксировать для разработчика; сотруднику достаточно понятных правил соседних записей. В таблице сначала рассматривается случай без подготовки и уборки.

Новый запросСостояние относительно 10:00–12:00Ожидаемое решениеЧто дополнительно уточнить
09:00–10:00Заканчивается на начале арендыМожно принять при отсутствии буферовНужна ли подготовка к 10:00
09:30–10:30Занимает начало действующей арендыОтказать в этом интервалеПредложить время до начала блокировки
10:30–11:00Полностью расположен внутриОтказать независимо от короткой длительностиНет ли ошибки выбора ресурса
09:00–13:00Полностью охватывает арендуОтказать: проверка одного начала недостаточнаВозможна ли другая площадка
11:30–12:30Занимает окончание действующей арендыОтказатьПроверить допустимый перенос начала
12:00–13:00Начинается на окончанииМожно принять только по принятому правилу буфераКогда закончится уборка
10:00–12:00Совпадает полностьюОтказать для другого заказаНе является ли запрос повтором той же операции
12:00–12:00Нулевая длительностьНе создавать обычную арендуНужно ли отдельное событие без занятия ресурса

Полезно проверить не только таблицу, но и её симметрию: результат не должен зависеть от того, какую бронь сравнивают первой. Ошибка «начало нового интервала не попало внутрь старого» пропускает случай, когда новая бронь полностью накрывает старую. Поэтому в техническом задании лучше приложить конкретные пары времени, а не ограничиваться фразой «проверять пересечение».

Почему две правильные проверки способны дать неправильный итог

Рассмотрим последовательность двух менеджеров. Первый прочитал, что зал свободен. Второй прочитал то же состояние. Первый записал бронь. Второй тоже записал бронь, поскольку его предварительная проверка была успешной. Ни один сотрудник не нарушил инструкцию, однако после завершения появились несовместимые обязательства. Исправлять нужно не внимательность людей, а границу согласованной операции.

Требование к системе звучит так: решение о доступности и создание блокирующей записи должны сохранять правило даже при конкурирующих запросах. Способ зависит от хранилища и архитектуры: используются ограничения базы, блокировки или иной согласованный механизм. Нельзя автоматически считать любой режим транзакции достаточным. В частности, важно понять, какое множество записей или какой ресурс защищает выбранное решение.

Если применяется повтор операции после конкурентного конфликта, заново оценивается актуальная доступность. Нельзя повторить только последнюю вставку, сохранив старый положительный ответ проверки. Для пользователя допустим понятный отказ или предложение другого времени. Недопустим «успех», который команда позже вынуждена превращать в отмену по телефону.

Рабочий сценарий

Пересечение броней одного ресурса

Подтверждать клиенту только действительно доступное время

01

Запрос

Сотрудник выбирает ресурс и интервал

02

Перепроверка

Сервер получает актуальные блокирующие записи

03

Конфликт

Сопоставляются интервалы и буферы подготовки

04

Фиксация

Доступность и новая бронь подтверждаются согласованно

05

Ответ

Клиенту обещают время только после подтверждения

06

Контроль

Отказ и альтернативный интервал видны менеджеру

Два одновременных сохранения?

Условие выполнено: Подтверждена только одна несовместимая бронь

Условие не выполнено: Доступность и новая бронь подтверждаются согласованно

Ответственный
руководитель площадки

Подтверждение
Отказ и альтернативный интервал видны менеджеру

Что измеряем
число подтверждённых несовместимых броней и доля конфликтов, завершённых выбором альтернативы

Скачать схему процесса в SVG · Скачать рабочую таблицу CSV

МоментМенеджер АМенеджер БКонтрольный вопрос
До сохраненияВидит свободный залВидит свободный залЯвляется ли экран обещанием или подсказкой
Первая попыткаОтправляет подтверждениеЕщё заполняет карточкуГде принимается окончательное решение
Конкурирующая попыткаПолучает результатОтправляет свой запросЗащищено ли правило между проверкой и записью
После обработкиИмеет одну подтверждённую броньВидит конфликт либо иной согласованный исходНе выданы ли два несовместимых подтверждения
Повторное чтениеОткрывает сохранённую карточкуИщет альтернативуСовпадает ли экран с фактическими записями

Паспорт блокирующей записи

Для диагностики полезно договориться о минимальном составе данных. У ресурса должен быть устойчивый идентификатор: «Большой зал» можно переименовать, поэтому само название не подходит для связи. У брони — собственный идентификатор и принадлежность к заказу. Отдельно сохраняются начало и окончание услуги, вычисленный или явно заданный интервал блокировки, статус и основание технического закрытия.

Часовой пояс нельзя восстанавливать по компьютеру менеджера. Если компания работает с несколькими городами, пользователь может находиться в одной зоне, а площадка — в другой. В карточке и подтверждении должно быть понятно, к какому местному времени относится обещание. Правило хранения и отображения фиксируется в проекте; приёмочный пример включает пользователя с отличающимися настройками устройства.

Время создания и время последней правки помогают восстановить последовательность, но не заменяют историю значимых переходов. Для спорной брони нужно увидеть, кто изменил ресурс, интервал или блокирующий статус. Комментарий «перенесли по просьбе клиента» полезен вместе с конкретной парой старого и нового состояния. Одной новой даты недостаточно, чтобы разобрать первоначальное обещание.

Перенос — это новое решение о доступности

При изменении существующей брони система сравнивает предлагаемый интервал с другими блокирующими записями. Собственную текущую запись исключают из сравнения по идентификатору, иначе любой перенос будет конфликтовать сам с собой. Но исключить все записи того же клиента или заказа нельзя: в одном заказе могут существовать отдельные реальные обязательства.

Если новый интервал недоступен, прежняя бронь должна остаться действующей. Сначала удалять старую запись, а затем пытаться создать новую опасно: отказ оставит клиента без обоих вариантов. На приёмке специально выбирают занятое время и после отказа повторно открывают исходную карточку. Проверяют не только сообщение, но и сохранность ресурса, времени и связанных условий.

Отдельный сценарий — два менеджера редактируют одну бронь. Даже если оба предлагаемых интервала свободны, второй пользователь способен незаметно перезаписать решение первого. Команда определяет, как обнаружить устаревшую версию карточки: например, предложить перечитать изменения и подтвердить новый выбор. Это другой вид конфликта, чем две разные брони одного ресурса, и его нельзя забыть в требованиях.

Повтор запроса после потери ответа

Менеджер нажал «Подтвердить», соединение прервалось, результат неизвестен. Отсутствие ответа браузеру не доказывает, что сервер ничего не сохранил. Если повтор всегда создаёт новый заказ, бизнес получит дубль. Если повтор всегда запрещён, сотрудник не сможет закончить работу после обычного сетевого сбоя. Нужна проверяемая связь попытки с итогом.

Практический вариант требований: у попытки подтверждения есть устойчивый идентификатор, который сохраняется при техническом повторе. Система умеет найти уже завершённый результат и вернуть его вместо нового действия. Формат и срок жизни такого идентификатора определяют при разработке. Он не должен использоваться как право доступа: найденную бронь всё равно показывают только разрешённому пользователю.

Не следует объединять по этому механизму разные намерения клиента. Один человек вправе забронировать зал дважды на разные дни. Даже совпадение контакта, времени и суммы не всегда означает технический дубль. Решение о повторе связано с конкретной командой, а подозрительные похожие заказы можно вынести в отдельный список для менеджера.

Разбор процесса при конкурентном отказе

Вход процесса — запрос на конкретный ресурс, время услуги и известные условия подготовки. Участники — менеджер, клиент, владелец календарных правил и система хранения. На первом шаге менеджер заполняет карточку; на втором сервер проверяет состав и полномочия; на третьем принимает согласованное решение о занятости. Выход — подтверждённая бронь либо объяснимый отказ без потери исходного обращения.

Ветка исключения начинается, когда выбранное время занято. Менеджер должен видеть достаточное объяснение, но не обязательно чужие контакты: для предложения альтернативы часто достаточно времени блокировки. Система сохраняет заполненные данные и позволяет изменить интервал. Если клиент просит исключение, оно направляется уполномоченной роли; обычная кнопка повтора не должна обходить правило.

Контроль процесса проводится по сохранённым обязательствам, а не по числу успешных уведомлений. Владелец площадки периодически проверяет пары конфликтующих интервалов, причины отказов и судьбу обращений после конфликта. Высокое число отказов может означать востребованность ресурса, неудобный подбор времени или техническую ошибку. Эти причины требуют разной реакции.

Матрица приёмки бронирования

СценарийПодготовкаОжидаемый итогАртефакт проверки
Параллельное созданиеДва пользователя, один зал, пересекающееся времяТолько один несовместимый запрос подтверждёнДве попытки и фактический список броней
Подготовительный буферУслуга закончилась, уборка ещё идётСледующая аренда не заняла буферПоля услуги и блокировки
Перенос в занятое времяЕсть действующая исходная броньОтказ не изменил прежнее обязательствоКарточка до и после отказа
Повтор после неизвестного ответаПервая команда сохранена, ответ не полученВозвращён прежний результат без второй брониИдентификатор попытки и количество записей
Редактирование устаревшей карточкиДва окна одной брониИзменения другого сотрудника не потеряны молчаИстория версий и решение пользователя
Отмена и новое созданиеОтменено блокирующее обязательствоВремя освобождено согласно принятому статусуИстория отмены и новая проверка
Другой часовой поясУстройство и площадка используют разные зоныПодтверждение относится к верному местному времениОтображение в обеих ролях
Ограниченная рольПользователь видит только занятостьОтказ объясним без раскрытия лишних данныхОтвет календаря и состав полей

Тест параллельности нужно выполнять действительно с перекрывающимися попытками. Два последовательных сохранения проверяют обычный отказ по уже видимой записи, но могут не обнаружить разрыв между проверкой и записью. В протоколе фиксируют число попыток, исходное состояние, полученные ответы и окончательное количество подтверждённых обязательств. Если проверка нерегулярно даёт два успеха, её нельзя считать пройденной на основании удачного повторного запуска.

Что передать в поддержку

Для будущего разбора достаточно короткого паспорта ресурса: идентификатор, часовой пояс, график доступности, буферы, блокирующие статусы и лицо, принимающее исключения. К нему добавляют таблицу граничных интервалов и несколько обезличенных примеров. Доступ к журналам ограничивают рабочей необходимостью; реальные контакты не нужно копировать в общие технические задачи.

Полезный диагностический запрос содержит номер брони, примерное время действия, ожидаемый ресурс и наблюдаемый ответ. Формулировка «календарь сломался» заставит поддержку заново выяснять весь маршрут. Скриншот помогает увидеть интерфейс, но основной разбор опирается на сохранённое состояние и идентификаторы. Это позволяет отличить конфликт ресурсов от устаревшего экрана, дубля команды или ошибки отображения времени.

Для технической реализации необходимо сверять гарантии конкретного хранилища. Например, официальное описание уровней изоляции PostgreSQL помогает обсуждать поведение конкурентных операций. Выбор одного режима по названию не заменяет проверку принятого правила на двух одновременных запросах. Упоминание документации здесь не утверждает, что эта база использовалась во всех календарных проектах.

Что обещать клиенту до подтверждения

Если выбранное время ещё не закреплено, назовите его предварительным вариантом. В условной аренде менеджер может обсуждать условия, пока другой сотрудник оформляет тот же зал. Скриншот свободного календаря в этот момент не должен становиться основанием безусловного обещания.

После конфликта сохраните содержание обращения и предложите разрешённые альтернативы. Если бизнес допускает ручное исключение, определите уполномоченного участника и последствия для уже подтверждённой брони. Обычный повтор сохранения не должен незаметно превращаться в такое исключение.

Документация и источники

Расскажите, что бронируете, какие перерывы нужны и кто меняет записи. Я отделю время услуги от блокировки ресурса и подготовлю проверку конфликтов, переносов и повторов. Направления автоматизации. Написать в Telegram · Написать в MAX

Короткие ответы

Вопросы по теме

Когда можно обещать клиенту время?

После подтверждения по согласованному механизму, а не по одному отображению свободного календаря.

Что должно произойти при неудачном переносе?

Согласованное исходное обязательство не должно исчезать из-за частичного неудачного изменения.

Повтор после потери ответа — новая бронь?

Не обязательно. Сначала устанавливают исходный результат по устойчивому ключу операции.