Флагманский проект — 2026
Строим с нуля продукт, которым заменим Bitrix24 и табличный хаос у компаний, сдающих в аренду оборудование для мероприятий: звук, свет, видео, сцены, риггинг. Пилотом стал Stage Group — один из крупнейших прокатов Казани с парком в тысячу с лишним единиц. Дальше — мультитенантный SaaS на РФ+СНГ, отдельный продукт под Европу и западные рынки.
FastAPI + React
PostgreSQL + MinIO
SaaS-платформа
Пилот на клиенте
Кейс за 60 секунд
Клиент и боль
Stage Group, Казань — один из крупнейших прокатов event-оборудования в регионе (парк больше тысячи единиц). Bitrix24 не знал, что у каждого микрофона свой серийник и история ремонтов: склад жил отдельно от смет, субаренда — в чатах и Excel, документы терялись.
Что построили
Отдельный продукт под специфику проката: сделки с живой сметой, склад с поштучным учётом и append-only историей (неизменяемая лента событий по каждой железке), автоматическая субаренда при дефиците, публичный доступ подрядчикам по токену. Архитектура сразу под мультитенантный SaaS (один продукт, разные клиенты).
Кому подойдёт
Компании ивент-проката и аренды оборудования, которым Bitrix24 и amoCRM малы, а GetCourse/Tilda не подходят для специфики цикла «сделка → смета → монтаж → возврат».
О клиенте
Основатель — Артур. Под его руководством компания выросла в один из крупнейших прокатов региона с техническим обеспечением мероприятий федерального уровня.
Stage Group работает в Казани с 2010 года. Одна из крупнейших технических баз региона — звук, свет, видео, сцена, риггинг. Парк — больше тысячи единиц оборудования.
ВТБ, OZON, Samsung, KION, LG, КАМАЗ, Ростсельмаш, «Ак Барс Банк», концерт Моргенштерна*, УНИКС (закрытие сезона), Break Rumble Kazan, фестиваль «Исток Fest».
День Молодёжи РТ (10 000 зрителей), День города Казани (9 000), Всероссийская Студенческая Весна, Фестиваль Движения Первых РТ. Федеральный уровень мероприятий.
Международный машиностроительный кластерный форум на «Казань-Экспо» — звук, свет, видео, сцена. Многозальные конференции, синхронный перевод, пресс-зоны.
* Алишер Моргенштерн включён Министерством юстиции РФ в реестр иностранных агентов. Упоминание носит информационный характер и иллюстрирует масштаб мероприятий клиента.
Проблема
Готовые CRM построены вокруг цикла «лид → сделка → продажа». В ивент-прокате цикл принципиально другой: сделка живёт неделями, смета меняется до последнего дня, оборудование бронируется, монтируется, возвращается, чинится, списывается. Bitrix24 гнут под это годами — и всё равно упираются в потолок.
В Bitrix24 есть товар и остаток. Для проката этого мало — у каждой микшерной консоли свой серийник, история ремонтов, царапины. Два одинаковых монитора — на самом деле не одинаковые. Bitrix24 не знает, как с этим работать.
Менеджер добавляет 12 радиомикрофонов в смету — система не скажет, что 8 уже уехали на другое мероприятие в те же даты. Узнают в день монтажа, когда грузчики обнаружат пустые ящики. Дальше — паника и срочная субаренда.
Своего не хватает — зовут партнёров. Кто, что, по какой цене, когда забрать — всё в чатах и Excel. Раз в пару месяцев что-то теряется: партнёру забыли заплатить, оборудование не вернули вовремя.
Смета для ивента живёт в Excel. Пять версий в папке Google Диска, у трёх людей разные. Клиент спрашивает «а что мы согласовали?» — тишина. Excel-генератор сметы написан отдельно, в CRM не интегрирован.
Технический директор мероприятия — часто не штатный, а внешний. Чтобы он увидел, что по его ивенту — ему пересылают документы и скриншоты сметы в Telegram. Отдельного интерфейса нет, по NDA пускать нельзя.
Bitrix24 заточен под стандартный B2B-цикл: лид → сделка → продажа. В прокате цикл другой: сделка → динамическая смета → бронь оборудования → монтаж → демонтаж → возврат → акт. Надстройки на Bitrix24 превратились в лоскутное одеяло.
Решение
Можно натянуть воронку на прокатный цикл, пересадить смету в поля сделки, прикрутить склад через Битрикс24.Товары. На выходе — хрупкая надстройка, которую нельзя продать другим прокатам, нельзя масштабировать и нельзя нормально развивать. Кастомизация заморожена — любое обновление платформы может её сломать.
Отдельный продукт на собственном стеке: FastAPI + React, PostgreSQL + MinIO + Redis. Домен — прокат event-оборудования. Логика сделки, динамическая смета, поштучный склад с append-only историей, автоматическая субаренда при дефиците, публичный доступ для подрядчиков. Архитектура под мультитенантность и compliance сразу — под РФ, СНГ и позже под Запад.
UI пилота
Минималистичный светлый интерфейс на шрифте Urbanist с фиолетовым акцентом. Собственный UI-kit, не Ant Design и не шаблонные Material-компоненты. Ниже — четыре ключевых раздела в текущем виде.




