Внутренние инструменты — это странный жанр. Ты не делаешь продукт для миллиона пользователей. Ты делаешь для двадцати человек, которые будут использовать это каждый день. И если облажалась — они скажут тебе об этом лично. Прямо на созвоне. Иногда с демонстрацией экрана, где всё сломано.
Я занимаюсь этим несколько лет. Python, внутренние сервисы, утилиты, автоматизация. За это время появился довольно конкретный взгляд на то, как надо работать. Не из учебника, а через синяки.
Мы никогда не работали наперёд
Ни разу. Ни одного кейса, где мы садились и говорили: «давайте сделаем инструмент, потому что через полгода понадобится». Всегда была живая проблема — что‑то медленное, ручное, раздражающее людей, которым нужно заниматься совсем другим. И всегда был дедлайн.
Честно говоря, я перестала считать это проблемой.
Когда знаешь реальную боль — не придумываешь абстрактные требования. Идёшь к людям и просишь: покажи, как ты делаешь это сейчас. И они показывают. Семь ручных шагов, огромные таблицы, копирование руками между двумя системами — и ты сразу видишь, что автоматизировать. Не то, что описали словами. То, что увидела глазами.
Я давно для себя поняла: требования в словах и требования в действиях — это разные вещи. Почти всегда.
Однажды мне передали сервис
Задача звучала просто: добавь несколько фич, отдел ждёт.
Сервис работал. Всё, что было до меня — работало исправно, не падало, отдел всем активно пользовался. Но когда начала копать под новый функционал, то обнаружила, что архитектура роста не предусматривала вообще. Я добавляла недостающий палец на руку, а у меня отваливались ноги.
Классика, в общем‑то: делалось быстро, под давлением, с установкой «лишь бы работало» — и это решение своё задание выполнило. Тогда. Но потом сервис стал важным, начал расти в требованиях, и каждое изменение превратилось в хождение по минному полю.
Я справилась — в сжатые сроки добавила всё, что просили. Но после этого пошла и честно сказала с чем столкнулась: вот что работает хорошо, вот где точки риска, вот что произойдёт, когда сервис продолжит расти. Без «тут всё плохо, кто это писал» — просто конкретно, с примерами.
И запросила полный рефакторинг.
Мне одобрили. Это, наверное, один из главных навыков в работе с внутренними инструментами — обосновать техдолг на языке рисков, а не на языке «красивого кода». Потому что красивый код никого не волнует. А «это замедлит каждую следующую фичу вдвое» — волнует.
Как я собираю требования
После одобрения рефакторинга первым делом созвонилась не с лидом и не с проджектом. С людьми, которые пользуются сервисом каждый день.
Спрашиваю примерно так: чем вы реально пользуетесь, а что висит мёртвым грузом? Что раздражает? Если бы вы сами делали эту фичу, то как бы она выглядела? Какой для вас результат: не какая кнопка, а что должно стать проще и удобнее?
Последний вопрос — самый важный. Люди почти всегда описывают решение вместо проблемы. «Хочу кнопку, которая делает N» — на самом деле им нужно просто не переключаться между двумя системами руками. Это разные задачи.
После отдела — к лиду / сеньору с техстеком и архитектурным предложением. Не «вот мой план, согласуйте», а «вот как я вижу, но где что не учла?» Это сохраняет кучу времени потом — гораздо дешевле переделать на бумаге, чем в коде.
Рефакторили по слоям
Отдельная ветка, изменения небольшими кусками, документацию обновляли параллельно — не «потом напишем».
Про документацию отдельно. Это не «приятное дополнение к коду» — это часть разработки, особенно когда твой PR будут смотреть люди из разных отделов. Человек, который видит проект впервые, должен понять структуру быстро, иначе вместо «несколько замечаний» получаешь «у меня вопросы» и ревью зависает.
Ревью всегда стараюсь выкатывать небольшими кусками. Большое ревью никто не читает внимательно — это не мнение, это практика.
Когда говорю себе "готово"
Не по чеклисту.
Сначала сама прохожу весь сценарий со стороны пользователя. Не «запустила → работает → ок», а реально воспроизвожу: типичный кейс, краевой кейс, и тот, который пользователь точно сделает не так, как я задумала. Потому что сделает 100%.
Смотрю на метрики: ничего не утекает, компоненты не конфликтуют.
Потом тестовая выдача: паре коллег и кому‑то из целевого отдела. Фидбек фильтрую жёстко: если критичное, то правлю сейчас; если «было бы удобнее если...», то в тудушку. Потмоу что если тащить всё это в релиз — не зарелизишь никогда.
Про сроки
Нетехнические коллеги иногда удивляются, почему «простая задача» занимает столько времени.
Тут я не использую метафоры, а просто раскладываю конкретно: вот сама задача, вот среднее время прохождения ревью в наших процессах (и иногда, почему это важно), вот правки по замечаниям, вот документация, вот тесты. Кстати, я часто работала по TDD (сначала тесты, потом код, потом рефакторинг) — это замедляет старт, но зато ускоряет финиш и сильно упрощает ревью! Ведь когда тесты описывают поведение, то код становится читаемым без дополнительных объяснений.
Когда раскладываешь всё это на стол — вопросов «почему так долго» обычно не остаётся.
Одна вещь, которую я усвоила
Это не упрощённая версия продукта. Это другая ответственность.
У продукта есть менеджеры, дизайнеры, поддержка, roadmap. У внутреннего инструмента — ты и двадцать человек с конкретной болью.
Если инструмент неудобный — они продолжат делать это руками. Молча. Возможно ты никогда не узнаешь.
И ещё одно, которое я усвоила через рефакторинг: внутренние сервисы растут всегда. То, что сделано «быстро под дедлайн» — вернётся с запросом на новую фичу. Это нормально. Ненормально, когда архитектура этого роста не предусматривает и каждое следующее изменение дороже предыдущего.
Именно поэтому я закладываю масштабируемость с первой итерации. Не чтобы усложнить — а потому что знаю: следующий запрос придёт раньше, чем кажется.
