Как мы меняли разработку лучшего* мобильного банка под требования бизнеса

В это воскресенье я выступал в онлайн-конференции “System Design. Проектирование успешных систем” с рассказом про изменения в мобильном банке Tinkoff, которые мы стартанули в начале 2020 года. История достаточно интересная, поэтому я хотел бы поделиться ей и в текстовом виде.

Сначала расскажу почему я могу про это рассказывать. В Tinkoff я чуть меньше пяти лет и сейчас руковожу управлением разработки цифровых экосистем, которое состоит из 2х платформ: онлайн-привлечение и мобильный банк.

Про наше привлечение я рассказывал уже несколько раз на разных конференциях, например, на Teamlead Conf 2018 про работу команд или на ArchDays 2019 про изменение в архитектуре нашего публичного веб.

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

И начнем мы с начала … ну с того, как это начиналось для меня:) Дальше посмотрим что изменилось в требованиях бизнеса, что мы сделали для их удовлетворения и какие результаты получили, ну и закончим рассказ подведением итогов.

Сноски для расшифроки сноски лучший из заголовка статьи . Tinkoff — лучшее мобильное приложение для розничных клиентов в Центральной и Восточной Европе по мнению Global Finance The World’s Best Digital Banks 2020 и лучший мобильный банк для ежедневных задач (daily banking) в Mobile Banking Rank 2020 от MarksWebb

Конец 2019 года

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

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

Процессы ориентированы на крупные релизы с заранее определенным составом задач, которые должны доехать до пользователя вместе. Определенная дата-ориентир задается, но обычно она съезжает, так как при этом планировании отталкиваются от желаний бизнеса, а не capacity команды разработки.

Если говорить про архитектуру приложения, то в четком соответствии с законом Конвея, приложение реализовано монолитно, но с некоторым горизонтальным разделением по техническим слоям.

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

В общем, это отлично работало до определенного момента, так как

  • Было несколько основных продуктов —в их пользу приоритизировались ресурсы команды
  • Команда была относительно небольшой — порядка 50 человек — получалось вручную управлять процессами и приоритетами
  • Основной фокус на расширении функциональности приложения — Команда в приоритете пилит бизнес фичи и техдолг копится
  • Крупные и непериодические релизы устраивали бизнес

А потом кое-что поменялось.

Что изменилось

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

Одновременно назрело изменение в структуре ИТ департамента, который до 2020 года имел скорее функциональную оргструктуру с матричным формированием команд для развития продуктов. В 2020 году департамент разделился оргсутрктурно на отдельные подразделения, которые матчились на бизнес-вертикали (инвестиции, страхование, банк для юрлиц) или платформы, навроде, онлайн-привлечения или мобильного банка для физлиц.

В итоге, нам пришлось заняться перепроектированием.

Как мы решили это учесть

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

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

В итоге, мы естественно и органично пришли к концепции feature команд, выделенных под бизнес-направления и нескольких платформенных команд, которые обеспечивают общие подходы, инструменты и правила игры в рамках платформы мобильного банка. А для нормального процесса релизов мы решили перейти на подход release trains.

Концепция конечно хороша и я про нее упоминал только в вебе в статьях

Но ее реализация требует определенной работы, в структуре команд, процессах их работы, а также архитектуре приложений. Давайте рассмотрим их подробнее.

Как мы к этому приспособились

Проще всего это анализировать в разрезе команд и релизов. С учетом большого количества команд мы хотели унифицировать их путем внедрения общих правил, которые делятся на процессные и технические. Процессы очень важны и мы поговорим про них в следующий раз, так как все изменения должны быть интегрированы в ежедневную работу команд. Технические правила можно контролировать в рамках CI/CD пайплайнов. Также если мы говорим про разделение на отдельные команды, то важно, чтобы они были максимально автономными, а это возможно в случае правильной архитектуры приложения, которое разделено на модули по областям ответственности команд.

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

  • занимаясь жестокими мерджами отдельных веток с готовыми задачами в релизную ветку — это плохо масштабируется
  • разрабатывая с использованием trunk base development, но закрывать фичи флагами, которые включаются только при готовности фичи

Если подвести итог, то все эти штуки связаны тесно с правильной архитектурой приложения, процессом обеспечения качества и автоматизацией процессов разработки aka devops engineering. И все эти связи зафиксированы на рисунке ниже.

Теперь давайте подробнее поговорим про каждый из этих трех аспектов. И начнем мы с архитектуры.

Архитектура

Здесь в первую очередь важно разделение приложения на модули, которых существует 2 типа:

  • Общие модули, например, common-di, common-util, common-db, common-api, которые относятся к базовой функциональности приложения и нужны всем командам. За эти модули отвечают платформенные команды
  • Фичевые модули, которые специфичны для каждой feature команды и содержат business specific код, который реализует те сценарии, которые нужны для банковских, страховых, инвестиционных и т.д. продуктов. У одной feature команды может быть целая группа своих модулей и они за них отвечают.

Если посмотреть внутрь модуля, то он концептуально выглядит как трио: Presentation Layer, Domain Layer, Data Layer. Причем Domain Layer не зависит от уровня данных или представления.