Скриншоты пилотной инсталляции. Тестовые данные — часть настройки среды, не реальные клиенты Stage Group.
Архитектурные решения
Каждое крупное решение — выбор между альтернативами с последствиями на годы. Фиксируется документом рядом с кодом: что выбрали, что отвергли, почему. Ниже — развилки, которые задали облик RentOS.
Отдельная таблица equipment_unit с FK на equipment
Атрибут serial_number прямо на estimate_item
Почему: Серийник живёт дольше позиции сметы. Радиомикрофон за пять лет побывает в 200 сметах — если хранить серийник в estimate_item, получаем дубликаты и нет единого места истории. Отдельная сущность — один серийник, одна строка, вся история рядом.
equipment_unit_history с запретом UPDATE/DELETE на уровне СУБД
Текущее состояние + soft-delete с флагом is_active
Почему: Снапшоты отвечают на «что сейчас», история отвечает на «что было». При споре со страховой (микрофон сломался на ивенте) или клиентом (потерялся за ивент Х) нужна хронология событий, а не текущее состояние. Миграция с одного на другое — переписать половину бэка. Выбор сразу.
Запрос к активным сметам в период на каждый вызов
Хранимое поле + триггеры на изменения смет
Почему: Триггеры и очереди на перерасчёт — источник рассинхрона. При сложных правилах (отмена сделки, изменение дат, частичный возврат) рано или поздно хранимое поле расходится с реальностью. Прямой запрос с индексом по (equipment_id, event_start, event_end) — предсказуемо и отлаживаемо. Когда упрёмся в производительность — кешируем через Redis с инвалидацией по сделке, не раньше.
uuid4() на всех таблицах
BIGSERIAL / int id
Почему: Мультитенантный SaaS по определению объединяет данные нескольких инсталляций при репликации и бэкапах. На int-id это боль: коллизии, маппинг, offset'ы. UUID — безопасный по умолчанию ID, нельзя угадать или перебрать, сливается между средами без конфликтов. Чуть больше индекса — но проблема далеко за горизонтом этого проекта.
FastAPI + SQLAlchemy 2.0 async + asyncpg
Flask/Django + gevent или thread pool
Почему: 80% работы бэка — I/O: запросы к БД, MinIO, генерация Excel. На sync-фреймворке каждый HTTP-запрос держит поток, потолок масштабирования — сотни параллельных. На async — десятки тысяч на одном воркере. Плюс нативный async — это one fewer magic layer, чем monkey-patching в gevent. Дебажить проще.
Две параллельные инсталляции с общим кодом и разным compliance-слоем
Одна база + флаги region на записях
Почему: ФЗ-152 и GDPR — это не «флаг в базе», это где физически крутится сервер и кому принадлежит юрлицо. Одна база для всех юрисдикций — юридическая мина. Общая кодовая база + разные инфры + разные юрлица — единственная конфигурация, которая не лопнет при первой же проверке.
В цифрах
Инвентарь
Главное отличие проката от магазина — каждая единица уникальна. У микшерной консоли есть серийник, история ремонтов, царапина на левой крышке. Система учитывает это на уровне модели данных.
В справочнике хранится «Микрофон Shure SM58» с базовой ценой. А у каждого физического микрофона — свой серийник, история ремонтов, текущая сделка. Для кабелей и стоек экземпляры не нужны — отслеживаем только по количеству. Флаг is_serialized решает всё.
quantity_available — не хранимое число, а вычисление. Система смотрит на все активные сметы в период запрашиваемых дат и отнимает забронированное. Менеджер в смете сразу видит: в эти даты из 30 радиомикрофонов свободно 12.
Каждое событие с единицей оборудования — отдельная запись в equipment_unit_history. Никаких UPDATE и DELETE — только append. Карточка единицы — это хронологический список: получено → выдано на ивент Х → возвращено → отдано в ремонт → возвращено из ремонта. Аудит-трейл на всю жизнь железки.
sound, light, video, rigging, power, other. Фильтрация по категориям во всех списках: склад, смета, загрузочный лист. Логист за одну секунду видит, что по звуку в этой сделке — не проматывая пять экранов.
-- Shure SM58 #A12-004891 — полная лента событий 2023-06-12 received -- пришёл от поставщика 2023-09-04 rented deal#142 -- ивент «Казань-Экспо», форум 2023-09-07 returned deal#142 2023-11-18 rented deal#188 -- День Молодёжи РТ 2023-11-19 returned deal#188 2024-02-03 sent_to_repair -- треснул корпус 2024-02-21 repaired -- заменили корпус 2024-05-10 rented deal#267 -- корпоративный ивент OZON -- Никаких UPDATE, никаких DELETE. Только INSERT.
Сценарии из жизни
Фичи описываются просто, настоящая проверка — edge cases. Восемь сценариев из жизни ивент-проката, каждый из которых ломает типовую CRM и заложен в модель данных RentOS изначально.
→ Смета approved — read-only. Система создаёт новую версию сметы с приписанными позициями, старая остаётся в истории с пометкой superseded_by. Клиент видит обе в приложении — можно сверить, что изменилось. Excel перегенерируется и уходит заново.
→ Смена event_start/event_end у сделки триггерит пересчёт quantity_available во всех позициях её сметы. Если в новых датах есть дефицит — менеджер видит жёлтые плашки на конкретных позициях. Возможно создать auto-сублизу прямо отсюда, без перехода в раздел.
→ Конфликт ловится в момент добавления позиции во вторую смету. Система не блокирует — показывает, в какой сделке уже забронировано, на чьей ответственности, с какими датами. Менеджеры видят друг друга и решают: приоритет, замена, сублиза.
→ В equipment_unit_history пишется sent_to_repair с ссылкой на сделку. В позиции сметы этот экземпляр заменяется на другой из того же equipment — без изменения суммы. По возвращении в офис — ремонт, или списание, или возврат в активы. Вся цепочка в карточке единицы.
→ У companies — разные ИНН и настройка НДС. Смета генерится под юрлицо сделки: в Excel подставляется нужный шаблон, итог с/без НДС. Документы (акт, счёт, договор) тоже рендерятся по шаблонам юрлица.
→ Статус sublease не перешёл в returned, return_date просрочена. Логист видит просрочку в сводке. На следующих этапах — автоматические напоминания партнёру по email/SMS, эскалация админу. Пока это ручная проверка, но данные уже лежат так, что автоматизация накручивается без переделок.
→ Открывает страницу сделки в своём приложении (он в роли tech_director), смотрит смету по позициям. Нашёл расхождение — оставляет комментарий в позиции с фото. Менеджер в офисе получает пуш, принимает решение. Всё внутри одной сделки, без звонков и переписок в Telegram.
→ Токены подрядчика одноразовые на IP не делаем — это неудобно, пусть смотрит с любого устройства. Но токен привязан к одной сделке с TTL. Если есть подозрение на утечку — админ инвалидирует токен одной кнопкой, генерит новый, отправляет подрядчику лично.
Субаренда
На крупном ивенте 40 радиомикрофонов — нормально. Своих 28. Раньше дефицит замечали в день монтажа — и начинали экстренные звонки коллегам. Теперь дефицит ловится в момент составления сметы и сразу превращается в задачу на субаренду.
Пишет: нужно 40 радиомикрофонов на 3 дня. Система смотрит склад, видит — 28 свободно, 12 не хватает.
quantity_own = 28, quantity_sublease = 12. Позиция сметы остаётся одной строкой, но внутри знает — часть своя, часть под субаренду.
Автоматически появляется задача: subleases, привязанная к сделке, со статусом searching. Логист открывает единое окно по сделке и видит — нужно найти 12 микрофонов.
Логист выбирает партнёра (компания или контакт с is_partner = true), ставит pickup_date, return_date, cost. Статус меняется: searching → agreed.
picked_up. По умолчанию принимаем на доверии (is_checked = false) — это норма для рынка. Если проверили каждую единицу — ставят галочку.
returned → closed. Вся цепочка видна одной лентой по сделке: какое оборудование своё, какое партнёрское, когда и кому отдали, когда вернули.
Сметы
В ивент-прокате смета меняется до последнего. Клиент дозаказывает, логист находит более дешёвую замену, менеджер пересчитывает скидку. Старые CRM под это не заточены — поэтому у всех в индустрии сметы живут в Excel. Мы вернули смету внутрь системы.
Constraint на уровне БД: один deal_id → один estimate со статусом не cancelled. Никаких «пяти версий в папке». Меняется смета → меняется она же, с журналом изменений.
Итог позиции: quantity × price_per_unit × days. Цену менеджер может переопределить вручную (VIP-клиент), дни — посчитать по периоду сделки. Итог сметы пересчитывается автоматически.
Процент от суммы, фиксированный рубль, или отсутствует. discount_type enum. Никаких «давайте минус 15%» в переписке — скидка в смете, утверждена, зафиксирована.
Смета со статусом approved не редактируется. Хочешь что-то поменять — создаёшь новую версию, старая остаётся в истории. Принципиально: утверждённая смета = договорное обязательство.
При переходе в approved триггерится генерация Excel-сметы — макет под брендинг клиента, логика итогов, скидок, НДС. Файл кладётся в MinIO, URL пишется в estimate.excel_file_url. Клиенту уходит ссылка.
В ивент-прокате смета и загрузочный лист — разные документы. Смета живёт до ивента и меняется. Загрузочный фиксируется за 1–2 дня и содержит серийники конкретных единиц. В roadmap как отдельная сущность — не смешиваем с estimate.
# Итог сметы — пересчитывается при каждом изменении позиции
subtotal = sum(
item.quantity * item.price_per_unit * item.days
for item in estimate.items
)
discount = (
subtotal * (estimate.discount_value / 100) if estimate.discount_type == "percent"
else estimate.discount_value if estimate.discount_type == "fixed"
else 0
)
estimate.total_amount = subtotal - discountПодрядчик
Технический директор ивента — часто внешний исполнитель на один проект. Дать ему аккаунт в CRM нельзя (риски безопасности), пересылать PDF по Telegram неудобно. Решение — публичная страница по уникальному UUID-токену.
Менеджер нажимает «Сгенерировать ссылку для подрядчика» в карточке сделки. Создаётся UUID, привязывается к deal_id, с датой окончания действия.
Эндпоинт /contractor/{token}не требует авторизации. Отдаёт смету, документы, контакты команды, адрес площадки. Только по этой сделке, ничего лишнего.
Ссылка скомпрометирована — админ инвалидирует токен, генерируется новый. Данные из CRM не попадают в публичный интернет ни на секунду дольше, чем нужно.
Роли
В прокате участвуют разные люди с очень разным уровнем доступа. Собственник, менеджеры по сделкам, логисты на складе, технические директора на площадке, внешние подрядчики. На каждого — свой набор прав. Матрица доступа — на уровне архитектуры, а не на уровне if-ов в коде.
Полный контроль: пользователи, настройки, все сделки и сметы, склад, субаренда, документы. Для собственника бизнеса и руководителя CRM.
Ведёт сделки и сметы, работает с контактами и компаниями. Видит склад (смотрит, не редактирует), управляет субарендой. Основная рабочая роль.
Владелец склада: оборудование, экземпляры, история перемещений, субаренда. Сделки видит в read-only — планирует выдачу и возврат.
Технический директор мероприятия. Видит только свои сделки и документы по ним. Нужен ему, чтобы на площадке открыть смету и сверить, что привезли.
Внешний подрядчик без аккаунта. Доступ по уникальной UUID-ссылке к публичной странице своего ивента. Авторизация не нужна, но данные под токеном и с ограниченным сроком действия.
Compliance
Если планируешь масштабировать продукт на РФ и СНГ, а потом отдельно на Европу — compliance должен быть заложен с первой строки кода. Доделывать потом будет в разы дороже и долго.
Данные физлиц (контакты, сотрудники, подрядчики) хранятся только на серверах в РФ. Это требование заложено в архитектуру, не прикручено поверх — трансграничной передачи персональных данных в пилоте не происходит.
Под европейский рынок — отдельное юрлицо и отдельная инсталляция с соблюдением GDPR. Код общий, инфраструктура и юридическая обёртка — разные. Никакой «мы тут одну базу для всех сделали».
Self-hosted объектное хранилище. Договоры, акты, Excel-сметы, фото повреждений — всё в MinIO внутри периметра клиента. AWS/Google в пилоте не используется.
equipment_unit_history не допускает UPDATE и DELETE — только запись. В любой момент можно доказать: что, когда, где, кто. Полезно при спорах со страховыми и клиентами.
Модель данных
UUID как первичный ключ везде — нельзя угадать или перебрать. Внешние ключи с ON DELETE RESTRICT на сделках и сметах — случайно удалить историю оборудования невозможно. Миграции через Alembic, откат на любую версию одной командой.
Физлица — клиенты, технические директора, сотрудники партнёров. ФИО, телефон, email, компания, отметка is_partner.
Юрлица — клиенты и партнёры по субаренде. Название, ИНН, контактное лицо, is_partner.
Сделки. Тип: rental / order. Статусы: new → in_progress → approved → in_work → done. Ответственный менеджер + технический директор ивента.
Сметы. Одна активная на сделку (DB-constraint). Статусы: draft → sent → approved. Процентная/фиксированная скидка. Ссылка на Excel в MinIO.
Позиции сметы. Количество своё + количество под субаренду. Статус бронирования: preliminary → confirmed → in_use → returned.
Справочник оборудования. Категория, цена в день, базовое количество, флаг is_serialized для поштучного учёта.
Физический экземпляр — только для is_serialized = true. Марка, модель, серийник (UNIQUE), статус, текущая сделка, дата покупки.
Лента событий по экземпляру. Только append. Типы: received, rented, returned, sent_to_repair, repaired, written_off. Карточка единицы собирается из этой таблицы.
Субаренда. Партнёр (компания или контакт), статусы searching → agreed → picked_up → returned → closed, даты, стоимость, флаг is_checked.
Файлы по сделке и смете. Типы: contract, invoice, act, excel_estimate, other. Файлы в MinIO, в БД только ссылка.
Пользователи CRM со связкой на роль. JWT + refresh token, bcrypt-хэши паролей, ротация сессий, логаут из всех устройств.
API
Бэкенд строится как набор узких, async-first сервисов с чёткой слоистой архитектурой. Фронт на React + TypeScript тянет типы из OpenAPI — несоответствий между бэком и фронтом физически не возникает.
Все запросы и ответы — Pydantic-схемы. Автовалидация, 422 при несоответствии, OpenAPI-документация из коробки. Фронт подтягивает типы без дублирования.
FastAPI + SQLAlchemy 2.0 async + asyncpg. Сервер не блокируется на запросах к БД. Одного воркера хватает на десятки одновременных пользователей.
router → service → repository → model. Роутеры знают только про HTTP, сервисы — про бизнес-правила, репозитории — только про запросы к БД. Переписать endpoint — не задевает бизнес-логику.
Каждое изменение схемы — отдельный файл с версией. Как git, только для базы. Откатиться на любую точку — одна команда. Никаких «я тут поменял ALTER TABLE на проде».
Access-токен 15 минут, refresh 30 дней в httpOnly-cookie. На каждый endpoint — декоратор: какой ролью можно. 5 ролей, матрица доступа на уровне архитектуры.
Для страницы мероприятия — отдельный тип токена. Привязан к deal_id, с TTL, без JWT-паролей. Отдельный роут /contractor/{token}, авторизация не требуется.
Методология
Продукт такой сложности нельзя собрать «по ТЗ на страницу». Нужна структура: от разговора с людьми, которые каждый день делают смету, до пилота на живых данных. Процесс фиксирован и воспроизводим для каждой новой фичи.
Не «какой UI вы хотите», а «покажите, как вы реально работаете». День на складе с логистом. Час с менеджером, пока он составляет смету. Разговор с техническим директором о том, что он делает на площадке. Терминология записана ровно так, как её произносит индустрия — загрузочный лист, позиция, сабик, линейка.
Каждая бизнес-сущность становится таблицей или полем. Не наоборот. Если процесс в жизни звучит «одна смета на сделку, после утверждения не правится» — это DB-constraint и enum status. Если «оборудование бывает уникальное и обезличенное» — это флаг is_serialized и вторая таблица. Модель не навязывает бизнесу свои правила.
Перед кодом — документ. Архитектура, схема БД, state-машины, API-контракт, RBAC-матрица, угрозы безопасности. Каждое крупное решение — с альтернативой и причиной выбора. Клиент читает и кивает (или возражает) до первой строки кода. Проект не сваливается в переделки на поздних этапах.
Техспек режется на десятки узких задач: «контакты — CRUD», «сделки — статусы и переходы», «сметы — утверждение + Excel», «equipment_unit — история». Каждая задача — с приёмочными критериями. Не «сделать красиво», а «endpoint возвращает 422 при таком-то входе, 200 — при таком-то».
Для сервисного слоя — тесты пишутся до кода. «Создание сметы на сделку, где уже есть активная смета» → ожидаем exception. «Утверждение сметы с пустыми позициями» → ожидаем 400. Реализация затыкает тесты, а не наоборот. Это экономит месяцы отладки на живых данных клиента.
Каждая фича прогоняется через отдельный проход: безопасность (OWASP Top 10), консистентность со спекой, утечки PII в логах, корректность N+1-запросов, здоровье миграций. Реальные баги лезут не из-за незнания, а из-за спешки. Отдельный шаг отлова этого — дешевле, чем инциденты на проде.
MVP разворачивается на клиенте. Работает рядом с Bitrix24 — менеджер ведёт сделку и там, и там, пока не убедимся в паритете. Расхождения — в бэклог. Только когда ни одного расхождения на нескольких сделках подряд — рубим старое и переезжаем полностью. Никакого «большого переключения».
После пилота — выжимка паттернов, которые повторились у клиента. То, что заложено сразу в архитектуру. То, что специфично для Stage Group и идёт в конфигурацию тенанта. Продуктовое и клиентское разделяется на этом этапе — чтобы SaaS-версия не несла на себе чужую историю.
Мобильные приложения
Веб-админка закрывает офис. Но ивент-бизнес живёт на площадке и на складе — где ноутбук не открыть и 4G не тянет. Нативные приложения в планах сразу после стабилизации MVP — с офлайн-режимом и синхронизацией по приходу связи.
В поле: открыть сделку, сверить смету с тем, что привезли, отметить позиции как in_use / returned, сфотографировать повреждённую единицу и приложить к equipment_unit_history. Push-уведомления о смене статуса сделки, вопросах от клиента, дефиците на складе.
Сканер штрихкодов на складе: камерой считал код — единица оборудования у тебя в руках, статус меняется на rented. Возврат — аналогично. Поиск по серийнику голосом. Карточка единицы с историей перемещений — свайпом вверх.
Веб-страница по токену уже адаптивна — отдельное приложение подрядчикам не нужно. Но для менеджеров и логистов нативные приложения с офлайн-режимом критичны: на ивенте 4G лагает, приложение должно работать, а потом досинхронизироваться.
Дорожная карта
RentOS задуман не как разовая CRM под одну компанию. Stage Group — пилот, на котором обкатывается логика. Следующие этапы — мультитенантный SaaS под русскоязычный рынок и отдельный продукт под западные юрисдикции.
Stage Group, Казань
Развёртывание на клиенте, обкатка бизнес-правил, доработки по фидбеку. Проверяем, что логика проката корректна на реальных сделках и реальном складе.
Multi-tenant SaaS
Сеть прокатов в городах-миллионниках России, Беларусь, Казахстан. ФЗ-152 уже учтён в архитектуре — данные физлиц на российских серверах. Мультитенантность: одна инсталляция, разные рабочие пространства.
Отдельное юрлицо и бренд
Отдельная компания под европейский и западный рынок. GDPR, локальные платёжные шлюзы, английский UI, мультивалютность, европейские дата-центры. Кодовая база общая — конфигурации и compliance-слой свои.
Технический стек
Кто делает
Качество архитектуры определяет не инструмент, а человек. Ниже — как устроена команда, как принимаются решения и как выстроен процесс вокруг реального кода.
Ярослав Хорев — sole developer + decision maker в этом проекте. 10+ лет коммерческой разработки, собственные запущенные продукты (LookBot, Tonema, LMS для квест-бизнеса), кейсы с крупными брендами (Додо пицца, Спортмастер, GeekBrains, МФТИ). Полный стек: от схемы БД и архитектуры до фронта, DevOps и общения с клиентом.
Архитектурное решение — документ с альтернативами, trade-off и причиной выбора. Хранится в репозитории проекта рядом с кодом. Клиент видит, за что платит, почему именно так, и что было отвергнуто. Через полгода можно вернуться и понять — почему мы тогда пошли этим путём.
Современный инструментарий — часть процесса: автодополнение, генерация тестов, статический анализ, ревью миграций. Но AI не пишет архитектуру, не принимает решения о модели данных и не общается с клиентом. Эти шаги делает разработчик, и именно за них платят. AI ускоряет рутину — не заменяет инженерное мышление.
Приватный репозиторий в GitHub, Conventional Commits, pre-commit хуки (gitleaks на секреты, линтеры), Alembic-миграции с ревью перед накатом, тесты в CI, отдельный dev-VPS для интеграционной отладки. Не «пушим на прод и молимся» — структурированный процесс с безопасными точками отката.
Итог
Клиент просил заменить CRM. Мы предложили построить продукт — с моделью данных под прокат, поштучным складом, автосубарендой, публичными страницами для подрядчиков и compliance под ФЗ-152. Всё, что нужно большому ивент-бизнесу, в одном периметре.
Результат — платформа, которая обкатывается на Stage Group и дальше пойдёт продуктом. Сначала мультитенантный SaaS для прокатов РФ и СНГ, потом отдельная компания под европейский и западный рынок. Один из самых амбициозных проектов в нашем портфолио.
Если Bitrix24, amoCRM или 1С не закрывают специфику вашего бизнеса — обсудим, что можно построить своё. Прокат, логистика, производство, любая отраслевая модель с нестандартным циклом сделки.
Написать в Telegram