Модуль Booking
Назначение
codex_django.booking это Django adapter layer для booking engine, который живет в codex-services.
Его задача не в том, чтобы заново реализовать логику расписаний.
Его задача в том, чтобы связать Django project models и Django transaction semantics с provider-oriented интерфейсом движка.
Этот модуль одновременно дает Django-проекту:
- переиспользуемые abstract models для booking-сущностей
- ORM-based adapters, которые преобразуют проектные данные во вход движка
- selector-функции, удобные для views и feature-кода
Поэтому booking лучше понимать как интеграционный слой между доменными данными в Django и scheduling intelligence из codex-services.
Архитектурная Граница
Основной алгоритм расчета записи делегирован ChainFinder и связанным DTO из codex-services.
codex_django.booking фокусируется на Django-специфичных задачах вокруг этого движка:
- как моделируются мастера, услуги, расписания и appointments
- как ORM-данные преобразуются в
BookingEngineRequestиMasterAvailability - как обрабатываются row locking и границы транзакций при создании записи
- как безопасно инвалидируется busy-slot cache
Это разделение важно, потому что сами scheduling rules остаются переиспользуемыми между фреймворками, а Django-проект при этом получает практичный способ интеграции.
Основные Строительные Блоки
Компонованные Booking-Модели
Пакет mixins задает abstract model mixins для основных booking-сущностей:
AbstractBookableMasterAbstractBookableServiceAbstractBookableAppointmentAbstractWorkingDayMasterDayOffMixinAbstractBookingSettings
Это не готовые project models. Это scaffold-примитивы, которые позволяют проекту сохранить свои foreign keys, категории, статусы и бизнес-детали, но при этом соответствовать ожиданиям adapter layer.
Ключевой дизайн-выбор здесь это composability вместо жестко зашитой схемы.
Availability Adapter
DjangoAvailabilityAdapter это центральная часть модуля.
Именно он переводит состояние Django ORM в provider data structures, которых ожидает booking engine.
Он отвечает за:
- построение engine request по service ids и master selections
- определение, какие мастера могут выполнять какие услуги
- сбор working hours, break intervals, days off и busy intervals
- построение
MasterAvailability - блокировку строк мастеров во время создания записи
По сути этот adapter выступает переводчиком контракта между Django models и ChainFinder.
High-Level Selectors
В booking.selectors находятся pure-function точки входа, которые используют views и generated feature code:
get_available_slots()get_nearest_slots()get_calendar_data()create_booking()
Такая организация выносит orchestration из model methods. Благодаря этому логику легче переиспользовать в views, API, management commands и будущем generated code.
Cache Adapter
BookingCacheAdapter это тонкий мост к Redis booking cache manager из core.
Стратегия кэширования здесь намеренно узкая:
- кэшируются busy intervals по мастеру и дате
- свободные окна вычисляются динамически на основе этих интервалов
- после успешного изменения бронирования инвалидируются только затронутые master/date записи
Это позволяет делать cache invalidation точечной и не хранить производные slot maps как главный источник истины.
Синхронизация Booking Settings
AbstractBookingSettings задает конфигурируемые booking defaults:
- размер шага сетки времени
- default buffer between appointments
- ограничения на запись заранее
- fallback working hours
Его save hook синхронизирует настройки в Redis, следуя тому же общему паттерну, который используется в других частях репозитория для runtime-accessed административного состояния.
Модель Конкурентности
Самый важный архитектурный вопрос в этом модуле это не сам расчет слотов, а безопасное создание записи под конкурирующей нагрузкой.
create_booking() следует защитному сценарию:
- открыть транзакцию
- заблокировать нужные строки мастеров
- пересчитать availability под блокировкой
- проверить, что нужное время все еще доступно
- сохранить appointment или multi-service chain
- инвалидировать кэш только после commit транзакции
Такой дизайн защищает от типичной ситуации, когда слот был свободен в момент показа пользователю, но занят к моменту подтверждения.
Для multi-service booking модуль вводит BookingPersistenceHook protocol.
Это оставляет persistence сложных booking chains на стороне конкретного проекта, но сохраняет общую логику locking и revalidation.
Runtime Flow
flowchart TD
A["Django view or API"] --> B["booking selectors"]
B --> C["DjangoAvailabilityAdapter"]
C --> D["Project ORM models"]
C --> E["BookingCacheAdapter"]
C --> F["codex-services ChainFinder"]
B --> F
G["create_booking transaction"] --> H["lock masters"]
H --> I["recompute availability"]
I --> J["persist appointment or chain"]
J --> K["invalidate cache on commit"]
Роль В Репозитории
booking это domain adapter layer для appointment scheduling.
Именно здесь репозиторий превращает универсальные возможности booking engine в Django-совместимые строительные блоки.
Поэтому он отличается от:
core, который дает общие инфраструктурные примитивыsystem, который дает project-state models и admin workflownotifications, который занимается dispatch уведомлений вокруг доменных событий
booking расположен ближе к предметному поведению, чем эти модули, но при этом все еще остается adapter library, а не готовым конечным booking-приложением.
См. Также
notificationsдля confirmation и reminder workflow поверх booking eventssystemдля settings models, которые могут хранить project-level booking defaultscodex-servicesдля самого slot-finding и chain-solving engine, с которым интегрируется этот модуль