Модули бывают без UI, тогда наружу они публикуют набор Use Cases, которые они предоставляют и которые можно использовать в других модулях. Иногда бывает так, что эта логика нужна только в одном месте приложения в рамках одного UI представления и тогда создается модуль, содержащий представление в виде MVP, Domain Layer и Data Layer. Такой модуль не публикует наружу интерфейсы Domain Layer.

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

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

Качество

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

Для того, чтобы автоматизировать эффективно мы пришли к использованию пирамиды тестирования, когда ясно какие виды тестов мы используем и для каких целей, а именно unit, интеграционные, ui, end-to-end тесты. Интересен был процесс внедрения их в команды, где разработчики и тестировщики совместно отвечали за базу автоматизированных тестов.

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

Кроме этого есть 2 проекта, которые находятся на стадии пилотов: crowdtesting и contract testing. Краудтестирование — это проект про использование толпы для тестирования функциональности мобильного приложения. Мы для этого используем внутреннюю платформу Klex, которая напоминает по своей сути Яндекс.Толоку. В принципе, проект рабочий, но требуется серьезная работа по подготовке тест кейсов в качестве задач для крауда. А контрактное тестирование — это шаг в сторону обеспечения того, что наши upstream’ы и конктракты с нами проверяются не на продакшене, а в рамках пайпланов.

Мобильный Devops

Здесь важно, что увеличилось количество команд, людей в командах и они начали генерировать больше сборок. Агрессивная автоматизация тестирования привела к возросшей нагрузке от прогона тестов. Поэтому CI/CD пайлайны и инфраструктуру по ним требовалось активно дорабатывать, чтобы успевать вывозить все ожидания, а лучше вообще снизить время сборки и прогонов тестов, чтобы их можно было запускать почаще.

Также важно иметь возможность проверять в шагах пайплайна технические правила к стилю, архитектуре и т.д. Это напоминает fitness functions из книги Evolutionary Architecture. В рамках iOS для этого можно использовать Danger, а в Android — Sonarqube.

Другой важной составляющей является мониторинг происходящего на клиентских устройствах или если смотреть шире выстраивание Mobile SRE для повышения надежность. Ну и одним из инструментов для повышения надежности является стабильный деплой изменений с использованием remote feature toggles, который может быть реализован через Firebase Remote Config

Итоги

Если подводить итоги, то можно сказать, что

  • Требования бизнеса поменялись
  • Нам пришлось редизайнить структуру команд
  • Это привело к перепроектированию
  • — Процессов разработки
  • — Архитектуры приложения
  • — Подходов к тестированию
  • — И инфраструктуре
  • Все эти изменения взаимосвязаны + реализуются параллельно

Интересно, что это не первое перепроектирование систем в моей карьере и раньше похожие вещи я делал для backend, web frontend и теперь для mobile. И у меня есть некоторые мысли про

Параллели между развитием back, web и mobile

По-факту, все эти подходы к построению систем нужны были для борьбы со сложностью и попыток ее обуздания. Под бекенд разработкой я имею в виду больше веб сервисы с публичным api, которое в свое время пытались проектировать с использованием SOA (Service Oriented Architecture). SOA было слишком сложным и не полетело, но на смену ему пришел микросервисный подход, который получив поддержку от devops подходов и современной инфраструктуре полетел отлично. В итоге, распил монолита на микросервисы стал стандартным решением для развития и эволюции legacy систем.

Прошло некоторое время. Логика начала постепенно переезжать на сторону фронтенда и собираться на стороне SPA (Single Page Application) и через некоторое время там появились собственные монолиты. Их начали пилить на микрофронтенды. Концептуально про этот подход я рассказывал на ArchDays 2019 на примере микрофронтедов Tinkoff.ru, а про практику рассказывал мой коллега на ArchDays 2020, когда этот подход был отлично имплементирован и решены все проблемы.

И наконец мы добираемся до мобильных приложениях. Правда, здесь у нас нет возможности разделить приложение на отдельные runtime элементы, но мы вполне можем применить модульный подход, про который я рассказывал выше.

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

Источники

  1. Выступление на Teamlead Conf 2018 про работу команд
  2. Выступление на ArchDays 2019 про изменение в архитектуре нашего публичного веб
  3. Обзор книги «SRE практики в разработке мобильных приложений»
  4. Статья «Как сделать API удобным для клиентов, особенно мобильных»
  5. Статья «Платформенные команды — что это такое и зачем они нужны»
  6. Статья «Ускоряем разработку: стандартный способ “в лоб” и более эффективный способ “сначала немного подумав”»
  7. Статья «Смена парадигмы работы с требованиями при переходе от квартальных релизов к двухнедельным»
  8. Статья «Эффективное взаимодействие продуктовых и платформенных команд разработки или “давайте жить дружно” © Леопольд»

Director of digital ecosystem development department at Tinkoff. Bachelor at applied math, Master at system analysis, Postgraduate studies at economics.

Director of digital ecosystem development department at Tinkoff. Bachelor at applied math, Master at system analysis, Postgraduate studies at economics.