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

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

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

1. Кому принадлежит запись, когда её имеют обе стороны

Когда запись живёт в двух системах, менять её могут двое. Менеджер утром правит телефон в CRM, а ваша ночная задача записывает туда значение, прочитанное в марте. Ни одна из сторон не сломана. Обе следуют правилу, которого никто не записал.

Направление каждого поля стоит зафиксировать до того, как вы напишете клиент: какая сторона создаёт запись, какая вправе обновлять какие поля и что происходит, когда поле записывают обе стороны. Правило «последний записал, тот и прав» тоже правило. Его выбирают, а не получают по умолчанию.

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

Удаление обходят стороной чаще всего. Если менеджер архивирует карточку в CRM, ваш продукт продолжает в неё писать, а если ваш продукт удаляет строку, CRM следует за ним. Ответьте на оба вопроса по одной строке на каждый, до первого запроса.

Полезная проверка: возьмите десять полей, которые повезёт интеграция, и назовите сторону, которой каждое принадлежит. Если на одной строке стоят два имени, именно там случится первый спор. Такой список читают за две минуты, и он сразу показывает пустые места.

2. Четыре минуты недоступности: не случайность, а часть проекта

Другая сторона будет недоступна. Обычно не неделю, а четыре минуты, посреди заказа, во вторник. Это не пограничный случай, который вы обнаружите в продакшене, а обычное свойство любой системы, которой вы не управляете.

Решите, что делает ваш продукт в эти четыре минуты. Возвращает ошибку и объясняет человеку, что делать. Ставит работу в очередь и отправляет, когда другая сторона вернётся. Или держит запрос до таймаута. Каждый вариант стоит чего-то, и ни один не является отсутствием решения.

Потом решите, кто читает очередь. Непрочитанная очередь это тот же сбой, только медленнее. Назовите человека, интервал и глубину, после которой он перестаёт ждать и звонит. Если такого человека нет, очередь вам не нужна.

Проверьте это там, где это ничего не стоит: выключите другую сторону на четыре минуты и проведите через неё один настоящий заказ. Запишите, что увидел человек за клавиатурой. Посмотрите, что осталось в очереди, когда всё вернётся.

3. Безопасность повтора важнее его скорости

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

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

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

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

Проверьте это намеренно: отправьте одно и то же тело запроса дважды, с паузой между отправками, и посчитайте строки. Если их две, дорогая часть найдена рано, пока это ещё одна функция, а не чистка списка.

4. Сбой, который никто не видит, никто не исправляет

Где-то на пути запрос отклонят, токен истечёт или задача упадёт на середине. Сайт всё равно покажет успех, потому что сайт закончил свой шаг. Сбой лежит в журнале, который никто не открывает. Так он и остаётся незамеченным неделями.

Решите, кто обязан его увидеть, где именно и что с ним можно сделать: оповещение в канале, который команда и так смотрит, лучше файла на диске, а строка «не отправлено» рядом с записью лучше стектрейса.

Решите, что человек делает, когда увидел сбой. Перезапускает одну запись, не переигрывая всю ночь. Если единственный способ это разработчик и консоль, сбой будет ждать, пока о нём не скажет клиент.

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

Тест: сломайте намеренно одну вещь там, где это ничего не стоит, и посмотрите, кто узнает об этом без подсказки. Если никто не узнал, вы нашли настоящую работу. Эта работа и есть предмет следующего счёта. Её дешевле увидеть сейчас, чем через квартал.

5. Когда стороны расходятся, права одна из них

Обе системы хранят значение одного поля, и значения различаются. Цена изменилась в учётной системе, менеджер поправил телефон в CRM, а у вашего продукта лежит утреннее значение. Расхождение не сбой, а обычный день.

Источник истины отвечает за каждое поле, а не за систему целиком: учётная система владеет суммой, CRM стадией и ответственным, ваш продукт тем, что собрал на источнике. Запишите эту таблицу. Правило «кто записал последним, тот и прав» тоже таблица, только нечитаемая. Без первой таблицы вторая работает сама.

Расхождение первым показывает отчёт. Отчёт, который читает обе стороны, не зная, какая из них побеждает, покажет два числа за один день. Команда перестанет его открывать.

Проверка: измените значение с одной стороны намеренно, прогните синхронизацию и посмотрите, какое значение выживет. Если это кого-то в комнате удивило, правила ещё нет. Договоритесь о нём до того, как это заметит отчёт.

6. Что записать до первого запроса

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

Отдайте эту страницу тому, кто напишет первый запрос, и тому, кого разбудят, когда он сломается. Если какую-то строку пока нельзя ответить, это и есть находка. Открытый вопрос и есть оценка, и закрыть его сейчас дешевле, чем во втором счёте.

Услуги покрывают такое соединение на системах, которые вы уже ведёте, а избранные работы показывают те же решения рядом с результатом на работающем продукте. Если хотите пройти этот путь внимательно, начните с интеграции продукта или напишите мне со страницей, которую вы только что заполнили. Пароли и клиентские данные в сообщение не добавляйте.