Привет, Хабр! Последние шесть месяцев мы посвятили тому, чтобы сделать коробочную версию Service Desk из нашего SaaS-сервиса. Это была наша первая разработка коробочного продукта. С чего мы начинали, через что прошли и какой результат получили – рассказываем в статье. Изначально у нас было REST API приложение для Битрикс24. Оно помогало организовать работу службы поддержки внутри привычного сервиса. Заявки от клиентов приходили через форму или телеграм-бота и отображались в виде задач. Для того, чтобы отправить ответ клиенту, требовалось лишь оставить комментарий в самой задаче. Когда мы увидели, что наше решение востребовано, и появился запрос на функционал, который нельзя реализовать в приложении для Битрикс24, мы решили преобразовать его в полноценный SaaS-сервис. Он тоже позволял управлять заявками в Битрикс24, но уже через интеграцию с сервисом. Также в «облаке» появились другие интеграции: с почтой, Telegram, VK, Одноклассниками и сервисом «нетмонет», который позволяет перечислять чаевые менеджерам. Коробочная версия сервис-деска давно была у нас в планах. Но перейти к действию побудили обращения клиентов. Некоторые тестировали облачный сервис-деск, им нравился функционал, но они не могли его использовать из-за правил информационной безопасности компании. На основе собранных данных мы приняли решение приступить к реализации коробочной версии раньше, чем планировали. Первоначальная оценка проекта показала, что разработка коробочного сервис-деска может занять год и более. Обычно на первом этапе задаются самые приближенные сроки, которые уточняются и корректируются по мере работы над реализацией проекта. В итоге сделали за 6 месяцев. И хотя у нашей команды не было опыта реализации именно standalone-решений, но общий опыт команды и сформировавшиеся в компании рабочие бизнес-процессы вселяли в нас оптимизм.  К работе мы приступили 1 ноября 2022 года.  Сначала взялись за проработку вопроса, в каком виде будем поставлять наш продукт конечному пользователю: в виде виртуальной машины, контейнера docker, отдельных файлов или в каком-то другом виде.  В ходе нескольких жарких совещаний и эмоциональных споров пришли к единому решению, что будем поставлять в виде docker-контейнера. Для себя отметили следующие плюсы такой реализации:  docker-образ может быть развернут на любой linux-системе, поддерживающей docker (для простоты использования разработали установочный скрипт для разворота на чистой Ubuntu 22); требует меньше ресурсов для разработки и тестирования (так как позволяет быстро разворачивать несколько тестовых экземпляров приложения на одном сервере); docker-контейнер упрощает процесс доставки обновлений (по крайней мере, на данном этапе развития продукта); небольшой вес образа и не требует значительных вычислительных мощностей; скорость и простота разворота; отлично сочетается с обфускацией кода. На этапе разработки кода основным моментом было заставить решение работать на домене клиента, так как «облако» работало только на доменах третьего уровня. Тут мы усовершенствовали и SaaS-сервис. Теперь обе версии сервис-деска можно использовать на доменах всех уровней. Также отличие коробочных продуктов – их создают для использования одной организацией, в то время как в облаке могут параллельно работать несколько компаний. Это тоже предстояло переделать. Следующий момент – SaaS-сервис работал по протоколу https, а нужна была возможность работать по простому http. Иначе клиенту, при желании протестировать программу, пришлось бы создавать себе SSL-сертификаты. Нужно было переделать мастера начальной настройки: доработать механизм его появления, регистрации пользователей и проверки лицензий, в том числе для деморежима. Еще одна из задач – заставить наш облачный сервис работать без интеграций. Чтобы его можно было использовать в закрытых системах и без выхода в Сеть после процесса установки и лицензирования.  Также перед нами встал вопрос о защите кода и лицензировании. Рассмотрев решения, которые были на рынке, остановились на IonCube.  При работе с IonCube стоит учитывать такие моменты: Обфускатор работает только с PHP 8.1 и выше, из-за чего нам пришлось обновлять версию PHP для всего решения. Было весело, несмотря на незначительную разницу в версии PHP. IonCube требует, чтобы в вызовах функции и методов были указаны все параметры, включая опциональные (в случае именованных параметров). Пришлось больше внимания уделить тестированию после внесения всех необходимых правок.  В случае ошибок в обфусцированном коде nginx просто отдает 502 и больше никакой информации не указывает. Будьте к этому готовы. В обфусцированном коде нельзя использовать функции, которые работают с именами переменных как со строками, например, compact(). IonCube, кроме обфускатора данных, предлагал также инструменты для управления лицензированием. Но если обфускатор нам понравился, то функционал лицензирования не подошел. Кроме того, для готовых решений уже могут существовать способы взлома. Систему лицензирования мы разрабатывали с нуля. Та, что была у SaaS-сервиса, тоже не подходила. Основное отличие в том, что облачный сервис-деск работает на нашем сервере, поэтому лицензирование скрывать не нужно. В случае с коробочной версией это необходимо, так как механизм лицензирования работает прямо у пользователя. Если его оставить без защиты, то клиент сможет сам продлить себе лицензию. Тут защитой является уникальность разработки, также дополнительно мы использовали обфускацию. В случае с коробочным продуктом важно продумать и возможность технического обслуживания. Облачный сервис находится на нашем сервере, поэтому, когда у пользователя проблемы, мы легко можем посмотреть необходимые логи. Коробка же будет установлена на серверах клиента. И нужен был механизм, который позволит отправлять техническую информацию в случае проблем. Если клиенту потребуется наша помощь, к заявке он приложит архив с необходимыми логами, которые автономно ведутся в решении. Также мы разработали механизм обновления продукта. Технически это устроено следующим образом: скачивается актуальный образ решения, из него создается новый docker-образ, после перезапуска контейнера система уже работает с обновленным кодом. Все вспомогательные операции выполняются механизмом docker.  Чтобы обновлять продукт было удобно, все эти операции мы добавили в скрипт, который запускается одной командой. Если клиент не обновлял свое решение регулярно, то ему не придется последовательно устанавливать обновления для каждого релиза. Он запустит скрипт и ему будут установлена последняя версия, которая включает в себя все предыдущие. Последним и продолжительным этапом работы было финальное тестирование. На него мы потратили много ресурсов. Это связано со сложностью коробочных версий: нужно тестировать сам процесс установки программы. Для этого нужны чистый сервер и чистая система, поэтому таких установок удавалось сделать лишь 10-15 за день.  При тестировании мы фиксировали сбои, исправляли ошибки, по-новой шифровали, скачивали и устанавливали программу. Правки могли быть минимальные, но требовали большого количества действий. Мы создали продукт, который отвечает запросам наших клиентов: это сервис-деск, который может работать внутри закрытой системы, без выхода в интернет. Однако у нас еще нет механизма переезда из облака в коробку. И это критическая проблема, мы уже начали ее решать. Клиенты попросят об этом в первую очередь.  Дальше начнем подключать интеграции, которых пока нет в коробочной версии: с Битрикс24, мессенджером, ботами и т. д. Тут есть свои сложности. По сравнению с другими сервисами в Админ24 очень много интеграций. Это значит, что разработчику нужно знать не только свое приложение, но и те, с которыми оно интегрируется, а также их API. На третьем этапе реализуем возможности для добавления пользовательского функционала. Исходный код закрыт и останется закрытым, но добавлять функционал можно будет через API. В случае с коробочным продуктом недостаточно сделать приложение, которым удобно пользоваться. Важно и то, чтобы клиент смог его установить. Одно дело, когда мы разворачиваем программу у себя на сервере — сделаем все необходимое для установки, даже если для этого понадобится много времени. Другое дело — когда программа создается для самостоятельной установки пользователем. Нужно максимально упростить этот процесс. В итоге у нас получился всего один установочный файл, который развернет сервис-деск. Также мы впервые разрабатывали standalone-решение. Это был интересный опыт, который поможет нам при развитии как наших текущих, так и совершенно новых проектов.   Отметим и то, что отлаженные процессы в компании позволили нам работать в спокойном и плодотворном режиме. В результате мы все тщательно продумали, совершали меньше ошибок в процессе разработки и выпустили продукт раньше, чем планировалось изначально.  Service Desk