Как мы сделали PWA для управления ремонтными проектами: от чата до ИИ-дизайнера интерьеров

от автора

Привет, Хабр! Меня зовут Алексей, я разработчик в строительной компании ВитионГруп. Мы занимаемся ремонтом квартир в Москве, одновременно ведём 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 всей компании на экране телефона. Включает всё, что есть у сотрудника, плюс ряд критичных функций:

  • Контроль коммуникации с заказчиками. Руководитель видит всю переписку сотрудников с заказчиками в реальном времени. Это позволяет следить за тем, чтобы стандарты общения, принятые в компании, соблюдались на каждом объекте, без необходимости присутствовать на каждом звонке

  • Финансовая картина. Видит, какие оплаты запрашивают мастера за выполненные работы, сколько планируется доходов от объектов, сколько планируется расходов, есть ли кассовый разрыв. При возникновении вопросов по тратам — может посмотреть, кто на что потратил, и задать вопрос техконтролю или снабжению

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

  • Выборочный контроль качества. Может в любой момент открыть чек-лист по любой скрытой работе (электрика, сантехника) и посмотреть фотографии, как она была выполнена — даже спустя месяцы после завершения этапа

  • Мгновенное внедрение улучшений. Если при посещении объекта или по жалобе заказчика обнаруживается системный недочёт — руководитель добавляет новый пункт в чек-лист прямо со смартфона. С этого момента каждый мастер на каждом объекте обязан этот пункт заполнить. Не нужны инструкции, обучения, совещания — изменение внедряется мгновенно

  • Прогноз спроса. Отслеживает статистику по расчётам стоимости ремонта — видит, растёт спрос или падает, и может прогнозировать загрузку компании.

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

Чат как единое «единое окно»: нетривиальная маршрутизация сообщений

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

Чат в ЛК заказчика, мастера и сотрудника, список чатов в кабинете сотрудника

Чат в ЛК заказчика, мастера и сотрудника, список чатов в кабинете сотрудника

Вот как это работает:

  1. Заказчик пишет в чат — сообщение появляется у всех сотрудников, привязанных к объекту.

  2. Любой сотрудник отвечает — заказчик видит ответ от «компании», с указанием конкретного сотрудника.

  3. Это выглядит не как групповой чат, а как личный: у заказчика есть его сообщения и сообщения компании, у сотрудников — сообщения заказчика выглядят, как сообщения собеседника, а все сообщении компании — как свои.

  4. По такому же принципу реализован и чат с мастером: на одной стороне мастер, на другой — компания — все сотрудники.

  5. Есть возможность переслать сообщение заказчика мастеру и наоборот.

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

Чат работает на вебсокетах, отправка уведомлений о новых сообщениях реализована с 5-секундной задержкой: это позволяет в момент отправки уведомления определить, не было ли оно уже прочитано получателем и отменить отправку: ведь нет смысла отправлять уведомление, если пользователь итак уже находится в чате и увидел сообщение.

Ответ на сообщение из пуша

Ответ на сообщение из пуша

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

Конструктор смет c экселькой под капотом

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

На данный момент в нашей внутренней системе это работает так:

  1. Смета каждого объекта формируется сметчиком в эксельке на основе шаблона, при помощи макроса в ней появляются отдельные листы со сметой для заказчика (только выполняемые на объекте работы и материалы, для них используемые), сметой для мастера (только работы со стоимостью для мастера), списком черновых материалов для закупки нашим снабжением и чистовых материалов для самостоятельной закупки заказчиком.

  2. Этот файл загружается в программу и разбирается на составляющие: заказчик видит свою смету (уже в PDF) и список чистовых материалов для самостоятельной закупки, мастер — список работ для выполнения с их объёмами и стоимостью, снабженец — списки материалов для закупки с необходимым количеством и разделением по этапам закупки. На основании объёмов выполняемых работ программа формирует план работ по объекту с учётом выходных дней и праздников.

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

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

Дальше — интереснее: удалось формализовать логику формирования сметы человеком — составили список вопросов, на основании которых она формируется, добавили каждой работе ещё один технический код, составили алгоритм, который формирует состав и объём выполняемых работ на основе ответов на вопросы. Материалы экселька рассчитывает сама по формулам. Упаковали список вопросов в телеграм-бот и форму на сайте, потестировали, причесали и отладили, и вот вам настоящая магия: за 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/