Проклятая старая CRM

Весь прошлый год наши ребята допиливали CRM 2.0 с BPMS Camunda и всего десятью процессами вместо сотен статусов, а затем старались раскатать ее на пользователей и сервисы, ничего не уронив. Надеюсь, окончательно выпилив первую црм-ку (старейшую часть всего Skyeng) из нашей экосистемы, они поделятся граблями и находками здесь.

xbl2txmfq3_tqyihpdzi6jm-i-k.jpeg

А пока, заинтересовавшись темой, я нашел похожий случай — и решил расспросить Дмитрия Косова из Финама про их опыт отказа от наследия ранних 2010-х.
Привет, я тот самый «Сережа из Брянска», который решил прокачивать знания разработки, ведя блог и скринкасты по теме PHP. В этом году я хочу добавить к своим активностям подкаст: приглашать в него коллег по отрасли. В первом эпизоде — рассказ о переезде с первого Zend на Symfony. Если захотите больше технических подробностей, также посмотрите доклад Димы на Youtube. Ну в нашем обсуждении после доклада вы узнаете:

  • как не терять и находить мотивацию, если понимаешь, что до запуска твоего кода на продакшне — еще целый год,


  • почему любая документация если не врет, то привирает,


  • и как организован процесс двухлетнего рефакторинга без остановки производства фич на примере реального проекта и команды.


Приятного прочтения или прослушивания.

Между какими фреймворками выбирали в 2011-м году. И как выбирали новый в 2016-м


Дима, Финам: Я специально посмотрел, готовясь к выпуску: у нас ровно 4600 файлов в папочке, где именно наш код — не vendor, не всякие js«ки. Весит эта папочка 16 метров. А первый коммит у нас бы сделан аж в декабре 2011 года, — его автор до сих пор работает, это наш тимлид.

Изначально стек был выбран правильно. И даже в 2012-м году он было вполне современным — первый Zend был вполне актуален. Я тогда работал на другой работе, но помню, что мы как раз в 12-м где-то в конце весны выбирали стек для нового проекта. Мы смотрели на:

  • Zend — как раз вышел второй, но был слишком молод, по нему не было комьюнити,


  • первый Yii —, но нам не понравилась концепция ActiveRecord,


  • и что-то еще из экзотики.


И тоже выбрали первый Zend. В тот момент это был хороший, актуальный выбор. Но язык ушел вперед. А ведь хочется использовать нормальные неймспейсы, а не именование классов через нижнее подчеркивание. Хочется подключать какие-то готовые библиотеки из open source, которых, понятное дело, под первый Zend больше никто не пишет. Хочется привлекать сотрудников в команду — пару раз, когда мы искали новых людей, у некоторых прямо на лице было написано: «Я за это не возьмусь».

В конечном итоге у первого Zend просто прекратилась поддержка. Например, на 7.0 они еще выпустили патч обновления безопасности, а 7.2 и 7.3 мы патчили уже сами.

Мы немножко тянули с началом процесса переезда.


Какого-то глобального рисеча не было — мы просто посмотрели, что есть современного, актуального. Сравнили с тем, что на других проектах: мы не единственная PHP-команда в компании. Поняли, что Symfony всем устраивает — выглядит как проект, который будет жить еще некоторое количество лет, имеет обширное комьюнити, массу готовых библиотек, новых утилит и так далее.

Начинал это дело я — впиливал первые моменты именно для переезда, по движению в сторону Symfony. Когда я пришел, меня погружали в разные части проекта, чтобы я познакомился с ним максимально широко — и к моменту начала масштабного рефакторинга я знал его достаточно хорошо. И еще один товарищ пришел после того, как мы начали. Мы погружали его в процессе —, но старались не сильно пугать. По крайней мере, по началу)

Ок. Мы выбрали фреймворк. Что дальше?


Сережа, Skyeng: Есть два пути — можно переписать всё и сразу. Можно попытаться потихоньку перетаскивать. С чего вы начали?

Дима, Финам: Мы начали с холивара, каким путем идти. Опыта переписывания такого объема не было ни у кого. Например, у меня с предыдущего места работы был опыт переписывания небольшого автономного сервиса — там мы просто на месяц заморозили разработку, все переписали и поехали дальше. Здесь нам не хватило бы и года. Может быть, процентов 80 мы бы и успели сделать за за год, но, знаешь…

