Привет, Хабр! Меня зовут Алексей, я разработчик в строительной компании ВитионГруп. Мы занимаемся ремонтом квартир в Москве, одновременно ведём 30–75 объектов, за 18 лет завершили более 1000 проектов.
В 2022 году я начал разрабатывать внутренний инструмент для управления ремонтными проектами. За три года из «чата с заказчиком» вырос полноценный продукт: PWA с чек-листами и таск-трекером, видеонаблюдением, конструктором смет, финансовым модулем и интеграцией с ИИ. Сейчас на базе этой системы работают два продукта по подписке, которыми пользуются строительные компании, а также частные мастера и их заказчики из разных регионов России и Казахстана.
В этой статье расскажу про архитектурные решения, грабли и нюансы, которые были неочевидны на старте.
Предметная область: почему готовые CRM не подходят
Прежде чем писать код, мы протестировали около 15 готовых решений. Проблема в том, что ремонтно-строительный проект — это не «сделка» и не «тикет». Это процесс на 6–18 месяцев, в котором параллельно участвуют:
-
заказчик (хочет видеть, что происходит, но не хочет вникать в детали);
-
сметчик (формализует пожелания заказчика и просчитывает объёмы работ и материалов)
-
менеджер (координирует всё);
-
руководитель (должен видеть картину по всем объектам одновременно, не погружаясь в каждый);
-
техконтроль (принимает работы у мастеров);
-
мастера разных специализаций (штукатуры, электрики, сантехники, плиточники — заезжают по очереди);
-
отдел снабжения (закупает и доставляет материалы).
Каждому нужен свой интерфейс, свой набор данных и свои права доступа. При этом все они работают над одним объектом, и информация должна быть синхронизирована в реальном времени.
Готовые CRM закрывали максимум 1–2 аспекта. Bitrix24, amoCRM — это воронки продаж, а не управление строительным проектом. Trello/Asana — управление задачами, но без смет, чек-листов с фотофиксацией и финансового контроля. Сметные программы содержат только функции по работе со сметой (а у нас, конечно же, давно составлена и отработана собственная смета). Специализированных решений для ремонта квартир, содержащих в себе все необходимые нам инструменты, на российском рынке мы не нашли.
Стек и архитектура
Почему PWA, а не нативное приложение
Ключевое требование: приложением пользуются все — от руководителя компании до мастера-штукатура. Мастера в основном работают на Android-смартфонах разных поколений, заказчики — часто на iPhone, менеджеры и сметчики иногда открывают систему с десктопа.
Три нативных приложения (iOS + Android + web) при нашем размере команды — нецелесообразно. PWA решила задачу: одна кодовая база, установка на рабочий стол, push-уведомления, работа без обновлений — пользователь всегда на актуальной версии.
Бэкенд реализован на PHP Laravel, фронтэнд — переработанный под нас шаблон AdminLTE (изначально для ускорения процесса разработки собирали интерфейс из простых готовых компонентов). Базовая (для собственного использования) версия программы сейчас представляет собой монолит с единой авторизацией и отдельными кабинетами для сотрудника, мастера и заказчика. В целом, такая схема на данный момент работает весьма сносно. Единственный глобальный момент, который не учли при планировании и пришлось подставить костыль — у одного заказчика может быть несколько объектов. Поэтому пришлось сделать возможность связки аккаунтов. В дальнейшем, для следующих версий программы, при проектировании уже сразу разделили аккаунты, профили и объекты.
Laravel отлично справляется с нашими задачами в первую очередь из-за своей распространённости: большинство из того, что нам на данный момент понадобилось, уже есть из коробки или в виде готовых пакетов. Пришлось делать самим только очевидные мелочи вроде отправки уведомлений в MAX — заодно оформили их отдельным пакетом по аналогии с laravel notification channels: уведомления отправляются стандартными средствами.
Разумеется, есть мелкие нюансы одного решения для всех платформ. На данный момент, например, есть один неприятный момент, решение которого пока не нашли: у нас в пушах о новых сообщениях в чате есть кнопки-экшны пометки сообщения прочитанным и ответа на него прямо из пуша. Так вот при прочтении сообщений кнопкой на некоторых версиях Android, шторка с пушами закрывается каждый раз при тыке кнопки прочтения — максимально неудобно, но со своей стороны пока сделать с этим ничего не можем.
По железной части: программа работает на виртуальном сервере reg.ru в Москве, для хранения загружаемых данных примонтирован сервер хранения с большим диском, арендуемых в FirstVDS, в постоянном режиме делаем бекапы всего на три разных сервера хранения, арендуемых у разных хостеров. Однажды полностью вышел из строя сервер хранения — пришлось заменить его другим и восстановить бекап — обошлось без потери данных, ну и пару раз находили понадобившуюся давно удалённую информацию. Других проблем, к счастью, пока не было. Хочется отметить отличную работу reg.ru: за всё время работы была только одна быстрая перезагрузка сервера, ничего по сути, нам не испортившая, и с тысячей извинений. В общем, ребята — молодцы.
Кодовую базу храним на GitHub — пока проблем, к счастью, нет, будем решать по мере появления. Деплой выполняется CI/CD скриптом, огромный плюс нашего «консервативного» фронтенда в том, что у него нет сборки — деплой простой, выполняется за считанные секунды «на горячую» — не прерывая работу программы. Благодаря этому имеем возможность публиковать все обновления максимально оперативно.
Архитектура ролей и прав доступа
В системе четыре типа кабинетов с принципиально разными интерфейсами:
Кабинет заказчика — минимум интерфейса, максимум прозрачности. Заказчик видит: видеотрансляцию с камер на объекте, чат с компанией (по принципу «единого окна»), фото/видео-отчёты по этапам, текущую смету, план работ, имеет доступ к ИИ-инструментам: эксперту по вопросам ремонта и дизайнеру интерьеров (может загрузить фото до ремонта и получить рендеры готовых интерьеров согласно своим пожеланиям). Не видит внутреннюю кухню: переписку с мастерами, себестоимость работ и остальное.
Кабинет сотрудника — доступ с внутренней системе в соответствии с набором разрешений, выставленных сотруднику руководителем. Это может быть переписка с заказчиками, сводка по объектам (всем или разрешённым), ведение расходов, работа с мастерами, чек-листы, сметы, аналитика и другое.
Кабинет мастера — только объекты, работы на которых мастер выполняет, в отдельном интерфейсе с набором необходимых мастеру функций. Персональный план работ с обратным отсчётом, переписка с компанией, чек-листы с видеоинструкциями, смета для мастера (без цен для заказчика), заявки на доставку материалов и забор их остатков, заявки на оплату чеков и выполненных работ, и другое.
Кабинет руководителя — по сути, dashboard всей компании на экране телефона. Включает всё, что есть у сотрудника, плюс ряд критичных функций:
-
Контроль коммуникации с заказчиками. Руководитель видит всю переписку сотрудников с заказчиками в реальном времени. Это позволяет следить за тем, чтобы стандарты общения, принятые в компании, соблюдались на каждом объекте, без необходимости присутствовать на каждом звонке
-
Финансовая картина. Видит, какие оплаты запрашивают мастера за выполненные работы, сколько планируется доходов от объектов, сколько планируется расходов, есть ли кассовый разрыв. При возникновении вопросов по тратам — может посмотреть, кто на что потратил, и задать вопрос техконтролю или снабжению
-
Управление пересменками бригад. Видит, какие работы заканчиваются и какие начинаются — чтобы максимально сократить технические перерывы между сменой бригад. Это критично: затянувшаяся пересменка — потерянные дни и деньги
-
Выборочный контроль качества. Может в любой момент открыть чек-лист по любой скрытой работе (электрика, сантехника) и посмотреть фотографии, как она была выполнена — даже спустя месяцы после завершения этапа
-
Мгновенное внедрение улучшений. Если при посещении объекта или по жалобе заказчика обнаруживается системный недочёт — руководитель добавляет новый пункт в чек-лист прямо со смартфона. С этого момента каждый мастер на каждом объекте обязан этот пункт заполнить. Не нужны инструкции, обучения, совещания — изменение внедряется мгновенно
-
Прогноз спроса. Отслеживает статистику по расчётам стоимости ремонта — видит, растёт спрос или падает, и может прогнозировать загрузку компании.
Технически в системе реализовано три отдельных интерфейса: кабинет заказчика, мастера и сотрудника. Кабинет руководителя — это кабинет интерфейс сотрудника с полным набором функций. Система позволяет завести нескольких руководителей по аналогии с сотрудниками. Разрешения выставляются каждому индивидуально, также есть «должности» — по сути наборы разрешений.
Чат как единое «единое окно»: нетривиальная маршрутизация сообщений
Одна из ключевых архитектурных задач — чат, в котором заказчик общается «с компанией», а не с конкретным человеком. При этом внутри компании сообщение видят все участники проекта и любой может ответить.
Вот как это работает:
-
Заказчик пишет в чат — сообщение появляется у всех сотрудников, привязанных к объекту.
-
Любой сотрудник отвечает — заказчик видит ответ от «компании», с указанием конкретного сотрудника.
-
Это выглядит не как групповой чат, а как личный: у заказчика есть его сообщения и сообщения компании, у сотрудников — сообщения заказчика выглядят, как сообщения собеседника, а все сообщении компании — как свои.
-
По такому же принципу реализован и чат с мастером: на одной стороне мастер, на другой — компания — все сотрудники.
-
Есть возможность переслать сообщение заказчика мастеру и наоборот.
-
В чате с заказчиком допускаются только текстовые сообщения — таким образом вся переписка автоматически документируется, и как показал наш опыт, при возникновении споров это отлично работает в суде. В чате с мастером допускается отправка голосовых сообщений: информацию до мастера иногда можно донести только при помощи интонаций.
Чат работает на вебсокетах, отправка уведомлений о новых сообщениях реализована с 5-секундной задержкой: это позволяет в момент отправки уведомления определить, не было ли оно уже прочитано получателем и отменить отправку: ведь нет смысла отправлять уведомление, если пользователь итак уже находится в чате и увидел сообщение.
Пуши с новыми сообщениями содержат две action-кнопки: «Прочитать» и «Ответить». Первая позволяет пометить сообщение прочитанным, а вторая — ответить на него сразу из пуша, не открывая чат. На айфоне это, к сожалению, не поддерживается.
Конструктор смет c экселькой под капотом
На протяжении многих лет мы оттачивали свою смету. Естественно, в эксельке. В итоге получился идеальный по точности шаблон сметы: файл с несколькими листами на тысячи строк, связанных друг с другом формулами. Отказываться от него никто категорически не захотел, поэтому пришлось вокруг него и построить сметную систему: добавили в каждую строку набор технических кодов, по которому её содержимое связывается с чем-либо в программе, добавили макросы.
На данный момент в нашей внутренней системе это работает так:
-
Смета каждого объекта формируется сметчиком в эксельке на основе шаблона, при помощи макроса в ней появляются отдельные листы со сметой для заказчика (только выполняемые на объекте работы и материалы, для них используемые), сметой для мастера (только работы со стоимостью для мастера), списком черновых материалов для закупки нашим снабжением и чистовых материалов для самостоятельной закупки заказчиком.
-
Этот файл загружается в программу и разбирается на составляющие: заказчик видит свою смету (уже в PDF) и список чистовых материалов для самостоятельной закупки, мастер — список работ для выполнения с их объёмами и стоимостью, снабженец — списки материалов для закупки с необходимым количеством и разделением по этапам закупки. На основании объёмов выполняемых работ программа формирует план работ по объекту с учётом выходных дней и праздников.
-
Все эти данные автоматически попадают в заявки на оплату работ, заказа материалов и тд — пользователям остаётся только проверить уже заполненные формы и при необходимости внести соответствующие изменения. Также, благодаря этому в любой момент программа знает, какие работы уже оплачены, какие материалы уже заказаны и сколько ещё осталось оплатить и заказать на объект.
-
В смету же вносятся оплаты работ заказчиками и они также попадают в программу. Всё это базово формирует финансовый модуль, сотрудникам остаётся лишь подтверждать оплаты и заводить организационные расходы.
Дальше — интереснее: удалось формализовать логику формирования сметы человеком — составили список вопросов, на основании которых она формируется, добавили каждой работе ещё один технический код, составили алгоритм, который формирует состав и объём выполняемых работ на основе ответов на вопросы. Материалы экселька рассчитывает сама по формулам. Упаковали список вопросов в телеграм-бот и форму на сайте, потестировали, причесали и отладили, и вот вам настоящая магия: за 30 секунд без смс и регистраций любой желающий может просчитать стоимость своего ремонта с точностью 85% (и то только потому что дальше уже идут детали и не-типовые решения): программа всего лишь заполняет эксельку и возвращает из неё итоговые суммы и сроки выполения работ.
С основными сложностями в этой схеме мы столкнулись при переработке нашей внутренней программы в программу для других ремонтных компаний по подписке. За основу также был взят наш шаблон сметы, цены в нём обнулены, так как у каждой компании в своём регионе цены разные. Из эксельки программа делает форму, в ней компания заполняет свои расценки и добавляет свои работы и материалы — вся эта информация уже хранится в БД. При формировании сметы объекта шаблон-экселька копируется в конкретную смету, в ней опять же формой-таблицей проставляются расценки компании и объёмы работ, и всё это сохраняется в файл. Макросы пришлось заменить PHP-кодом, но логика осталась прежней: на основании этой эксельки формируются разные сметы и списки.
Очевидно, что схема максимально нетривиальна, плюс, как показала практика, компании, пользующиеся программой по подписке всё же любят полностью заполнять всё своими данными, даже если в итоге получается то же самое, что им изначально предлагалось нами. К тому же, в нашей внутренней программе затруднено оперативное редактирование сметы: ведь это делается в эксельке, а значит нужно иметь под рукой ноутбук. Поэтому мы всё же решились отказаться от экселек и сейчас занимаемся реализацией всего, что они умеют, сразу в программе: работа большая, но то, что получается, нам уже нравится — должно быть интересно.
Чек-листы: формализация строительных процессов
Это, пожалуй, самая интересная часть с точки зрения предметной области. Мы взяли 18 лет опыта ремонтных работ и формализовали каждый вид работ в структурированный чек-лист.
Каждый чек-лист содержит:
-
текстовое описание каждого шага выполнения работы
-
фото- и видеообразцы правильного выполнения
-
обязательные фото или видео, которые мастер должен загрузить по завершении
-
пункты проверки для техконтроля
Архитектура наследования: базовые чек-листы создаются нами (ВитионГруп) во внутренней системе. Они автоматически синхронизируются в программу «Управление ремонтом» для внешних компаний. При этом каждая компания может убрать ненужные виды работ из своего перечня или добавить свои виды работ с собственными чек-листами — кастомизация одной компании не влияет на другие.
По сути, это многослойная система контента: базовый слой (наш) + пользовательский слой (для каждой компании).
Технически программы полностью разделены и независимы друг от друга, имеют разные БД. Раз в сутки в автоматическом режиме из внутренней программы во внешнюю выгружаются обновления. Встроенные данные хранятся отдельно от пользовательских. Таким образом, все компании получают динамично развивающуюся систему с ежедневными обновлениями и автоматическим внедрением всех нововведений как по функциональной части, так и по наполнению.
Видеонаблюдение
На каждом объекте устанавливаются IP-камеры, трансляция доступна заказчику прямо в личном кабинете. Это оказалось критически важным для дистанционных проектов — у нас есть заказчики, которые ни разу не были на объекте до сдачи. Мы используем камеры Ростелекома — у них есть возможность предоставления доступа к трансляции по ссылке.
Подключаем их к интернету при помощи модемов с сим-картами. Интересно, что никто из заказчиков почему-то не соглашается заранее проводить интернет к себе в квартиру — мы даже перестали предлагать это.
Интеграция с ИИ
В системе три точки интеграции с ИИ:
1. Редактирование текста в чате. Кнопка «волшебная палочка» — исправляет орфографические и синтаксические ошибки в сообщении перед отправкой. Особенно полезно при наборе текста голосом, а также для мастеров, которые допускают столько ошибок, что сообщение становится буквально нечитаемым. ИИ-шка каким-то чудом их понимает и всё правильно исправляет.
Используем для этого гига-чат. Сейчас такую функцию уже предлагают многие телефоны «из коробки», но иметь дополнительную функцию на виду прямо в чате всё ещё удобно и привычно.
2. Виртуальный эксперт. Отвечает на вопросы заказчиков, мастеров и сотрудников о строительстве и ремонте. Работает с изображениями.
Это снова гига-чат с соответствующим контекстом
3. Дизайнер интерьеров. По фотографии помещения до ремонта и пожеланиям пользователя генерирует идеи дизайна интерьера. Тут пока используем иностранные разработки — отечественных аналогов, хорошо справляющихся с задачей ещё не нашли.
По интеграции всё стандартно: API, вебхуки, оплата по токенам за использованные ресурсы. Выбрали GigaChat из-за хранения данных на российских серверах и отсутствия рисков с зарубежными API, а также, чтобы поддержать отечественного производителя, ну и вообще мы — патриоты.
Мультитенантность: от внутреннего инструмента к SaaS
Самый интересный архитектурный вызов возник, когда мы решили сделать из внутреннего инструмента продукт по подписке.
Проблема: наша внутренняя система («Личный кабинет») постоянно развивается и наполняется. Продукт для внешних компаний («Управление ремонтом») должен получать все обновления базового контента (чек-листы, виды работ, инструкции), но при этом у каждой компании — своя клиентская база, свои сметы, свои настройки, свои мастера.
Решение: двухслойная архитектура данных.
-
Базовый слой — заполняется нами в «Личном кабинете», автоматически синхронизируется в «Управление ремонтом». Это виды работ, списки материалов, чек-листы, видеоинструкции, шаблоны смет и так далее
-
Пользовательский слой — данные каждой компании. Изолированы, невидимы для других компаний
При обновлении базового слоя компании автоматически получают новый контент. Их собственные кастомизации при этом не затрагиваются.
Архитектурное решение весьма простое: взяли БД внутренней программы, ко всему добавили «tenant_id» — ID компании. Для данных, выгружаемых из внутренней программы он — NULL. Значения сортировок сделали очень большими числами, сделали таблицу сущностей, удалённых компаниями. Таким образом, компании могут добавлять свои данные, ставить их между встроенными, удалять (фактически — скрывать) встроенные данные, получать все обновления встроенных данных, и никак не влиять на данные друг друга.
Программа для заказчиков и мастеров
Одновременно с разработкой «Управления ремонтом» реализовали ещё одну идею (а точнее просьбу подписчиков нашего YouTube-канала) — программу для взаимодействия заказчиков и частных мастеров — «Мой ремонт». Здесь мы не просто урезали функции базовой версии, а выпустили полноценное, заточенное под свои задачи приложение, на другом стеке и с другой архитектурой: для бэкенда снова используем любимый Laravel, а для фронтенда выбрали React. Получились два отдельных проекта, взаимодействующих по API с документацией в Swagger. Работает очень быстро, выглядит красиво и современно, но деплой фронтенда занимает какое-то время на сборку — работу программы приходится приостанавливать. В планах сделать бесшовно — собирать и уже затем заменять файлы, но пока это не критично — деплоим «оптом» и не в «прайм-тайм».
В эту программу также ежедневно выгружаются новые данные из внутренней программы, некоторые разделы похожи: есть чек-лист, фото-отчёты, смета и проект, но здесь другая логика: заказчик сам управляет всем процессом, самостоятельно находит мастеров и добавляет их к объекту, ведёт расчёты, принимает работы по чек-листу и тд.
Из интересного по наполнению: на основании нашего шаблона сметы сделали в программе раздел рекомендуемых цен для частных мастеров на все виды работ. Программа также предлагает их при заполнении сметы. Расценки — самый часто задаваемый вопрос, как от заказчиков, так и от мастеров.
По технике: в этой программе удалось реализовать максимально крутой чат, как внешне, так и технически, с пагинацией, быстрым поиском, возможностью создания групповых чатов, кучей функций и стабильной работой на всех устройствах. Гоняли его на миллиардах сообщений: работает отлично. В целом, если бы не MAX, можно было бы и запустить его как отдельный продукт) В общем, всей командой получили удовольствие как от работы над ним, так и от полученного результата.
Уведомления: Push, Email, Telegram и MAX
Система отправляет уведомления по нескольким каналам:
-
Push-уведомления (через PWA Service Worker)
-
Email (на почту организации или индивидуальные для пользователей)
-
Telegram (при помощи бота)
-
MAX (при помощи бота)
Все уведомления отправляются при помощи Laravel Notifications, для MAX выпустили свой пакет. Каждый пользователь может выбрать виды уведомлений, которые он получает и канал их доставки.
Цифры
-
Одновременно ведём от 30 до 75 объектов
-
Более 1000 завершённых проектов за всё время
-
Экономим 50% рабочего времени сотрудников (вместо разъездов — приёмка в приложении)
-
50% заказчиков обращаются повторно
-
Пользователи внешних программ из разных регионов России и Казахстана
Что дальше
Планы:
-
Усиление ИИ-компонентов: в первую очередь думаем над разработкой полноценного ИИ-сотрудника, который всегда в курсе всей информацией и может ответственно и безошибочно ответить на вопросы вида «что решил заказчик объекта N по такому-то вопросу», «проводились ли такие-то работы и когда», «что там в смете по вопросу X» и так далее
-
Адаптация программы под строительство частных домов: мы сами занимаемся этим и активно дорабатываем чек-листы, шаблоны смет и добавляем новые функции
-
Внедрение управления умным домом: уже интегрировались по MQTT-протоколу с нашим партнёром по системам умного дома, но пока много вопросов, в первую очередь к ним
Вместо заключения
Строительная отрасль — один из последних бастионов «аналогового» бизнеса. Большинство компаний до сих пор управляют проектами через мессенджеры и таблицы. При этом потребности те же, что в любой другой сфере: прозрачность, контроль, масштабируемость.
Мы не пытались сделать «платформу для всех» — мы автоматизировали собственные процессы, отточенные за 18 лет работы. И оказалось, что этот опыт востребован: другие компании из регионов подписываются на систему, чтобы не проходить тот же путь с нуля.
Прикладываю большой видеообзор всех программ, о которых шла речь:
Спасибо, если вы вдруг дочитали это до конца. Буду рад ответить на вопросы в комментариях — и про архитектуру, и про предметную область. Строительный бизнес изнутри выглядит неожиданно интересно с точки зрения разработки.
ссылка на оригинал статьи https://habr.com/ru/articles/1023398/