Ленивые разработчики или сложные системы: почему в ИТ даже простые доработки требуют больше времени, чем кажется
Нередко простые доработки занимают гораздо больше времени, чем ожидается изначально. Важно смотреть не только на само изменение, но и на контекст, в котором оно осуществляется. И не раздражаться и не считать разработчиков ленивыми, если первоначальное ожидание по срокам реализации сильно расходится с реальностью.
Меня зовут Матвей Софьин, системный аналитик медицинской компании СберЗдоровье. В своей практике я не раз сталкивался с ситуациями, когда задачи кажутся простыми, но приходят в разработку и выполняются неожиданно долго. Рассказываю, почему это может происходить на простом и понятном примере реальной задачи в СберЗдоровье. Надеюсь, мой рассказ поможет быть более терпеливыми тем, кто выступает в роли заказчиков для доработок ИТ-систем.
Исходная задача и ожидания
СберЗдоровье активно развивает сервис онлайн-медицины (Телемед), благодаря которому пользователи могут изучить информацию о специалистах и записаться на онлайн прием к врачу. Еще одно направление — сервис записи к врачам на очный прием. Все можно сделать буквально в несколько кликов.
Чтобы сделать выбор специалиста удобнее для пользователя, внутри карточки каждого врача, в разделе «О враче», есть подробная информация о нем.
После небольшого исследования мы поняли, что нашим пользователям важно еще и сразу видеть особенности приема врача, чтобы не перебирать десятки специалистов, а иметь возможность сразу выбрать того, кто подходит под критерии поиска. В этом, среди прочего, могут помочь признаки — например, что врач принимает только взрослых, или принимает детей с 7 лет. Эта информация у нас была, но добраться до нее было непросто — надо было заходить в карточку каждого врача и переключаться на отдельную вкладку. Для понимания привожу исходные скриншоты карточки врача:
В рамках основного экрана с перечнем всех врачей этой информации у нас не было.
Чтобы реализовать такой функционал, мы решили улучшить карточки врачей и ввести специализацию. Специализация должна описывать и категоризировать, с чем может помочь врач. Макет дизайна карточки врача выглядел так:
После первой оценки задачи заказчиком представлялось, что нужно всего лишь:
- добавить пару полей в базе данных и панели администратора контента Телемеда;
- добавить поля в API для передачи данных на мобильные клиенты;
- доработать карточку врача в мобильных клиентах;
- заполнить поля через панель администратора.
Заказчику могло показаться, что с технической стороной задачи, как и в случае с приключением Рика и Морти, можно справиться за условные 20 минут и больше времени уйдет на наполнение карточек данными.
Реальность подкинула несколько вопросов
В реальности оказалось, что путь не такой прямой, как кажется.
Задача попала в разработку, мы провели системный анализ и поняли, что это задание «с двойным дном» и «подводными камнями», которые надо проработать. Например, сразу возник ряд вопросов:
- Где хранить справочник значений для этого поля — в хранилище нормативно-справочной информации (НСИ) или на сервере Телемеда?
- Как связана специализация со специальностью и клиникой врача?
- Как отображать и фильтровать «принимает детей» в приложениях клиентов?
- Надо ли менять импорт врачей?
- Как показывать информацию о специализации в списке врачей в панели администратора?
И это только часть из возникающих вопросов.
Начали с устранения путаницы в терминах
Помимо решения выявленных проблем, в первую очередь, нам надо было устранить путаницу между двумя терминами — «специализация» и «специальность».
«Специальность» у нас уже была — например, терапевт, аллерголог, дерматолог. Это устоявшийся термин и вопрос об отказе от него даже не поднимался. Под «Специализацией» мы как раз хотели ввести новую информацию с особенностями приема — например, «Принимает детей с 7 лет», «Проводит диагностику и лечение пациентов с заболеваниями сердечно-сосудистой системы». В итоге мы решили заменить один термин «Специализация» на два — «Особенности приема» и «Конкретизацию»:
- «Особенности приема» выбирается из заранее заданного списка.
- «Конкретизация» — свободное текстовое поле, которое дополняет особенности приема у конкретного врача.
Выбор места хранения значений
Мы разрабатываем хранилище нормативно-справочной информации (НСИ) и информация о специализации врачей выглядела хорошим кандидатом на вынос в нее.
Но мы столкнулись с тем, что для хранения в рамках НСИ нужны:
- интеграция;
- панель администратора для изменений;
- согласование с архитекторами.
Это правильный, но долгий путь. При этом в нашем случае требования к объему данных в справочнике были смехотворны: 10 значений, единичные правки в год.
Поэтому мы выбрали быстрое решение — реализовали хранение на стороне Телемеда. Если в будущем мы будем переходить на целевое решение, миграция не вызовет проблем.
Определение связи между особенностями приема, специальностью и клиникой
При записи на приём врачи «привязаны» к клинике и специальности. При этом каждый врач может работать в разных клиниках одновременно. Более того, в каждой клинике могут быть разные специальности — например, условный Петров Дмитрий Васильевич может быть терапевтом в клинике «Альфа», а в клинике «Бета» — дерматологом и аллергологом.
Но сразу возник вопрос, как связать эти данные с особенностями приема — нужно ли связывать их с клиникой или только со специальностью. Например, если врач работает педиатром в нескольких клиниках, то во всех клиниках его особенности приема одни и те же или они разные в разных клиниках?
После аналитики мы убедились, что ситуации, когда врач работает в нескольких клиниках, крайне редки. И чаще всего врач работает по одной специальности. Поэтому для простоты приняли решение связать особенности приёма только со специальностью — они остаются неизменными, пока есть хотя бы одна клиника, в которой врач работает, например, педиатром.
Отображение и фильтрация признаков в приложениях клиентов
Надо было решить, как выводить несколько признаков в общем списке и на карточке конкретного врача. Например, если один врач «принимает детей с 7 лет» и «принимает взрослых», надо ли оба пункта выводить в интерфейс? Выяснили, что признаки обладают «наследственностью» — если врач принимает детей с 3 лет, то он принимает детей с 7 лет и с 15 лет. Также у нас все специалисты, кроме педиатра и детского невролога, всегда принимают взрослых. Поэтому решили, что в списке врачей будем показывать только приём детей, а на карточке врача отображать и прием детей, и прием взрослых. Также для определенности поведения системы ввели правило: если вариантов «Принимает детей от Х лет» несколько — отображается наименьший по возрасту и только один.
Примеры интерфейса:
Также нам было важно понять, как фильтровать врачей по новым параметрам в клиентских приложениях. У нас есть признак «Принимает детей с рождения», «Принимает детей с года», «Принимает детей с 7 лет» и так далее — все связано с возрастами. Тут возникал вопрос в работе фильтров — нужно ли условно по умолчанию включать параметр «Принимает детей с 7 лет», если уже выбран «Принимает детей с года». Некорректная работа фильтров скажется на UX, чего нам нельзя допускать.
В итоге мы решили добавить в фильтрацию признак «Дети», в котором скрывается все подмножество с приемом детей: «Принимает детей с года», «Принимает детей с 7 лет» и так далее. Отдельно сделали фильтр «Принимает взрослых».
Примечание: Реализация фильтров в списке врачей на клиентах — отдельная задача, которая на момент выхода статьи находится в разработке. Пока я писал статью, прилетело НЛО и поменяло приоритеты задач:) Но в основе фильтрации, естественно, лежит информация об особенностях приема.
Изменение импорта врачей
В СберЗдоровье реализована функциональность импорта врачей. Фактически это процесс, который охватывает работу с данными врача от момента подачи и заполнения заявки до их проверки и создания карточки специалиста на нашем портале.
Если информацию об особенностях приёма вносить сразу, нам пришлось бы изменять механику работы:
- менять анкету;
- менять API импорта анкет;
- обучать специалистов работать с новыми данными и объяснять врачам, какую информацию нужно вносить.
Для уменьшения издержек мы решили оставить процесс без изменений, но добавить возможность внесения этой информации уже в готовой карточке врача.
Отображение в панели администратора
Среди прочего стал вопрос о необходимости сохранения истории изменений признаков и их описания у врачей. После анализа мы решили, что несмотря на то, что в теории такие знания могут быть полезны, но на практике можем прожить и без них.
Дальше нам нужно было определиться с отображением особенностей приема в админке и вариантом их выведения в общий список врачей. Причем надо было решить сразу несколько сопутствующих вопросов для списка врачей:
- Нужно ли создавать отдельную колонку в UI для признаков?
- Как выводить особенности приёма: текстом или значками?
- При наведении выводить список значений (например, «Принимает детей с года», «Принимает детей с 7 лет») или «склеивать» в одно (например, «Дети») ?
- Выводить ли текстовое описание в списке?
В своем кейсе мы решили обозначать информацию значками, при наведении на которые отображается подробная информация. При этом значки «склеиваем» — не дробим по возрасту, а показываем только взрослые или дети.
Реальность подкинула еще несколько вопросов
Кроме трудностей, возникших на этапе системного анализа, нам пришлось искать ответы еще и на вопросы, которые появились во время технического анализа непосредственно перед разработкой функциональности. Таких было несколько.
- Какой порядок признаков в API выбрать?
- В каком формате передавать описания на клиенты — JSON или HTML?
- Как хранить в базе особенности приема? Например, разработчики решали, хранить ли в виде битовой маски и по каким полям строить индекс в базе.
- Какой сервис использовать для построения списка по enum?
Каждый из них требовал анализа и проработки вариантов, что тоже сказалось на трудозатратах команды и времени решения задачи.
Главные выводы
Часто задачи для ИТ сложно оценить без предварительного анализа и погружения в детали — подчас даже при реализации условно простой фичи неожиданные трудности, вопросы и подводные камни начинают возникать как из шляпы фокусника. Если ИТ-продукт достиг сколь либо большого уровня зрелости и он существует не обособленно, а в контексте других продуктов внутри компании, то быстрые небольшие доработки для него маловероятны — внутренние и внешние логические связи могут потребовать множества хоть и небольших, но решений.
Безусловно, это не значит, что сроки выполнения таких задач не поддаются прогнозированию и не допускают установки дедлайнов. Просто надо держать в уме догму — «Каждая затребованная заказчиком функция всегда оказывается сложнее, чем кажется из его объяснений».
Не стоит требовать от команды разработки сразу финальные жесткие сроки — лучше спокойно относиться к этапам системного и технического анализа, а после каждого из них уточнять предполагаемые сроки. Например, в нашем кейсе на добавление простой функциональности вместо условных ожидаемых 20 минут ушло две рабочие недели. C’est la vie (такова жизнь).