Есть принцип: первые 80% работы занимают 80% времени. Оставшиеся 20% работы займут еще 80% времени.


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

А вот почему так. У нас больше 250 таблиц в базе данных, и если отмести какие-то служебные таблички, это порядка 200 сущностей. Они довольно сильно друг с другом связаны и за счет этого количества связей очень сложно побить код на какие-то автономные логические куски. Как не разбивай, все равно из этого куска будет торчать связь: например, звонки и телефония связаны с менеджерами и клиентами. Поэтому мы поняли: если развернуть новое приложение, начать писать новые фичи для него, а старые потихоньку переносить — это выльется в двойную работу. Ведь код, который мы перенесем в новое приложение, нельзя полностью выпилить из старого. И нам придется поддерживать его в двух местах.

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


Это опыт переписывания слоя к доступу данных. Потому что когда-то давно вместе с первым Zend«ом в качестве основной базы данных была выбрана Mongo. Но практика показала, что выбор это не очень правильный.

Сережа, Skyeng: Да, у вас реляционные связи все, а вы документо-ориентированную базу выбрали.

Дима, Финам: Да, и когда я пришел, ребята как раз были в процессе переписывания с Mongo на PostgreSQL… И нам пришла в голову идея, что у нас есть слой доступа к данным. И раз мы уже умеем переписывать слои к доступу данных, может быть, мы возьмем от него чуть-чуть шире и захватим сразу слой ORM.

Если представить приложение как такой пирог, будет 5 слоев: ORM, доступ к данным, бизнес-логика, контроллер, вьюхи. И мы можем затронуть 2,5 слоя — полностью поменять ORM и доступ к данным, плюс частично — бизнес-логику. Не сами алгоритмы, а те классы и объекты, с которыми эти алгоритмы работают. Я четко знал, что тут можно впилить отдельно доктрину, ну и сделал это.

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


Начало пути может выглядеть примерно так. А дальше мы применили принцип, что мамонта нужно есть по частям. Иногда куски на поверку оказывались больше, чем мы думали, но базово в двухнедельный спринт бралась одна задача по переезду — и мы следили, чтобы не было фичевых задач в той же области.

Я ловил баги, откатывал, выкатывал


Сережа, Skyeng: Все-таки рефакторинг ответственная штука, как вы себя подстраховывали?

Дима, Финам: У нас есть некоторое количество юнит-тестов — ключевые моменты они покрывают. Есть какое-то количество функциональных тестов, автоматизированных нашим тестировщиком. Основная работа CRM — это работа с данными. И тестировать без данных, одними юнит-тестами не всегда получится: проще отправить пакет, проверить, что он нормально обработается, что по нему создалась сущность с нужными параметрами.

Естественно, мы проверяли много руками: особенно какие-то ключевые и важные вещи, вроде тех же клиентов и звонков.


Хорошо помню, как я делал эту задачу. Я звонил нашему руководителю колл-центра, и мы договаривались, что когда у них закончится рабочий день и останется только дежурный, я выложусь, а дежурный все проверит на реальных звонках. Я выкладывался, наблюдал в логах, ловил пачку багов, откатывался, правил их, предупреждал дежурного, выкатывал, снова ловил следующую пачку, откатывал… И так несколько итераций.

Сережа, Skyeng: Пройдя не весь, но вот уже наверняка больше половины пути, чтобы ты себе посоветовал тогдашнему?

Дима, Финам: Я бы, наверное, посоветовал немножко раньше развернуть то самое Symfony приложение поверх нашего. Чтобы убедиться, что то, что мы пишем, то, что мы делаем, оно действительно заработает. Я помню, как мы его развернули, запустили сначала из консоли, потом из контроллера, постучались к нашему слою бизнес-логики — и убедились, что приложение его видит, может обратиться ко всем сервисам, дернуть все методы, выгрузить результаты.

Просто я понял, каким сильным мотиватором оказалось осознание того, что мы действительно все правильно написали. Проверять, что ты идешь в правильном направлении, убеждаться, что ты все делаешь правильно, надо пораньше.

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

p.s.


Спасибо, что читали и слушали. Больше подкастов по теме PHP можно найти здесь.

А если хочется больше интересных докладов и разговоров вокруг них, «приходите» на третий виртуальный PHP-митап 30 мая.

© Habrahabr.ru