Все посты
SaaSArchitectureMulti-tenancyNext.js

Мультитенантный SaaS: что мне на самом деле пришлось разобрать

Опубликовано 30 октября 2025 г. · 6 мин чтения

BookUp начался потому что меня это раздражало

Каждый барбершоп и салон здесь ведёт бронирования через Telegram DM и бумажный блокнот. Работает, пока не перестаёт — двойные брони, пропущенные записи, невозможность видеть свою неделю одним взглядом. Так что я построил то, что хотел бы у них видеть.

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

Сложная инженерная часть — сделать "каждый бизнес получает своё пространство" настоящим. Это мультитенантность, и вот что она на самом деле включает.

Поддомены: то, что видит клиент

Когда клиент бронирует в барбершопе Мустафы, он идёт на mustafa.bookup.uz. Не на bookup.uz/businesses/mustafa — этот URL говорит "вы снимаете место в чужом приложении." Поддомен говорит "это место Мустафы."

В Next.js это работает в middleware. Каждый запрос приходит, читаю заголовок host, отрезаю базовый домен, получаю слаг тенанта.

Приятное: wildcard DNS решает это бесплатно. Одна DNS-запись, каждый поддомен идёт на тот же сервер. Когда новый бизнес регистрируется — он сразу в сети.

Изоляция данных: та часть, которая кусает

Одна база данных, общие таблицы, в каждой строке тенанта есть столбец tenant_id. Это стандартный подход.

Часть, которая кусает, если не осторожен: вы где-то забываете добавить фильтр по тенанту. Строите запрос "последние брони", он отлично работает в dev с данными одного тенанта, а в production вы случайно показываете брони одного бизнеса на дашборде другого.

Что хотел бы сделать с первого дня: применять это на уровне модуля, а не сервиса.

Онбординг: не оставляйте людей в пустой комнате

Новый тенант регистрируется, выбирает слаг, попадает на дашборд. Пустое расписание. Нет услуг. Нет персонала.

Что я сделал: автоматически создаю три примерные услуги и заполнителя сотрудника. Тенант видит, как выглядит его страница бронирования с данными. Может удалить примеры, но первое впечатление — "о, вот как это работает", а не "с чего вообще начать."

Что бы сказал себе раньше

ID тенанта должен быть в токене аутентификации, контексте запроса и конструкторе запросов с первого дня.

Поддомены лучше путевых префиксов. URL транслирует владение, а владение делает продукт ощущаться премиальным.

Пустое состояние онбординга — первый реальный опыт пользователя. Инвестируйте туда рано.