Есть мини CRM написанная на PHP, под каждого заказчика создается субдомен на моем сервере с установленной копией. Помимо общих обновлений для CRM, делаются обновления по хотелкам отдельных клиентов в их копиях на субдоменах, т.е. от клиента к клиента код начинает существенно отличаться.
Как лучше организовать работу с общими обновлениями системы?
Сейчас есть 1 репозиторий и под каждого клиента заведена отдельная ветка, на каждую из которых по очереди выкатывается один и тот же комит с обновлением.
И вынести доделки в модули, чтобы сайт каждого клиента можно было собрать с нуля одним скриптом с нужными параметрами. Если сайт однозначно определяется модулями - так же однозначно определятся и нужные ему миграции при необходимости обновления не только кода, но и базы.
Можно делать специфических клиентов отдельными ветками и новые фичи мерджить в них явно либо прям переносом кода с отдельными коммитами (а то и в отдельной репе), но придётся регулярно воевать с конфликтами, и вообще это плохой путь. Но некоторые так делают, в том числе не только по историческим причинам, но и потому, что доработки под некоторых клиентов могут быть настолько объёмны, что тянут на отдельный проект, содержать который в рамках всеобщего универсального проекта может быть крайне сложно. Например, для моего работодателя разработчик в систему учёта заявок с нуля написал интеграцию с почтой под наших хотелки, основательно вкрученную в ядро всей системы.
Но в целом если хочется сделать хорошо, то лучше выделять ядро, а отдельный функционал выносить в включаемые фичи, в подключаемые модули, в кастомные хуки итд итп. Также в некоторых случаях может помочь создание переиспользуемых библиотек. Например, если есть несколько клиентов с различными почтовыми интеграциями, то вместо написания супермодуля по работе с почтой или нескольких огромных модулей сделать отдельную библиотеку, скрывающую сложные вопросы работы с почтой (приём, отправка, авторизация, SMTP/POP3/IMAP/TLS/etc, формирование писем, их парсинг итд, с ООП, конечно), а сами модули сделать лёгкими и компактными, использующими эту библиотеку.
Можно посмотреть как делают другие. Даже Битрикс (при всей обоснованной критике его громоздкости и технологической отсталости) написан так, что дополнительный функционал в нём делается не ковырянием в ядре, а модулями, компонентами, кастомными темами итд итп.
Код должен быть один на всех, а свистоперделки отключаться для "нехотящих" клиентов. Проще сделать 1 раз систему подключаемых модулей, чем обслуживать 50 веток кода... Кроме того - можно дополнительно брать эн денег за подключение модулей тем кто "раньше не хотел"...
ThunderCat, полностью поддерживаю.
Вариант с разделением кода сложномасшатируемый, при увеличении числа клиентов будет происходить хаос и будут возникать конфликты в коде. Лучше использовать подход "Feature Flags"
ThunderCat, поддерживаю про единое ядро для всех. И делать это надо как можно раньше, ПОКА НЕ ПОЗДНО, а то потом начнется "ой, клиентов много, мороки много, работает - не трогай" и всё в таком духе.
В теории модули на "вкл/выкл" - это прекрасно, но мы говорим не об универсальной развесистой платформе, вокруг которой по документации пляшут разработчики-прикладники.
Мини-CRM же. Логика под каждого клиента, максимально близкая к его рабочим процессам. Одни и те же модули под разных клиентов будут разными, причем принципиально разными. И разрабатывать, и поддерживать их придется наособицу.
Другое дело - что ветвить проект под эти различия нет смысла просто потому, что эти ветки никогда не будут мержиться. Нечего в них объединять.
Мини-CRM же. Логика под каждого клиента, максимально близкая к его рабочим процессам.
отличий не больше чем в плагинах вордпресса. Ядро полюбому достаточно универсальное, если на его основе делается 50 "разных" црм. Реально проще вынести хотелки в модули/конфиги и подключать по мере необходимости. Тот же 1эс примерно так и работает - на конфигурациях, обслуживая абсолютно разные предприятия на одном движке (вот уж не думал что когда-либо приведу 1с в качестве удачного примера...).
ThunderCat, у CRM для мебельщиков и CRM для рекламщиков, разумеется, будут общие модули.
Технические - юзеры, доступ, настройки, почта, события и т.п.
Бухгалтерские - контакты, контрагенты, реквизиты, шаблоны документов...
А потом все-таки наступает тот решительный момент, когда общее - кончается. Ну не может быть единого модуля заказа у двух настолько отличающихся предприятий. Либо от него останется только название и интерфейс, а все остальное придется разделить. Либо придется ваять что-то настолько универсально-обобщенное, что тот код, который все равно будет разным, будет даже более громоздким, чем если бы обобщения не было вовсе.
Во всяком случае, моя практика привела к таким выводам. Возможно, если бы я работал не один, а студией, и еще несколько лет - мне бы открылся какой-то более правильный путь... пока, увы, я его даже не представляю.
А потом все-таки наступает тот решительный момент, когда общее - кончается.
Естественно, цена универсальности - повышающаяся сложность. Другой ворпрос что обслуживание 50 менее сложных проектов все равно сложнее 1 более сложной системы. Чем вникать каждый раз чем отличается релиз 30 от 45, проще просмотреть в конфиге набор включенных функций для 30 и 45. И 1 раз поправить модуль для 45 (который скорее всего еще и в 4 и 38 используется).
Суть в том что написать 50 систем проще чем 1, а обслуживать проще 1, а не 50 (даже с учетом большей сложности).