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

Я занимаюсь этим несколько лет. Python, внутренние сервисы, утилиты, автоматизация. За это время появился довольно конкретный взгляд на то, как надо работать. Не из учебника, а через синяки.


Мы никогда не работали наперёд

Ни разу. Ни одного кейса, где мы садились и говорили: «давайте сделаем инструмент, потому что через полгода понадобится». Всегда была живая проблема — что‑то медленное, ручное, раздражающее людей, которым нужно заниматься совсем другим. И всегда был дедлайн.

Честно говоря, я перестала считать это проблемой.

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

Я давно для себя поняла: требования в словах и требования в действиях — это разные вещи. Почти всегда.


Однажды мне передали сервис

Задача звучала просто: добавь несколько фич, отдел ждёт.

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

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

Я справилась — в сжатые сроки добавила всё, что просили. Но после этого пошла и честно сказала с чем столкнулась: вот что работает хорошо, вот где точки риска, вот что произойдёт, когда сервис продолжит расти. Без «тут всё плохо, кто это писал» — просто конкретно, с примерами.

И запросила полный рефакторинг.

Мне одобрили. Это, наверное, один из главных навыков в работе с внутренними инструментами — обосновать техдолг на языке рисков, а не на языке «красивого кода». Потому что красивый код никого не волнует. А «это замедлит каждую следующую фичу вдвое» — волнует.


Как я собираю требования

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

Спрашиваю примерно так: чем вы реально пользуетесь, а что висит мёртвым грузом? Что раздражает? Если бы вы сами делали эту фичу, то как бы она выглядела? Какой для вас результат: не какая кнопка, а что должно стать проще и удобнее?

Последний вопрос — самый важный. Люди почти всегда описывают решение вместо проблемы. «Хочу кнопку, которая делает N» — на самом деле им нужно просто не переключаться между двумя системами руками. Это разные задачи.

После отдела — к лиду / сеньору с техстеком и архитектурным предложением. Не «вот мой план, согласуйте», а «вот как я вижу, но где что не учла?» Это сохраняет кучу времени потом — гораздо дешевле переделать на бумаге, чем в коде.


Рефакторили по слоям

Отдельная ветка, изменения небольшими кусками, документацию обновляли параллельно — не «потом напишем».

Про документацию отдельно. Это не «приятное дополнение к коду» — это часть разработки, особенно когда твой PR будут смотреть люди из разных отделов. Человек, который видит проект впервые, должен понять структуру быстро, иначе вместо «несколько замечаний» получаешь «у меня вопросы» и ревью зависает.

Ревью всегда стараюсь выкатывать небольшими кусками. Большое ревью никто не читает внимательно — это не мнение, это практика.


Когда говорю себе "готово"

Не по чеклисту.

Сначала сама прохожу весь сценарий со стороны пользователя. Не «запустила → работает → ок», а реально воспроизвожу: типичный кейс, краевой кейс, и тот, который пользователь точно сделает не так, как я задумала. Потому что сделает 100%.

Смотрю на метрики: ничего не утекает, компоненты не конфликтуют.

Потом тестовая выдача: паре коллег и кому‑то из целевого отдела. Фидбек фильтрую жёстко: если критичное, то правлю сейчас; если «было бы удобнее если...», то в тудушку. Потмоу что если тащить всё это в релиз — не зарелизишь никогда.


Про сроки

Нетехнические коллеги иногда удивляются, почему «простая задача» занимает столько времени.

Тут я не использую метафоры, а просто раскладываю конкретно: вот сама задача, вот среднее время прохождения ревью в наших процессах (и иногда, почему это важно), вот правки по замечаниям, вот документация, вот тесты. Кстати, я часто работала по TDD (сначала тесты, потом код, потом рефакторинг) — это замедляет старт, но зато ускоряет финиш и сильно упрощает ревью! Ведь когда тесты описывают поведение, то код становится читаемым без дополнительных объяснений.

Когда раскладываешь всё это на стол — вопросов «почему так долго» обычно не остаётся.


Одна вещь, которую я усвоила

Это не упрощённая версия продукта. Это другая ответственность.

У продукта есть менеджеры, дизайнеры, поддержка, roadmap. У внутреннего инструмента — ты и двадцать человек с конкретной болью.

Если инструмент неудобный — они продолжат делать это руками. Молча. Возможно ты никогда не узнаешь.

И ещё одно, которое я усвоила через рефакторинг: внутренние сервисы растут всегда. То, что сделано «быстро под дедлайн» — вернётся с запросом на новую фичу. Это нормально. Ненормально, когда архитектура этого роста не предусматривает и каждое следующее изменение дороже предыдущего.

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